diff options
author | Steve French <sfrench@us.ibm.com> | 2008-05-13 21:39:32 +0000 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-05-13 21:39:32 +0000 |
commit | 77c57ec89682c73785d12d51a6d1f873b292fa42 (patch) | |
tree | 229a4ee931747a3a04d8b6634f8bafe7cc950ffd | |
parent | 582d21e5e319d38c0485d8b9e92f6f2341f7c79b (diff) | |
download | lwn-77c57ec89682c73785d12d51a6d1f873b292fa42.tar.gz lwn-77c57ec89682c73785d12d51a6d1f873b292fa42.zip |
[CIFS] don't explicitly do a FindClose on rewind when directory search has ended
Do the following series of operations on a CIFS share:
opendir(dir)
readdir(dir)
unlink(file in dir)
rewinddir(dir)
readdir(dir)
If the readdir read all entries in the directory this will make CIFS throw an error like this:
CIFS VFS: Send error in FindClose = -9
CIFS requests "Close at end of search" of the server by setting this bit when issuing FindFirst or FindNext. Therefore when all search entries are returned, the server may return "end of search" and close the search implicitly when this bit is set by the client on the request. We check for this when a readdir is explicitly closed - but when the client notices that a directory has changed after the last operation, we attempt to close the directory before reopening by reissuing a second FindFirst. But, the directory may already been implicitly closed (due to end of search) because the first readdir finished. So we only want to issue a FindClose call in this case when we don't expect it to already be closed.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r-- | fs/cifs/readdir.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 34ec32100c72..713c25110197 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -670,8 +670,11 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, (index_to_find < first_entry_in_buffer)) { /* close and restart search */ cFYI(1, ("search backing up - close and restart search")); - cifsFile->invalidHandle = true; - CIFSFindClose(xid, pTcon, cifsFile->netfid); + if (!cifsFile->srch_inf.endOfSearch && + !cifsFile->invalidHandle) { + cifsFile->invalidHandle = true; + CIFSFindClose(xid, pTcon, cifsFile->netfid); + } kfree(cifsFile->search_resume_name); cifsFile->search_resume_name = NULL; if (cifsFile->srch_inf.ntwrk_buf_start) { |