diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 28 |
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) { |