* changes to the tcon->tidStatus should be done while holding this lock.
  */
 GLOBAL_EXTERN rwlock_t         cifs_tcp_ses_lock;
-GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;  /* protects list inserts on 3 above */
+
+/*
+ * This lock protects the cifs_file->llist and cifs_file->flist
+ * list operations, and updates to some flags (cifs_file->invalidHandle)
+ * It will be moved to either use the tcon->stat_lock or equivalent later.
+ * If cifs_tcp_ses_lock and the lock below are both needed to be held, then
+ * the cifs_tcp_ses_lock must be grabbed first and released last.
+ */
+GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
 
 GLOBAL_EXTERN struct list_head GlobalOplock_Q;
 
 
        pTcon = cifs_sb->tcon;
        if (pSMBFile) {
                struct cifsLockInfo *li, *tmp;
-
+               write_lock(&GlobalSMBSeslock);
                pSMBFile->closePend = true;
                if (pTcon) {
                        /* no sense reconnecting to close a file that is
                           already closed */
                        if (!pTcon->need_reconnect) {
+                               write_unlock(&GlobalSMBSeslock);
                                timeout = 2;
                                while ((atomic_read(&pSMBFile->wrtPending) != 0)
                                        && (timeout <= 2048)) {
                                        timeout *= 4;
                                }
                                if (atomic_read(&pSMBFile->wrtPending))
-                                       cERROR(1,
-                                               ("close with pending writes"));
-                               rc = CIFSSMBClose(xid, pTcon,
+                                       cERROR(1, ("close with pending write"));
+                               if (!pTcon->need_reconnect &&
+                                   !pSMBFile->invalidHandle)
+                                       rc = CIFSSMBClose(xid, pTcon,
                                                  pSMBFile->netfid);
-                       }
-               }
+                       } else
+                               write_unlock(&GlobalSMBSeslock);
+               } else
+                       write_unlock(&GlobalSMBSeslock);
 
                /* Delete any outstanding lock records.
                   We'll lose them when the file is closed anyway. */
                pTcon = cifs_sb->tcon;
 
                cFYI(1, ("Freeing private data in close dir"));
+               write_lock(&GlobalSMBSeslock);
                if (!pCFileStruct->srch_inf.endOfSearch &&
                    !pCFileStruct->invalidHandle) {
                        pCFileStruct->invalidHandle = true;
+                       write_unlock(&GlobalSMBSeslock);
                        rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
                        cFYI(1, ("Closing uncompleted readdir with rc %d",
                                 rc));
                        /* not much we can do if it fails anyway, ignore rc */
                        rc = 0;
-               }
+               } else
+                       write_unlock(&GlobalSMBSeslock);
                ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
                if (ptmp) {
                        cFYI(1, ("closedir free smb buf in srch struct"));
 
                                continue;
 
                        cifs_stats_inc(&tcon->num_oplock_brks);
+                       write_lock(&GlobalSMBSeslock);
                        list_for_each(tmp2, &tcon->openFileList) {
                                netfile = list_entry(tmp2, struct cifsFileInfo,
                                                     tlist);
                                if (pSMB->Fid != netfile->netfid)
                                        continue;
 
+                               write_unlock(&GlobalSMBSeslock);
                                read_unlock(&cifs_tcp_ses_lock);
                                cFYI(1, ("file id match, oplock break"));
                                pCifsInode = CIFS_I(netfile->pInode);
 
                                return true;
                        }
+                       write_unlock(&GlobalSMBSeslock);
                        read_unlock(&cifs_tcp_ses_lock);
                        cFYI(1, ("No matching file for oplock break"));
                        return true;
 
           (index_to_find < first_entry_in_buffer)) {
                /* close and restart search */
                cFYI(1, ("search backing up - close and restart search"));
+               write_lock(&GlobalSMBSeslock);
                if (!cifsFile->srch_inf.endOfSearch &&
                    !cifsFile->invalidHandle) {
                        cifsFile->invalidHandle = true;
+                       write_unlock(&GlobalSMBSeslock);
                        CIFSFindClose(xid, pTcon, cifsFile->netfid);
-               }
+               } else
+                       write_unlock(&GlobalSMBSeslock);
                if (cifsFile->srch_inf.ntwrk_buf_start) {
                        cFYI(1, ("freeing SMB ff cache buf on search rewind"));
                        if (cifsFile->srch_inf.smallBuf)