aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ead1a3bb0256..b691b893a848 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -488,12 +488,13 @@ int cifs_close(struct inode *inode, struct file *file)
488 pTcon = cifs_sb->tcon; 488 pTcon = cifs_sb->tcon;
489 if (pSMBFile) { 489 if (pSMBFile) {
490 struct cifsLockInfo *li, *tmp; 490 struct cifsLockInfo *li, *tmp;
491 491 write_lock(&GlobalSMBSeslock);
492 pSMBFile->closePend = true; 492 pSMBFile->closePend = true;
493 if (pTcon) { 493 if (pTcon) {
494 /* no sense reconnecting to close a file that is 494 /* no sense reconnecting to close a file that is
495 already closed */ 495 already closed */
496 if (pTcon->tidStatus != CifsNeedReconnect) { 496 if (!pTcon->need_reconnect) {
497 write_unlock(&GlobalSMBSeslock);
497 timeout = 2; 498 timeout = 2;
498 while ((atomic_read(&pSMBFile->wrtPending) != 0) 499 while ((atomic_read(&pSMBFile->wrtPending) != 0)
499 && (timeout <= 2048)) { 500 && (timeout <= 2048)) {
@@ -510,12 +511,15 @@ int cifs_close(struct inode *inode, struct file *file)
510 timeout *= 4; 511 timeout *= 4;
511 } 512 }
512 if (atomic_read(&pSMBFile->wrtPending)) 513 if (atomic_read(&pSMBFile->wrtPending))
513 cERROR(1, 514 cERROR(1, ("close with pending write"));
514 ("close with pending writes")); 515 if (!pTcon->need_reconnect &&
515 rc = CIFSSMBClose(xid, pTcon, 516 !pSMBFile->invalidHandle)
517 rc = CIFSSMBClose(xid, pTcon,
516 pSMBFile->netfid); 518 pSMBFile->netfid);
517 } 519 } else
518 } 520 write_unlock(&GlobalSMBSeslock);
521 } else
522 write_unlock(&GlobalSMBSeslock);
519 523
520 /* Delete any outstanding lock records. 524 /* Delete any outstanding lock records.
521 We'll lose them when the file is closed anyway. */ 525 We'll lose them when the file is closed anyway. */
@@ -587,15 +591,18 @@ int cifs_closedir(struct inode *inode, struct file *file)
587 pTcon = cifs_sb->tcon; 591 pTcon = cifs_sb->tcon;
588 592
589 cFYI(1, ("Freeing private data in close dir")); 593 cFYI(1, ("Freeing private data in close dir"));
594 write_lock(&GlobalSMBSeslock);
590 if (!pCFileStruct->srch_inf.endOfSearch && 595 if (!pCFileStruct->srch_inf.endOfSearch &&
591 !pCFileStruct->invalidHandle) { 596 !pCFileStruct->invalidHandle) {
592 pCFileStruct->invalidHandle = true; 597 pCFileStruct->invalidHandle = true;
598 write_unlock(&GlobalSMBSeslock);
593 rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); 599 rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
594 cFYI(1, ("Closing uncompleted readdir with rc %d", 600 cFYI(1, ("Closing uncompleted readdir with rc %d",
595 rc)); 601 rc));
596 /* not much we can do if it fails anyway, ignore rc */ 602 /* not much we can do if it fails anyway, ignore rc */
597 rc = 0; 603 rc = 0;
598 } 604 } else
605 write_unlock(&GlobalSMBSeslock);
599 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; 606 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
600 if (ptmp) { 607 if (ptmp) {
601 cFYI(1, ("closedir free smb buf in srch struct")); 608 cFYI(1, ("closedir free smb buf in srch struct"));
@@ -1404,7 +1411,10 @@ retry:
1404 if ((wbc->nr_to_write -= n_iov) <= 0) 1411 if ((wbc->nr_to_write -= n_iov) <= 0)
1405 done = 1; 1412 done = 1;
1406 index = next; 1413 index = next;
1407 } 1414 } else
1415 /* Need to re-find the pages we skipped */
1416 index = pvec.pages[0]->index + 1;
1417
1408 pagevec_release(&pvec); 1418 pagevec_release(&pvec);
1409 } 1419 }
1410 if (!scanned && !done) { 1420 if (!scanned && !done) {