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.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 894b1f7b299d..1e7e4c06d9e3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -467,7 +467,7 @@ reopen_error_exit:
467int cifs_close(struct inode *inode, struct file *file) 467int cifs_close(struct inode *inode, struct file *file)
468{ 468{
469 int rc = 0; 469 int rc = 0;
470 int xid; 470 int xid, timeout;
471 struct cifs_sb_info *cifs_sb; 471 struct cifs_sb_info *cifs_sb;
472 struct cifsTconInfo *pTcon; 472 struct cifsTconInfo *pTcon;
473 struct cifsFileInfo *pSMBFile = 473 struct cifsFileInfo *pSMBFile =
@@ -485,9 +485,9 @@ int cifs_close(struct inode *inode, struct file *file)
485 /* no sense reconnecting to close a file that is 485 /* no sense reconnecting to close a file that is
486 already closed */ 486 already closed */
487 if (pTcon->tidStatus != CifsNeedReconnect) { 487 if (pTcon->tidStatus != CifsNeedReconnect) {
488 int timeout = 2; 488 timeout = 2;
489 while ((atomic_read(&pSMBFile->wrtPending) != 0) 489 while ((atomic_read(&pSMBFile->wrtPending) != 0)
490 && (timeout < 1000) ) { 490 && (timeout <= 2048)) {
491 /* Give write a better chance to get to 491 /* Give write a better chance to get to
492 server ahead of the close. We do not 492 server ahead of the close. We do not
493 want to add a wait_q here as it would 493 want to add a wait_q here as it would
@@ -522,12 +522,30 @@ int cifs_close(struct inode *inode, struct file *file)
522 list_del(&pSMBFile->flist); 522 list_del(&pSMBFile->flist);
523 list_del(&pSMBFile->tlist); 523 list_del(&pSMBFile->tlist);
524 write_unlock(&GlobalSMBSeslock); 524 write_unlock(&GlobalSMBSeslock);
525 timeout = 10;
526 /* We waited above to give the SMBWrite a chance to issue
527 on the wire (so we do not get SMBWrite returning EBADF
528 if writepages is racing with close. Note that writepages
529 does not specify a file handle, so it is possible for a file
530 to be opened twice, and the application close the "wrong"
531 file handle - in these cases we delay long enough to allow
532 the SMBWrite to get on the wire before the SMB Close.
533 We allow total wait here over 45 seconds, more than
534 oplock break time, and more than enough to allow any write
535 to complete on the server, or to time out on the client */
536 while ((atomic_read(&pSMBFile->wrtPending) != 0)
537 && (timeout <= 50000)) {
538 cERROR(1, ("writes pending, delay free of handle"));
539 msleep(timeout);
540 timeout *= 8;
541 }
525 kfree(pSMBFile->search_resume_name); 542 kfree(pSMBFile->search_resume_name);
526 kfree(file->private_data); 543 kfree(file->private_data);
527 file->private_data = NULL; 544 file->private_data = NULL;
528 } else 545 } else
529 rc = -EBADF; 546 rc = -EBADF;
530 547
548 read_lock(&GlobalSMBSeslock);
531 if (list_empty(&(CIFS_I(inode)->openFileList))) { 549 if (list_empty(&(CIFS_I(inode)->openFileList))) {
532 cFYI(1, ("closing last open instance for inode %p", inode)); 550 cFYI(1, ("closing last open instance for inode %p", inode));
533 /* if the file is not open we do not know if we can cache info 551 /* if the file is not open we do not know if we can cache info
@@ -535,6 +553,7 @@ int cifs_close(struct inode *inode, struct file *file)
535 CIFS_I(inode)->clientCanCacheRead = FALSE; 553 CIFS_I(inode)->clientCanCacheRead = FALSE;
536 CIFS_I(inode)->clientCanCacheAll = FALSE; 554 CIFS_I(inode)->clientCanCacheAll = FALSE;
537 } 555 }
556 read_unlock(&GlobalSMBSeslock);
538 if ((rc == 0) && CIFS_I(inode)->write_behind_rc) 557 if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
539 rc = CIFS_I(inode)->write_behind_rc; 558 rc = CIFS_I(inode)->write_behind_rc;
540 FreeXid(xid); 559 FreeXid(xid);
@@ -767,7 +786,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
767 mutex_lock(&fid->lock_mutex); 786 mutex_lock(&fid->lock_mutex);
768 list_for_each_entry_safe(li, tmp, &fid->llist, llist) { 787 list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
769 if (pfLock->fl_start <= li->offset && 788 if (pfLock->fl_start <= li->offset &&
770 length >= li->length) { 789 (pfLock->fl_start + length) >=
790 (li->offset + li->length)) {
771 stored_rc = CIFSSMBLock(xid, pTcon, 791 stored_rc = CIFSSMBLock(xid, pTcon,
772 netfid, 792 netfid,
773 li->length, li->offset, 793 li->length, li->offset,
@@ -1022,6 +1042,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1022 } 1042 }
1023 1043
1024 read_lock(&GlobalSMBSeslock); 1044 read_lock(&GlobalSMBSeslock);
1045refind_writable:
1025 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1046 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1026 if (open_file->closePend) 1047 if (open_file->closePend)
1027 continue; 1048 continue;
@@ -1029,24 +1050,49 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1029 ((open_file->pfile->f_flags & O_RDWR) || 1050 ((open_file->pfile->f_flags & O_RDWR) ||
1030 (open_file->pfile->f_flags & O_WRONLY))) { 1051 (open_file->pfile->f_flags & O_WRONLY))) {
1031 atomic_inc(&open_file->wrtPending); 1052 atomic_inc(&open_file->wrtPending);
1053
1054 if (!open_file->invalidHandle) {
1055 /* found a good writable file */
1056 read_unlock(&GlobalSMBSeslock);
1057 return open_file;
1058 }
1059
1032 read_unlock(&GlobalSMBSeslock); 1060 read_unlock(&GlobalSMBSeslock);
1033 if ((open_file->invalidHandle) && 1061 /* Had to unlock since following call can block */
1034 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { 1062 rc = cifs_reopen_file(open_file->pfile, FALSE);
1035 rc = cifs_reopen_file(open_file->pfile, FALSE); 1063 if (!rc) {
1036 /* if it fails, try another handle - might be */ 1064 if (!open_file->closePend)
1037 /* dangerous to hold up writepages with retry */ 1065 return open_file;
1038 if (rc) { 1066 else { /* start over in case this was deleted */
1039 cFYI(1, 1067 /* since the list could be modified */
1040 ("failed on reopen file in wp"));
1041 read_lock(&GlobalSMBSeslock); 1068 read_lock(&GlobalSMBSeslock);
1042 /* can not use this handle, no write 1069 atomic_dec(&open_file->wrtPending);
1043 pending on this one after all */ 1070 goto refind_writable;
1044 atomic_dec
1045 (&open_file->wrtPending);
1046 continue;
1047 } 1071 }
1048 } 1072 }
1049 return open_file; 1073
1074 /* if it fails, try another handle if possible -
1075 (we can not do this if closePending since
1076 loop could be modified - in which case we
1077 have to start at the beginning of the list
1078 again. Note that it would be bad
1079 to hold up writepages here (rather than
1080 in caller) with continuous retries */
1081 cFYI(1, ("wp failed on reopen file"));
1082 read_lock(&GlobalSMBSeslock);
1083 /* can not use this handle, no write
1084 pending on this one after all */
1085 atomic_dec(&open_file->wrtPending);
1086
1087 if (open_file->closePend) /* list could have changed */
1088 goto refind_writable;
1089 /* else we simply continue to the next entry. Thus
1090 we do not loop on reopen errors. If we
1091 can not reopen the file, for example if we
1092 reconnected to a server with another client
1093 racing to delete or lock the file we would not
1094 make progress if we restarted before the beginning
1095 of the loop here. */
1050 } 1096 }
1051 } 1097 }
1052 read_unlock(&GlobalSMBSeslock); 1098 read_unlock(&GlobalSMBSeslock);
@@ -1709,7 +1755,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1709 struct page *page; 1755 struct page *page;
1710 struct cifs_sb_info *cifs_sb; 1756 struct cifs_sb_info *cifs_sb;
1711 struct cifsTconInfo *pTcon; 1757 struct cifsTconInfo *pTcon;
1712 int bytes_read = 0; 1758 unsigned int bytes_read = 0;
1713 unsigned int read_size, i; 1759 unsigned int read_size, i;
1714 char *smb_read_data = NULL; 1760 char *smb_read_data = NULL;
1715 struct smb_com_read_rsp *pSMBr; 1761 struct smb_com_read_rsp *pSMBr;
@@ -1803,7 +1849,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1803 1849
1804 i += bytes_read >> PAGE_CACHE_SHIFT; 1850 i += bytes_read >> PAGE_CACHE_SHIFT;
1805 cifs_stats_bytes_read(pTcon, bytes_read); 1851 cifs_stats_bytes_read(pTcon, bytes_read);
1806 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { 1852 if ((bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1807 i++; /* account for partial page */ 1853 i++; /* account for partial page */
1808 1854
1809 /* server copy of file can have smaller size 1855 /* server copy of file can have smaller size