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.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 48b29d24c9f4..7e36ae34e947 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -183,6 +183,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
183 int create_options = CREATE_NOT_DIR; 183 int create_options = CREATE_NOT_DIR;
184 FILE_ALL_INFO *buf; 184 FILE_ALL_INFO *buf;
185 struct TCP_Server_Info *server = tcon->ses->server; 185 struct TCP_Server_Info *server = tcon->ses->server;
186 struct cifs_open_parms oparms;
186 187
187 if (!server->ops->open) 188 if (!server->ops->open)
188 return -ENOSYS; 189 return -ENOSYS;
@@ -224,9 +225,16 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
224 if (backup_cred(cifs_sb)) 225 if (backup_cred(cifs_sb))
225 create_options |= CREATE_OPEN_BACKUP_INTENT; 226 create_options |= CREATE_OPEN_BACKUP_INTENT;
226 227
227 rc = server->ops->open(xid, tcon, full_path, disposition, 228 oparms.tcon = tcon;
228 desired_access, create_options, fid, oplock, buf, 229 oparms.cifs_sb = cifs_sb;
229 cifs_sb); 230 oparms.desired_access = desired_access;
231 oparms.create_options = create_options;
232 oparms.disposition = disposition;
233 oparms.path = full_path;
234 oparms.fid = fid;
235 oparms.reconnect = false;
236
237 rc = server->ops->open(xid, &oparms, oplock, buf);
230 238
231 if (rc) 239 if (rc)
232 goto out; 240 goto out;
@@ -553,11 +561,10 @@ cifs_relock_file(struct cifsFileInfo *cfile)
553 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 561 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
554 int rc = 0; 562 int rc = 0;
555 563
556 /* we are going to update can_cache_brlcks here - need a write access */ 564 down_read(&cinode->lock_sem);
557 down_write(&cinode->lock_sem);
558 if (cinode->can_cache_brlcks) { 565 if (cinode->can_cache_brlcks) {
559 /* can cache locks - no need to push them */ 566 /* can cache locks - no need to relock */
560 up_write(&cinode->lock_sem); 567 up_read(&cinode->lock_sem);
561 return rc; 568 return rc;
562 } 569 }
563 570
@@ -568,7 +575,7 @@ cifs_relock_file(struct cifsFileInfo *cfile)
568 else 575 else
569 rc = tcon->ses->server->ops->push_mand_locks(cfile); 576 rc = tcon->ses->server->ops->push_mand_locks(cfile);
570 577
571 up_write(&cinode->lock_sem); 578 up_read(&cinode->lock_sem);
572 return rc; 579 return rc;
573} 580}
574 581
@@ -587,7 +594,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
587 int desired_access; 594 int desired_access;
588 int disposition = FILE_OPEN; 595 int disposition = FILE_OPEN;
589 int create_options = CREATE_NOT_DIR; 596 int create_options = CREATE_NOT_DIR;
590 struct cifs_fid fid; 597 struct cifs_open_parms oparms;
591 598
592 xid = get_xid(); 599 xid = get_xid();
593 mutex_lock(&cfile->fh_mutex); 600 mutex_lock(&cfile->fh_mutex);
@@ -637,9 +644,10 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
637 644
638 rc = cifs_posix_open(full_path, NULL, inode->i_sb, 645 rc = cifs_posix_open(full_path, NULL, inode->i_sb,
639 cifs_sb->mnt_file_mode /* ignored */, 646 cifs_sb->mnt_file_mode /* ignored */,
640 oflags, &oplock, &fid.netfid, xid); 647 oflags, &oplock, &cfile->fid.netfid, xid);
641 if (rc == 0) { 648 if (rc == 0) {
642 cifs_dbg(FYI, "posix reopen succeeded\n"); 649 cifs_dbg(FYI, "posix reopen succeeded\n");
650 oparms.reconnect = true;
643 goto reopen_success; 651 goto reopen_success;
644 } 652 }
645 /* 653 /*
@@ -654,7 +662,16 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
654 create_options |= CREATE_OPEN_BACKUP_INTENT; 662 create_options |= CREATE_OPEN_BACKUP_INTENT;
655 663
656 if (server->ops->get_lease_key) 664 if (server->ops->get_lease_key)
657 server->ops->get_lease_key(inode, &fid); 665 server->ops->get_lease_key(inode, &cfile->fid);
666
667 oparms.tcon = tcon;
668 oparms.cifs_sb = cifs_sb;
669 oparms.desired_access = desired_access;
670 oparms.create_options = create_options;
671 oparms.disposition = disposition;
672 oparms.path = full_path;
673 oparms.fid = &cfile->fid;
674 oparms.reconnect = true;
658 675
659 /* 676 /*
660 * Can not refresh inode by passing in file_info buf to be returned by 677 * Can not refresh inode by passing in file_info buf to be returned by
@@ -663,9 +680,14 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
663 * version of file size can be stale. If we knew for sure that inode was 680 * version of file size can be stale. If we knew for sure that inode was
664 * not dirty locally we could do this. 681 * not dirty locally we could do this.
665 */ 682 */
666 rc = server->ops->open(xid, tcon, full_path, disposition, 683 rc = server->ops->open(xid, &oparms, &oplock, NULL);
667 desired_access, create_options, &fid, &oplock, 684 if (rc == -ENOENT && oparms.reconnect == false) {
668 NULL, cifs_sb); 685 /* durable handle timeout is expired - open the file again */
686 rc = server->ops->open(xid, &oparms, &oplock, NULL);
687 /* indicate that we need to relock the file */
688 oparms.reconnect = true;
689 }
690
669 if (rc) { 691 if (rc) {
670 mutex_unlock(&cfile->fh_mutex); 692 mutex_unlock(&cfile->fh_mutex);
671 cifs_dbg(FYI, "cifs_reopen returned 0x%x\n", rc); 693 cifs_dbg(FYI, "cifs_reopen returned 0x%x\n", rc);
@@ -696,8 +718,9 @@ reopen_success:
696 * to the server to get the new inode info. 718 * to the server to get the new inode info.
697 */ 719 */
698 720
699 server->ops->set_fid(cfile, &fid, oplock); 721 server->ops->set_fid(cfile, &cfile->fid, oplock);
700 cifs_relock_file(cfile); 722 if (oparms.reconnect)
723 cifs_relock_file(cfile);
701 724
702reopen_error_exit: 725reopen_error_exit:
703 kfree(full_path); 726 kfree(full_path);
@@ -999,7 +1022,7 @@ try_again:
999 rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next); 1022 rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next);
1000 if (!rc) 1023 if (!rc)
1001 goto try_again; 1024 goto try_again;
1002 locks_delete_block(flock); 1025 posix_unblock_lock(flock);
1003 } 1026 }
1004 return rc; 1027 return rc;
1005} 1028}
@@ -1092,6 +1115,7 @@ struct lock_to_push {
1092static int 1115static int
1093cifs_push_posix_locks(struct cifsFileInfo *cfile) 1116cifs_push_posix_locks(struct cifsFileInfo *cfile)
1094{ 1117{
1118 struct inode *inode = cfile->dentry->d_inode;
1095 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1119 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1096 struct file_lock *flock, **before; 1120 struct file_lock *flock, **before;
1097 unsigned int count = 0, i = 0; 1121 unsigned int count = 0, i = 0;
@@ -1102,12 +1126,12 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1102 1126
1103 xid = get_xid(); 1127 xid = get_xid();
1104 1128
1105 lock_flocks(); 1129 spin_lock(&inode->i_lock);
1106 cifs_for_each_lock(cfile->dentry->d_inode, before) { 1130 cifs_for_each_lock(inode, before) {
1107 if ((*before)->fl_flags & FL_POSIX) 1131 if ((*before)->fl_flags & FL_POSIX)
1108 count++; 1132 count++;
1109 } 1133 }
1110 unlock_flocks(); 1134 spin_unlock(&inode->i_lock);
1111 1135
1112 INIT_LIST_HEAD(&locks_to_send); 1136 INIT_LIST_HEAD(&locks_to_send);
1113 1137
@@ -1126,8 +1150,8 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1126 } 1150 }
1127 1151
1128 el = locks_to_send.next; 1152 el = locks_to_send.next;
1129 lock_flocks(); 1153 spin_lock(&inode->i_lock);
1130 cifs_for_each_lock(cfile->dentry->d_inode, before) { 1154 cifs_for_each_lock(inode, before) {
1131 flock = *before; 1155 flock = *before;
1132 if ((flock->fl_flags & FL_POSIX) == 0) 1156 if ((flock->fl_flags & FL_POSIX) == 0)
1133 continue; 1157 continue;
@@ -1152,7 +1176,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1152 lck->offset = flock->fl_start; 1176 lck->offset = flock->fl_start;
1153 el = el->next; 1177 el = el->next;
1154 } 1178 }
1155 unlock_flocks(); 1179 spin_unlock(&inode->i_lock);
1156 1180
1157 list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { 1181 list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
1158 int stored_rc; 1182 int stored_rc;
@@ -3546,11 +3570,12 @@ static int cifs_release_page(struct page *page, gfp_t gfp)
3546 return cifs_fscache_release_page(page, gfp); 3570 return cifs_fscache_release_page(page, gfp);
3547} 3571}
3548 3572
3549static void cifs_invalidate_page(struct page *page, unsigned long offset) 3573static void cifs_invalidate_page(struct page *page, unsigned int offset,
3574 unsigned int length)
3550{ 3575{
3551 struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host); 3576 struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host);
3552 3577
3553 if (offset == 0) 3578 if (offset == 0 && length == PAGE_CACHE_SIZE)
3554 cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); 3579 cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
3555} 3580}
3556 3581