diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2013-07-09 10:40:58 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-07-10 14:08:40 -0400 |
commit | 9cbc0b7339b0542a1d13922d2745a2636ce44853 (patch) | |
tree | af06d88f00880c95d35c584338fbdebf1112843e /fs/cifs/file.c | |
parent | 064f6047a123d61dd52bb44605c999cd8ef727d9 (diff) |
CIFS: Reconnect durable handles for SMB2
On reconnects, we need to reopen file and then obtain all byte-range
locks held by the client. SMB2 protocol provides feature to make
this process atomic by reconnecting to the same file handle
with all it's byte-range locks. This patch adds this capability
for SMB2 shares.
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steven French <steven@steven-GA-970A-DS3.(none)>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index f36f9a7893da..ba7eed2ee662 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -232,6 +232,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, | |||
232 | oparms.disposition = disposition; | 232 | oparms.disposition = disposition; |
233 | oparms.path = full_path; | 233 | oparms.path = full_path; |
234 | oparms.fid = fid; | 234 | oparms.fid = fid; |
235 | oparms.reconnect = false; | ||
235 | 236 | ||
236 | rc = server->ops->open(xid, &oparms, oplock, buf); | 237 | rc = server->ops->open(xid, &oparms, oplock, buf); |
237 | 238 | ||
@@ -594,7 +595,6 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) | |||
594 | int desired_access; | 595 | int desired_access; |
595 | int disposition = FILE_OPEN; | 596 | int disposition = FILE_OPEN; |
596 | int create_options = CREATE_NOT_DIR; | 597 | int create_options = CREATE_NOT_DIR; |
597 | struct cifs_fid fid; | ||
598 | struct cifs_open_parms oparms; | 598 | struct cifs_open_parms oparms; |
599 | 599 | ||
600 | xid = get_xid(); | 600 | xid = get_xid(); |
@@ -645,7 +645,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) | |||
645 | 645 | ||
646 | rc = cifs_posix_open(full_path, NULL, inode->i_sb, | 646 | rc = cifs_posix_open(full_path, NULL, inode->i_sb, |
647 | cifs_sb->mnt_file_mode /* ignored */, | 647 | cifs_sb->mnt_file_mode /* ignored */, |
648 | oflags, &oplock, &fid.netfid, xid); | 648 | oflags, &oplock, &cfile->fid.netfid, xid); |
649 | if (rc == 0) { | 649 | if (rc == 0) { |
650 | cifs_dbg(FYI, "posix reopen succeeded\n"); | 650 | cifs_dbg(FYI, "posix reopen succeeded\n"); |
651 | goto reopen_success; | 651 | goto reopen_success; |
@@ -662,7 +662,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) | |||
662 | create_options |= CREATE_OPEN_BACKUP_INTENT; | 662 | create_options |= CREATE_OPEN_BACKUP_INTENT; |
663 | 663 | ||
664 | if (server->ops->get_lease_key) | 664 | if (server->ops->get_lease_key) |
665 | server->ops->get_lease_key(inode, &fid); | 665 | server->ops->get_lease_key(inode, &cfile->fid); |
666 | 666 | ||
667 | oparms.tcon = tcon; | 667 | oparms.tcon = tcon; |
668 | oparms.cifs_sb = cifs_sb; | 668 | oparms.cifs_sb = cifs_sb; |
@@ -670,7 +670,8 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) | |||
670 | oparms.create_options = create_options; | 670 | oparms.create_options = create_options; |
671 | oparms.disposition = disposition; | 671 | oparms.disposition = disposition; |
672 | oparms.path = full_path; | 672 | oparms.path = full_path; |
673 | oparms.fid = &fid; | 673 | oparms.fid = &cfile->fid; |
674 | oparms.reconnect = true; | ||
674 | 675 | ||
675 | /* | 676 | /* |
676 | * 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 |
@@ -710,8 +711,9 @@ reopen_success: | |||
710 | * to the server to get the new inode info. | 711 | * to the server to get the new inode info. |
711 | */ | 712 | */ |
712 | 713 | ||
713 | server->ops->set_fid(cfile, &fid, oplock); | 714 | server->ops->set_fid(cfile, &cfile->fid, oplock); |
714 | cifs_relock_file(cfile); | 715 | if (oparms.reconnect) |
716 | cifs_relock_file(cfile); | ||
715 | 717 | ||
716 | reopen_error_exit: | 718 | reopen_error_exit: |
717 | kfree(full_path); | 719 | kfree(full_path); |
@@ -1508,6 +1510,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, | |||
1508 | if (!rc) | 1510 | if (!rc) |
1509 | goto out; | 1511 | goto out; |
1510 | 1512 | ||
1513 | |||
1511 | /* | 1514 | /* |
1512 | * Windows 7 server can delay breaking lease from read to None | 1515 | * Windows 7 server can delay breaking lease from read to None |
1513 | * if we set a byte-range lock on a file - break it explicitly | 1516 | * if we set a byte-range lock on a file - break it explicitly |