aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-06-17 09:05:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-06-24 18:39:41 -0400
commit2c6292ae4be00454882246d07f38cdf15a823c2a (patch)
tree40bfa681a0f94f6df2b3f8140452f0eab7809b1c
parentca171baaad1420a29cca98be5bdf5596cd70b294 (diff)
cifs: don't pass superblock to cifs_mount()
To close sget() races we'll need to be able to set cifs_sb up before we get the superblock, so we'll want to be able to do cifs_mount() earlier. Fortunately, it's easy to do - setting ->s_maxbytes can be done in cifs_read_super(), ditto for ->s_time_gran and as for putting MS_POSIXACL into ->s_flags, we can mirror it in ->mnt_cifs_flags until cifs_read_super() is called. Kill unused 'devname' argument, while we are at it... Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsfs.c13
-rw-r--r--fs/cifs/cifsproto.h6
-rw-r--r--fs/cifs/connect.c28
4 files changed, 26 insertions, 22 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index ffb1459dc6ec..7260e11e21f8 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -42,6 +42,7 @@
42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ 42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ 43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */ 44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
45#define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
45 46
46struct cifs_sb_info { 47struct cifs_sb_info {
47 struct rb_root tlink_tree; 48 struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index bfab2bc83726..8f7451f3c8e6 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -116,7 +116,7 @@ cifs_read_super(struct super_block *sb, struct smb_vol *volume_info,
116 spin_lock_init(&cifs_sb->tlink_tree_lock); 116 spin_lock_init(&cifs_sb->tlink_tree_lock);
117 cifs_sb->tlink_tree = RB_ROOT; 117 cifs_sb->tlink_tree = RB_ROOT;
118 118
119 rc = cifs_mount(sb, cifs_sb, volume_info, devname); 119 rc = cifs_mount(cifs_sb, volume_info);
120 120
121 if (rc) { 121 if (rc) {
122 if (!silent) 122 if (!silent)
@@ -124,6 +124,17 @@ cifs_read_super(struct super_block *sb, struct smb_vol *volume_info,
124 return rc; 124 return rc;
125 } 125 }
126 126
127 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
128 sb->s_flags |= MS_POSIXACL;
129
130 if (cifs_sb_master_tcon(cifs_sb)->ses->capabilities & CAP_LARGE_FILES)
131 sb->s_maxbytes = MAX_LFS_FILESIZE;
132 else
133 sb->s_maxbytes = MAX_NON_LFS;
134
135 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
136 sb->s_time_gran = 100;
137
127 sb->s_magic = CIFS_MAGIC_NUMBER; 138 sb->s_magic = CIFS_MAGIC_NUMBER;
128 sb->s_op = &cifs_super_ops; 139 sb->s_op = &cifs_super_ops;
129 sb->s_bdi = &cifs_sb->bdi; 140 sb->s_bdi = &cifs_sb->bdi;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 953f84413c77..5814fe543f95 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -157,8 +157,7 @@ extern int cifs_match_super(struct super_block *, void *);
157extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); 157extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info);
158extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, 158extern int cifs_setup_volume_info(struct smb_vol **pvolume_info,
159 char *mount_data, const char *devname); 159 char *mount_data, const char *devname);
160extern int cifs_mount(struct super_block *, struct cifs_sb_info *, 160extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *);
161 struct smb_vol *, const char *);
162extern int cifs_umount(struct super_block *, struct cifs_sb_info *); 161extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
163extern void cifs_dfs_release_automount_timer(void); 162extern void cifs_dfs_release_automount_timer(void);
164void cifs_proc_init(void); 163void cifs_proc_init(void);
@@ -218,7 +217,8 @@ extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo,
218 struct dfs_info3_param **preferrals, 217 struct dfs_info3_param **preferrals,
219 int remap); 218 int remap);
220extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, 219extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
221 struct super_block *sb, struct smb_vol *vol); 220 struct cifs_sb_info *cifs_sb,
221 struct smb_vol *vol);
222extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, 222extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon,
223 struct kstatfs *FSData); 223 struct kstatfs *FSData);
224extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, 224extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 78fd7557e35d..3011ac8c9249 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2546,7 +2546,7 @@ ip_connect(struct TCP_Server_Info *server)
2546} 2546}
2547 2547
2548void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, 2548void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
2549 struct super_block *sb, struct smb_vol *vol_info) 2549 struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info)
2550{ 2550{
2551 /* if we are reconnecting then should we check to see if 2551 /* if we are reconnecting then should we check to see if
2552 * any requested capabilities changed locally e.g. via 2552 * any requested capabilities changed locally e.g. via
@@ -2600,22 +2600,23 @@ void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
2600 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 2600 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2601 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { 2601 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2602 cFYI(1, "negotiated posix acl support"); 2602 cFYI(1, "negotiated posix acl support");
2603 if (sb) 2603 if (cifs_sb)
2604 sb->s_flags |= MS_POSIXACL; 2604 cifs_sb->mnt_cifs_flags |=
2605 CIFS_MOUNT_POSIXACL;
2605 } 2606 }
2606 2607
2607 if (vol_info && vol_info->posix_paths == 0) 2608 if (vol_info && vol_info->posix_paths == 0)
2608 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 2609 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2609 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 2610 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2610 cFYI(1, "negotiate posix pathnames"); 2611 cFYI(1, "negotiate posix pathnames");
2611 if (sb) 2612 if (cifs_sb)
2612 CIFS_SB(sb)->mnt_cifs_flags |= 2613 cifs_sb->mnt_cifs_flags |=
2613 CIFS_MOUNT_POSIX_PATHS; 2614 CIFS_MOUNT_POSIX_PATHS;
2614 } 2615 }
2615 2616
2616 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { 2617 if (cifs_sb && (cifs_sb->rsize > 127 * 1024)) {
2617 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { 2618 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2618 CIFS_SB(sb)->rsize = 127 * 1024; 2619 cifs_sb->rsize = 127 * 1024;
2619 cFYI(DBG2, "larger reads not supported by srv"); 2620 cFYI(DBG2, "larger reads not supported by srv");
2620 } 2621 }
2621 } 2622 }
@@ -2971,8 +2972,7 @@ out:
2971} 2972}
2972 2973
2973int 2974int
2974cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 2975cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
2975 struct smb_vol *volume_info, const char *devname)
2976{ 2976{
2977 int rc = 0; 2977 int rc = 0;
2978 int xid; 2978 int xid;
@@ -3026,14 +3026,6 @@ try_mount_again:
3026 goto mount_fail_check; 3026 goto mount_fail_check;
3027 } 3027 }
3028 3028
3029 if (pSesInfo->capabilities & CAP_LARGE_FILES)
3030 sb->s_maxbytes = MAX_LFS_FILESIZE;
3031 else
3032 sb->s_maxbytes = MAX_NON_LFS;
3033
3034 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
3035 sb->s_time_gran = 100;
3036
3037 /* search for existing tcon to this server share */ 3029 /* search for existing tcon to this server share */
3038 tcon = cifs_get_tcon(pSesInfo, volume_info); 3030 tcon = cifs_get_tcon(pSesInfo, volume_info);
3039 if (IS_ERR(tcon)) { 3031 if (IS_ERR(tcon)) {
@@ -3046,7 +3038,7 @@ try_mount_again:
3046 if (tcon->ses->capabilities & CAP_UNIX) { 3038 if (tcon->ses->capabilities & CAP_UNIX) {
3047 /* reset of caps checks mount to see if unix extensions 3039 /* reset of caps checks mount to see if unix extensions
3048 disabled for just this mount */ 3040 disabled for just this mount */
3049 reset_cifs_unix_caps(xid, tcon, sb, volume_info); 3041 reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info);
3050 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && 3042 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
3051 (le64_to_cpu(tcon->fsUnixInfo.Capability) & 3043 (le64_to_cpu(tcon->fsUnixInfo.Capability) &
3052 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { 3044 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {