* [PATCH 0/8] SMB2 durable handles support
@ 2013-07-10 9:59 Pavel Shilovsky
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
0 siblings, 1 reply; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
This patchset implements SMB2 procotol feature -- durable handles. It allows to restore all file handle information after reconnect events. In particular, there is no need to reobtain byte-range locks.
While adding the feature, the patchset simplifies open codepath by introducing new cifs_open_parms structure.
Pavel Shilovsky (8):
CIFS: Fix lease context buffer parsing
CIFS: Respect create_options in smb2_open_file
CIFS: Simplify SMB2_open code path
CIFS: Simplify SMB2 create context handling
CIFS: Request durable open for SMB2 opens
CIFS: Introduce cifs_open_parms struct
CIFS: Make SMB2_open use cifs_open_parms struct
CIFS: Reconnect durable handles for SMB2
fs/cifs/cifsglob.h | 17 +++-
fs/cifs/dir.c | 14 +++-
fs/cifs/file.c | 39 ++++++---
fs/cifs/smb1ops.c | 29 ++++---
fs/cifs/smb2file.c | 24 +++---
fs/cifs/smb2inode.c | 57 ++++++++------
fs/cifs/smb2ops.c | 54 ++++++++-----
fs/cifs/smb2pdu.c | 219 +++++++++++++++++++++++++++++++++++++--------------
fs/cifs/smb2pdu.h | 14 +++-
fs/cifs/smb2proto.h | 16 ++--
10 files changed, 325 insertions(+), 158 deletions(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/8] CIFS: Fix lease context buffer parsing
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2013-07-10 9:59 ` Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 2/8] CIFS: Respect create_options in smb2_open_file Pavel Shilovsky
` (7 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
to prevent missing RqLs context if it's not the first one.
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/smb2pdu.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 2b312e4..19fafeb 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -853,23 +853,24 @@ parse_lease_state(struct smb2_create_rsp *rsp)
char *data_offset;
struct create_lease *lc;
bool found = false;
+ unsigned int next = 0;
+ char *name;
- data_offset = (char *)rsp;
- data_offset += 4 + le32_to_cpu(rsp->CreateContextsOffset);
+ data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset);
lc = (struct create_lease *)data_offset;
do {
- char *name = le16_to_cpu(lc->ccontext.NameOffset) + (char *)lc;
+ lc = (struct create_lease *)((char *)lc + next);
+ name = le16_to_cpu(lc->ccontext.NameOffset) + (char *)lc;
if (le16_to_cpu(lc->ccontext.NameLength) != 4 ||
strncmp(name, "RqLs", 4)) {
- lc = (struct create_lease *)((char *)lc
- + le32_to_cpu(lc->ccontext.Next));
+ next = le32_to_cpu(lc->ccontext.Next);
continue;
}
if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
return SMB2_OPLOCK_LEVEL_NOCHANGE;
found = true;
break;
- } while (le32_to_cpu(lc->ccontext.Next) != 0);
+ } while (next != 0);
if (!found)
return 0;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/8] CIFS: Respect create_options in smb2_open_file
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-10 9:59 ` [PATCH 1/8] CIFS: Fix lease context buffer parsing Pavel Shilovsky
@ 2013-07-10 9:59 ` Pavel Shilovsky
[not found] ` <1373450401-4135-3-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-10 9:59 ` [PATCH 3/8] CIFS: Simplify SMB2_open code path Pavel Shilovsky
` (6 subsequent siblings)
8 siblings, 1 reply; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
and eliminated unused file_attribute parms of SMB2_open.
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/smb2file.c | 2 +-
fs/cifs/smb2inode.c | 25 ++++++++++++-------------
fs/cifs/smb2ops.c | 6 +++---
fs/cifs/smb2pdu.c | 10 +++++++---
fs/cifs/smb2proto.h | 4 ++--
5 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 5da1b55..46a4299 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -88,7 +88,7 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
rc = SMB2_open(xid, tcon, smb2_path, &fid->persistent_fid,
&fid->volatile_fid, desired_access, disposition,
- 0, 0, smb2_oplock, smb2_data);
+ create_options, smb2_oplock, smb2_data);
if (rc)
goto out;
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index fff6dfb..f50eefd 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -41,8 +41,7 @@ static int
smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path,
__u32 desired_access, __u32 create_disposition,
- __u32 file_attributes, __u32 create_options,
- void *data, int command)
+ __u32 create_options, void *data, int command)
{
int rc, tmprc = 0;
u64 persistent_fid, volatile_fid;
@@ -54,8 +53,8 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
return -ENOMEM;
rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
- desired_access, create_disposition, file_attributes,
- create_options, &oplock, NULL);
+ desired_access, create_disposition, create_options,
+ &oplock, NULL);
if (rc) {
kfree(utf16_path);
return rc;
@@ -129,8 +128,8 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
return -ENOMEM;
rc = smb2_open_op_close(xid, tcon, cifs_sb, full_path,
- FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0,
- smb2_data, SMB2_OP_QUERY_INFO);
+ FILE_READ_ATTRIBUTES, FILE_OPEN, 0, smb2_data,
+ SMB2_OP_QUERY_INFO);
if (rc)
goto out;
@@ -145,7 +144,7 @@ smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
struct cifs_sb_info *cifs_sb)
{
return smb2_open_op_close(xid, tcon, cifs_sb, name,
- FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0,
+ FILE_WRITE_ATTRIBUTES, FILE_CREATE,
CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR);
}
@@ -164,7 +163,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
data.Attributes = cpu_to_le32(dosattrs);
tmprc = smb2_open_op_close(xid, tcon, cifs_sb, name,
- FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0,
+ FILE_WRITE_ATTRIBUTES, FILE_CREATE,
CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO);
if (tmprc == 0)
cifs_i->cifsAttrs = dosattrs;
@@ -175,7 +174,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
struct cifs_sb_info *cifs_sb)
{
return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
- 0, CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
+ CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
NULL, SMB2_OP_DELETE);
}
@@ -184,7 +183,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
struct cifs_sb_info *cifs_sb)
{
return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
- 0, CREATE_DELETE_ON_CLOSE, NULL,
+ CREATE_DELETE_ON_CLOSE, NULL,
SMB2_OP_DELETE);
}
@@ -203,7 +202,7 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
}
rc = smb2_open_op_close(xid, tcon, cifs_sb, from_name, access,
- FILE_OPEN, 0, 0, smb2_to_name, command);
+ FILE_OPEN, 0, smb2_to_name, command);
smb2_rename_path:
kfree(smb2_to_name);
return rc;
@@ -234,7 +233,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
{
__le64 eof = cpu_to_le64(size);
return smb2_open_op_close(xid, tcon, cifs_sb, full_path,
- FILE_WRITE_DATA, FILE_OPEN, 0, 0, &eof,
+ FILE_WRITE_DATA, FILE_OPEN, 0, &eof,
SMB2_OP_SET_EOF);
}
@@ -250,7 +249,7 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
if (IS_ERR(tlink))
return PTR_ERR(tlink);
rc = smb2_open_op_close(xid, tlink_tcon(tlink), cifs_sb, full_path,
- FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, 0, buf,
+ FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
SMB2_OP_SET_INFO);
cifs_put_tlink(tlink);
return rc;
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 92aa87c..85b15e0 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -222,7 +222,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
return -ENOMEM;
rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
- FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL);
+ FILE_READ_ATTRIBUTES, FILE_OPEN, 0, &oplock, NULL);
if (rc) {
kfree(utf16_path);
return rc;
@@ -450,7 +450,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
return -ENOMEM;
rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
- FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_OPEN, 0, 0,
+ FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_OPEN, 0,
&oplock, NULL);
kfree(utf16_path);
if (rc) {
@@ -533,7 +533,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
rc = SMB2_open(xid, tcon, &srch_path, &persistent_fid, &volatile_fid,
- FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL);
+ FILE_READ_ATTRIBUTES, FILE_OPEN, 0, &oplock, NULL);
if (rc)
return rc;
buf->f_type = SMB2_MAGIC_NUMBER;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 19fafeb..4c046a5 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -881,8 +881,8 @@ parse_lease_state(struct smb2_create_rsp *rsp)
int
SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
u64 *persistent_fid, u64 *volatile_fid, __u32 desired_access,
- __u32 create_disposition, __u32 file_attributes, __u32 create_options,
- __u8 *oplock, struct smb2_file_all_info *buf)
+ __u32 create_disposition, __u32 create_options, __u8 *oplock,
+ struct smb2_file_all_info *buf)
{
struct smb2_create_req *req;
struct smb2_create_rsp *rsp;
@@ -895,6 +895,7 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
int copy_size;
int rc = 0;
int num_iovecs = 2;
+ __u32 file_attributes = 0;
cifs_dbg(FYI, "create/open\n");
@@ -907,13 +908,16 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
if (rc)
return rc;
+ if (create_options & CREATE_OPTION_READONLY)
+ file_attributes |= ATTR_READONLY;
+
req->ImpersonationLevel = IL_IMPERSONATION;
req->DesiredAccess = cpu_to_le32(desired_access);
/* File attributes ignored on open (used in create though) */
req->FileAttributes = cpu_to_le32(file_attributes);
req->ShareAccess = FILE_SHARE_ALL_LE;
req->CreateDisposition = cpu_to_le32(create_disposition);
- req->CreateOptions = cpu_to_le32(create_options);
+ req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req)
- 8 /* pad */ - 4 /* do not count rfc1001 len field */);
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index d4e1eb8..d71a3e2 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -109,8 +109,8 @@ extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
extern int SMB2_open(const unsigned int xid, struct cifs_tcon *tcon,
__le16 *path, u64 *persistent_fid, u64 *volatile_fid,
__u32 desired_access, __u32 create_disposition,
- __u32 file_attributes, __u32 create_options,
- __u8 *oplock, struct smb2_file_all_info *buf);
+ __u32 create_options, __u8 *oplock,
+ struct smb2_file_all_info *buf);
extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, u32 opcode,
bool is_fsctl, char *in_data, u32 indatalen,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/8] CIFS: Simplify SMB2_open code path
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-10 9:59 ` [PATCH 1/8] CIFS: Fix lease context buffer parsing Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 2/8] CIFS: Respect create_options in smb2_open_file Pavel Shilovsky
@ 2013-07-10 9:59 ` Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 4/8] CIFS: Simplify SMB2 create context handling Pavel Shilovsky
` (5 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
by passing a filename to a separate iovec regardless of its length.
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/smb2pdu.c | 59 ++++++++++++++++++++++-------------------------------
fs/cifs/smb2pdu.h | 2 +-
2 files changed, 25 insertions(+), 36 deletions(-)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 4c046a5..9a35dcd 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -894,7 +894,7 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
__le16 *copy_path = NULL;
int copy_size;
int rc = 0;
- int num_iovecs = 2;
+ unsigned int num_iovecs = 2;
__u32 file_attributes = 0;
cifs_dbg(FYI, "create/open\n");
@@ -919,47 +919,36 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
req->CreateDisposition = cpu_to_le32(create_disposition);
req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
- req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req)
- - 8 /* pad */ - 4 /* do not count rfc1001 len field */);
+ /* do not count rfc1001 len field */
+ req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) - 4);
iov[0].iov_base = (char *)req;
/* 4 for rfc1002 length field */
iov[0].iov_len = get_rfc1002_length(req) + 4;
/* MUST set path len (NameLength) to 0 opening root of share */
- if (uni_path_len >= 4) {
- req->NameLength = cpu_to_le16(uni_path_len - 2);
- /* -1 since last byte is buf[0] which is sent below (path) */
- iov[0].iov_len--;
- if (uni_path_len % 8 != 0) {
- copy_size = uni_path_len / 8 * 8;
- if (copy_size < uni_path_len)
- copy_size += 8;
-
- copy_path = kzalloc(copy_size, GFP_KERNEL);
- if (!copy_path)
- return -ENOMEM;
- memcpy((char *)copy_path, (const char *)path,
- uni_path_len);
- uni_path_len = copy_size;
- path = copy_path;
- }
-
- iov[1].iov_len = uni_path_len;
- iov[1].iov_base = path;
- /*
- * -1 since last byte is buf[0] which was counted in
- * smb2_buf_len.
- */
- inc_rfc1001_len(req, uni_path_len - 1);
- } else {
- iov[0].iov_len += 7;
- req->hdr.smb2_buf_length = cpu_to_be32(be32_to_cpu(
- req->hdr.smb2_buf_length) + 8 - 1);
- num_iovecs = 1;
- req->NameLength = 0;
+ req->NameLength = cpu_to_le16(uni_path_len - 2);
+ /* -1 since last byte is buf[0] which is sent below (path) */
+ iov[0].iov_len--;
+ if (uni_path_len % 8 != 0) {
+ copy_size = uni_path_len / 8 * 8;
+ if (copy_size < uni_path_len)
+ copy_size += 8;
+
+ copy_path = kzalloc(copy_size, GFP_KERNEL);
+ if (!copy_path)
+ return -ENOMEM;
+ memcpy((char *)copy_path, (const char *)path,
+ uni_path_len);
+ uni_path_len = copy_size;
+ path = copy_path;
}
+ iov[1].iov_len = uni_path_len;
+ iov[1].iov_base = path;
+ /* -1 since last byte is buf[0] which was counted in smb2_buf_len */
+ inc_rfc1001_len(req, uni_path_len - 1);
+
if (!server->oplocks)
*oplock = SMB2_OPLOCK_LEVEL_NONE;
@@ -976,7 +965,7 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
iov[num_iovecs].iov_len = sizeof(struct create_lease);
req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
req->CreateContextsOffset = cpu_to_le32(
- sizeof(struct smb2_create_req) - 4 - 8 +
+ sizeof(struct smb2_create_req) - 4 +
iov[num_iovecs-1].iov_len);
req->CreateContextsLength = cpu_to_le32(
sizeof(struct create_lease));
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index f31043b..8b1025f 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -428,7 +428,7 @@ struct smb2_create_req {
__le16 NameLength;
__le32 CreateContextsOffset;
__le32 CreateContextsLength;
- __u8 Buffer[8];
+ __u8 Buffer[0];
} __packed;
struct smb2_create_rsp {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/8] CIFS: Simplify SMB2 create context handling
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (2 preceding siblings ...)
2013-07-10 9:59 ` [PATCH 3/8] CIFS: Simplify SMB2_open code path Pavel Shilovsky
@ 2013-07-10 9:59 ` Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 5/8] CIFS: Request durable open for SMB2 opens Pavel Shilovsky
` (4 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
to make it easier to add other create context further.
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/smb2pdu.c | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 9a35dcd..e65ccdb 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -878,6 +878,29 @@ parse_lease_state(struct smb2_create_rsp *rsp)
return smb2_map_lease_to_oplock(lc->lcontext.LeaseState);
}
+static int
+add_lease_context(struct kvec *iov, unsigned int *num_iovec, __u8 *oplock)
+{
+ struct smb2_create_req *req = iov[0].iov_base;
+ unsigned int num = *num_iovec;
+
+ iov[num].iov_base = create_lease_buf(oplock+1, *oplock);
+ if (iov[num].iov_base == NULL)
+ return -ENOMEM;
+ iov[num].iov_len = sizeof(struct create_lease);
+ req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
+ if (!req->CreateContextsOffset)
+ req->CreateContextsOffset = cpu_to_le32(
+ sizeof(struct smb2_create_req) - 4 +
+ iov[num - 1].iov_len);
+ req->CreateContextsLength = cpu_to_le32(
+ le32_to_cpu(req->CreateContextsLength) +
+ sizeof(struct create_lease));
+ inc_rfc1001_len(&req->hdr, sizeof(struct create_lease));
+ *num_iovec = num + 1;
+ return 0;
+}
+
int
SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
u64 *persistent_fid, u64 *volatile_fid, __u32 desired_access,
@@ -956,21 +979,12 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
*oplock == SMB2_OPLOCK_LEVEL_NONE)
req->RequestedOplockLevel = *oplock;
else {
- iov[num_iovecs].iov_base = create_lease_buf(oplock+1, *oplock);
- if (iov[num_iovecs].iov_base == NULL) {
+ rc = add_lease_context(iov, &num_iovecs, oplock);
+ if (rc) {
cifs_small_buf_release(req);
kfree(copy_path);
- return -ENOMEM;
+ return rc;
}
- iov[num_iovecs].iov_len = sizeof(struct create_lease);
- req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
- req->CreateContextsOffset = cpu_to_le32(
- sizeof(struct smb2_create_req) - 4 +
- iov[num_iovecs-1].iov_len);
- req->CreateContextsLength = cpu_to_le32(
- sizeof(struct create_lease));
- inc_rfc1001_len(&req->hdr, sizeof(struct create_lease));
- num_iovecs++;
}
rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/8] CIFS: Request durable open for SMB2 opens
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (3 preceding siblings ...)
2013-07-10 9:59 ` [PATCH 4/8] CIFS: Simplify SMB2 create context handling Pavel Shilovsky
@ 2013-07-10 9:59 ` Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 6/8] CIFS: Introduce cifs_open_parms struct Pavel Shilovsky
` (3 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
by passing durable context together with a handle caching lease or
batch oplock.
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/smb2file.c | 2 +-
fs/cifs/smb2pdu.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++-
fs/cifs/smb2pdu.h | 6 +++++
3 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 46a4299..150a9b1 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -81,7 +81,7 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
}
desired_access |= FILE_READ_ATTRIBUTES;
- *smb2_oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
+ *smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE);
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index e65ccdb..140a613 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -847,6 +847,28 @@ create_lease_buf(u8 *lease_key, u8 oplock)
return buf;
}
+static struct create_durable *
+create_durable_buf(void)
+{
+ struct create_durable *buf;
+
+ buf = kzalloc(sizeof(struct create_durable), GFP_KERNEL);
+ if (!buf)
+ return NULL;
+
+ buf->ccontext.DataOffset = cpu_to_le16(offsetof
+ (struct create_durable, Reserved));
+ buf->ccontext.DataLength = cpu_to_le32(16);
+ buf->ccontext.NameOffset = cpu_to_le16(offsetof
+ (struct create_durable, Name));
+ buf->ccontext.NameLength = cpu_to_le16(4);
+ buf->Name[0] = 'D';
+ buf->Name[1] = 'H';
+ buf->Name[2] = 'n';
+ buf->Name[3] = 'Q';
+ return buf;
+}
+
static __u8
parse_lease_state(struct smb2_create_rsp *rsp)
{
@@ -901,6 +923,28 @@ add_lease_context(struct kvec *iov, unsigned int *num_iovec, __u8 *oplock)
return 0;
}
+static int
+add_durable_context(struct kvec *iov, unsigned int *num_iovec)
+{
+ struct smb2_create_req *req = iov[0].iov_base;
+ unsigned int num = *num_iovec;
+
+ iov[num].iov_base = create_durable_buf();
+ if (iov[num].iov_base == NULL)
+ return -ENOMEM;
+ iov[num].iov_len = sizeof(struct create_durable);
+ if (!req->CreateContextsOffset)
+ req->CreateContextsOffset =
+ cpu_to_le32(sizeof(struct smb2_create_req) - 4 +
+ iov[1].iov_len);
+ req->CreateContextsLength =
+ cpu_to_le32(le32_to_cpu(req->CreateContextsLength) +
+ sizeof(struct create_durable));
+ inc_rfc1001_len(&req->hdr, sizeof(struct create_durable));
+ *num_iovec = num + 1;
+ return 0;
+}
+
int
SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
u64 *persistent_fid, u64 *volatile_fid, __u32 desired_access,
@@ -911,7 +955,7 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
struct smb2_create_rsp *rsp;
struct TCP_Server_Info *server;
struct cifs_ses *ses = tcon->ses;
- struct kvec iov[3];
+ struct kvec iov[4];
int resp_buftype;
int uni_path_len;
__le16 *copy_path = NULL;
@@ -987,6 +1031,22 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
}
}
+ if (*oplock == SMB2_OPLOCK_LEVEL_BATCH) {
+ /* need to set Next field of lease context if we request it */
+ if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) {
+ struct create_context *ccontext =
+ (struct create_context *)iov[num_iovecs-1].iov_base;
+ ccontext->Next = sizeof(struct create_lease);
+ }
+ rc = add_durable_context(iov, &num_iovecs);
+ if (rc) {
+ cifs_small_buf_release(req);
+ kfree(copy_path);
+ kfree(iov[num_iovecs-1].iov_base);
+ return rc;
+ }
+ }
+
rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
rsp = (struct smb2_create_rsp *)iov[0].iov_base;
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 8b1025f..3e30f0a 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -485,6 +485,12 @@ struct create_lease {
struct lease_context lcontext;
} __packed;
+struct create_durable {
+ struct create_context ccontext;
+ __u8 Name[8];
+ __u8 Reserved[16];
+} __packed;
+
/* this goes in the ioctl buffer when doing a copychunk request */
struct copychunk_ioctl {
char SourceKey[24];
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 6/8] CIFS: Introduce cifs_open_parms struct
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (4 preceding siblings ...)
2013-07-10 9:59 ` [PATCH 5/8] CIFS: Request durable open for SMB2 opens Pavel Shilovsky
@ 2013-07-10 9:59 ` Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 7/8] CIFS: Make SMB2_open use " Pavel Shilovsky
` (2 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
and pass it to the open() call.
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/cifsglob.h | 16 +++++++++++++---
fs/cifs/dir.c | 13 ++++++++++---
fs/cifs/file.c | 26 ++++++++++++++++++++------
fs/cifs/smb1ops.c | 29 ++++++++++++++++-------------
fs/cifs/smb2file.c | 22 +++++++++++-----------
fs/cifs/smb2proto.h | 8 +++-----
6 files changed, 73 insertions(+), 41 deletions(-)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 913e3df..107e657 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -192,6 +192,7 @@ struct cifs_writedata;
struct cifs_io_parms;
struct cifs_search_info;
struct cifsInodeInfo;
+struct cifs_open_parms;
struct smb_version_operations {
int (*send_cancel)(struct TCP_Server_Info *, void *,
@@ -305,9 +306,8 @@ struct smb_version_operations {
const char *, const char *,
struct cifs_sb_info *);
/* open a file for non-posix mounts */
- int (*open)(const unsigned int, struct cifs_tcon *, const char *, int,
- int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *,
- struct cifs_sb_info *);
+ int (*open)(const unsigned int, struct cifs_open_parms *,
+ __u32 *, FILE_ALL_INFO *);
/* set fid protocol-specific info */
void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32);
/* close a file */
@@ -907,6 +907,16 @@ struct cifs_search_info {
bool smallBuf:1; /* so we know which buf_release function to call */
};
+struct cifs_open_parms {
+ struct cifs_tcon *tcon;
+ struct cifs_sb_info *cifs_sb;
+ int disposition;
+ int desired_access;
+ int create_options;
+ const char *path;
+ struct cifs_fid *fid;
+};
+
struct cifs_fid {
__u16 netfid;
#ifdef CONFIG_CIFS_SMB2
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 5699b50..66435c9 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -204,6 +204,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
struct inode *newinode = NULL;
int disposition;
struct TCP_Server_Info *server = tcon->ses->server;
+ struct cifs_open_parms oparms;
*oplock = 0;
if (tcon->ses->server->oplocks)
@@ -319,9 +320,15 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
if (backup_cred(cifs_sb))
create_options |= CREATE_OPEN_BACKUP_INTENT;
- rc = server->ops->open(xid, tcon, full_path, disposition,
- desired_access, create_options, fid, oplock,
- buf, cifs_sb);
+ oparms.tcon = tcon;
+ oparms.cifs_sb = cifs_sb;
+ oparms.desired_access = desired_access;
+ oparms.create_options = create_options;
+ oparms.disposition = disposition;
+ oparms.path = full_path;
+ oparms.fid = fid;
+
+ rc = server->ops->open(xid, &oparms, oplock, buf);
if (rc) {
cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc);
goto out;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 48b29d2..12a9754 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,
int create_options = CREATE_NOT_DIR;
FILE_ALL_INFO *buf;
struct TCP_Server_Info *server = tcon->ses->server;
+ struct cifs_open_parms oparms;
if (!server->ops->open)
return -ENOSYS;
@@ -224,9 +225,15 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
if (backup_cred(cifs_sb))
create_options |= CREATE_OPEN_BACKUP_INTENT;
- rc = server->ops->open(xid, tcon, full_path, disposition,
- desired_access, create_options, fid, oplock, buf,
- cifs_sb);
+ oparms.tcon = tcon;
+ oparms.cifs_sb = cifs_sb;
+ oparms.desired_access = desired_access;
+ oparms.create_options = create_options;
+ oparms.disposition = disposition;
+ oparms.path = full_path;
+ oparms.fid = fid;
+
+ rc = server->ops->open(xid, &oparms, oplock, buf);
if (rc)
goto out;
@@ -588,6 +595,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
int disposition = FILE_OPEN;
int create_options = CREATE_NOT_DIR;
struct cifs_fid fid;
+ struct cifs_open_parms oparms;
xid = get_xid();
mutex_lock(&cfile->fh_mutex);
@@ -656,6 +664,14 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
if (server->ops->get_lease_key)
server->ops->get_lease_key(inode, &fid);
+ oparms.tcon = tcon;
+ oparms.cifs_sb = cifs_sb;
+ oparms.desired_access = desired_access;
+ oparms.create_options = create_options;
+ oparms.disposition = disposition;
+ oparms.path = full_path;
+ oparms.fid = &fid;
+
/*
* Can not refresh inode by passing in file_info buf to be returned by
* CIFSSMBOpen and then calling get_inode_info with returned buf since
@@ -663,9 +679,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
* version of file size can be stale. If we knew for sure that inode was
* not dirty locally we could do this.
*/
- rc = server->ops->open(xid, tcon, full_path, disposition,
- desired_access, create_options, &fid, &oplock,
- NULL, cifs_sb);
+ rc = server->ops->open(xid, &oparms, &oplock, NULL);
if (rc) {
mutex_unlock(&cfile->fh_mutex);
cifs_dbg(FYI, "cifs_reopen returned 0x%x\n", rc);
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index e813f04..6457690 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -674,20 +674,23 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
}
static int
-cifs_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
- int disposition, int desired_access, int create_options,
- struct cifs_fid *fid, __u32 *oplock, FILE_ALL_INFO *buf,
- struct cifs_sb_info *cifs_sb)
-{
- if (!(tcon->ses->capabilities & CAP_NT_SMBS))
- return SMBLegacyOpen(xid, tcon, path, disposition,
- desired_access, create_options,
- &fid->netfid, oplock, buf,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
+cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+ __u32 *oplock, FILE_ALL_INFO *buf)
+{
+ if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
+ return SMBLegacyOpen(xid, oparms->tcon, oparms->path,
+ oparms->disposition,
+ oparms->desired_access,
+ oparms->create_options,
+ &oparms->fid->netfid, oplock, buf,
+ oparms->cifs_sb->local_nls,
+ oparms->cifs_sb->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR);
- return CIFSSMBOpen(xid, tcon, path, disposition, desired_access,
- create_options, &fid->netfid, oplock, buf,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+ return CIFSSMBOpen(xid, oparms->tcon, oparms->path,
+ oparms->disposition, oparms->desired_access,
+ oparms->create_options, &oparms->fid->netfid, oplock,
+ buf, oparms->cifs_sb->local_nls,
+ oparms->cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
}
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 150a9b1..5bab192 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -57,17 +57,16 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
}
int
-smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
- int disposition, int desired_access, int create_options,
- struct cifs_fid *fid, __u32 *oplock, FILE_ALL_INFO *buf,
- struct cifs_sb_info *cifs_sb)
+smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+ __u32 *oplock, FILE_ALL_INFO *buf)
{
int rc;
__le16 *smb2_path;
struct smb2_file_all_info *smb2_data = NULL;
__u8 smb2_oplock[17];
+ struct cifs_fid *fid = oparms->fid;
- smb2_path = cifs_convert_path_to_utf16(path, cifs_sb);
+ smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
if (smb2_path == NULL) {
rc = -ENOMEM;
goto out;
@@ -80,21 +79,22 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
goto out;
}
- desired_access |= FILE_READ_ATTRIBUTES;
+ oparms->desired_access |= FILE_READ_ATTRIBUTES;
*smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
- if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
+ if (oparms->tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE);
- rc = SMB2_open(xid, tcon, smb2_path, &fid->persistent_fid,
- &fid->volatile_fid, desired_access, disposition,
- create_options, smb2_oplock, smb2_data);
+ rc = SMB2_open(xid, oparms->tcon, smb2_path, &fid->persistent_fid,
+ &fid->volatile_fid, oparms->desired_access,
+ oparms->disposition, oparms->create_options, smb2_oplock,
+ smb2_data);
if (rc)
goto out;
if (buf) {
/* open response does not have IndexNumber field - get it */
- rc = SMB2_get_srv_num(xid, tcon, fid->persistent_fid,
+ rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid,
fid->volatile_fid,
&smb2_data->IndexNumber);
if (rc) {
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index d71a3e2..206efde 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -84,11 +84,9 @@ extern int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
const char *from_name, const char *to_name,
struct cifs_sb_info *cifs_sb);
-extern int smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon,
- const char *full_path, int disposition,
- int desired_access, int create_options,
- struct cifs_fid *fid, __u32 *oplock,
- FILE_ALL_INFO *buf, struct cifs_sb_info *cifs_sb);
+extern int smb2_open_file(const unsigned int xid,
+ struct cifs_open_parms *oparms,
+ __u32 *oplock, FILE_ALL_INFO *buf);
extern void smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
extern int smb2_unlock_range(struct cifsFileInfo *cfile,
struct file_lock *flock, const unsigned int xid);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 7/8] CIFS: Make SMB2_open use cifs_open_parms struct
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (5 preceding siblings ...)
2013-07-10 9:59 ` [PATCH 6/8] CIFS: Introduce cifs_open_parms struct Pavel Shilovsky
@ 2013-07-10 9:59 ` Pavel Shilovsky
2013-07-10 10:00 ` [PATCH 8/8] CIFS: Reconnect durable handles for SMB2 Pavel Shilovsky
2013-07-10 14:50 ` [PATCH 0/8] SMB2 durable handles support Scott Lovenberg
8 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 9:59 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
to prepare it for further durable handle reconnect processing.
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/smb2file.c | 5 +----
fs/cifs/smb2inode.c | 35 +++++++++++++++++++++--------------
fs/cifs/smb2ops.c | 51 +++++++++++++++++++++++++++++++++------------------
fs/cifs/smb2pdu.c | 19 +++++++++----------
fs/cifs/smb2proto.h | 6 ++----
5 files changed, 66 insertions(+), 50 deletions(-)
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 5bab192..3989929 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -85,10 +85,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
if (oparms->tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE);
- rc = SMB2_open(xid, oparms->tcon, smb2_path, &fid->persistent_fid,
- &fid->volatile_fid, oparms->desired_access,
- oparms->disposition, oparms->create_options, smb2_oplock,
- smb2_data);
+ rc = SMB2_open(xid, oparms, smb2_path, smb2_oplock, smb2_data);
if (rc)
goto out;
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index f50eefd..9841df7 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -44,17 +44,22 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
__u32 create_options, void *data, int command)
{
int rc, tmprc = 0;
- u64 persistent_fid, volatile_fid;
__le16 *utf16_path;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+ struct cifs_open_parms oparms;
+ struct cifs_fid fid;
utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
if (!utf16_path)
return -ENOMEM;
- rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
- desired_access, create_disposition, create_options,
- &oplock, NULL);
+ oparms.tcon = tcon;
+ oparms.desired_access = desired_access;
+ oparms.disposition = create_disposition;
+ oparms.create_options = create_options;
+ oparms.fid = &fid;
+
+ rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
if (rc) {
kfree(utf16_path);
return rc;
@@ -64,8 +69,8 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
case SMB2_OP_DELETE:
break;
case SMB2_OP_QUERY_INFO:
- tmprc = SMB2_query_info(xid, tcon, persistent_fid,
- volatile_fid,
+ tmprc = SMB2_query_info(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid,
(struct smb2_file_all_info *)data);
break;
case SMB2_OP_MKDIR:
@@ -75,19 +80,21 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
*/
break;
case SMB2_OP_RENAME:
- tmprc = SMB2_rename(xid, tcon, persistent_fid, volatile_fid,
- (__le16 *)data);
+ tmprc = SMB2_rename(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid, (__le16 *)data);
break;
case SMB2_OP_HARDLINK:
- tmprc = SMB2_set_hardlink(xid, tcon, persistent_fid,
- volatile_fid, (__le16 *)data);
+ tmprc = SMB2_set_hardlink(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid, (__le16 *)data);
break;
case SMB2_OP_SET_EOF:
- tmprc = SMB2_set_eof(xid, tcon, persistent_fid, volatile_fid,
- current->tgid, (__le64 *)data);
+ tmprc = SMB2_set_eof(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid, current->tgid,
+ (__le64 *)data);
break;
case SMB2_OP_SET_INFO:
- tmprc = SMB2_set_info(xid, tcon, persistent_fid, volatile_fid,
+ tmprc = SMB2_set_info(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid,
(FILE_BASIC_INFO *)data);
break;
default:
@@ -95,7 +102,7 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
break;
}
- rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid);
+ rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
if (tmprc)
rc = tmprc;
kfree(utf16_path);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 85b15e0..86954b0 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -213,22 +213,28 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path)
{
int rc;
- __u64 persistent_fid, volatile_fid;
__le16 *utf16_path;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+ struct cifs_open_parms oparms;
+ struct cifs_fid fid;
utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
if (!utf16_path)
return -ENOMEM;
- rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
- FILE_READ_ATTRIBUTES, FILE_OPEN, 0, &oplock, NULL);
+ oparms.tcon = tcon;
+ oparms.desired_access = FILE_READ_ATTRIBUTES;
+ oparms.disposition = FILE_OPEN;
+ oparms.create_options = 0;
+ oparms.fid = &fid;
+
+ rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
if (rc) {
kfree(utf16_path);
return rc;
}
- rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid);
+ rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
kfree(utf16_path);
return rc;
}
@@ -443,15 +449,19 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
__le16 *utf16_path;
int rc;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
- __u64 persistent_fid, volatile_fid;
+ struct cifs_open_parms oparms;
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
if (!utf16_path)
return -ENOMEM;
- rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
- FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_OPEN, 0,
- &oplock, NULL);
+ oparms.tcon = tcon;
+ oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
+ oparms.disposition = FILE_OPEN;
+ oparms.create_options = 0;
+ oparms.fid = fid;
+
+ rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
kfree(utf16_path);
if (rc) {
cifs_dbg(VFS, "open dir failed\n");
@@ -460,14 +470,12 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
srch_inf->entries_in_buffer = 0;
srch_inf->index_of_last_entry = 0;
- fid->persistent_fid = persistent_fid;
- fid->volatile_fid = volatile_fid;
- rc = SMB2_query_directory(xid, tcon, persistent_fid, volatile_fid, 0,
- srch_inf);
+ rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
+ fid->volatile_fid, 0, srch_inf);
if (rc) {
cifs_dbg(VFS, "query directory failed\n");
- SMB2_close(xid, tcon, persistent_fid, volatile_fid);
+ SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
}
return rc;
}
@@ -528,17 +536,24 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
struct kstatfs *buf)
{
int rc;
- u64 persistent_fid, volatile_fid;
__le16 srch_path = 0; /* Null - open root of share */
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+ struct cifs_open_parms oparms;
+ struct cifs_fid fid;
+
+ oparms.tcon = tcon;
+ oparms.desired_access = FILE_READ_ATTRIBUTES;
+ oparms.disposition = FILE_OPEN;
+ oparms.create_options = 0;
+ oparms.fid = &fid;
- rc = SMB2_open(xid, tcon, &srch_path, &persistent_fid, &volatile_fid,
- FILE_READ_ATTRIBUTES, FILE_OPEN, 0, &oplock, NULL);
+ rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL);
if (rc)
return rc;
buf->f_type = SMB2_MAGIC_NUMBER;
- rc = SMB2_QFS_info(xid, tcon, persistent_fid, volatile_fid, buf);
- SMB2_close(xid, tcon, persistent_fid, volatile_fid);
+ rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+ buf);
+ SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
return rc;
}
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 140a613..9d7341d 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -946,14 +946,13 @@ add_durable_context(struct kvec *iov, unsigned int *num_iovec)
}
int
-SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
- u64 *persistent_fid, u64 *volatile_fid, __u32 desired_access,
- __u32 create_disposition, __u32 create_options, __u8 *oplock,
- struct smb2_file_all_info *buf)
+SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
+ __u8 *oplock, struct smb2_file_all_info *buf)
{
struct smb2_create_req *req;
struct smb2_create_rsp *rsp;
struct TCP_Server_Info *server;
+ struct cifs_tcon *tcon = oparms->tcon;
struct cifs_ses *ses = tcon->ses;
struct kvec iov[4];
int resp_buftype;
@@ -975,16 +974,16 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
if (rc)
return rc;
- if (create_options & CREATE_OPTION_READONLY)
+ if (oparms->create_options & CREATE_OPTION_READONLY)
file_attributes |= ATTR_READONLY;
req->ImpersonationLevel = IL_IMPERSONATION;
- req->DesiredAccess = cpu_to_le32(desired_access);
+ req->DesiredAccess = cpu_to_le32(oparms->desired_access);
/* File attributes ignored on open (used in create though) */
req->FileAttributes = cpu_to_le32(file_attributes);
req->ShareAccess = FILE_SHARE_ALL_LE;
- req->CreateDisposition = cpu_to_le32(create_disposition);
- req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
+ req->CreateDisposition = cpu_to_le32(oparms->disposition);
+ req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK);
uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
/* do not count rfc1001 len field */
req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) - 4);
@@ -1055,8 +1054,8 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
goto creat_exit;
}
- *persistent_fid = rsp->PersistentFileId;
- *volatile_fid = rsp->VolatileFileId;
+ oparms->fid->persistent_fid = rsp->PersistentFileId;
+ oparms->fid->volatile_fid = rsp->VolatileFileId;
if (buf) {
memcpy(buf, &rsp->CreationTime, 32);
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 206efde..1a5ecbe 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -104,10 +104,8 @@ extern int SMB2_tcon(const unsigned int xid, struct cifs_ses *ses,
const char *tree, struct cifs_tcon *tcon,
const struct nls_table *);
extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
-extern int SMB2_open(const unsigned int xid, struct cifs_tcon *tcon,
- __le16 *path, u64 *persistent_fid, u64 *volatile_fid,
- __u32 desired_access, __u32 create_disposition,
- __u32 create_options, __u8 *oplock,
+extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
+ __le16 *path, __u8 *oplock,
struct smb2_file_all_info *buf);
extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, u32 opcode,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 8/8] CIFS: Reconnect durable handles for SMB2
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (6 preceding siblings ...)
2013-07-10 9:59 ` [PATCH 7/8] CIFS: Make SMB2_open use " Pavel Shilovsky
@ 2013-07-10 10:00 ` Pavel Shilovsky
[not found] ` <1373450401-4135-9-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-10 14:50 ` [PATCH 0/8] SMB2 durable handles support Scott Lovenberg
8 siblings, 1 reply; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 10:00 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
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-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/cifsglob.h | 1 +
fs/cifs/dir.c | 1 +
fs/cifs/file.c | 15 +++++++++------
fs/cifs/smb2file.c | 3 ++-
fs/cifs/smb2inode.c | 1 +
fs/cifs/smb2ops.c | 3 +++
fs/cifs/smb2pdu.c | 38 ++++++++++++++++++++++++++++++++++----
fs/cifs/smb2pdu.h | 8 +++++++-
8 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 107e657..1b1b144 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -915,6 +915,7 @@ struct cifs_open_parms {
int create_options;
const char *path;
struct cifs_fid *fid;
+ bool reconnect:1;
};
struct cifs_fid {
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 66435c9..585e01a 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -327,6 +327,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
oparms.disposition = disposition;
oparms.path = full_path;
oparms.fid = fid;
+ oparms.reconnect = false;
rc = server->ops->open(xid, &oparms, oplock, buf);
if (rc) {
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 12a9754..2cd4a7c 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,
oparms.disposition = disposition;
oparms.path = full_path;
oparms.fid = fid;
+ oparms.reconnect = false;
rc = server->ops->open(xid, &oparms, oplock, buf);
@@ -594,7 +595,6 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
int desired_access;
int disposition = FILE_OPEN;
int create_options = CREATE_NOT_DIR;
- struct cifs_fid fid;
struct cifs_open_parms oparms;
xid = get_xid();
@@ -645,7 +645,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
rc = cifs_posix_open(full_path, NULL, inode->i_sb,
cifs_sb->mnt_file_mode /* ignored */,
- oflags, &oplock, &fid.netfid, xid);
+ oflags, &oplock, &cfile->fid.netfid, xid);
if (rc == 0) {
cifs_dbg(FYI, "posix reopen succeeded\n");
goto reopen_success;
@@ -662,7 +662,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
create_options |= CREATE_OPEN_BACKUP_INTENT;
if (server->ops->get_lease_key)
- server->ops->get_lease_key(inode, &fid);
+ server->ops->get_lease_key(inode, &cfile->fid);
oparms.tcon = tcon;
oparms.cifs_sb = cifs_sb;
@@ -670,7 +670,8 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
oparms.create_options = create_options;
oparms.disposition = disposition;
oparms.path = full_path;
- oparms.fid = &fid;
+ oparms.fid = &cfile->fid;
+ oparms.reconnect = true;
/*
* Can not refresh inode by passing in file_info buf to be returned by
@@ -710,8 +711,9 @@ reopen_success:
* to the server to get the new inode info.
*/
- server->ops->set_fid(cfile, &fid, oplock);
- cifs_relock_file(cfile);
+ server->ops->set_fid(cfile, &cfile->fid, oplock);
+ if (oparms.reconnect)
+ cifs_relock_file(cfile);
reopen_error_exit:
kfree(full_path);
@@ -1507,6 +1509,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
if (!rc)
goto out;
+
/*
* Windows 7 server can delay breaking lease from read to None
* if we set a byte-range lock on a file - break it explicitly
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 3989929..04a81a4 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -40,7 +40,8 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
oplock &= 0xFF;
if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
return;
- if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
+ if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
+ oplock == SMB2_OPLOCK_LEVEL_BATCH) {
cinode->clientCanCacheAll = true;
cinode->clientCanCacheRead = true;
cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 9841df7..c6ec163 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -58,6 +58,7 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
oparms.disposition = create_disposition;
oparms.create_options = create_options;
oparms.fid = &fid;
+ oparms.reconnect = false;
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
if (rc) {
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 86954b0..300ff85 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -227,6 +227,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
oparms.disposition = FILE_OPEN;
oparms.create_options = 0;
oparms.fid = &fid;
+ oparms.reconnect = false;
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
if (rc) {
@@ -460,6 +461,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
oparms.disposition = FILE_OPEN;
oparms.create_options = 0;
oparms.fid = fid;
+ oparms.reconnect = false;
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
kfree(utf16_path);
@@ -546,6 +548,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
oparms.disposition = FILE_OPEN;
oparms.create_options = 0;
oparms.fid = &fid;
+ oparms.reconnect = false;
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL);
if (rc)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 9d7341d..c7ad06f 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -857,7 +857,7 @@ create_durable_buf(void)
return NULL;
buf->ccontext.DataOffset = cpu_to_le16(offsetof
- (struct create_durable, Reserved));
+ (struct create_durable, Data));
buf->ccontext.DataLength = cpu_to_le32(16);
buf->ccontext.NameOffset = cpu_to_le16(offsetof
(struct create_durable, Name));
@@ -869,6 +869,30 @@ create_durable_buf(void)
return buf;
}
+static struct create_durable *
+create_reconnect_durable_buf(struct cifs_fid *fid)
+{
+ struct create_durable *buf;
+
+ buf = kzalloc(sizeof(struct create_durable), GFP_KERNEL);
+ if (!buf)
+ return NULL;
+
+ buf->ccontext.DataOffset = cpu_to_le16(offsetof
+ (struct create_durable, Data));
+ buf->ccontext.DataLength = cpu_to_le32(16);
+ buf->ccontext.NameOffset = cpu_to_le16(offsetof
+ (struct create_durable, Name));
+ buf->ccontext.NameLength = cpu_to_le16(4);
+ buf->Data.Fid.PersistentFileId = fid->persistent_fid;
+ buf->Data.Fid.VolatileFileId = fid->volatile_fid;
+ buf->Name[0] = 'D';
+ buf->Name[1] = 'H';
+ buf->Name[2] = 'n';
+ buf->Name[3] = 'C';
+ return buf;
+}
+
static __u8
parse_lease_state(struct smb2_create_rsp *rsp)
{
@@ -924,12 +948,18 @@ add_lease_context(struct kvec *iov, unsigned int *num_iovec, __u8 *oplock)
}
static int
-add_durable_context(struct kvec *iov, unsigned int *num_iovec)
+add_durable_context(struct kvec *iov, unsigned int *num_iovec,
+ struct cifs_open_parms *oparms)
{
struct smb2_create_req *req = iov[0].iov_base;
unsigned int num = *num_iovec;
- iov[num].iov_base = create_durable_buf();
+ if (oparms->reconnect) {
+ iov[num].iov_base = create_reconnect_durable_buf(oparms->fid);
+ /* indicate that we don't need to relock the file */
+ oparms->reconnect = false;
+ } else
+ iov[num].iov_base = create_durable_buf();
if (iov[num].iov_base == NULL)
return -ENOMEM;
iov[num].iov_len = sizeof(struct create_durable);
@@ -1037,7 +1067,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
(struct create_context *)iov[num_iovecs-1].iov_base;
ccontext->Next = sizeof(struct create_lease);
}
- rc = add_durable_context(iov, &num_iovecs);
+ rc = add_durable_context(iov, &num_iovecs, oparms);
if (rc) {
cifs_small_buf_release(req);
kfree(copy_path);
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 3e30f0a..36b0d37 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -488,7 +488,13 @@ struct create_lease {
struct create_durable {
struct create_context ccontext;
__u8 Name[8];
- __u8 Reserved[16];
+ union {
+ __u8 Reserved[16];
+ struct {
+ __u64 PersistentFileId;
+ __u64 VolatileFileId;
+ } Fid;
+ } Data;
} __packed;
/* this goes in the ioctl buffer when doing a copychunk request */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 2/8] CIFS: Respect create_options in smb2_open_file
[not found] ` <1373450401-4135-3-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2013-07-10 14:45 ` Steve French
[not found] ` <CAH2r5mtvpFs8un95EkNWZLptifoExrm1bJ30UbHi-DEb1ENWxw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 17+ messages in thread
From: Steve French @ 2013-07-10 14:45 UTC (permalink / raw)
To: Pavel Shilovsky; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA
Won't we need the file attributes parm on SMB2 create to pass in on
the call to create symlink (where we have to pass that it is a reparse
point)?
On Wed, Jul 10, 2013 at 4:59 AM, Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> and eliminated unused file_attribute parms of SMB2_open.
>
> Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/smb2file.c | 2 +-
> fs/cifs/smb2inode.c | 25 ++++++++++++-------------
> fs/cifs/smb2ops.c | 6 +++---
> fs/cifs/smb2pdu.c | 10 +++++++---
> fs/cifs/smb2proto.h | 4 ++--
> 5 files changed, 25 insertions(+), 22 deletions(-)
>
> diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
> index 5da1b55..46a4299 100644
> --- a/fs/cifs/smb2file.c
> +++ b/fs/cifs/smb2file.c
> @@ -88,7 +88,7 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
>
> rc = SMB2_open(xid, tcon, smb2_path, &fid->persistent_fid,
> &fid->volatile_fid, desired_access, disposition,
> - 0, 0, smb2_oplock, smb2_data);
> + create_options, smb2_oplock, smb2_data);
> if (rc)
> goto out;
>
> diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
> index fff6dfb..f50eefd 100644
> --- a/fs/cifs/smb2inode.c
> +++ b/fs/cifs/smb2inode.c
> @@ -41,8 +41,7 @@ static int
> smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
> struct cifs_sb_info *cifs_sb, const char *full_path,
> __u32 desired_access, __u32 create_disposition,
> - __u32 file_attributes, __u32 create_options,
> - void *data, int command)
> + __u32 create_options, void *data, int command)
> {
> int rc, tmprc = 0;
> u64 persistent_fid, volatile_fid;
> @@ -54,8 +53,8 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
> - desired_access, create_disposition, file_attributes,
> - create_options, &oplock, NULL);
> + desired_access, create_disposition, create_options,
> + &oplock, NULL);
> if (rc) {
> kfree(utf16_path);
> return rc;
> @@ -129,8 +128,8 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> rc = smb2_open_op_close(xid, tcon, cifs_sb, full_path,
> - FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0,
> - smb2_data, SMB2_OP_QUERY_INFO);
> + FILE_READ_ATTRIBUTES, FILE_OPEN, 0, smb2_data,
> + SMB2_OP_QUERY_INFO);
> if (rc)
> goto out;
>
> @@ -145,7 +144,7 @@ smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> struct cifs_sb_info *cifs_sb)
> {
> return smb2_open_op_close(xid, tcon, cifs_sb, name,
> - FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0,
> + FILE_WRITE_ATTRIBUTES, FILE_CREATE,
> CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR);
> }
>
> @@ -164,7 +163,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
> dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
> data.Attributes = cpu_to_le32(dosattrs);
> tmprc = smb2_open_op_close(xid, tcon, cifs_sb, name,
> - FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0,
> + FILE_WRITE_ATTRIBUTES, FILE_CREATE,
> CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO);
> if (tmprc == 0)
> cifs_i->cifsAttrs = dosattrs;
> @@ -175,7 +174,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> struct cifs_sb_info *cifs_sb)
> {
> return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
> - 0, CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
> + CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
> NULL, SMB2_OP_DELETE);
> }
>
> @@ -184,7 +183,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> struct cifs_sb_info *cifs_sb)
> {
> return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
> - 0, CREATE_DELETE_ON_CLOSE, NULL,
> + CREATE_DELETE_ON_CLOSE, NULL,
> SMB2_OP_DELETE);
> }
>
> @@ -203,7 +202,7 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
> }
>
> rc = smb2_open_op_close(xid, tcon, cifs_sb, from_name, access,
> - FILE_OPEN, 0, 0, smb2_to_name, command);
> + FILE_OPEN, 0, smb2_to_name, command);
> smb2_rename_path:
> kfree(smb2_to_name);
> return rc;
> @@ -234,7 +233,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
> {
> __le64 eof = cpu_to_le64(size);
> return smb2_open_op_close(xid, tcon, cifs_sb, full_path,
> - FILE_WRITE_DATA, FILE_OPEN, 0, 0, &eof,
> + FILE_WRITE_DATA, FILE_OPEN, 0, &eof,
> SMB2_OP_SET_EOF);
> }
>
> @@ -250,7 +249,7 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
> if (IS_ERR(tlink))
> return PTR_ERR(tlink);
> rc = smb2_open_op_close(xid, tlink_tcon(tlink), cifs_sb, full_path,
> - FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, 0, buf,
> + FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
> SMB2_OP_SET_INFO);
> cifs_put_tlink(tlink);
> return rc;
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index 92aa87c..85b15e0 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -222,7 +222,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
> - FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL);
> + FILE_READ_ATTRIBUTES, FILE_OPEN, 0, &oplock, NULL);
> if (rc) {
> kfree(utf16_path);
> return rc;
> @@ -450,7 +450,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
> - FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_OPEN, 0, 0,
> + FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_OPEN, 0,
> &oplock, NULL);
> kfree(utf16_path);
> if (rc) {
> @@ -533,7 +533,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
> u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
>
> rc = SMB2_open(xid, tcon, &srch_path, &persistent_fid, &volatile_fid,
> - FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL);
> + FILE_READ_ATTRIBUTES, FILE_OPEN, 0, &oplock, NULL);
> if (rc)
> return rc;
> buf->f_type = SMB2_MAGIC_NUMBER;
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index 19fafeb..4c046a5 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -881,8 +881,8 @@ parse_lease_state(struct smb2_create_rsp *rsp)
> int
> SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
> u64 *persistent_fid, u64 *volatile_fid, __u32 desired_access,
> - __u32 create_disposition, __u32 file_attributes, __u32 create_options,
> - __u8 *oplock, struct smb2_file_all_info *buf)
> + __u32 create_disposition, __u32 create_options, __u8 *oplock,
> + struct smb2_file_all_info *buf)
> {
> struct smb2_create_req *req;
> struct smb2_create_rsp *rsp;
> @@ -895,6 +895,7 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
> int copy_size;
> int rc = 0;
> int num_iovecs = 2;
> + __u32 file_attributes = 0;
>
> cifs_dbg(FYI, "create/open\n");
>
> @@ -907,13 +908,16 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
> if (rc)
> return rc;
>
> + if (create_options & CREATE_OPTION_READONLY)
> + file_attributes |= ATTR_READONLY;
> +
> req->ImpersonationLevel = IL_IMPERSONATION;
> req->DesiredAccess = cpu_to_le32(desired_access);
> /* File attributes ignored on open (used in create though) */
> req->FileAttributes = cpu_to_le32(file_attributes);
> req->ShareAccess = FILE_SHARE_ALL_LE;
> req->CreateDisposition = cpu_to_le32(create_disposition);
> - req->CreateOptions = cpu_to_le32(create_options);
> + req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
> uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
> req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req)
> - 8 /* pad */ - 4 /* do not count rfc1001 len field */);
> diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
> index d4e1eb8..d71a3e2 100644
> --- a/fs/cifs/smb2proto.h
> +++ b/fs/cifs/smb2proto.h
> @@ -109,8 +109,8 @@ extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
> extern int SMB2_open(const unsigned int xid, struct cifs_tcon *tcon,
> __le16 *path, u64 *persistent_fid, u64 *volatile_fid,
> __u32 desired_access, __u32 create_disposition,
> - __u32 file_attributes, __u32 create_options,
> - __u8 *oplock, struct smb2_file_all_info *buf);
> + __u32 create_options, __u8 *oplock,
> + struct smb2_file_all_info *buf);
> extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
> u64 persistent_fid, u64 volatile_fid, u32 opcode,
> bool is_fsctl, char *in_data, u32 indatalen,
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 0/8] SMB2 durable handles support
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (7 preceding siblings ...)
2013-07-10 10:00 ` [PATCH 8/8] CIFS: Reconnect durable handles for SMB2 Pavel Shilovsky
@ 2013-07-10 14:50 ` Scott Lovenberg
[not found] ` <CAFB9KM0=SOvVqHsarp9KijoUYeG=7=QwnWZMoJDgajbfPH42ZA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
8 siblings, 1 reply; 17+ messages in thread
From: Scott Lovenberg @ 2013-07-10 14:50 UTC (permalink / raw)
To: Pavel Shilovsky; +Cc: linux-cifs
On Wed, Jul 10, 2013 at 5:59 AM, Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> This patchset implements SMB2 procotol feature -- durable handles. It allows to restore all file handle information after reconnect events. In particular, there is no need to reobtain byte-range locks.
>
> While adding the feature, the patchset simplifies open codepath by introducing new cifs_open_parms structure.
>
> Pavel Shilovsky (8):
> CIFS: Fix lease context buffer parsing
> CIFS: Respect create_options in smb2_open_file
> CIFS: Simplify SMB2_open code path
> CIFS: Simplify SMB2 create context handling
> CIFS: Request durable open for SMB2 opens
> CIFS: Introduce cifs_open_parms struct
> CIFS: Make SMB2_open use cifs_open_parms struct
> CIFS: Reconnect durable handles for SMB2
>
Forgive my ignorance, but I thought this patch set was merged a while
ago (around the 4.0 release)? Is this a respin?
--
Peace and Blessings,
-Scott.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/8] CIFS: Respect create_options in smb2_open_file
[not found] ` <CAH2r5mtvpFs8un95EkNWZLptifoExrm1bJ30UbHi-DEb1ENWxw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-07-10 16:22 ` Pavel Shilovsky
0 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 16:22 UTC (permalink / raw)
To: Steve French; +Cc: linux-cifs
2013/7/10 Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> Won't we need the file attributes parm on SMB2 create to pass in on
> the call to create symlink (where we have to pass that it is a reparse
> point)?
It will be used for symlinks but now it does nothing. The further
patches add cifs_open_parms structure that makes it easier to extend
params list for SMB2_open syscall (by adding new field to this
struct).
--
Best regards,
Pavel Shilovsky.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 0/8] SMB2 durable handles support
[not found] ` <CAFB9KM0=SOvVqHsarp9KijoUYeG=7=QwnWZMoJDgajbfPH42ZA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-07-10 16:25 ` Pavel Shilovsky
[not found] ` <CAKywueRqRxnuqAG5dyZcmCwFpoYk=XU+jMrJ48RvYvPeBH6doA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-10 16:25 UTC (permalink / raw)
To: Scott Lovenberg; +Cc: linux-cifs
2013/7/10 Scott Lovenberg <scott.lovenberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> On Wed, Jul 10, 2013 at 5:59 AM, Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
>> This patchset implements SMB2 procotol feature -- durable handles. It allows to restore all file handle information after reconnect events. In particular, there is no need to reobtain byte-range locks.
>>
>> While adding the feature, the patchset simplifies open codepath by introducing new cifs_open_parms structure.
>>
>> Pavel Shilovsky (8):
>> CIFS: Fix lease context buffer parsing
>> CIFS: Respect create_options in smb2_open_file
>> CIFS: Simplify SMB2_open code path
>> CIFS: Simplify SMB2 create context handling
>> CIFS: Request durable open for SMB2 opens
>> CIFS: Introduce cifs_open_parms struct
>> CIFS: Make SMB2_open use cifs_open_parms struct
>> CIFS: Reconnect durable handles for SMB2
>>
>
> Forgive my ignorance, but I thought this patch set was merged a while
> ago (around the 4.0 release)? Is this a respin?
I think you mean Samba 4.0 release but this patchset is targeted for
cifs filesystem kernel client.
--
Best regards,
Pavel Shilovsky.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 0/8] SMB2 durable handles support
[not found] ` <CAKywueRqRxnuqAG5dyZcmCwFpoYk=XU+jMrJ48RvYvPeBH6doA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-07-10 16:30 ` Scott Lovenberg
2013-07-10 17:57 ` Steve French
0 siblings, 1 reply; 17+ messages in thread
From: Scott Lovenberg @ 2013-07-10 16:30 UTC (permalink / raw)
To: Pavel Shilovsky; +Cc: linux-cifs
On Wed, Jul 10, 2013 at 12:25 PM, Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> 2013/7/10 Scott Lovenberg <scott.lovenberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
>> On Wed, Jul 10, 2013 at 5:59 AM, Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
>>> This patchset implements SMB2 procotol feature -- durable handles. It allows to restore all file handle information after reconnect events. In particular, there is no need to reobtain byte-range locks.
>>>
>>> While adding the feature, the patchset simplifies open codepath by introducing new cifs_open_parms structure.
>>>
>>> Pavel Shilovsky (8):
>>> CIFS: Fix lease context buffer parsing
>>> CIFS: Respect create_options in smb2_open_file
>>> CIFS: Simplify SMB2_open code path
>>> CIFS: Simplify SMB2 create context handling
>>> CIFS: Request durable open for SMB2 opens
>>> CIFS: Introduce cifs_open_parms struct
>>> CIFS: Make SMB2_open use cifs_open_parms struct
>>> CIFS: Reconnect durable handles for SMB2
>>>
>>
>> Forgive my ignorance, but I thought this patch set was merged a while
>> ago (around the 4.0 release)? Is this a respin?
>
> I think you mean Samba 4.0 release but this patchset is targeted for
> cifs filesystem kernel client.
D'oh! Should have had my coffee before posting. Sorry for the noise.
--
Peace and Blessings,
-Scott.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 0/8] SMB2 durable handles support
2013-07-10 16:30 ` Scott Lovenberg
@ 2013-07-10 17:57 ` Steve French
0 siblings, 0 replies; 17+ messages in thread
From: Steve French @ 2013-07-10 17:57 UTC (permalink / raw)
To: Scott Lovenberg; +Cc: Pavel Shilovsky, linux-cifs
Minor endian warning found and fixed in this series
Author: Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Wed Jul 10 12:50:57 2013 -0500
Fix minor endian error in durable handle patch series
Fix endian warning:
CHECK fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.c:1068:40: warning: incorrect type in assignment
(different base types)
fs/cifs/smb2pdu.c:1068:40: expected restricted __le32 [usertype] Next
fs/cifs/smb2pdu.c:1068:40: got unsigned long
Signed-off-by: Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index c7ad06f..abc9c28 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1065,7 +1065,8 @@ SMB2_open(const unsigned int xid, struct
cifs_open_parms *oparms, __le16 *pat
if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) {
struct create_context *ccontext =
(struct create_context *)iov[num_iovecs-1].iov_base;
- ccontext->Next = sizeof(struct create_lease);
+ ccontext->Next =
+ cpu_to_le32(sizeof(struct create_lease));
}
rc = add_durable_context(iov, &num_iovecs, oparms);
if (rc) {
On Wed, Jul 10, 2013 at 11:30 AM, Scott Lovenberg
<scott.lovenberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Wed, Jul 10, 2013 at 12:25 PM, Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
>> 2013/7/10 Scott Lovenberg <scott.lovenberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
>>> On Wed, Jul 10, 2013 at 5:59 AM, Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
>>>> This patchset implements SMB2 procotol feature -- durable handles. It allows to restore all file handle information after reconnect events. In particular, there is no need to reobtain byte-range locks.
>>>>
>>>> While adding the feature, the patchset simplifies open codepath by introducing new cifs_open_parms structure.
>>>>
>>>> Pavel Shilovsky (8):
>>>> CIFS: Fix lease context buffer parsing
>>>> CIFS: Respect create_options in smb2_open_file
>>>> CIFS: Simplify SMB2_open code path
>>>> CIFS: Simplify SMB2 create context handling
>>>> CIFS: Request durable open for SMB2 opens
>>>> CIFS: Introduce cifs_open_parms struct
>>>> CIFS: Make SMB2_open use cifs_open_parms struct
>>>> CIFS: Reconnect durable handles for SMB2
>>>>
>>>
>>> Forgive my ignorance, but I thought this patch set was merged a while
>>> ago (around the 4.0 release)? Is this a respin?
>>
>> I think you mean Samba 4.0 release but this patchset is targeted for
>> cifs filesystem kernel client.
>
> D'oh! Should have had my coffee before posting. Sorry for the noise.
>
> --
> Peace and Blessings,
> -Scott.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Thanks,
Steve
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH] CIFS: Reopen the file if reconnect durable handle failed
[not found] ` <1373450401-4135-9-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2013-07-11 12:47 ` Pavel Shilovsky
[not found] ` <1373546829-4925-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
0 siblings, 1 reply; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-11 12:47 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/file.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 2cd4a7c..b149ae4 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -681,6 +681,13 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
* not dirty locally we could do this.
*/
rc = server->ops->open(xid, &oparms, &oplock, NULL);
+ if (rc == -ENOENT && oparms.reconnect == false) {
+ /* durable handle timeout is expired - open the file again */
+ rc = server->ops->open(xid, &oparms, &oplock, NULL);
+ /* indicate that we need to relock the file */
+ oparms.reconnect = true;
+ }
+
if (rc) {
mutex_unlock(&cfile->fh_mutex);
cifs_dbg(FYI, "cifs_reopen returned 0x%x\n", rc);
@@ -1509,7 +1516,6 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
if (!rc)
goto out;
-
/*
* Windows 7 server can delay breaking lease from read to None
* if we set a byte-range lock on a file - break it explicitly
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] CIFS: Reopen the file if reconnect durable handle failed
[not found] ` <1373546829-4925-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2013-07-11 12:50 ` Pavel Shilovsky
0 siblings, 0 replies; 17+ messages in thread
From: Pavel Shilovsky @ 2013-07-11 12:50 UTC (permalink / raw)
To: linux-cifs
2013/7/11 Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>:
> Signed-off-by: Pavel Shilovsky <pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/file.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 2cd4a7c..b149ae4 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -681,6 +681,13 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
> * not dirty locally we could do this.
> */
> rc = server->ops->open(xid, &oparms, &oplock, NULL);
> + if (rc == -ENOENT && oparms.reconnect == false) {
> + /* durable handle timeout is expired - open the file again */
> + rc = server->ops->open(xid, &oparms, &oplock, NULL);
> + /* indicate that we need to relock the file */
> + oparms.reconnect = true;
> + }
> +
> if (rc) {
> mutex_unlock(&cfile->fh_mutex);
> cifs_dbg(FYI, "cifs_reopen returned 0x%x\n", rc);
> @@ -1509,7 +1516,6 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
> if (!rc)
> goto out;
>
> -
> /*
> * Windows 7 server can delay breaking lease from read to None
> * if we set a byte-range lock on a file - break it explicitly
> --
> 1.7.10.4
>
This is a follow-on patch for 8/8 patch from the durable handles
series and it should be merged into that patch. It fixes the problem
when durable file handle timeout expired on the server and reopen
returns -ENOENT for such files.
--
Best regards,
Pavel Shilovsky.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2013-07-11 12:50 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-10 9:59 [PATCH 0/8] SMB2 durable handles support Pavel Shilovsky
[not found] ` <1373450401-4135-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-10 9:59 ` [PATCH 1/8] CIFS: Fix lease context buffer parsing Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 2/8] CIFS: Respect create_options in smb2_open_file Pavel Shilovsky
[not found] ` <1373450401-4135-3-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-10 14:45 ` Steve French
[not found] ` <CAH2r5mtvpFs8un95EkNWZLptifoExrm1bJ30UbHi-DEb1ENWxw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-07-10 16:22 ` Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 3/8] CIFS: Simplify SMB2_open code path Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 4/8] CIFS: Simplify SMB2 create context handling Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 5/8] CIFS: Request durable open for SMB2 opens Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 6/8] CIFS: Introduce cifs_open_parms struct Pavel Shilovsky
2013-07-10 9:59 ` [PATCH 7/8] CIFS: Make SMB2_open use " Pavel Shilovsky
2013-07-10 10:00 ` [PATCH 8/8] CIFS: Reconnect durable handles for SMB2 Pavel Shilovsky
[not found] ` <1373450401-4135-9-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-11 12:47 ` [PATCH] CIFS: Reopen the file if reconnect durable handle failed Pavel Shilovsky
[not found] ` <1373546829-4925-1-git-send-email-pshilovsky-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2013-07-11 12:50 ` Pavel Shilovsky
2013-07-10 14:50 ` [PATCH 0/8] SMB2 durable handles support Scott Lovenberg
[not found] ` <CAFB9KM0=SOvVqHsarp9KijoUYeG=7=QwnWZMoJDgajbfPH42ZA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-07-10 16:25 ` Pavel Shilovsky
[not found] ` <CAKywueRqRxnuqAG5dyZcmCwFpoYk=XU+jMrJ48RvYvPeBH6doA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-07-10 16:30 ` Scott Lovenberg
2013-07-10 17:57 ` Steve French
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.