All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [v2 4/4] CIFS: Migrate to shared superblock model
Date: Thu,  5 May 2011 13:55:14 +0400	[thread overview]
Message-ID: <1304589314-1147-4-git-send-email-piastry@etersoft.ru> (raw)
In-Reply-To: <1304589314-1147-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>

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.

Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
---
 fs/cifs/cifsfs.c   |   18 ++++++++++-
 fs/cifs/cifsglob.h |    5 +++
 fs/cifs/connect.c  |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 112 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 446b5c2..ba0b7ae 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -644,6 +644,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;
 	char *copied_data = NULL;
 
@@ -661,13 +662,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;
+
+	sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
 	if (IS_ERR(sb)) {
 		kfree(cifs_sb);
 		root = ERR_CAST(sb);
 		goto out;
 	}
 
+	if (sb->s_fs_info) {
+		cFYI(1, "Use existing superblock");
+		goto out_shared;
+	}
+
 	sb->s_flags = flags;
 
 	/*
@@ -700,6 +709,13 @@ out:
 	cifs_cleanup_volume_info(&volume_info);
 	return root;
 
+out_shared:
+	root = cifs_get_root(volume_info, sb);
+	if (root)
+		cFYI(1, "dentry root is: %p", root);
+	cifs_cleanup_volume_info(&volume_info);
+	return root;
+
 err_out:
 	kfree(cifs_sb);
 	deactivate_locked_super(sb);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7ad7d69..55901b0 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -211,6 +211,11 @@ struct smb_vol {
 	struct nls_table *local_nls;
 };
 
+struct cifs_mnt_data {
+	struct cifs_sb_info *cifs_sb;
+	struct smb_vol *vol;
+};
+
 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 1cacfaa..1d39dcf 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2135,6 +2135,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 const u32 ACTUAL_MOUNT_FLAGS = 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;
+
+static int
+compare_mount_options(struct cifs_sb_info *old, struct cifs_sb_info *new)
+{
+	if ((old->mnt_cifs_flags & ACTUAL_MOUNT_FLAGS) !=
+	    (new->mnt_cifs_flags & ACTUAL_MOUNT_FLAGS))
+		return 0;
+
+	if (old->rsize != new->rsize || old->wsize != new->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, *new_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;
+	new_cifs_sb = mnt_data->cifs_sb;
+
+	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(cifs_sb, new_cifs_sb);
+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

  parent reply	other threads:[~2011-05-05  9:55 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-05  9:55 [v2 1/4] CIFS: Simplify connection structure search calls Pavel Shilovsky
     [not found] ` <1304589314-1147-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-05-05  9:55   ` [v2 2/4] CIFS: Simplify mount code for further shared sb capability Pavel Shilovsky
2011-05-05  9:55   ` [v2 3/4] CIFS: Migrate from prefixpath logic Pavel Shilovsky
     [not found]     ` <1304589314-1147-3-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-05-24 11:11       ` Jeff Layton
2011-05-05  9:55   ` Pavel Shilovsky [this message]
     [not found]     ` <1304589314-1147-4-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-05-24 11:22       ` [v2 4/4] CIFS: Migrate to shared superblock model Jeff Layton
     [not found]         ` <20110524072250.7337d434-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-05-25 19:10           ` Pavel Shilovsky
     [not found]             ` <BANLkTi=Y8qx_d4S5YJev61mtavZKtr0B7w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-05-25 19:36               ` Jeff Layton
     [not found]                 ` <20110525153626.294d2c89-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2011-05-26  6:06                   ` Pavel Shilovsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1304589314-1147-4-git-send-email-piastry@etersoft.ru \
    --to=piastry-7qunaywfiewox3rin2dayq@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.