All of lore.kernel.org
 help / color / mirror / Atom feed
* [v4 PATCH 3/4] CIFS: Migrate from prefixpath logic
@ 2011-05-26  6:01 Pavel Shilovsky
       [not found] ` <1306389721-28550-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26  6:01 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

Now we point superblock to a server share root and set a root dentry
appropriately. This let us share superblock between mounts like
//server/sharename/foo/bar and //server/sharename/foo further.

Reviewed-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
---
 fs/cifs/cifs_fs_sb.h |    2 -
 fs/cifs/cifsfs.c     |  101 ++++++++++++++++++++++++++++++++++++++-
 fs/cifs/cifsglob.h   |   75 +++++++++++++++++++++++++++++
 fs/cifs/cifsproto.h  |    5 +-
 fs/cifs/connect.c    |  128 ++------------------------------------------------
 fs/cifs/dir.c        |    7 +--
 fs/cifs/inode.c      |   19 ++-----
 7 files changed, 189 insertions(+), 148 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index a9d5692..c96b44b 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -56,8 +56,6 @@ struct cifs_sb_info {
 	mode_t	mnt_file_mode;
 	mode_t	mnt_dir_mode;
 	unsigned int mnt_cifs_flags;
-	int	prepathlen;
-	char   *prepath; /* relative path under the share to mount to */
 	char   *mountdata; /* options received at mount time or via DFS refs */
 	struct backing_dev_info bdi;
 	struct delayed_work prune_tlinks;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 1d2a93c..46fdd55 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -415,8 +415,6 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
 		seq_printf(s, ",nocase");
 	if (tcon->retry)
 		seq_printf(s, ",hard");
-	if (cifs_sb->prepath)
-		seq_printf(s, ",prepath=%s", cifs_sb->prepath);
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
 		seq_printf(s, ",posixpaths");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
@@ -530,6 +528,100 @@ static const struct super_operations cifs_super_ops = {
 #endif
 };
 
+/*
+ * Get root dentry from superblock according to prefix path mount option.
+ * Return dentry with refcount + 1 on success and NULL otherwise.
+ */
+static struct dentry *
+cifs_get_root(struct smb_vol *vol, struct super_block *sb)
+{
+	int xid, rc;
+	struct inode *inode;
+	struct qstr name;
+	struct dentry *dparent = NULL, *dchild = NULL, *alias;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+	unsigned int i, full_len, len;
+	char *full_path = NULL, *pstart;
+	char sep;
+
+	full_path = cifs_build_path_to_root(vol, cifs_sb,
+					    cifs_sb_master_tcon(cifs_sb));
+	if (full_path == NULL)
+		return NULL;
+
+	cFYI(1, "Get root dentry for %s", full_path);
+
+	xid = GetXid();
+	sep = CIFS_DIR_SEP(cifs_sb);
+	dparent = dget(sb->s_root);
+	full_len = strlen(full_path);
+	full_path[full_len] = sep;
+	pstart = full_path + 1;
+
+	for (i = 1, len = 0; i <= full_len; i++) {
+		if (full_path[i] != sep || !len) {
+			len++;
+			continue;
+		}
+
+		full_path[i] = 0;
+		cFYI(1, "get dentry for %s", pstart);
+
+		name.name = pstart;
+		name.len = len;
+		name.hash = full_name_hash(pstart, len);
+		dchild = d_lookup(dparent, &name);
+		if (dchild == NULL) {
+			cFYI(1, "not exists");
+			dchild = d_alloc(dparent, &name);
+			if (dchild == NULL) {
+				dput(dparent);
+				dparent = NULL;
+				goto out;
+			}
+		}
+
+		cFYI(1, "get inode");
+		if (dchild->d_inode == NULL) {
+			cFYI(1, "not exists");
+			inode = NULL;
+			if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
+				rc = cifs_get_inode_info_unix(&inode, full_path,
+							      sb, xid);
+			else
+				rc = cifs_get_inode_info(&inode, full_path,
+							 NULL, sb, xid, NULL);
+			if (rc) {
+				dput(dchild);
+				dput(dparent);
+				dparent = NULL;
+				goto out;
+			}
+			alias = d_materialise_unique(dchild, inode);
+			if (alias != NULL) {
+				dput(dchild);
+				if (IS_ERR(alias)) {
+					dput(dparent);
+					dparent = NULL;
+					goto out;
+				}
+				dchild = alias;
+			}
+		}
+		cFYI(1, "parent %p, child %p", dparent, dchild);
+
+		dput(dparent);
+		dparent = dchild;
+		len = 0;
+		pstart = full_path + i + 1;
+		full_path[i] = sep;
+	}
+out:
+	_FreeXid(xid);
+	kfree(full_path);
+	return dparent;
+}
+
 static struct dentry *
 cifs_do_mount(struct file_system_type *fs_type,
 	      int flags, const char *dev_name, void *data)
@@ -585,7 +677,10 @@ cifs_do_mount(struct file_system_type *fs_type,
 
 	sb->s_flags |= MS_ACTIVE;
 
-	root = dget(sb->s_root);
+	root = cifs_get_root(volume_info, sb);
+	if (root == NULL)
+		goto out_super;
+	cFYI(1, "dentry root is: %p", root);
 	goto out;
 
 out_super:
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index fd877c1..f57387a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -155,6 +155,61 @@ struct cifs_cred {
  *****************************************************************
  */
 
+struct smb_vol {
+	char *username;
+	char *password;
+	char *domainname;
+	char *UNC;
+	char *UNCip;
+	char *iocharset;  /* local code page for mapping to and from Unicode */
+	char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
+	char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
+	uid_t cred_uid;
+	uid_t linux_uid;
+	gid_t linux_gid;
+	mode_t file_mode;
+	mode_t dir_mode;
+	unsigned secFlg;
+	bool retry:1;
+	bool intr:1;
+	bool setuids:1;
+	bool override_uid:1;
+	bool override_gid:1;
+	bool dynperm:1;
+	bool noperm:1;
+	bool no_psx_acl:1; /* set if posix acl support should be disabled */
+	bool cifs_acl:1;
+	bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
+	bool server_ino:1; /* use inode numbers from server ie UniqueId */
+	bool direct_io:1;
+	bool strict_io:1; /* strict cache behavior */
+	bool remap:1;      /* set to remap seven reserved chars in filenames */
+	bool posix_paths:1; /* unset to not ask for posix pathnames. */
+	bool no_linux_ext:1;
+	bool sfu_emul:1;
+	bool nullauth:1;   /* attempt to authenticate with null user */
+	bool nocase:1;     /* request case insensitive filenames */
+	bool nobrl:1;      /* disable sending byte range locks to srv */
+	bool mand_lock:1;  /* send mandatory not posix byte range lock reqs */
+	bool seal:1;       /* request transport encryption on share */
+	bool nodfs:1;      /* Do not request DFS, even if available */
+	bool local_lease:1; /* check leases only on local system, not remote */
+	bool noblocksnd:1;
+	bool noautotune:1;
+	bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
+	bool fsc:1;	/* enable fscache */
+	bool mfsymlinks:1; /* use Minshall+French Symlinks */
+	bool multiuser:1;
+	unsigned int rsize;
+	unsigned int wsize;
+	bool sockopt_tcp_nodelay:1;
+	unsigned short int port;
+	unsigned long actimeo; /* attribute cache timeout (jiffies) */
+	char *prepath;
+	struct sockaddr_storage srcaddr; /* allow binding to a local IP */
+	struct nls_table *local_nls;
+};
+
 struct TCP_Server_Info {
 	struct list_head tcp_ses_list;
 	struct list_head smb_ses_list;
@@ -509,6 +564,26 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
 		return '\\';
 }
 
+static inline void
+convert_delimiter(char *path, char delim)
+{
+	int i;
+	char old_delim;
+
+	if (path == NULL)
+		return;
+
+	if (delim == '/')
+		old_delim = '\\';
+	else
+		old_delim = '/';
+
+	for (i = 0; path[i] != '\0'; i++) {
+		if (path[i] == old_delim)
+			path[i] = delim;
+	}
+}
+
 #ifdef CONFIG_CIFS_STATS
 #define cifs_stats_inc atomic_inc
 
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 8aea885..bba7470 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -57,8 +57,9 @@ extern int init_cifs_idmap(void);
 extern void exit_cifs_idmap(void);
 extern void cifs_destroy_idmaptrees(void);
 extern char *build_path_from_dentry(struct dentry *);
-extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
-					struct cifsTconInfo *tcon);
+extern char *cifs_build_path_to_root(struct smb_vol *vol,
+				     struct cifs_sb_info *cifs_sb,
+				     struct cifsTconInfo *tcon);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 extern char *cifs_compose_mount_options(const char *sb_mountdata,
 		const char *fullpath, const struct dfs_info3_param *ref,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2e7a79c..4f34519 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -57,61 +57,6 @@
 
 extern mempool_t *cifs_req_poolp;
 
-struct smb_vol {
-	char *username;
-	char *password;
-	char *domainname;
-	char *UNC;
-	char *UNCip;
-	char *iocharset;  /* local code page for mapping to and from Unicode */
-	char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
-	char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
-	uid_t cred_uid;
-	uid_t linux_uid;
-	gid_t linux_gid;
-	mode_t file_mode;
-	mode_t dir_mode;
-	unsigned secFlg;
-	bool retry:1;
-	bool intr:1;
-	bool setuids:1;
-	bool override_uid:1;
-	bool override_gid:1;
-	bool dynperm:1;
-	bool noperm:1;
-	bool no_psx_acl:1; /* set if posix acl support should be disabled */
-	bool cifs_acl:1;
-	bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
-	bool server_ino:1; /* use inode numbers from server ie UniqueId */
-	bool direct_io:1;
-	bool strict_io:1; /* strict cache behavior */
-	bool remap:1;      /* set to remap seven reserved chars in filenames */
-	bool posix_paths:1; /* unset to not ask for posix pathnames. */
-	bool no_linux_ext:1;
-	bool sfu_emul:1;
-	bool nullauth:1;   /* attempt to authenticate with null user */
-	bool nocase:1;     /* request case insensitive filenames */
-	bool nobrl:1;      /* disable sending byte range locks to srv */
-	bool mand_lock:1;  /* send mandatory not posix byte range lock reqs */
-	bool seal:1;       /* request transport encryption on share */
-	bool nodfs:1;      /* Do not request DFS, even if available */
-	bool local_lease:1; /* check leases only on local system, not remote */
-	bool noblocksnd:1;
-	bool noautotune:1;
-	bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
-	bool fsc:1;	/* enable fscache */
-	bool mfsymlinks:1; /* use Minshall+French Symlinks */
-	bool multiuser:1;
-	unsigned int rsize;
-	unsigned int wsize;
-	bool sockopt_tcp_nodelay:1;
-	unsigned short int port;
-	unsigned long actimeo; /* attribute cache timeout (jiffies) */
-	char *prepath;
-	struct sockaddr_storage srcaddr; /* allow binding to a local IP */
-	struct nls_table *local_nls;
-};
-
 /* FIXME: should these be tunable? */
 #define TLINK_ERROR_EXPIRE	(1 * HZ)
 #define TLINK_IDLE_EXPIRE	(600 * HZ)
@@ -2566,12 +2511,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
 					CIFS_MOUNT_POSIX_PATHS;
 		}
 
-		/* We might be setting the path sep back to a different
-		form if we are reconnecting and the server switched its
-		posix path capability for this share */
-		if (sb && (CIFS_SB(sb)->prepathlen > 0))
-			CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
-
 		if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
 			if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
 				CIFS_SB(sb)->rsize = 127 * 1024;
@@ -2612,26 +2551,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
 	}
 }
 
-static void
-convert_delimiter(char *path, char delim)
-{
-	int i;
-	char old_delim;
-
-	if (path == NULL)
-		return;
-
-	if (delim == '/')
-		old_delim = '\\';
-	else
-		old_delim = '/';
-
-	for (i = 0; path[i] != '\0'; i++) {
-		if (path[i] == old_delim)
-			path[i] = delim;
-	}
-}
-
 void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
 			struct cifs_sb_info *cifs_sb)
 {
@@ -2652,18 +2571,6 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
 		/* Windows ME may prefer this */
 		cFYI(1, "readsize set to minimum: 2048");
 	}
-	/* calculate prepath */
-	cifs_sb->prepath = pvolume_info->prepath;
-	if (cifs_sb->prepath) {
-		cifs_sb->prepathlen = strlen(cifs_sb->prepath);
-		/* we can not convert the / to \ in the path
-		separators in the prefixpath yet because we do not
-		know (until reset_cifs_unix_caps is called later)
-		whether POSIX PATH CAP is available. We normalize
-		the / to \ after reset_cifs_unix_caps is called */
-		pvolume_info->prepath = NULL;
-	} else
-		cifs_sb->prepathlen = 0;
 	cifs_sb->mnt_uid = pvolume_info->linux_uid;
 	cifs_sb->mnt_gid = pvolume_info->linux_gid;
 	cifs_sb->mnt_file_mode = pvolume_info->file_mode;
@@ -2827,24 +2734,13 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
 	char *full_path;
 
 	int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
-	full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
+	full_path = kmalloc(unc_len + 1, GFP_KERNEL);
 	if (full_path == NULL)
 		return ERR_PTR(-ENOMEM);
 
 	strncpy(full_path, volume_info->UNC, unc_len);
-	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
-		int i;
-		for (i = 0; i < unc_len; i++) {
-			if (full_path[i] == '\\')
-				full_path[i] = '/';
-		}
-	}
-
-	if (cifs_sb->prepathlen)
-		strncpy(full_path + unc_len, cifs_sb->prepath,
-				cifs_sb->prepathlen);
-
-	full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
+	full_path[unc_len] = 0; /* add trailing null */
+	convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
 	return full_path;
 }
 
@@ -3036,10 +2932,6 @@ try_mount_again:
 	else
 		tcon->unix_ext = 0; /* server does not support them */
 
-	/* convert forward to back slashes in prepath here if needed */
-	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
-		convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
-
 	if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
 		cifs_sb->rsize = 1024 * 127;
 		cFYI(DBG2, "no very large read support, rsize now 127K");
@@ -3069,10 +2961,10 @@ remote_path_check:
 	}
 #endif
 
-	/* check if a whole path (including prepath) is not remote */
+	/* check if a whole path is not remote */
 	if (!rc && tcon) {
 		/* build_path_to_root works only when we have a valid tcon */
-		full_path = cifs_build_path_to_root(cifs_sb, tcon);
+		full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
 		if (full_path == NULL) {
 			rc = -ENOMEM;
 			goto mount_fail_check;
@@ -3098,10 +2990,6 @@ remote_path_check:
 			rc = -ELOOP;
 			goto mount_fail_check;
 		}
-		/* convert forward to back slashes in prepath here if needed */
-		if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
-			convert_delimiter(cifs_sb->prepath,
-					CIFS_DIR_SEP(cifs_sb));
 
 		rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb,
 					 true);
@@ -3327,7 +3215,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
 	struct rb_root *root = &cifs_sb->tlink_tree;
 	struct rb_node *node;
 	struct tcon_link *tlink;
-	char *tmp;
 
 	cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
 
@@ -3344,11 +3231,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
 	}
 	spin_unlock(&cifs_sb->tlink_tree_lock);
 
-	tmp = cifs_sb->prepath;
-	cifs_sb->prepathlen = 0;
-	cifs_sb->prepath = NULL;
-	kfree(tmp);
-
 	return 0;
 }
 
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 9ea65cf..c33446d 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -50,7 +50,6 @@ build_path_from_dentry(struct dentry *direntry)
 {
 	struct dentry *temp;
 	int namelen;
-	int pplen;
 	int dfsplen;
 	char *full_path;
 	char dirsep;
@@ -63,13 +62,12 @@ build_path_from_dentry(struct dentry *direntry)
 		when the server crashed */
 
 	dirsep = CIFS_DIR_SEP(cifs_sb);
-	pplen = cifs_sb->prepathlen;
 	if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
 		dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
 	else
 		dfsplen = 0;
 cifs_bp_rename_retry:
-	namelen = pplen + dfsplen;
+	namelen = dfsplen;
 	for (temp = direntry; !IS_ROOT(temp);) {
 		namelen += (1 + temp->d_name.len);
 		temp = temp->d_parent;
@@ -100,7 +98,7 @@ cifs_bp_rename_retry:
 			return NULL;
 		}
 	}
-	if (namelen != pplen + dfsplen) {
+	if (namelen != dfsplen) {
 		cERROR(1, "did not end path lookup where expected namelen is %d",
 			namelen);
 		/* presumably this is only possible if racing with a rename
@@ -126,7 +124,6 @@ cifs_bp_rename_retry:
 			}
 		}
 	}
-	strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
 	return full_path;
 }
 
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index de02ed5..791d85e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -735,10 +735,10 @@ static const struct inode_operations cifs_ipc_inode_ops = {
 	.lookup = cifs_lookup,
 };
 
-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
-				struct cifsTconInfo *tcon)
+char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
+			      struct cifsTconInfo *tcon)
 {
-	int pplen = cifs_sb->prepathlen;
+	int pplen = vol->prepath ? strlen(vol->prepath) : 0;
 	int dfsplen;
 	char *full_path = NULL;
 
@@ -772,7 +772,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
 			}
 		}
 	}
-	strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
+	strncpy(full_path + dfsplen, vol->prepath, pplen);
 	full_path[dfsplen + pplen] = 0; /* add trailing null */
 	return full_path;
 }
@@ -884,19 +884,13 @@ struct inode *cifs_root_iget(struct super_block *sb)
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 	struct inode *inode = NULL;
 	long rc;
-	char *full_path;
 	struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
-	full_path = cifs_build_path_to_root(cifs_sb, tcon);
-	if (full_path == NULL)
-		return ERR_PTR(-ENOMEM);
-
 	xid = GetXid();
 	if (tcon->unix_ext)
-		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
+		rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
 	else
-		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
-						xid, NULL);
+		rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
 
 	if (!inode) {
 		inode = ERR_PTR(rc);
@@ -922,7 +916,6 @@ struct inode *cifs_root_iget(struct super_block *sb)
 	}
 
 out:
-	kfree(full_path);
 	/* can not call macro FreeXid here since in a void func
 	 * TODO: This is no longer true
 	 */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 1/2] CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size
       [not found] ` <1306389721-28550-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
@ 2011-05-26  6:01   ` Pavel Shilovsky
       [not found]     ` <1306389721-28550-2-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
  2011-05-26  6:02   ` [PATCH 2/2] CIFS: Add rwpidforward mount option Pavel Shilovsky
  2011-05-26  6:02   ` [v4 PATCH 4/4] CIFS: Migrate to shared superblock model Pavel Shilovsky
  2 siblings, 1 reply; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26  6:01 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

We need it to make them work with mandatory locking style because
we can fail in a situation like when kernel need to flush dirty pages
and there is a lock held by a process who opened file.

Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
---
 fs/cifs/cifsglob.h  |    8 ++++++++
 fs/cifs/cifsproto.h |   13 +++++--------
 fs/cifs/cifssmb.c   |   33 ++++++++++++++++++++++++++-------
 fs/cifs/dir.c       |   18 ++++++++++--------
 fs/cifs/file.c      |   31 +++++++++++++++++++++----------
 fs/cifs/inode.c     |   24 ++++++++++++++++++------
 fs/cifs/link.c      |   12 ++++++++----
 7 files changed, 96 insertions(+), 43 deletions(-)

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7f90488..ca0c378 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -529,6 +529,14 @@ struct cifsFileInfo {
 	struct work_struct oplock_break; /* work for oplock breaks */
 };
 
+struct cifs_io_parms {
+	__u16 netfid;
+	__u32 pid;
+	__u64 offset;
+	unsigned int length;
+	struct cifsTconInfo *tcon;
+};
+
 /*
  * Take a reference on the file private data. Must be called with
  * cifs_file_list_lock held.
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index bba7470..e41f607 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -349,15 +349,12 @@ extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
 			const int netfid, unsigned int count,
 			const __u64 lseek, unsigned int *nbytes, char **buf,
 			int *return_buf_type);
-extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
-			const int netfid, const unsigned int count,
-			const __u64 lseek, unsigned int *nbytes,
-			const char *buf, const char __user *ubuf,
+extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
+			unsigned int *nbytes, const char *buf,
+			const char __user *ubuf, const int long_op);
+extern int CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
+			unsigned int *nbytes, struct kvec *iov, const int nvec,
 			const int long_op);
-extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
-			const int netfid, const unsigned int count,
-			const __u64 offset, unsigned int *nbytes,
-			struct kvec *iov, const int nvec, const int long_op);
 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName, __u64 *inode_number,
 			const struct nls_table *nls_codepage,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 136df01..f39fa08 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1487,9 +1487,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
 
 
 int
-CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
-	     const int netfid, const unsigned int count,
-	     const __u64 offset, unsigned int *nbytes, const char *buf,
+CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
+	     unsigned int *nbytes, const char *buf,
 	     const char __user *ubuf, const int long_op)
 {
 	int rc = -EACCES;
@@ -1498,6 +1497,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
 	int bytes_returned, wct;
 	__u32 bytes_sent;
 	__u16 byte_count;
+	__u32 pid = io_parms->pid;
+	__u16 netfid = io_parms->netfid;
+	__u64 offset = io_parms->offset;
+	struct cifsTconInfo *tcon = io_parms->tcon;
+	unsigned int count = io_parms->length;
 
 	*nbytes = 0;
 
@@ -1519,6 +1523,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
 		      (void **) &pSMBr);
 	if (rc)
 		return rc;
+
+	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
+	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
+
 	/* tcon and ses pointer are checked in smb_init */
 	if (tcon->ses->server == NULL)
 		return -ECONNABORTED;
@@ -1778,6 +1786,9 @@ cifs_async_writev(struct cifs_writedata *wdata)
 		goto async_writev_out;
 	}
 
+	smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
+	smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
+
 	smb->AndXCommand = 0xFF;	/* none */
 	smb->Fid = wdata->cfile->netfid;
 	smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
@@ -1841,16 +1852,20 @@ async_writev_out:
 }
 
 int
-CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
-	     const int netfid, const unsigned int count,
-	     const __u64 offset, unsigned int *nbytes, struct kvec *iov,
-	     int n_vec, const int long_op)
+CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
+	      unsigned int *nbytes, struct kvec *iov, int n_vec,
+	      const int long_op)
 {
 	int rc = -EACCES;
 	WRITE_REQ *pSMB = NULL;
 	int wct;
 	int smb_hdr_len;
 	int resp_buf_type = 0;
+	__u32 pid = io_parms->pid;
+	__u16 netfid = io_parms->netfid;
+	__u64 offset = io_parms->offset;
+	struct cifsTconInfo *tcon = io_parms->tcon;
+	unsigned int count = io_parms->length;
 
 	*nbytes = 0;
 
@@ -1868,6 +1883,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
 	if (rc)
 		return rc;
+
+	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
+	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
+
 	/* tcon and ses pointer are checked in smb_init */
 	if (tcon->ses->server == NULL)
 		return -ECONNABORTED;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index c33446d..aa0669a 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -354,6 +354,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 	struct cifs_sb_info *cifs_sb;
 	struct tcon_link *tlink;
 	struct cifsTconInfo *pTcon;
+	struct cifs_io_parms io_parms;
 	char *full_path = NULL;
 	struct inode *newinode = NULL;
 	int oplock = 0;
@@ -436,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 	 * timestamps in, but we can reuse it safely */
 
 	pdev = (struct win_dev *)buf;
+	io_parms.netfid = fileHandle;
+	io_parms.pid = current->tgid;
+	io_parms.tcon = pTcon;
+	io_parms.offset = 0;
+	io_parms.length = sizeof(struct win_dev);
 	if (S_ISCHR(mode)) {
 		memcpy(pdev->type, "IntxCHR", 8);
 		pdev->major =
 		      cpu_to_le64(MAJOR(device_number));
 		pdev->minor =
 		      cpu_to_le64(MINOR(device_number));
-		rc = CIFSSMBWrite(xid, pTcon,
-			fileHandle,
-			sizeof(struct win_dev),
-			0, &bytes_written, (char *)pdev,
+		rc = CIFSSMBWrite(xid, &io_parms,
+			&bytes_written, (char *)pdev,
 			NULL, 0);
 	} else if (S_ISBLK(mode)) {
 		memcpy(pdev->type, "IntxBLK", 8);
@@ -453,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 		      cpu_to_le64(MAJOR(device_number));
 		pdev->minor =
 		      cpu_to_le64(MINOR(device_number));
-		rc = CIFSSMBWrite(xid, pTcon,
-			fileHandle,
-			sizeof(struct win_dev),
-			0, &bytes_written, (char *)pdev,
+		rc = CIFSSMBWrite(xid, &io_parms,
+			&bytes_written, (char *)pdev,
 			NULL, 0);
 	} /* else if (S_ISFIFO) */
 	CIFSSMBClose(xid, pTcon, fileHandle);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 00b926c..dfc0d35 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
 		cifsi->server_eof = end_of_write;
 }
 
-static ssize_t cifs_write(struct cifsFileInfo *open_file,
+static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
 			  const char *write_data, size_t write_size,
 			  loff_t *poffset)
 {
@@ -869,6 +869,7 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
 	int xid;
 	struct dentry *dentry = open_file->dentry;
 	struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
+	struct cifs_io_parms io_parms;
 
 	cifs_sb = CIFS_SB(dentry->d_sb);
 
@@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
 			/* iov[0] is reserved for smb header */
 			iov[1].iov_base = (char *)write_data + total_written;
 			iov[1].iov_len = len;
-			rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len,
-					   *poffset, &bytes_written, iov, 1, 0);
+			io_parms.netfid = open_file->netfid;
+			io_parms.pid = pid;
+			io_parms.tcon = pTcon;
+			io_parms.offset = *poffset;
+			io_parms.length = len;
+			rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
+					   1, 0);
 		}
 		if (rc || (bytes_written == 0)) {
 			if (total_written)
@@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
 
 	open_file = find_writable_file(CIFS_I(mapping->host), false);
 	if (open_file) {
-		bytes_written = cifs_write(open_file, write_data,
-					   to - from, &offset);
+		bytes_written = cifs_write(open_file, open_file->pid,
+					   write_data, to - from, &offset);
 		cifsFileInfo_put(open_file);
 		/* Does mm or vfs already set times? */
 		inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
@@ -1363,8 +1369,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
 		/* BB check if anything else missing out of ppw
 		   such as updating last write time */
 		page_data = kmap(page);
-		rc = cifs_write(file->private_data, page_data + offset,
-				copied, &pos);
+		rc = cifs_write(file->private_data, current->tgid,
+				page_data + offset, copied, &pos);
 		/* if (rc < 0) should we set writebehind rc? */
 		kunmap(page);
 
@@ -1515,6 +1521,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
 	struct cifsFileInfo *open_file;
 	struct cifsTconInfo *pTcon;
 	struct cifs_sb_info *cifs_sb;
+	struct cifs_io_parms io_parms;
 	int xid, rc;
 
 	len = iov_length(iov, nr_segs);
@@ -1573,9 +1580,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
 				if (rc != 0)
 					break;
 			}
-			rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid,
-					   cur_len, *poffset, &written,
-					   to_send, npages, 0);
+			io_parms.netfid = open_file->netfid;
+			io_parms.pid = current->tgid;
+			io_parms.tcon = pTcon;
+			io_parms.offset = *poffset;
+			io_parms.length = cur_len;
+			rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send,
+					   npages, 0);
 		} while (rc == -EAGAIN);
 
 		for (i = 0; i < npages; i++)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 791d85e..53ea625 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1866,6 +1866,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 	struct tcon_link *tlink = NULL;
 	struct cifsTconInfo *pTcon = NULL;
+	struct cifs_io_parms io_parms;
 
 	/*
 	 * To avoid spurious oplock breaks from server, in the case of
@@ -1887,8 +1888,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
 		cFYI(1, "SetFSize for attrs rc = %d", rc);
 		if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 			unsigned int bytes_written;
-			rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
-					  &bytes_written, NULL, NULL, 1);
+
+			io_parms.netfid = nfid;
+			io_parms.pid = npid;
+			io_parms.tcon = pTcon;
+			io_parms.offset = 0;
+			io_parms.length = attrs->ia_size;
+			rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
+					  NULL, NULL, 1);
 			cFYI(1, "Wrt seteof rc %d", rc);
 		}
 	} else
@@ -1923,10 +1930,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 			if (rc == 0) {
 				unsigned int bytes_written;
-				rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
-						  attrs->ia_size,
-						  &bytes_written, NULL,
-						  NULL, 1);
+
+				io_parms.netfid = netfid;
+				io_parms.pid = current->tgid;
+				io_parms.tcon = pTcon;
+				io_parms.offset = 0;
+				io_parms.length = attrs->ia_size;
+				rc = CIFSSMBWrite(xid, &io_parms,
+						  &bytes_written,
+						  NULL, NULL,  1);
 				cFYI(1, "wrt seteof rc %d", rc);
 				CIFSSMBClose(xid, pTcon, netfid);
 			}
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index ce417a9..1a6a388 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
 	__u16 netfid = 0;
 	u8 *buf;
 	unsigned int bytes_written = 0;
+	struct cifs_io_parms io_parms;
 
 	buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
 	if (!buf)
@@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
 		return rc;
 	}
 
-	rc = CIFSSMBWrite(xid, tcon, netfid,
-			  CIFS_MF_SYMLINK_FILE_SIZE /* length */,
-			  0 /* offset */,
-			  &bytes_written, buf, NULL, 0);
+	io_parms.netfid = netfid;
+	io_parms.pid = current->tgid;
+	io_parms.tcon = tcon;
+	io_parms.offset = 0;
+	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
+
+	rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
 	CIFSSMBClose(xid, tcon, netfid);
 	kfree(buf);
 	if (rc != 0)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/2] CIFS: Add rwpidforward mount option
       [not found] ` <1306389721-28550-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
  2011-05-26  6:01   ` [PATCH 1/2] CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size Pavel Shilovsky
@ 2011-05-26  6:02   ` Pavel Shilovsky
  2011-05-26  6:02   ` [v4 PATCH 4/4] CIFS: Migrate to shared superblock model Pavel Shilovsky
  2 siblings, 0 replies; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26  6:02 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

Add rwpidforward mount option that switches on a mode when we forward
pid of a process who opened a file to any read and write operation.

This can prevent applications like WINE from failing on read or write
operation on a previously locked file region from the same netfd from
another process if we use mandatory brlock style.

It is actual for WINE because during a run of WINE program two processes
work on the same netfd - share the same file struct between several VFS
fds:
1) WINE-server does open and lock;
2) WINE-application does read and write.

Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
---
 fs/cifs/README       |    3 ++
 fs/cifs/cifs_fs_sb.h |    1 +
 fs/cifs/cifsfs.c     |    8 +++++
 fs/cifs/cifsglob.h   |    1 +
 fs/cifs/cifsproto.h  |    5 +--
 fs/cifs/cifssmb.c    |   17 +++++++---
 fs/cifs/connect.c    |    4 ++
 fs/cifs/file.c       |   82 +++++++++++++++++++++++++++++++++++++------------
 fs/cifs/inode.c      |   11 +++++--
 fs/cifs/link.c       |   22 ++++++++-----
 10 files changed, 115 insertions(+), 39 deletions(-)

diff --git a/fs/cifs/README b/fs/cifs/README
index 4a3ca0e..c5c2c5e 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -457,6 +457,9 @@ A partial list of the supported mount options follows:
 		otherwise - read from the server. All written data are stored
 		in the cache, but if the client doesn't have Exclusive Oplock,
 		it writes the data to the server.
+  rwpidforward  Forward pid of a process who opened a file to any read or write
+		operation on that file. This prevent applications like WINE
+		from failing on read and write if we use mandatory brlock style.
   acl   	Allow setfacl and getfacl to manage posix ACLs if server
 		supports them.  (default)
   noacl 	Do not allow setfacl and getfacl calls on this mount
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index c96b44b..ffb1459 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -41,6 +41,7 @@
 #define CIFS_MOUNT_MF_SYMLINKS	0x10000 /* Minshall+French Symlinks enabled */
 #define CIFS_MOUNT_MULTIUSER	0x20000 /* multiuser mount */
 #define CIFS_MOUNT_STRICT_IO	0x40000 /* strict cache mode */
+#define CIFS_MOUNT_RWPIDFORWARD	0x80000 /* use pid forwarding for rw */
 
 struct cifs_sb_info {
 	struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 360fe2e..26981bf 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -415,12 +415,20 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
 		seq_printf(s, ",nocase");
 	if (tcon->retry)
 		seq_printf(s, ",hard");
+	if (tcon->unix_ext)
+		seq_printf(s, ",unix");
+	else
+		seq_printf(s, ",nounix");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
 		seq_printf(s, ",posixpaths");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
 		seq_printf(s, ",setuids");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
 		seq_printf(s, ",serverino");
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+		seq_printf(s, ",rwpidforward");
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
+		seq_printf(s, ",forcemand");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
 		seq_printf(s, ",directio");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index ca0c378..310cdda 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -200,6 +200,7 @@ struct smb_vol {
 	bool fsc:1;	/* enable fscache */
 	bool mfsymlinks:1; /* use Minshall+French Symlinks */
 	bool multiuser:1;
+	bool rwpidforward:1; /* pid forward for read/write operations */
 	unsigned int rsize;
 	unsigned int wsize;
 	bool sockopt_tcp_nodelay:1;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index e41f607..1706345 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -345,9 +345,8 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
 			const int smb_file_id);
 
-extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
-			const int netfid, unsigned int count,
-			const __u64 lseek, unsigned int *nbytes, char **buf,
+extern int CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms,
+			unsigned int *nbytes, char **buf,
 			int *return_buf_type);
 extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
 			unsigned int *nbytes, const char *buf,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f39fa08..19fd815 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1382,8 +1382,7 @@ openRetry:
 }
 
 int
-CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
-	    const unsigned int count, const __u64 lseek, unsigned int *nbytes,
+CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
 	    char **buf, int *pbuf_type)
 {
 	int rc = -EACCES;
@@ -1393,13 +1392,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
 	int wct;
 	int resp_buf_type = 0;
 	struct kvec iov[1];
+	__u32 pid = io_parms->pid;
+	__u16 netfid = io_parms->netfid;
+	__u64 offset = io_parms->offset;
+	struct cifsTconInfo *tcon = io_parms->tcon;
+	unsigned int count = io_parms->length;
 
 	cFYI(1, "Reading %d bytes on fid %d", count, netfid);
 	if (tcon->ses->capabilities & CAP_LARGE_FILES)
 		wct = 12;
 	else {
 		wct = 10; /* old style read */
-		if ((lseek >> 32) > 0)  {
+		if ((offset >> 32) > 0)  {
 			/* can not handle this big offset for old */
 			return -EIO;
 		}
@@ -1410,15 +1414,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
 	if (rc)
 		return rc;
 
+	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
+	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
+
 	/* tcon and ses pointer are checked in smb_init */
 	if (tcon->ses->server == NULL)
 		return -ECONNABORTED;
 
 	pSMB->AndXCommand = 0xFF;       /* none */
 	pSMB->Fid = netfid;
-	pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
+	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
 	if (wct == 12)
-		pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
+		pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
 
 	pSMB->Remaining = 0;
 	pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 3172baa..4ebb940 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1359,6 +1359,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
 			vol->server_ino = 1;
 		} else if (strnicmp(data, "noserverino", 9) == 0) {
 			vol->server_ino = 0;
+		} else if (strnicmp(data, "rwpidforward", 4) == 0) {
+			vol->rwpidforward = 1;
 		} else if (strnicmp(data, "cifsacl", 7) == 0) {
 			vol->cifs_acl = 1;
 		} else if (strnicmp(data, "nocifsacl", 9) == 0) {
@@ -2689,6 +2691,8 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
 	if (pvolume_info->mand_lock)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
+	if (pvolume_info->rwpidforward)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
 	if (pvolume_info->cifs_acl)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
 	if (pvolume_info->override_uid)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index dfc0d35..7db74d1 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
 			else
 				posix_lock_type = CIFS_WRLCK;
 			rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
-					length,	pfLock,
-					posix_lock_type, wait_flag);
+					length, pfLock, posix_lock_type,
+					wait_flag);
 			FreeXid(xid);
 			return rc;
 		}
@@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
 			posix_lock_type = CIFS_UNLCK;
 
 		rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
-				      length, pfLock,
-				      posix_lock_type, wait_flag);
+				      length, pfLock, posix_lock_type,
+				      wait_flag);
 	} else {
 		struct cifsFileInfo *fid = file->private_data;
 
@@ -1346,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
 {
 	int rc;
 	struct inode *inode = mapping->host;
+	struct cifsFileInfo *cfile = file->private_data;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
+	__u32 pid;
+
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+		pid = cfile->pid;
+	else
+		pid = current->tgid;
 
 	cFYI(1, "write_end for page %p from pos %lld with %d bytes",
 		 page, pos, copied);
@@ -1369,8 +1377,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
 		/* BB check if anything else missing out of ppw
 		   such as updating last write time */
 		page_data = kmap(page);
-		rc = cifs_write(file->private_data, current->tgid,
-				page_data + offset, copied, &pos);
+		rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
 		/* if (rc < 0) should we set writebehind rc? */
 		kunmap(page);
 
@@ -1523,6 +1530,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
 	struct cifs_sb_info *cifs_sb;
 	struct cifs_io_parms io_parms;
 	int xid, rc;
+	__u32 pid;
 
 	len = iov_length(iov, nr_segs);
 	if (!len)
@@ -1554,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
 
 	xid = GetXid();
 	open_file = file->private_data;
+
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+		pid = open_file->pid;
+	else
+		pid = current->tgid;
+
 	pTcon = tlink_tcon(open_file->tlink);
 	inode = file->f_path.dentry->d_inode;
 
@@ -1581,7 +1595,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
 					break;
 			}
 			io_parms.netfid = open_file->netfid;
-			io_parms.pid = current->tgid;
+			io_parms.pid = pid;
 			io_parms.tcon = pTcon;
 			io_parms.offset = *poffset;
 			io_parms.length = cur_len;
@@ -1682,7 +1696,9 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
 	struct cifsTconInfo *pTcon;
 	struct cifsFileInfo *open_file;
 	struct smb_com_read_rsp *pSMBr;
+	struct cifs_io_parms io_parms;
 	char *read_data;
+	__u32 pid;
 
 	if (!nr_segs)
 		return 0;
@@ -1697,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
 	open_file = file->private_data;
 	pTcon = tlink_tcon(open_file->tlink);
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+		pid = open_file->pid;
+	else
+		pid = current->tgid;
+
 	if ((file->f_flags & O_ACCMODE) == O_WRONLY)
 		cFYI(1, "attempting read on write only file instance");
 
@@ -1712,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
 				if (rc != 0)
 					break;
 			}
-			rc = CIFSSMBRead(xid, pTcon, open_file->netfid,
-					 cur_len, *poffset, &bytes_read,
+			io_parms.netfid = open_file->netfid;
+			io_parms.pid = pid;
+			io_parms.tcon = pTcon;
+			io_parms.offset = *poffset;
+			io_parms.length = len;
+			rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
 					 &read_data, &buf_type);
 			pSMBr = (struct smb_com_read_rsp *)read_data;
 			if (read_data) {
@@ -1794,7 +1819,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
 	int xid;
 	char *current_offset;
 	struct cifsFileInfo *open_file;
+	struct cifs_io_parms io_parms;
 	int buf_type = CIFS_NO_BUFFER;
+	__u32 pid;
 
 	xid = GetXid();
 	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
@@ -1807,6 +1834,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
 	open_file = file->private_data;
 	pTcon = tlink_tcon(open_file->tlink);
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+		pid = open_file->pid;
+	else
+		pid = current->tgid;
+
 	if ((file->f_flags & O_ACCMODE) == O_WRONLY)
 		cFYI(1, "attempting read on write only file instance");
 
@@ -1829,11 +1861,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
 				if (rc != 0)
 					break;
 			}
-			rc = CIFSSMBRead(xid, pTcon,
-					 open_file->netfid,
-					 current_read_size, *poffset,
-					 &bytes_read, &current_offset,
-					 &buf_type);
+			io_parms.netfid = open_file->netfid;
+			io_parms.pid = pid;
+			io_parms.tcon = pTcon;
+			io_parms.offset = *poffset;
+			io_parms.length = current_read_size;
+			rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
+					 &current_offset, &buf_type);
 		}
 		if (rc || (bytes_read == 0)) {
 			if (total_read) {
@@ -1970,7 +2004,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 	char *smb_read_data = NULL;
 	struct smb_com_read_rsp *pSMBr;
 	struct cifsFileInfo *open_file;
+	struct cifs_io_parms io_parms;
 	int buf_type = CIFS_NO_BUFFER;
+	__u32 pid;
 
 	xid = GetXid();
 	if (file->private_data == NULL) {
@@ -1992,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 		goto read_complete;
 
 	cFYI(DBG2, "rpages: num pages %d", num_pages);
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+		pid = open_file->pid;
+	else
+		pid = current->tgid;
+
 	for (i = 0; i < num_pages; ) {
 		unsigned contig_pages;
 		struct page *tmp_page;
@@ -2033,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 				if (rc != 0)
 					break;
 			}
-
-			rc = CIFSSMBRead(xid, pTcon,
-					 open_file->netfid,
-					 read_size, offset,
-					 &bytes_read, &smb_read_data,
-					 &buf_type);
+			io_parms.netfid = open_file->netfid;
+			io_parms.pid = pid;
+			io_parms.tcon = pTcon;
+			io_parms.offset = offset;
+			io_parms.length = read_size;
+			rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
+					 &smb_read_data, &buf_type);
 			/* BB more RC checks ? */
 			if (rc == -EAGAIN) {
 				if (smb_read_data) {
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 53ea625..e2d9dd8 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -374,6 +374,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
 	__u16 netfid;
 	struct tcon_link *tlink;
 	struct cifsTconInfo *tcon;
+	struct cifs_io_parms io_parms;
 	char buf[24];
 	unsigned int bytes_read;
 	char *pbuf;
@@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
 	if (rc == 0) {
 		int buf_type = CIFS_NO_BUFFER;
 			/* Read header */
-		rc = CIFSSMBRead(xid, tcon, netfid,
-				 24 /* length */, 0 /* offset */,
-				 &bytes_read, &pbuf, &buf_type);
+		io_parms.netfid = netfid;
+		io_parms.pid = current->tgid;
+		io_parms.tcon = tcon;
+		io_parms.offset = 0;
+		io_parms.length = 24;
+		rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
+				 &buf_type);
 		if ((rc == 0) && (bytes_read >= 8)) {
 			if (memcmp("IntxBLK", pbuf, 8) == 0) {
 				cFYI(1, "Block device");
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 1a6a388..4682d44 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -235,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
 	unsigned int bytes_read = 0;
 	int buf_type = CIFS_NO_BUFFER;
 	unsigned int link_len = 0;
+	struct cifs_io_parms io_parms;
 	FILE_ALL_INFO file_info;
 
 	rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
@@ -253,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
 	if (!buf)
 		return -ENOMEM;
 	pbuf = buf;
+	io_parms.netfid = netfid;
+	io_parms.pid = current->tgid;
+	io_parms.tcon = tcon;
+	io_parms.offset = 0;
+	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
 
-	rc = CIFSSMBRead(xid, tcon, netfid,
-			 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
-			 0 /* offset */,
-			 &bytes_read, &pbuf, &buf_type);
+	rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
 	CIFSSMBClose(xid, tcon, netfid);
 	if (rc != 0) {
 		kfree(buf);
@@ -296,6 +299,7 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
 	__u16 netfid = 0;
 	struct tcon_link *tlink;
 	struct cifsTconInfo *pTcon;
+	struct cifs_io_parms io_parms;
 	u8 *buf;
 	char *pbuf;
 	unsigned int bytes_read = 0;
@@ -332,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
 		goto out;
 	}
 	pbuf = buf;
+	io_parms.netfid = netfid;
+	io_parms.pid = current->tgid;
+	io_parms.tcon = pTcon;
+	io_parms.offset = 0;
+	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
 
-	rc = CIFSSMBRead(xid, pTcon, netfid,
-			 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
-			 0 /* offset */,
-			 &bytes_read, &pbuf, &buf_type);
+	rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
 	CIFSSMBClose(xid, pTcon, netfid);
 	if (rc != 0) {
 		kfree(buf);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found] ` <1306389721-28550-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
  2011-05-26  6:01   ` [PATCH 1/2] CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size Pavel Shilovsky
  2011-05-26  6:02   ` [PATCH 2/2] CIFS: Add rwpidforward mount option Pavel Shilovsky
@ 2011-05-26  6:02   ` Pavel Shilovsky
       [not found]     ` <1306389721-28550-4-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
  2 siblings, 1 reply; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26  6:02 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

Add cifs_match_super to use in sget to share superblock between mounts
that have the same //server/sharename, credentials and mount options.
It helps us to improve performance on work with future SMB2.1 leases.

Reviewed-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
---
 fs/cifs/cifsfs.c   |   19 ++++++++++-
 fs/cifs/cifsglob.h |   19 +++++++++++
 fs/cifs/connect.c  |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 46fdd55..360fe2e 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -630,6 +630,7 @@ cifs_do_mount(struct file_system_type *fs_type,
 	struct super_block *sb;
 	struct cifs_sb_info *cifs_sb;
 	struct smb_vol *volume_info;
+	struct cifs_mnt_data mnt_data;
 	struct dentry *root;
 
 	cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
@@ -646,12 +647,21 @@ cifs_do_mount(struct file_system_type *fs_type,
 
 	cifs_setup_cifs_sb(volume_info, cifs_sb);
 
-	sb = sget(fs_type, NULL, set_anon_super, NULL);
+	mnt_data.vol = volume_info;
+	mnt_data.cifs_sb = cifs_sb;
+	mnt_data.flags = flags;
+
+	sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
 	if (IS_ERR(sb)) {
 		root = ERR_CAST(sb);
 		goto out_cifs_sb;
 	}
 
+	if (sb->s_fs_info) {
+		cFYI(1, "Use existing superblock");
+		goto out_shared;
+	}
+
 	/*
 	 * Copy mount params for use in submounts. Better to do
 	 * the copy here and deal with the error before cleanup gets
@@ -680,9 +690,16 @@ cifs_do_mount(struct file_system_type *fs_type,
 	root = cifs_get_root(volume_info, sb);
 	if (root == NULL)
 		goto out_super;
+
 	cFYI(1, "dentry root is: %p", root);
 	goto out;
 
+out_shared:
+	root = cifs_get_root(volume_info, sb);
+	if (root)
+		cFYI(1, "dentry root is: %p", root);
+	goto out;
+
 out_super:
 	kfree(cifs_sb->mountdata);
 	deactivate_locked_super(sb);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index f57387a..7f90488 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -210,6 +210,25 @@ struct smb_vol {
 	struct nls_table *local_nls;
 };
 
+#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
+			 CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
+			 CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
+			 CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
+			 CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
+			 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
+			 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
+			 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
+			 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
+
+#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
+		      MS_NODEV | MS_SYNCHRONOUS)
+
+struct cifs_mnt_data {
+	struct cifs_sb_info *cifs_sb;
+	struct smb_vol *vol;
+	int flags;
+};
+
 struct TCP_Server_Info {
 	struct list_head tcp_ses_list;
 	struct list_head smb_ses_list;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4f34519..3172baa 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2146,6 +2146,96 @@ cifs_put_tlink(struct tcon_link *tlink)
 	return;
 }
 
+static inline struct tcon_link *
+cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb);
+
+static int
+compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
+{
+	struct cifs_sb_info *old = CIFS_SB(sb);
+	struct cifs_sb_info *new = mnt_data->cifs_sb;
+
+	if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
+		return 0;
+
+	if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
+	    (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
+		return 0;
+
+	if (old->rsize != new->rsize)
+		return 0;
+
+	if (new->wsize && new->wsize > old->wsize)
+		return 0;
+
+	if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
+		return 0;
+
+	if (old->mnt_file_mode != new->mnt_file_mode ||
+	    old->mnt_dir_mode != new->mnt_dir_mode)
+		return 0;
+
+	if (strcmp(old->local_nls->charset, new->local_nls->charset))
+		return 0;
+
+	if (old->actimeo != new->actimeo)
+		return 0;
+
+	return 1;
+}
+
+int
+cifs_match_super(struct super_block *sb, void *data)
+{
+	struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
+	struct smb_vol *volume_info;
+	struct cifs_sb_info *cifs_sb;
+	struct TCP_Server_Info *tcp_srv;
+	struct cifsSesInfo *ses;
+	struct cifsTconInfo *tcon;
+	struct tcon_link *tlink;
+	struct sockaddr_storage addr;
+	int rc = 0;
+
+	memset(&addr, 0, sizeof(struct sockaddr_storage));
+
+	spin_lock(&cifs_tcp_ses_lock);
+	cifs_sb = CIFS_SB(sb);
+	tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
+	if (IS_ERR(tlink)) {
+		spin_unlock(&cifs_tcp_ses_lock);
+		return rc;
+	}
+	tcon = tlink_tcon(tlink);
+	ses = tcon->ses;
+	tcp_srv = ses->server;
+
+	volume_info = mnt_data->vol;
+
+	if (!volume_info->UNCip || !volume_info->UNC)
+		goto out;
+
+	rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
+				volume_info->UNCip,
+				strlen(volume_info->UNCip),
+				volume_info->port);
+	if (!rc)
+		goto out;
+
+	if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
+	    !match_session(ses, volume_info) ||
+	    !match_tcon(tcon, volume_info->UNC)) {
+		rc = 0;
+		goto out;
+	}
+
+	rc = compare_mount_options(sb, mnt_data);
+out:
+	cifs_put_tlink(tlink);
+	spin_unlock(&cifs_tcp_ses_lock);
+	return rc;
+}
+
 int
 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
 	     const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found]     ` <1306389721-28550-4-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
@ 2011-05-26 14:09       ` Jeff Layton
  2011-05-26 15:20       ` Jeff Layton
  1 sibling, 0 replies; 13+ messages in thread
From: Jeff Layton @ 2011-05-26 14:09 UTC (permalink / raw)
  To: Pavel Shilovsky; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA

On Thu, 26 May 2011 10:02:01 +0400
Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:

> Add cifs_match_super to use in sget to share superblock between mounts
> that have the same //server/sharename, credentials and mount options.
> It helps us to improve performance on work with future SMB2.1 leases.
> 
> Reviewed-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
> ---
>  fs/cifs/cifsfs.c   |   19 ++++++++++-
>  fs/cifs/cifsglob.h |   19 +++++++++++
>  fs/cifs/connect.c  |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 127 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 46fdd55..360fe2e 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -630,6 +630,7 @@ cifs_do_mount(struct file_system_type *fs_type,
>  	struct super_block *sb;
>  	struct cifs_sb_info *cifs_sb;
>  	struct smb_vol *volume_info;
> +	struct cifs_mnt_data mnt_data;
>  	struct dentry *root;
>  
>  	cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
> @@ -646,12 +647,21 @@ cifs_do_mount(struct file_system_type *fs_type,
>  
>  	cifs_setup_cifs_sb(volume_info, cifs_sb);
>  
> -	sb = sget(fs_type, NULL, set_anon_super, NULL);
> +	mnt_data.vol = volume_info;
> +	mnt_data.cifs_sb = cifs_sb;
> +	mnt_data.flags = flags;
> +
> +	sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
>  	if (IS_ERR(sb)) {
>  		root = ERR_CAST(sb);
>  		goto out_cifs_sb;
>  	}
>  
> +	if (sb->s_fs_info) {
> +		cFYI(1, "Use existing superblock");
> +		goto out_shared;
> +	}
> +
>  	/*
>  	 * Copy mount params for use in submounts. Better to do
>  	 * the copy here and deal with the error before cleanup gets
> @@ -680,9 +690,16 @@ cifs_do_mount(struct file_system_type *fs_type,
>  	root = cifs_get_root(volume_info, sb);
>  	if (root == NULL)
>  		goto out_super;
> +
>  	cFYI(1, "dentry root is: %p", root);
>  	goto out;
>  
> +out_shared:
> +	root = cifs_get_root(volume_info, sb);
> +	if (root)
> +		cFYI(1, "dentry root is: %p", root);
> +	goto out;
> +
>  out_super:
>  	kfree(cifs_sb->mountdata);
>  	deactivate_locked_super(sb);
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index f57387a..7f90488 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -210,6 +210,25 @@ struct smb_vol {
>  	struct nls_table *local_nls;
>  };
>  
> +#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
> +			 CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
> +			 CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
> +			 CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
> +			 CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
> +			 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
> +			 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
> +			 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
> +			 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
> +
> +#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
> +		      MS_NODEV | MS_SYNCHRONOUS)
> +
> +struct cifs_mnt_data {
> +	struct cifs_sb_info *cifs_sb;
> +	struct smb_vol *vol;
> +	int flags;
> +};
> +
>  struct TCP_Server_Info {
>  	struct list_head tcp_ses_list;
>  	struct list_head smb_ses_list;
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 4f34519..3172baa 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -2146,6 +2146,96 @@ cifs_put_tlink(struct tcon_link *tlink)
>  	return;
>  }
>  
> +static inline struct tcon_link *
> +cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb);
> +
> +static int
> +compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
> +{
> +	struct cifs_sb_info *old = CIFS_SB(sb);
> +	struct cifs_sb_info *new = mnt_data->cifs_sb;
> +
> +	if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
> +		return 0;
> +
> +	if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
> +	    (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
> +		return 0;
> +
> +	if (old->rsize != new->rsize)
> +		return 0;
> +
> +	if (new->wsize && new->wsize > old->wsize)
> +		return 0;
> +

Currently, this will never be checked as the wsize in the new sb isn't
set yet and will always be 0. I think the right fix is to have
cifs_setup_cifs_sb() set the wsize in the new sb unconditionally to
whatever it was set to in the smb_vol. If we end up using the new sb
then cifs_negotiate_wsize will later negotiate it downward if needed.

> +	if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
> +		return 0;
> +
> +	if (old->mnt_file_mode != new->mnt_file_mode ||
> +	    old->mnt_dir_mode != new->mnt_dir_mode)
> +		return 0;
> +
> +	if (strcmp(old->local_nls->charset, new->local_nls->charset))
> +		return 0;
> +
> +	if (old->actimeo != new->actimeo)
> +		return 0;
> +
> +	return 1;
> +}
> +
> +int
> +cifs_match_super(struct super_block *sb, void *data)
> +{
> +	struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
> +	struct smb_vol *volume_info;
> +	struct cifs_sb_info *cifs_sb;
> +	struct TCP_Server_Info *tcp_srv;
> +	struct cifsSesInfo *ses;
> +	struct cifsTconInfo *tcon;
> +	struct tcon_link *tlink;
> +	struct sockaddr_storage addr;
> +	int rc = 0;
> +
> +	memset(&addr, 0, sizeof(struct sockaddr_storage));
> +
> +	spin_lock(&cifs_tcp_ses_lock);
> +	cifs_sb = CIFS_SB(sb);
> +	tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
> +	if (IS_ERR(tlink)) {
> +		spin_unlock(&cifs_tcp_ses_lock);
> +		return rc;
> +	}
> +	tcon = tlink_tcon(tlink);
> +	ses = tcon->ses;
> +	tcp_srv = ses->server;
> +
> +	volume_info = mnt_data->vol;
> +
> +	if (!volume_info->UNCip || !volume_info->UNC)
> +		goto out;
> +
> +	rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
> +				volume_info->UNCip,
> +				strlen(volume_info->UNCip),
> +				volume_info->port);
> +	if (!rc)
> +		goto out;
> +
> +	if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
> +	    !match_session(ses, volume_info) ||
> +	    !match_tcon(tcon, volume_info->UNC)) {
> +		rc = 0;
> +		goto out;
> +	}
> +
> +	rc = compare_mount_options(sb, mnt_data);
> +out:
> +	cifs_put_tlink(tlink);
> +	spin_unlock(&cifs_tcp_ses_lock);
> +	return rc;
> +}
> +
>  int
>  get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
>  	     const struct nls_table *nls_codepage, unsigned int *pnum_referrals,


-- 
Jeff Layton <jlayton-vpEMnDpepFuMZCB2o+C8xQ@public.gmane.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found]     ` <1306389721-28550-4-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
  2011-05-26 14:09       ` Jeff Layton
@ 2011-05-26 15:20       ` Jeff Layton
       [not found]         ` <20110526112001.6602ce52-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
  1 sibling, 1 reply; 13+ messages in thread
From: Jeff Layton @ 2011-05-26 15:20 UTC (permalink / raw)
  To: Pavel Shilovsky; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA

On Thu, 26 May 2011 10:02:01 +0400
Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:

> Add cifs_match_super to use in sget to share superblock between mounts
> that have the same //server/sharename, credentials and mount options.
> It helps us to improve performance on work with future SMB2.1 leases.
> 
> Reviewed-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
> ---
>  fs/cifs/cifsfs.c   |   19 ++++++++++-
>  fs/cifs/cifsglob.h |   19 +++++++++++
>  fs/cifs/connect.c  |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 127 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 46fdd55..360fe2e 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -630,6 +630,7 @@ cifs_do_mount(struct file_system_type *fs_type,
>  	struct super_block *sb;
>  	struct cifs_sb_info *cifs_sb;
>  	struct smb_vol *volume_info;
> +	struct cifs_mnt_data mnt_data;
>  	struct dentry *root;
>  
>  	cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
> @@ -646,12 +647,21 @@ cifs_do_mount(struct file_system_type *fs_type,
>  
>  	cifs_setup_cifs_sb(volume_info, cifs_sb);
>  
> -	sb = sget(fs_type, NULL, set_anon_super, NULL);
> +	mnt_data.vol = volume_info;
> +	mnt_data.cifs_sb = cifs_sb;
> +	mnt_data.flags = flags;
> +
> +	sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
>  	if (IS_ERR(sb)) {
>  		root = ERR_CAST(sb);
>  		goto out_cifs_sb;
>  	}
>  
> +	if (sb->s_fs_info) {
> +		cFYI(1, "Use existing superblock");
> +		goto out_shared;
> +	}
> +
>  	/*
>  	 * Copy mount params for use in submounts. Better to do
>  	 * the copy here and deal with the error before cleanup gets
> @@ -680,9 +690,16 @@ cifs_do_mount(struct file_system_type *fs_type,
>  	root = cifs_get_root(volume_info, sb);
>  	if (root == NULL)
>  		goto out_super;
> +
>  	cFYI(1, "dentry root is: %p", root);
>  	goto out;
>  
> +out_shared:
> +	root = cifs_get_root(volume_info, sb);
> +	if (root)
> +		cFYI(1, "dentry root is: %p", root);
> +	goto out;
> +
>  out_super:
>  	kfree(cifs_sb->mountdata);
>  	deactivate_locked_super(sb);
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index f57387a..7f90488 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -210,6 +210,25 @@ struct smb_vol {
>  	struct nls_table *local_nls;
>  };
>  
> +#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
> +			 CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
> +			 CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
> +			 CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
> +			 CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
> +			 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
> +			 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
> +			 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
> +			 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
> +
> +#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
> +		      MS_NODEV | MS_SYNCHRONOUS)
> +
> +struct cifs_mnt_data {
> +	struct cifs_sb_info *cifs_sb;
> +	struct smb_vol *vol;
> +	int flags;
> +};
> +
>  struct TCP_Server_Info {
>  	struct list_head tcp_ses_list;
>  	struct list_head smb_ses_list;
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 4f34519..3172baa 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -2146,6 +2146,96 @@ cifs_put_tlink(struct tcon_link *tlink)
>  	return;
>  }
>  
> +static inline struct tcon_link *
> +cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb);
> +
> +static int
> +compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
> +{
> +	struct cifs_sb_info *old = CIFS_SB(sb);
> +	struct cifs_sb_info *new = mnt_data->cifs_sb;
> +
> +	if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
> +		return 0;
> +
> +	if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
> +	    (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
> +		return 0;
> +
> +	if (old->rsize != new->rsize)
> +		return 0;
> +
> +	if (new->wsize && new->wsize > old->wsize)
> +		return 0;
> +

...also I think the above condition should be reversed. We don't want
to match if new->wsize is smaller than the existing one. Since the
specified wsize is just a starting point for negotiation, wsize now
means "any wsize less than or equal to this size". If the old->wsize is
bigger than that, then it's outside that range and we shouldn't match.

> +	if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
> +		return 0;
> +
> +	if (old->mnt_file_mode != new->mnt_file_mode ||
> +	    old->mnt_dir_mode != new->mnt_dir_mode)
> +		return 0;
> +
> +	if (strcmp(old->local_nls->charset, new->local_nls->charset))
> +		return 0;
> +
> +	if (old->actimeo != new->actimeo)
> +		return 0;
> +
> +	return 1;
> +}
> +
> +int
> +cifs_match_super(struct super_block *sb, void *data)
> +{
> +	struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
> +	struct smb_vol *volume_info;
> +	struct cifs_sb_info *cifs_sb;
> +	struct TCP_Server_Info *tcp_srv;
> +	struct cifsSesInfo *ses;
> +	struct cifsTconInfo *tcon;
> +	struct tcon_link *tlink;
> +	struct sockaddr_storage addr;
> +	int rc = 0;
> +
> +	memset(&addr, 0, sizeof(struct sockaddr_storage));
> +
> +	spin_lock(&cifs_tcp_ses_lock);
> +	cifs_sb = CIFS_SB(sb);
> +	tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
> +	if (IS_ERR(tlink)) {
> +		spin_unlock(&cifs_tcp_ses_lock);
> +		return rc;
> +	}
> +	tcon = tlink_tcon(tlink);
> +	ses = tcon->ses;
> +	tcp_srv = ses->server;
> +
> +	volume_info = mnt_data->vol;
> +
> +	if (!volume_info->UNCip || !volume_info->UNC)
> +		goto out;
> +
> +	rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
> +				volume_info->UNCip,
> +				strlen(volume_info->UNCip),
> +				volume_info->port);
> +	if (!rc)
> +		goto out;
> +
> +	if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
> +	    !match_session(ses, volume_info) ||
> +	    !match_tcon(tcon, volume_info->UNC)) {
> +		rc = 0;
> +		goto out;
> +	}
> +
> +	rc = compare_mount_options(sb, mnt_data);
> +out:
> +	cifs_put_tlink(tlink);
> +	spin_unlock(&cifs_tcp_ses_lock);
> +	return rc;
> +}
> +
>  int
>  get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
>  	     const struct nls_table *nls_codepage, unsigned int *pnum_referrals,


-- 
Jeff Layton <jlayton-vpEMnDpepFuMZCB2o+C8xQ@public.gmane.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found]         ` <20110526112001.6602ce52-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
@ 2011-05-26 16:06           ` Steve French
       [not found]             ` <BANLkTim+a8swvWytQwUQqE+1s+wVnX3gRg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 13+ messages in thread
From: Steve French @ 2011-05-26 16:06 UTC (permalink / raw)
  To: Jeff Layton; +Cc: Pavel Shilovsky, linux-cifs-u79uwXL29TY76Z2rM5mHXA

On Thu, May 26, 2011 at 10:20 AM, Jeff Layton <jlayton-vpEMnDpepFuMZCB2o+C8xQ@public.gmane.org> wrote:
> On Thu, 26 May 2011 10:02:01 +0400
> Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:
>
>> Add cifs_match_super to use in sget to share superblock between mounts
>> that have the same //server/sharename, credentials and mount options.
>> It helps us to improve performance on work with future SMB2.1 leases.
<snip>
>> +static int
>> +compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
>> +{
>> +     struct cifs_sb_info *old = CIFS_SB(sb);
>> +     struct cifs_sb_info *new = mnt_data->cifs_sb;
>> +
>> +     if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
>> +             return 0;
>> +
>> +     if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
>> +         (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
>> +             return 0;
>> +
>> +     if (old->rsize != new->rsize)
>> +             return 0;
>> +
>> +     if (new->wsize && new->wsize > old->wsize)
>> +             return 0;
>> +
>
> ...also I think the above condition should be reversed. We don't want
> to match if new->wsize is smaller than the existing one. Since the
> specified wsize is just a starting point for negotiation, wsize now
> means "any wsize less than or equal to this size". If the old->wsize is
> bigger than that, then it's outside that range and we shouldn't match.

A more important question is whether the user intentionally tried to
specify a wsize.  I don't see a problem matching a new default mount
request (with no wsize specified, using therefore a default wsize)
with an existing mount (with a larger explicitly specified wsize).
If a user explicitly requests to override to a particular wsize on the 2nd
mount - seems more logical to give them what they ask for if
possible whether larger or smaller.


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found]             ` <BANLkTim+a8swvWytQwUQqE+1s+wVnX3gRg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-05-26 16:14               ` Pavel Shilovsky
       [not found]                 ` <BANLkTi==YrNa1quPtEFW0T3_yxCrCq_+sA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2011-05-26 18:45               ` Jeff Layton
  1 sibling, 1 reply; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26 16:14 UTC (permalink / raw)
  To: Steve French; +Cc: Jeff Layton, linux-cifs-u79uwXL29TY76Z2rM5mHXA

2011/5/26 Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> On Thu, May 26, 2011 at 10:20 AM, Jeff Layton <jlayton-vpEMnDpepFvY2uhgrK1nQg@public.gmane.orgt> wrote:
>> On Thu, 26 May 2011 10:02:01 +0400
>> Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:
>>
>>> Add cifs_match_super to use in sget to share superblock between mounts
>>> that have the same //server/sharename, credentials and mount options.
>>> It helps us to improve performance on work with future SMB2.1 leases.
> <snip>
>>> +static int
>>> +compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
>>> +{
>>> +     struct cifs_sb_info *old = CIFS_SB(sb);
>>> +     struct cifs_sb_info *new = mnt_data->cifs_sb;
>>> +
>>> +     if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
>>> +             return 0;
>>> +
>>> +     if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
>>> +         (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
>>> +             return 0;
>>> +
>>> +     if (old->rsize != new->rsize)
>>> +             return 0;
>>> +
>>> +     if (new->wsize && new->wsize > old->wsize)
>>> +             return 0;
>>> +
>>
>> ...also I think the above condition should be reversed. We don't want
>> to match if new->wsize is smaller than the existing one. Since the
>> specified wsize is just a starting point for negotiation, wsize now
>> means "any wsize less than or equal to this size". If the old->wsize is
>> bigger than that, then it's outside that range and we shouldn't match.
>
> A more important question is whether the user intentionally tried to
> specify a wsize.  I don't see a problem matching a new default mount
> request (with no wsize specified, using therefore a default wsize)
> with an existing mount (with a larger explicitly specified wsize).
> If a user explicitly requests to override to a particular wsize on the 2nd
> mount - seems more logical to give them what they ask for if
> possible whether larger or smaller.
>

If I understand right, Jeff suggested to change wsize logic to: "less
or equal that specified one". In this case we can share any sb that
match this criteria. So, in this case it should be "if (new->wsize &&
new->wsize <= old->wsize) return 0;"

-- 
Best regards,
Pavel Shilovsky.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found]                 ` <BANLkTi==YrNa1quPtEFW0T3_yxCrCq_+sA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-05-26 16:17                   ` Pavel Shilovsky
       [not found]                     ` <BANLkTikkbBO6iZsf7ckUFFiMdUbuLi7HNA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26 16:17 UTC (permalink / raw)
  To: Steve French; +Cc: Jeff Layton, linux-cifs-u79uwXL29TY76Z2rM5mHXA

2011/5/26 Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>:
> 2011/5/26 Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
>> On Thu, May 26, 2011 at 10:20 AM, Jeff Layton <jlayton@poochiereds.net> wrote:
>>> On Thu, 26 May 2011 10:02:01 +0400
>>> Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:
>>>
>>>> Add cifs_match_super to use in sget to share superblock between mounts
>>>> that have the same //server/sharename, credentials and mount options.
>>>> It helps us to improve performance on work with future SMB2.1 leases.
>> <snip>
>>>> +static int
>>>> +compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
>>>> +{
>>>> +     struct cifs_sb_info *old = CIFS_SB(sb);
>>>> +     struct cifs_sb_info *new = mnt_data->cifs_sb;
>>>> +
>>>> +     if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
>>>> +             return 0;
>>>> +
>>>> +     if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
>>>> +         (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
>>>> +             return 0;
>>>> +
>>>> +     if (old->rsize != new->rsize)
>>>> +             return 0;
>>>> +
>>>> +     if (new->wsize && new->wsize > old->wsize)
>>>> +             return 0;
>>>> +
>>>
>>> ...also I think the above condition should be reversed. We don't want
>>> to match if new->wsize is smaller than the existing one. Since the
>>> specified wsize is just a starting point for negotiation, wsize now
>>> means "any wsize less than or equal to this size". If the old->wsize is
>>> bigger than that, then it's outside that range and we shouldn't match.
>>
>> A more important question is whether the user intentionally tried to
>> specify a wsize.  I don't see a problem matching a new default mount
>> request (with no wsize specified, using therefore a default wsize)
>> with an existing mount (with a larger explicitly specified wsize).
>> If a user explicitly requests to override to a particular wsize on the 2nd
>> mount - seems more logical to give them what they ask for if
>> possible whether larger or smaller.
>>
>
> If I understand right, Jeff suggested to change wsize logic to: "less
> or equal that specified one". In this case we can share any sb that
> match this criteria. So, in this case it should be "if (new->wsize &&
> new->wsize <= old->wsize) return 0;"

Sorry - new->wsize >= old->wsize
>
> --
> Best regards,
> Pavel Shilovsky.
>



-- 
Best regards,
Pavel Shilovsky.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found]                     ` <BANLkTikkbBO6iZsf7ckUFFiMdUbuLi7HNA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-05-26 16:21                       ` Pavel Shilovsky
  0 siblings, 0 replies; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26 16:21 UTC (permalink / raw)
  To: Steve French; +Cc: Jeff Layton, linux-cifs-u79uwXL29TY76Z2rM5mHXA

2011/5/26 Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>:
> 2011/5/26 Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>:
>> If I understand right, Jeff suggested to change wsize logic to: "less
>> or equal that specified one". In this case we can share any sb that
>> match this criteria. So, in this case it should be "if (new->wsize &&
>> new->wsize <= old->wsize) return 0;"
>
> Sorry - new->wsize >= old->wsize

Sorry again - I confused myself :)

The code should be:
if (new->wsize && new->wsize < old->wsize)
  return 0; /* don't match */

-- 
Best regards,
Pavel Shilovsky.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [v4 PATCH 4/4] CIFS: Migrate to shared superblock model
       [not found]             ` <BANLkTim+a8swvWytQwUQqE+1s+wVnX3gRg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2011-05-26 16:14               ` Pavel Shilovsky
@ 2011-05-26 18:45               ` Jeff Layton
  1 sibling, 0 replies; 13+ messages in thread
From: Jeff Layton @ 2011-05-26 18:45 UTC (permalink / raw)
  To: Steve French; +Cc: Pavel Shilovsky, linux-cifs-u79uwXL29TY76Z2rM5mHXA

On Thu, 26 May 2011 11:06:59 -0500
Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> On Thu, May 26, 2011 at 10:20 AM, Jeff Layton <jlayton-vpEMnDpepFvY2uhgrK1nQg@public.gmane.orgt> wrote:
> > On Thu, 26 May 2011 10:02:01 +0400
> > Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:
> >
> >> Add cifs_match_super to use in sget to share superblock between mounts
> >> that have the same //server/sharename, credentials and mount options.
> >> It helps us to improve performance on work with future SMB2.1 leases.
> <snip>
> >> +static int
> >> +compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
> >> +{
> >> +     struct cifs_sb_info *old = CIFS_SB(sb);
> >> +     struct cifs_sb_info *new = mnt_data->cifs_sb;
> >> +
> >> +     if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
> >> +             return 0;
> >> +
> >> +     if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
> >> +         (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
> >> +             return 0;
> >> +
> >> +     if (old->rsize != new->rsize)
> >> +             return 0;
> >> +
> >> +     if (new->wsize && new->wsize > old->wsize)
> >> +             return 0;
> >> +
> >
> > ...also I think the above condition should be reversed. We don't want
> > to match if new->wsize is smaller than the existing one. Since the
> > specified wsize is just a starting point for negotiation, wsize now
> > means "any wsize less than or equal to this size". If the old->wsize is
> > bigger than that, then it's outside that range and we shouldn't match.
> 
> A more important question is whether the user intentionally tried to
> specify a wsize.  I don't see a problem matching a new default mount
> request (with no wsize specified, using therefore a default wsize)
> with an existing mount (with a larger explicitly specified wsize).
> If a user explicitly requests to override to a particular wsize on the 2nd
> mount - seems more logical to give them what they ask for if
> possible whether larger or smaller.
> 
> 

Good point. That will probably mean that you'll need to separately
track the "requested" wsize and the "actual" wsize. Honestly though, I
don't see this as a huge issue. I suggest we take this patch as-is and
plan to fix that later.

-- 
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size
       [not found]     ` <1306389721-28550-2-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
@ 2011-05-26 18:51       ` Jeff Layton
       [not found]         ` <20110526145147.4fa2ba35-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
  0 siblings, 1 reply; 13+ messages in thread
From: Jeff Layton @ 2011-05-26 18:51 UTC (permalink / raw)
  To: Pavel Shilovsky; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA

On Thu, 26 May 2011 10:01:59 +0400
Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:

> We need it to make them work with mandatory locking style because
> we can fail in a situation like when kernel need to flush dirty pages
> and there is a lock held by a process who opened file.
> 
> Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
> ---
>  fs/cifs/cifsglob.h  |    8 ++++++++
>  fs/cifs/cifsproto.h |   13 +++++--------
>  fs/cifs/cifssmb.c   |   33 ++++++++++++++++++++++++++-------
>  fs/cifs/dir.c       |   18 ++++++++++--------
>  fs/cifs/file.c      |   31 +++++++++++++++++++++----------
>  fs/cifs/inode.c     |   24 ++++++++++++++++++------
>  fs/cifs/link.c      |   12 ++++++++----
>  7 files changed, 96 insertions(+), 43 deletions(-)
> 
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 7f90488..ca0c378 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -529,6 +529,14 @@ struct cifsFileInfo {
>  	struct work_struct oplock_break; /* work for oplock breaks */
>  };
>  
> +struct cifs_io_parms {
> +	__u16 netfid;
> +	__u32 pid;
> +	__u64 offset;
> +	unsigned int length;
> +	struct cifsTconInfo *tcon;
> +};
> +
	^^^^^^^^^^
I'm not sure this is really needed -- it seems like it would make more
sense to just pass in a cifsFileInfo pointer to these functions. That
already contains most of these args, aside from the offset and length.

>  /*
>   * Take a reference on the file private data. Must be called with
>   * cifs_file_list_lock held.
> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> index bba7470..e41f607 100644
> --- a/fs/cifs/cifsproto.h
> +++ b/fs/cifs/cifsproto.h
> @@ -349,15 +349,12 @@ extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
>  			const int netfid, unsigned int count,
>  			const __u64 lseek, unsigned int *nbytes, char **buf,
>  			int *return_buf_type);
> -extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
> -			const int netfid, const unsigned int count,
> -			const __u64 lseek, unsigned int *nbytes,
> -			const char *buf, const char __user *ubuf,
> +extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
> +			unsigned int *nbytes, const char *buf,
> +			const char __user *ubuf, const int long_op);
> +extern int CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
> +			unsigned int *nbytes, struct kvec *iov, const int nvec,
>  			const int long_op);
> -extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
> -			const int netfid, const unsigned int count,
> -			const __u64 offset, unsigned int *nbytes,
> -			struct kvec *iov, const int nvec, const int long_op);
>  extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
>  			const unsigned char *searchName, __u64 *inode_number,
>  			const struct nls_table *nls_codepage,
> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> index 136df01..f39fa08 100644
> --- a/fs/cifs/cifssmb.c
> +++ b/fs/cifs/cifssmb.c
> @@ -1487,9 +1487,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
>  
>  
>  int
> -CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
> -	     const int netfid, const unsigned int count,
> -	     const __u64 offset, unsigned int *nbytes, const char *buf,
> +CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
> +	     unsigned int *nbytes, const char *buf,
>  	     const char __user *ubuf, const int long_op)
>  {
>  	int rc = -EACCES;
> @@ -1498,6 +1497,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
>  	int bytes_returned, wct;
>  	__u32 bytes_sent;
>  	__u16 byte_count;
> +	__u32 pid = io_parms->pid;
> +	__u16 netfid = io_parms->netfid;
> +	__u64 offset = io_parms->offset;
> +	struct cifsTconInfo *tcon = io_parms->tcon;
> +	unsigned int count = io_parms->length;
>  
>  	*nbytes = 0;
>  
> @@ -1519,6 +1523,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
>  		      (void **) &pSMBr);
>  	if (rc)
>  		return rc;
> +
> +	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
> +	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
> +
>  	/* tcon and ses pointer are checked in smb_init */
>  	if (tcon->ses->server == NULL)
>  		return -ECONNABORTED;
> @@ -1778,6 +1786,9 @@ cifs_async_writev(struct cifs_writedata *wdata)
>  		goto async_writev_out;
>  	}
>  
> +	smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
> +	smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
> +
>  	smb->AndXCommand = 0xFF;	/* none */
>  	smb->Fid = wdata->cfile->netfid;
>  	smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
> @@ -1841,16 +1852,20 @@ async_writev_out:
>  }
>  
>  int
> -CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
> -	     const int netfid, const unsigned int count,
> -	     const __u64 offset, unsigned int *nbytes, struct kvec *iov,
> -	     int n_vec, const int long_op)
> +CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
> +	      unsigned int *nbytes, struct kvec *iov, int n_vec,
> +	      const int long_op)
>  {
>  	int rc = -EACCES;
>  	WRITE_REQ *pSMB = NULL;
>  	int wct;
>  	int smb_hdr_len;
>  	int resp_buf_type = 0;
> +	__u32 pid = io_parms->pid;
> +	__u16 netfid = io_parms->netfid;
> +	__u64 offset = io_parms->offset;
> +	struct cifsTconInfo *tcon = io_parms->tcon;
> +	unsigned int count = io_parms->length;
>  
>  	*nbytes = 0;
>  
> @@ -1868,6 +1883,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
>  	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
>  	if (rc)
>  		return rc;
> +
> +	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
> +	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
> +
>  	/* tcon and ses pointer are checked in smb_init */
>  	if (tcon->ses->server == NULL)
>  		return -ECONNABORTED;
> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
> index c33446d..aa0669a 100644
> --- a/fs/cifs/dir.c
> +++ b/fs/cifs/dir.c
> @@ -354,6 +354,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>  	struct cifs_sb_info *cifs_sb;
>  	struct tcon_link *tlink;
>  	struct cifsTconInfo *pTcon;
> +	struct cifs_io_parms io_parms;
>  	char *full_path = NULL;
>  	struct inode *newinode = NULL;
>  	int oplock = 0;
> @@ -436,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>  	 * timestamps in, but we can reuse it safely */
>  
>  	pdev = (struct win_dev *)buf;
> +	io_parms.netfid = fileHandle;
> +	io_parms.pid = current->tgid;
> +	io_parms.tcon = pTcon;
> +	io_parms.offset = 0;
> +	io_parms.length = sizeof(struct win_dev);
>  	if (S_ISCHR(mode)) {
>  		memcpy(pdev->type, "IntxCHR", 8);
>  		pdev->major =
>  		      cpu_to_le64(MAJOR(device_number));
>  		pdev->minor =
>  		      cpu_to_le64(MINOR(device_number));
> -		rc = CIFSSMBWrite(xid, pTcon,
> -			fileHandle,
> -			sizeof(struct win_dev),
> -			0, &bytes_written, (char *)pdev,
> +		rc = CIFSSMBWrite(xid, &io_parms,
> +			&bytes_written, (char *)pdev,
>  			NULL, 0);
>  	} else if (S_ISBLK(mode)) {
>  		memcpy(pdev->type, "IntxBLK", 8);
> @@ -453,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>  		      cpu_to_le64(MAJOR(device_number));
>  		pdev->minor =
>  		      cpu_to_le64(MINOR(device_number));
> -		rc = CIFSSMBWrite(xid, pTcon,
> -			fileHandle,
> -			sizeof(struct win_dev),
> -			0, &bytes_written, (char *)pdev,
> +		rc = CIFSSMBWrite(xid, &io_parms,
> +			&bytes_written, (char *)pdev,
>  			NULL, 0);
>  	} /* else if (S_ISFIFO) */
>  	CIFSSMBClose(xid, pTcon, fileHandle);
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 00b926c..dfc0d35 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
>  		cifsi->server_eof = end_of_write;
>  }
>  
> -static ssize_t cifs_write(struct cifsFileInfo *open_file,
> +static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
>  			  const char *write_data, size_t write_size,
>  			  loff_t *poffset)
>  {
> @@ -869,6 +869,7 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
>  	int xid;
>  	struct dentry *dentry = open_file->dentry;
>  	struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
> +	struct cifs_io_parms io_parms;
>  
>  	cifs_sb = CIFS_SB(dentry->d_sb);
>  
> @@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
>  			/* iov[0] is reserved for smb header */
>  			iov[1].iov_base = (char *)write_data + total_written;
>  			iov[1].iov_len = len;
> -			rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len,
> -					   *poffset, &bytes_written, iov, 1, 0);
> +			io_parms.netfid = open_file->netfid;
> +			io_parms.pid = pid;
> +			io_parms.tcon = pTcon;
> +			io_parms.offset = *poffset;
> +			io_parms.length = len;
> +			rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
> +					   1, 0);
>  		}
>  		if (rc || (bytes_written == 0)) {
>  			if (total_written)
> @@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
>  
>  	open_file = find_writable_file(CIFS_I(mapping->host), false);
>  	if (open_file) {
> -		bytes_written = cifs_write(open_file, write_data,
> -					   to - from, &offset);
> +		bytes_written = cifs_write(open_file, open_file->pid,
> +					   write_data, to - from, &offset);
>  		cifsFileInfo_put(open_file);
>  		/* Does mm or vfs already set times? */
>  		inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
> @@ -1363,8 +1369,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
>  		/* BB check if anything else missing out of ppw
>  		   such as updating last write time */
>  		page_data = kmap(page);
> -		rc = cifs_write(file->private_data, page_data + offset,
> -				copied, &pos);
> +		rc = cifs_write(file->private_data, current->tgid,
> +				page_data + offset, copied, &pos);
>  		/* if (rc < 0) should we set writebehind rc? */
>  		kunmap(page);
>  
> @@ -1515,6 +1521,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
>  	struct cifsFileInfo *open_file;
>  	struct cifsTconInfo *pTcon;
>  	struct cifs_sb_info *cifs_sb;
> +	struct cifs_io_parms io_parms;
>  	int xid, rc;
>  
>  	len = iov_length(iov, nr_segs);
> @@ -1573,9 +1580,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
>  				if (rc != 0)
>  					break;
>  			}
> -			rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid,
> -					   cur_len, *poffset, &written,
> -					   to_send, npages, 0);
> +			io_parms.netfid = open_file->netfid;
> +			io_parms.pid = current->tgid;
> +			io_parms.tcon = pTcon;
> +			io_parms.offset = *poffset;
> +			io_parms.length = cur_len;
> +			rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send,
> +					   npages, 0);
>  		} while (rc == -EAGAIN);
>  
>  		for (i = 0; i < npages; i++)
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index 791d85e..53ea625 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -1866,6 +1866,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
>  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
>  	struct tcon_link *tlink = NULL;
>  	struct cifsTconInfo *pTcon = NULL;
> +	struct cifs_io_parms io_parms;
>  
>  	/*
>  	 * To avoid spurious oplock breaks from server, in the case of
> @@ -1887,8 +1888,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
>  		cFYI(1, "SetFSize for attrs rc = %d", rc);
>  		if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
>  			unsigned int bytes_written;
> -			rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
> -					  &bytes_written, NULL, NULL, 1);
> +
> +			io_parms.netfid = nfid;
> +			io_parms.pid = npid;
> +			io_parms.tcon = pTcon;
> +			io_parms.offset = 0;
> +			io_parms.length = attrs->ia_size;
> +			rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
> +					  NULL, NULL, 1);
>  			cFYI(1, "Wrt seteof rc %d", rc);
>  		}
>  	} else
> @@ -1923,10 +1930,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
>  					CIFS_MOUNT_MAP_SPECIAL_CHR);
>  			if (rc == 0) {
>  				unsigned int bytes_written;
> -				rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
> -						  attrs->ia_size,
> -						  &bytes_written, NULL,
> -						  NULL, 1);
> +
> +				io_parms.netfid = netfid;
> +				io_parms.pid = current->tgid;
> +				io_parms.tcon = pTcon;
> +				io_parms.offset = 0;
> +				io_parms.length = attrs->ia_size;
> +				rc = CIFSSMBWrite(xid, &io_parms,
> +						  &bytes_written,
> +						  NULL, NULL,  1);
>  				cFYI(1, "wrt seteof rc %d", rc);
>  				CIFSSMBClose(xid, pTcon, netfid);
>  			}
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index ce417a9..1a6a388 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
>  	__u16 netfid = 0;
>  	u8 *buf;
>  	unsigned int bytes_written = 0;
> +	struct cifs_io_parms io_parms;
>  
>  	buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
>  	if (!buf)
> @@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
>  		return rc;
>  	}
>  
> -	rc = CIFSSMBWrite(xid, tcon, netfid,
> -			  CIFS_MF_SYMLINK_FILE_SIZE /* length */,
> -			  0 /* offset */,
> -			  &bytes_written, buf, NULL, 0);
> +	io_parms.netfid = netfid;
> +	io_parms.pid = current->tgid;
> +	io_parms.tcon = tcon;
> +	io_parms.offset = 0;
> +	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
> +
> +	rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
>  	CIFSSMBClose(xid, tcon, netfid);
>  	kfree(buf);
>  	if (rc != 0)


-- 
Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size
       [not found]         ` <20110526145147.4fa2ba35-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
@ 2011-05-26 18:56           ` Pavel Shilovsky
  0 siblings, 0 replies; 13+ messages in thread
From: Pavel Shilovsky @ 2011-05-26 18:56 UTC (permalink / raw)
  To: Jeff Layton; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA

2011/5/26 Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>:
> On Thu, 26 May 2011 10:01:59 +0400
> Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:
>
>> We need it to make them work with mandatory locking style because
>> we can fail in a situation like when kernel need to flush dirty pages
>> and there is a lock held by a process who opened file.
>>
>> Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
>> ---
>>  fs/cifs/cifsglob.h  |    8 ++++++++
>>  fs/cifs/cifsproto.h |   13 +++++--------
>>  fs/cifs/cifssmb.c   |   33 ++++++++++++++++++++++++++-------
>>  fs/cifs/dir.c       |   18 ++++++++++--------
>>  fs/cifs/file.c      |   31 +++++++++++++++++++++----------
>>  fs/cifs/inode.c     |   24 ++++++++++++++++++------
>>  fs/cifs/link.c      |   12 ++++++++----
>>  7 files changed, 96 insertions(+), 43 deletions(-)
>>
>> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
>> index 7f90488..ca0c378 100644
>> --- a/fs/cifs/cifsglob.h
>> +++ b/fs/cifs/cifsglob.h
>> @@ -529,6 +529,14 @@ struct cifsFileInfo {
>>       struct work_struct oplock_break; /* work for oplock breaks */
>>  };
>>
>> +struct cifs_io_parms {
>> +     __u16 netfid;
>> +     __u32 pid;
>> +     __u64 offset;
>> +     unsigned int length;
>> +     struct cifsTconInfo *tcon;
>> +};
>> +
>        ^^^^^^^^^^
> I'm not sure this is really needed -- it seems like it would make more
> sense to just pass in a cifsFileInfo pointer to these functions. That
> already contains most of these args, aside from the offset and length.

I thought about it but let's look: cifsFileInfo pointer has only
netfid and tcon - it has pid, but we don't always need the pid of
process who opened the file - so sometimes we overwrite it. That's why
I decided to create new struct - it seems cleaner to me.

>
>>  /*
>>   * Take a reference on the file private data. Must be called with
>>   * cifs_file_list_lock held.
>> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
>> index bba7470..e41f607 100644
>> --- a/fs/cifs/cifsproto.h
>> +++ b/fs/cifs/cifsproto.h
>> @@ -349,15 +349,12 @@ extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
>>                       const int netfid, unsigned int count,
>>                       const __u64 lseek, unsigned int *nbytes, char **buf,
>>                       int *return_buf_type);
>> -extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
>> -                     const int netfid, const unsigned int count,
>> -                     const __u64 lseek, unsigned int *nbytes,
>> -                     const char *buf, const char __user *ubuf,
>> +extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
>> +                     unsigned int *nbytes, const char *buf,
>> +                     const char __user *ubuf, const int long_op);
>> +extern int CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
>> +                     unsigned int *nbytes, struct kvec *iov, const int nvec,
>>                       const int long_op);
>> -extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
>> -                     const int netfid, const unsigned int count,
>> -                     const __u64 offset, unsigned int *nbytes,
>> -                     struct kvec *iov, const int nvec, const int long_op);
>>  extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
>>                       const unsigned char *searchName, __u64 *inode_number,
>>                       const struct nls_table *nls_codepage,
>> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
>> index 136df01..f39fa08 100644
>> --- a/fs/cifs/cifssmb.c
>> +++ b/fs/cifs/cifssmb.c
>> @@ -1487,9 +1487,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
>>
>>
>>  int
>> -CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
>> -          const int netfid, const unsigned int count,
>> -          const __u64 offset, unsigned int *nbytes, const char *buf,
>> +CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
>> +          unsigned int *nbytes, const char *buf,
>>            const char __user *ubuf, const int long_op)
>>  {
>>       int rc = -EACCES;
>> @@ -1498,6 +1497,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
>>       int bytes_returned, wct;
>>       __u32 bytes_sent;
>>       __u16 byte_count;
>> +     __u32 pid = io_parms->pid;
>> +     __u16 netfid = io_parms->netfid;
>> +     __u64 offset = io_parms->offset;
>> +     struct cifsTconInfo *tcon = io_parms->tcon;
>> +     unsigned int count = io_parms->length;
>>
>>       *nbytes = 0;
>>
>> @@ -1519,6 +1523,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
>>                     (void **) &pSMBr);
>>       if (rc)
>>               return rc;
>> +
>> +     pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
>> +     pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
>> +
>>       /* tcon and ses pointer are checked in smb_init */
>>       if (tcon->ses->server == NULL)
>>               return -ECONNABORTED;
>> @@ -1778,6 +1786,9 @@ cifs_async_writev(struct cifs_writedata *wdata)
>>               goto async_writev_out;
>>       }
>>
>> +     smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
>> +     smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
>> +
>>       smb->AndXCommand = 0xFF;        /* none */
>>       smb->Fid = wdata->cfile->netfid;
>>       smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
>> @@ -1841,16 +1852,20 @@ async_writev_out:
>>  }
>>
>>  int
>> -CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
>> -          const int netfid, const unsigned int count,
>> -          const __u64 offset, unsigned int *nbytes, struct kvec *iov,
>> -          int n_vec, const int long_op)
>> +CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
>> +           unsigned int *nbytes, struct kvec *iov, int n_vec,
>> +           const int long_op)
>>  {
>>       int rc = -EACCES;
>>       WRITE_REQ *pSMB = NULL;
>>       int wct;
>>       int smb_hdr_len;
>>       int resp_buf_type = 0;
>> +     __u32 pid = io_parms->pid;
>> +     __u16 netfid = io_parms->netfid;
>> +     __u64 offset = io_parms->offset;
>> +     struct cifsTconInfo *tcon = io_parms->tcon;
>> +     unsigned int count = io_parms->length;
>>
>>       *nbytes = 0;
>>
>> @@ -1868,6 +1883,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
>>       rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
>>       if (rc)
>>               return rc;
>> +
>> +     pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
>> +     pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
>> +
>>       /* tcon and ses pointer are checked in smb_init */
>>       if (tcon->ses->server == NULL)
>>               return -ECONNABORTED;
>> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
>> index c33446d..aa0669a 100644
>> --- a/fs/cifs/dir.c
>> +++ b/fs/cifs/dir.c
>> @@ -354,6 +354,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>       struct cifs_sb_info *cifs_sb;
>>       struct tcon_link *tlink;
>>       struct cifsTconInfo *pTcon;
>> +     struct cifs_io_parms io_parms;
>>       char *full_path = NULL;
>>       struct inode *newinode = NULL;
>>       int oplock = 0;
>> @@ -436,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>        * timestamps in, but we can reuse it safely */
>>
>>       pdev = (struct win_dev *)buf;
>> +     io_parms.netfid = fileHandle;
>> +     io_parms.pid = current->tgid;
>> +     io_parms.tcon = pTcon;
>> +     io_parms.offset = 0;
>> +     io_parms.length = sizeof(struct win_dev);
>>       if (S_ISCHR(mode)) {
>>               memcpy(pdev->type, "IntxCHR", 8);
>>               pdev->major =
>>                     cpu_to_le64(MAJOR(device_number));
>>               pdev->minor =
>>                     cpu_to_le64(MINOR(device_number));
>> -             rc = CIFSSMBWrite(xid, pTcon,
>> -                     fileHandle,
>> -                     sizeof(struct win_dev),
>> -                     0, &bytes_written, (char *)pdev,
>> +             rc = CIFSSMBWrite(xid, &io_parms,
>> +                     &bytes_written, (char *)pdev,
>>                       NULL, 0);
>>       } else if (S_ISBLK(mode)) {
>>               memcpy(pdev->type, "IntxBLK", 8);
>> @@ -453,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>                     cpu_to_le64(MAJOR(device_number));
>>               pdev->minor =
>>                     cpu_to_le64(MINOR(device_number));
>> -             rc = CIFSSMBWrite(xid, pTcon,
>> -                     fileHandle,
>> -                     sizeof(struct win_dev),
>> -                     0, &bytes_written, (char *)pdev,
>> +             rc = CIFSSMBWrite(xid, &io_parms,
>> +                     &bytes_written, (char *)pdev,
>>                       NULL, 0);
>>       } /* else if (S_ISFIFO) */
>>       CIFSSMBClose(xid, pTcon, fileHandle);
>> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
>> index 00b926c..dfc0d35 100644
>> --- a/fs/cifs/file.c
>> +++ b/fs/cifs/file.c
>> @@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
>>               cifsi->server_eof = end_of_write;
>>  }
>>
>> -static ssize_t cifs_write(struct cifsFileInfo *open_file,
>> +static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
>>                         const char *write_data, size_t write_size,
>>                         loff_t *poffset)
>>  {
>> @@ -869,6 +869,7 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
>>       int xid;
>>       struct dentry *dentry = open_file->dentry;
>>       struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
>> +     struct cifs_io_parms io_parms;
>>
>>       cifs_sb = CIFS_SB(dentry->d_sb);
>>
>> @@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
>>                       /* iov[0] is reserved for smb header */
>>                       iov[1].iov_base = (char *)write_data + total_written;
>>                       iov[1].iov_len = len;
>> -                     rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len,
>> -                                        *poffset, &bytes_written, iov, 1, 0);
>> +                     io_parms.netfid = open_file->netfid;
>> +                     io_parms.pid = pid;
>> +                     io_parms.tcon = pTcon;
>> +                     io_parms.offset = *poffset;
>> +                     io_parms.length = len;
>> +                     rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
>> +                                        1, 0);
>>               }
>>               if (rc || (bytes_written == 0)) {
>>                       if (total_written)
>> @@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
>>
>>       open_file = find_writable_file(CIFS_I(mapping->host), false);
>>       if (open_file) {
>> -             bytes_written = cifs_write(open_file, write_data,
>> -                                        to - from, &offset);
>> +             bytes_written = cifs_write(open_file, open_file->pid,
>> +                                        write_data, to - from, &offset);
>>               cifsFileInfo_put(open_file);
>>               /* Does mm or vfs already set times? */
>>               inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
>> @@ -1363,8 +1369,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
>>               /* BB check if anything else missing out of ppw
>>                  such as updating last write time */
>>               page_data = kmap(page);
>> -             rc = cifs_write(file->private_data, page_data + offset,
>> -                             copied, &pos);
>> +             rc = cifs_write(file->private_data, current->tgid,
>> +                             page_data + offset, copied, &pos);
>>               /* if (rc < 0) should we set writebehind rc? */
>>               kunmap(page);
>>
>> @@ -1515,6 +1521,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
>>       struct cifsFileInfo *open_file;
>>       struct cifsTconInfo *pTcon;
>>       struct cifs_sb_info *cifs_sb;
>> +     struct cifs_io_parms io_parms;
>>       int xid, rc;
>>
>>       len = iov_length(iov, nr_segs);
>> @@ -1573,9 +1580,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
>>                               if (rc != 0)
>>                                       break;
>>                       }
>> -                     rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid,
>> -                                        cur_len, *poffset, &written,
>> -                                        to_send, npages, 0);
>> +                     io_parms.netfid = open_file->netfid;
>> +                     io_parms.pid = current->tgid;
>> +                     io_parms.tcon = pTcon;
>> +                     io_parms.offset = *poffset;
>> +                     io_parms.length = cur_len;
>> +                     rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send,
>> +                                        npages, 0);
>>               } while (rc == -EAGAIN);
>>
>>               for (i = 0; i < npages; i++)
>> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
>> index 791d85e..53ea625 100644
>> --- a/fs/cifs/inode.c
>> +++ b/fs/cifs/inode.c
>> @@ -1866,6 +1866,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
>>       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
>>       struct tcon_link *tlink = NULL;
>>       struct cifsTconInfo *pTcon = NULL;
>> +     struct cifs_io_parms io_parms;
>>
>>       /*
>>        * To avoid spurious oplock breaks from server, in the case of
>> @@ -1887,8 +1888,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
>>               cFYI(1, "SetFSize for attrs rc = %d", rc);
>>               if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
>>                       unsigned int bytes_written;
>> -                     rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
>> -                                       &bytes_written, NULL, NULL, 1);
>> +
>> +                     io_parms.netfid = nfid;
>> +                     io_parms.pid = npid;
>> +                     io_parms.tcon = pTcon;
>> +                     io_parms.offset = 0;
>> +                     io_parms.length = attrs->ia_size;
>> +                     rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
>> +                                       NULL, NULL, 1);
>>                       cFYI(1, "Wrt seteof rc %d", rc);
>>               }
>>       } else
>> @@ -1923,10 +1930,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
>>                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
>>                       if (rc == 0) {
>>                               unsigned int bytes_written;
>> -                             rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
>> -                                               attrs->ia_size,
>> -                                               &bytes_written, NULL,
>> -                                               NULL, 1);
>> +
>> +                             io_parms.netfid = netfid;
>> +                             io_parms.pid = current->tgid;
>> +                             io_parms.tcon = pTcon;
>> +                             io_parms.offset = 0;
>> +                             io_parms.length = attrs->ia_size;
>> +                             rc = CIFSSMBWrite(xid, &io_parms,
>> +                                               &bytes_written,
>> +                                               NULL, NULL,  1);
>>                               cFYI(1, "wrt seteof rc %d", rc);
>>                               CIFSSMBClose(xid, pTcon, netfid);
>>                       }
>> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
>> index ce417a9..1a6a388 100644
>> --- a/fs/cifs/link.c
>> +++ b/fs/cifs/link.c
>> @@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
>>       __u16 netfid = 0;
>>       u8 *buf;
>>       unsigned int bytes_written = 0;
>> +     struct cifs_io_parms io_parms;
>>
>>       buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
>>       if (!buf)
>> @@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
>>               return rc;
>>       }
>>
>> -     rc = CIFSSMBWrite(xid, tcon, netfid,
>> -                       CIFS_MF_SYMLINK_FILE_SIZE /* length */,
>> -                       0 /* offset */,
>> -                       &bytes_written, buf, NULL, 0);
>> +     io_parms.netfid = netfid;
>> +     io_parms.pid = current->tgid;
>> +     io_parms.tcon = tcon;
>> +     io_parms.offset = 0;
>> +     io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
>> +
>> +     rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
>>       CIFSSMBClose(xid, tcon, netfid);
>>       kfree(buf);
>>       if (rc != 0)
>
>
> --
> Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> --
> 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
>



-- 
Best regards,
Pavel Shilovsky.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-05-26 18:56 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-26  6:01 [v4 PATCH 3/4] CIFS: Migrate from prefixpath logic Pavel Shilovsky
     [not found] ` <1306389721-28550-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-05-26  6:01   ` [PATCH 1/2] CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size Pavel Shilovsky
     [not found]     ` <1306389721-28550-2-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-05-26 18:51       ` Jeff Layton
     [not found]         ` <20110526145147.4fa2ba35-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2011-05-26 18:56           ` Pavel Shilovsky
2011-05-26  6:02   ` [PATCH 2/2] CIFS: Add rwpidforward mount option Pavel Shilovsky
2011-05-26  6:02   ` [v4 PATCH 4/4] CIFS: Migrate to shared superblock model Pavel Shilovsky
     [not found]     ` <1306389721-28550-4-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-05-26 14:09       ` Jeff Layton
2011-05-26 15:20       ` Jeff Layton
     [not found]         ` <20110526112001.6602ce52-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-05-26 16:06           ` Steve French
     [not found]             ` <BANLkTim+a8swvWytQwUQqE+1s+wVnX3gRg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-05-26 16:14               ` Pavel Shilovsky
     [not found]                 ` <BANLkTi==YrNa1quPtEFW0T3_yxCrCq_+sA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-05-26 16:17                   ` Pavel Shilovsky
     [not found]                     ` <BANLkTikkbBO6iZsf7ckUFFiMdUbuLi7HNA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-05-26 16:21                       ` Pavel Shilovsky
2011-05-26 18:45               ` Jeff Layton

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.