From: Jeff Layton Date: Tue, 23 Sep 2008 01:33:33 +0000 (-0400) Subject: cifs: have find_writeable_file prefer filehandles opened by same task X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=2846d3864738dd6e290755d0692cf377e09ba79f;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git cifs: have find_writeable_file prefer filehandles opened by same task When the CIFS client goes to write out pages, it needs to pick a filehandle to write to. find_writeable_file however just picks the first filehandle that it finds. This can cause problems when a lock is issued against a particular filehandle and we pick a different filehandle to write to. This patch tries to avert this situation by having find_writable_file prefer filehandles that have a pid that matches the current task. This seems to fix lock test 11 from the connectathon test suite when run against a windows server. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cbefe1f1f9fe..d39e852a28a9 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1065,6 +1065,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode) struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) { struct cifsFileInfo *open_file; + bool any_available = false; int rc; /* Having a null inode here (because mapping->host was set to zero by @@ -1080,8 +1081,10 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) read_lock(&GlobalSMBSeslock); refind_writable: list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { - if (open_file->closePend) + if (open_file->closePend || + (!any_available && open_file->pid != current->tgid)) continue; + if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) || (open_file->pfile->f_flags & O_WRONLY))) { @@ -1131,6 +1134,11 @@ refind_writable: of the loop here. */ } } + /* couldn't find useable FH with same pid, try any available */ + if (!any_available) { + any_available = true; + goto refind_writable; + } read_unlock(&GlobalSMBSeslock); return NULL; }