aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2011-05-26 23:50:55 -0400
committerSteve French <sfrench@us.ibm.com>2011-05-26 23:50:55 -0400
commitf87d39d951329cd8f462bf9007d334122c0599d0 (patch)
treeba4c4d9dee6958c7d8ee87070a58d80389be2d2f /fs/cifs/connect.c
parent641a58d66d086327042e9d73c6606fd02c8f067c (diff)
[CIFS] Migrate from prefixpath logic
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@redhat.com> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c128
1 files changed, 5 insertions, 123 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 581654fb174..49568811598 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -57,61 +57,6 @@
57 57
58extern mempool_t *cifs_req_poolp; 58extern mempool_t *cifs_req_poolp;
59 59
60struct smb_vol {
61 char *username;
62 char *password;
63 char *domainname;
64 char *UNC;
65 char *UNCip;
66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
68 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
69 uid_t cred_uid;
70 uid_t linux_uid;
71 gid_t linux_gid;
72 mode_t file_mode;
73 mode_t dir_mode;
74 unsigned secFlg;
75 bool retry:1;
76 bool intr:1;
77 bool setuids:1;
78 bool override_uid:1;
79 bool override_gid:1;
80 bool dynperm:1;
81 bool noperm:1;
82 bool no_psx_acl:1; /* set if posix acl support should be disabled */
83 bool cifs_acl:1;
84 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
85 bool server_ino:1; /* use inode numbers from server ie UniqueId */
86 bool direct_io:1;
87 bool strict_io:1; /* strict cache behavior */
88 bool remap:1; /* set to remap seven reserved chars in filenames */
89 bool posix_paths:1; /* unset to not ask for posix pathnames. */
90 bool no_linux_ext:1;
91 bool sfu_emul:1;
92 bool nullauth:1; /* attempt to authenticate with null user */
93 bool nocase:1; /* request case insensitive filenames */
94 bool nobrl:1; /* disable sending byte range locks to srv */
95 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
96 bool seal:1; /* request transport encryption on share */
97 bool nodfs:1; /* Do not request DFS, even if available */
98 bool local_lease:1; /* check leases only on local system, not remote */
99 bool noblocksnd:1;
100 bool noautotune:1;
101 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
102 bool fsc:1; /* enable fscache */
103 bool mfsymlinks:1; /* use Minshall+French Symlinks */
104 bool multiuser:1;
105 unsigned int rsize;
106 unsigned int wsize;
107 bool sockopt_tcp_nodelay:1;
108 unsigned short int port;
109 unsigned long actimeo; /* attribute cache timeout (jiffies) */
110 char *prepath;
111 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
112 struct nls_table *local_nls;
113};
114
115/* FIXME: should these be tunable? */ 60/* FIXME: should these be tunable? */
116#define TLINK_ERROR_EXPIRE (1 * HZ) 61#define TLINK_ERROR_EXPIRE (1 * HZ)
117#define TLINK_IDLE_EXPIRE (600 * HZ) 62#define TLINK_IDLE_EXPIRE (600 * HZ)
@@ -2569,12 +2514,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2569 CIFS_MOUNT_POSIX_PATHS; 2514 CIFS_MOUNT_POSIX_PATHS;
2570 } 2515 }
2571 2516
2572 /* We might be setting the path sep back to a different
2573 form if we are reconnecting and the server switched its
2574 posix path capability for this share */
2575 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2576 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2577
2578 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { 2517 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2579 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { 2518 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2580 CIFS_SB(sb)->rsize = 127 * 1024; 2519 CIFS_SB(sb)->rsize = 127 * 1024;
@@ -2619,26 +2558,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2619 } 2558 }
2620} 2559}
2621 2560
2622static void
2623convert_delimiter(char *path, char delim)
2624{
2625 int i;
2626 char old_delim;
2627
2628 if (path == NULL)
2629 return;
2630
2631 if (delim == '/')
2632 old_delim = '\\';
2633 else
2634 old_delim = '/';
2635
2636 for (i = 0; path[i] != '\0'; i++) {
2637 if (path[i] == old_delim)
2638 path[i] = delim;
2639 }
2640}
2641
2642void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, 2561void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2643 struct cifs_sb_info *cifs_sb) 2562 struct cifs_sb_info *cifs_sb)
2644{ 2563{
@@ -2659,18 +2578,6 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2659 /* Windows ME may prefer this */ 2578 /* Windows ME may prefer this */
2660 cFYI(1, "readsize set to minimum: 2048"); 2579 cFYI(1, "readsize set to minimum: 2048");
2661 } 2580 }
2662 /* calculate prepath */
2663 cifs_sb->prepath = pvolume_info->prepath;
2664 if (cifs_sb->prepath) {
2665 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2666 /* we can not convert the / to \ in the path
2667 separators in the prefixpath yet because we do not
2668 know (until reset_cifs_unix_caps is called later)
2669 whether POSIX PATH CAP is available. We normalize
2670 the / to \ after reset_cifs_unix_caps is called */
2671 pvolume_info->prepath = NULL;
2672 } else
2673 cifs_sb->prepathlen = 0;
2674 cifs_sb->mnt_uid = pvolume_info->linux_uid; 2581 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2675 cifs_sb->mnt_gid = pvolume_info->linux_gid; 2582 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2676 cifs_sb->mnt_file_mode = pvolume_info->file_mode; 2583 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
@@ -2834,24 +2741,13 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
2834 char *full_path; 2741 char *full_path;
2835 2742
2836 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); 2743 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2837 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL); 2744 full_path = kmalloc(unc_len + 1, GFP_KERNEL);
2838 if (full_path == NULL) 2745 if (full_path == NULL)
2839 return ERR_PTR(-ENOMEM); 2746 return ERR_PTR(-ENOMEM);
2840 2747
2841 strncpy(full_path, volume_info->UNC, unc_len); 2748 strncpy(full_path, volume_info->UNC, unc_len);
2842 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { 2749 full_path[unc_len] = 0; /* add trailing null */
2843 int i; 2750 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
2844 for (i = 0; i < unc_len; i++) {
2845 if (full_path[i] == '\\')
2846 full_path[i] = '/';
2847 }
2848 }
2849
2850 if (cifs_sb->prepathlen)
2851 strncpy(full_path + unc_len, cifs_sb->prepath,
2852 cifs_sb->prepathlen);
2853
2854 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2855 return full_path; 2751 return full_path;
2856} 2752}
2857 2753
@@ -3049,10 +2945,6 @@ try_mount_again:
3049 CIFSSMBQFSAttributeInfo(xid, tcon); 2945 CIFSSMBQFSAttributeInfo(xid, tcon);
3050 } 2946 }
3051 2947
3052 /* convert forward to back slashes in prepath here if needed */
3053 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
3054 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
3055
3056 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { 2948 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
3057 cifs_sb->rsize = 1024 * 127; 2949 cifs_sb->rsize = 1024 * 127;
3058 cFYI(DBG2, "no very large read support, rsize now 127K"); 2950 cFYI(DBG2, "no very large read support, rsize now 127K");
@@ -3082,10 +2974,10 @@ remote_path_check:
3082 } 2974 }
3083#endif 2975#endif
3084 2976
3085 /* check if a whole path (including prepath) is not remote */ 2977 /* check if a whole path is not remote */
3086 if (!rc && tcon) { 2978 if (!rc && tcon) {
3087 /* build_path_to_root works only when we have a valid tcon */ 2979 /* build_path_to_root works only when we have a valid tcon */
3088 full_path = cifs_build_path_to_root(cifs_sb, tcon); 2980 full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
3089 if (full_path == NULL) { 2981 if (full_path == NULL) {
3090 rc = -ENOMEM; 2982 rc = -ENOMEM;
3091 goto mount_fail_check; 2983 goto mount_fail_check;
@@ -3111,10 +3003,6 @@ remote_path_check:
3111 rc = -ELOOP; 3003 rc = -ELOOP;
3112 goto mount_fail_check; 3004 goto mount_fail_check;
3113 } 3005 }
3114 /* convert forward to back slashes in prepath here if needed */
3115 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
3116 convert_delimiter(cifs_sb->prepath,
3117 CIFS_DIR_SEP(cifs_sb));
3118 3006
3119 rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb, 3007 rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb,
3120 true); 3008 true);
@@ -3340,7 +3228,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3340 struct rb_root *root = &cifs_sb->tlink_tree; 3228 struct rb_root *root = &cifs_sb->tlink_tree;
3341 struct rb_node *node; 3229 struct rb_node *node;
3342 struct tcon_link *tlink; 3230 struct tcon_link *tlink;
3343 char *tmp;
3344 3231
3345 cancel_delayed_work_sync(&cifs_sb->prune_tlinks); 3232 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3346 3233
@@ -3357,11 +3244,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3357 } 3244 }
3358 spin_unlock(&cifs_sb->tlink_tree_lock); 3245 spin_unlock(&cifs_sb->tlink_tree_lock);
3359 3246
3360 tmp = cifs_sb->prepath;
3361 cifs_sb->prepathlen = 0;
3362 cifs_sb->prepath = NULL;
3363 kfree(tmp);
3364
3365 return 0; 3247 return 0;
3366} 3248}
3367 3249