All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.