diff options
author | Ronnie Sahlberg <lsahlber@redhat.com> | 2019-09-09 15:30:00 +1000 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2019-09-16 11:43:38 -0500 |
commit | 496902dc173dead0e5eeba1f2fd4abd9ba6f2da0 (patch) | |
tree | 196a00f93a641cb5e1cc4c9981c1e24dcfae66bb /fs/cifs/file.c | |
parent | 563317ec3083f7e126d7e30821ff8505ac338ee5 (diff) | |
download | linux-496902dc173dead0e5eeba1f2fd4abd9ba6f2da0.tar.bz2 |
cifs: add a helper to find an existing readable handle to a file
and convert smb2_query_path_info() to use it.
This will eliminate the need for a SMB2_Create when we already have an
open handle that can be used. This will also prevent a oplock break
in case the other handle holds a lease.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 6124b1d1ab05..4b95700c507c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2008,6 +2008,42 @@ cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, return -ENOENT; } +int +cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, + struct cifsFileInfo **ret_file) +{ + struct list_head *tmp; + struct cifsFileInfo *cfile; + struct cifsInodeInfo *cinode; + char *full_path; + + *ret_file = NULL; + + spin_lock(&tcon->open_file_lock); + list_for_each(tmp, &tcon->openFileList) { + cfile = list_entry(tmp, struct cifsFileInfo, + tlist); + full_path = build_path_from_dentry(cfile->dentry); + if (full_path == NULL) { + spin_unlock(&tcon->open_file_lock); + return -ENOMEM; + } + if (strcmp(full_path, name)) { + kfree(full_path); + continue; + } + + kfree(full_path); + cinode = CIFS_I(d_inode(cfile->dentry)); + spin_unlock(&tcon->open_file_lock); + *ret_file = find_readable_file(cinode, 0); + return *ret_file ? 0 : -ENOENT; + } + + spin_unlock(&tcon->open_file_lock); + return -ENOENT; +} + static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) { struct address_space *mapping = page->mapping; |