]> err.no Git - linux-2.6/commitdiff
[CIFS] don't explicitly do a FindClose on rewind when directory search has ended
authorSteve French <sfrench@us.ibm.com>
Tue, 13 May 2008 21:39:32 +0000 (21:39 +0000)
committerSteve French <sfrench@us.ibm.com>
Tue, 13 May 2008 21:39:32 +0000 (21:39 +0000)
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>
fs/cifs/readdir.c

index 34ec32100c7242a68039533e0360985277edded8..713c2511019726167970cdc3afc899a1d133419f 100644 (file)
@@ -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) {