diff options
author | Jeff Layton <jlayton@redhat.com> | 2008-09-22 21:33:33 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-09-22 22:24:13 -0400 |
commit | 2846d3864738dd6e290755d0692cf377e09ba79f (patch) | |
tree | 48f32072b0e2989ebfae167dfe04d7480c3e8167 | |
parent | 232087cb734c7035c0a8947fb05d3e8092ff6c4d (diff) |
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 <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r-- | fs/cifs/file.c | 10 |
1 files changed, 9 insertions, 1 deletions
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) | |||
1065 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | 1065 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) |
1066 | { | 1066 | { |
1067 | struct cifsFileInfo *open_file; | 1067 | struct cifsFileInfo *open_file; |
1068 | bool any_available = false; | ||
1068 | int rc; | 1069 | int rc; |
1069 | 1070 | ||
1070 | /* Having a null inode here (because mapping->host was set to zero by | 1071 | /* 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) | |||
1080 | read_lock(&GlobalSMBSeslock); | 1081 | read_lock(&GlobalSMBSeslock); |
1081 | refind_writable: | 1082 | refind_writable: |
1082 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | 1083 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
1083 | if (open_file->closePend) | 1084 | if (open_file->closePend || |
1085 | (!any_available && open_file->pid != current->tgid)) | ||
1084 | continue; | 1086 | continue; |
1087 | |||
1085 | if (open_file->pfile && | 1088 | if (open_file->pfile && |
1086 | ((open_file->pfile->f_flags & O_RDWR) || | 1089 | ((open_file->pfile->f_flags & O_RDWR) || |
1087 | (open_file->pfile->f_flags & O_WRONLY))) { | 1090 | (open_file->pfile->f_flags & O_WRONLY))) { |
@@ -1131,6 +1134,11 @@ refind_writable: | |||
1131 | of the loop here. */ | 1134 | of the loop here. */ |
1132 | } | 1135 | } |
1133 | } | 1136 | } |
1137 | /* couldn't find useable FH with same pid, try any available */ | ||
1138 | if (!any_available) { | ||
1139 | any_available = true; | ||
1140 | goto refind_writable; | ||
1141 | } | ||
1134 | read_unlock(&GlobalSMBSeslock); | 1142 | read_unlock(&GlobalSMBSeslock); |
1135 | return NULL; | 1143 | return NULL; |
1136 | } | 1144 | } |