aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c91
1 files changed, 49 insertions, 42 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 56095b24d5b9..c2ed0f57a66c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2185,27 +2185,30 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2185{ 2185{
2186 int rc = 0; 2186 int rc = 0;
2187 int xid; 2187 int xid;
2188 struct smb_vol volume_info; 2188 struct smb_vol *volume_info;
2189 struct cifsSesInfo *pSesInfo = NULL; 2189 struct cifsSesInfo *pSesInfo = NULL;
2190 struct cifsTconInfo *tcon = NULL; 2190 struct cifsTconInfo *tcon = NULL;
2191 struct TCP_Server_Info *srvTcp = NULL; 2191 struct TCP_Server_Info *srvTcp = NULL;
2192 2192
2193 xid = GetXid(); 2193 xid = GetXid();
2194 2194
2195/* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ 2195 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2196 if (!volume_info) {
2197 rc = -ENOMEM;
2198 goto out;
2199 }
2196 2200
2197 memset(&volume_info, 0, sizeof(struct smb_vol)); 2201 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2198 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
2199 rc = -EINVAL; 2202 rc = -EINVAL;
2200 goto out; 2203 goto out;
2201 } 2204 }
2202 2205
2203 if (volume_info.nullauth) { 2206 if (volume_info->nullauth) {
2204 cFYI(1, ("null user")); 2207 cFYI(1, ("null user"));
2205 volume_info.username = ""; 2208 volume_info->username = "";
2206 } else if (volume_info.username) { 2209 } else if (volume_info->username) {
2207 /* BB fixme parse for domain name here */ 2210 /* BB fixme parse for domain name here */
2208 cFYI(1, ("Username: %s", volume_info.username)); 2211 cFYI(1, ("Username: %s", volume_info->username));
2209 } else { 2212 } else {
2210 cifserror("No username specified"); 2213 cifserror("No username specified");
2211 /* In userspace mount helper we can get user name from alternate 2214 /* In userspace mount helper we can get user name from alternate
@@ -2216,27 +2219,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2216 2219
2217 2220
2218 /* this is needed for ASCII cp to Unicode converts */ 2221 /* this is needed for ASCII cp to Unicode converts */
2219 if (volume_info.iocharset == NULL) { 2222 if (volume_info->iocharset == NULL) {
2220 cifs_sb->local_nls = load_nls_default(); 2223 cifs_sb->local_nls = load_nls_default();
2221 /* load_nls_default can not return null */ 2224 /* load_nls_default can not return null */
2222 } else { 2225 } else {
2223 cifs_sb->local_nls = load_nls(volume_info.iocharset); 2226 cifs_sb->local_nls = load_nls(volume_info->iocharset);
2224 if (cifs_sb->local_nls == NULL) { 2227 if (cifs_sb->local_nls == NULL) {
2225 cERROR(1, ("CIFS mount error: iocharset %s not found", 2228 cERROR(1, ("CIFS mount error: iocharset %s not found",
2226 volume_info.iocharset)); 2229 volume_info->iocharset));
2227 rc = -ELIBACC; 2230 rc = -ELIBACC;
2228 goto out; 2231 goto out;
2229 } 2232 }
2230 } 2233 }
2231 2234
2232 /* get a reference to a tcp session */ 2235 /* get a reference to a tcp session */
2233 srvTcp = cifs_get_tcp_session(&volume_info); 2236 srvTcp = cifs_get_tcp_session(volume_info);
2234 if (IS_ERR(srvTcp)) { 2237 if (IS_ERR(srvTcp)) {
2235 rc = PTR_ERR(srvTcp); 2238 rc = PTR_ERR(srvTcp);
2236 goto out; 2239 goto out;
2237 } 2240 }
2238 2241
2239 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username); 2242 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
2240 if (pSesInfo) { 2243 if (pSesInfo) {
2241 cFYI(1, ("Existing smb sess found (status=%d)", 2244 cFYI(1, ("Existing smb sess found (status=%d)",
2242 pSesInfo->status)); 2245 pSesInfo->status));
@@ -2274,24 +2277,24 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2274 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); 2277 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2275 write_unlock(&cifs_tcp_ses_lock); 2278 write_unlock(&cifs_tcp_ses_lock);
2276 2279
2277 /* volume_info.password freed at unmount */ 2280 /* volume_info->password freed at unmount */
2278 if (volume_info.password) { 2281 if (volume_info->password) {
2279 pSesInfo->password = volume_info.password; 2282 pSesInfo->password = volume_info->password;
2280 /* set to NULL to prevent freeing on exit */ 2283 /* set to NULL to prevent freeing on exit */
2281 volume_info.password = NULL; 2284 volume_info->password = NULL;
2282 } 2285 }
2283 if (volume_info.username) 2286 if (volume_info->username)
2284 strncpy(pSesInfo->userName, volume_info.username, 2287 strncpy(pSesInfo->userName, volume_info->username,
2285 MAX_USERNAME_SIZE); 2288 MAX_USERNAME_SIZE);
2286 if (volume_info.domainname) { 2289 if (volume_info->domainname) {
2287 int len = strlen(volume_info.domainname); 2290 int len = strlen(volume_info->domainname);
2288 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); 2291 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2289 if (pSesInfo->domainName) 2292 if (pSesInfo->domainName)
2290 strcpy(pSesInfo->domainName, 2293 strcpy(pSesInfo->domainName,
2291 volume_info.domainname); 2294 volume_info->domainname);
2292 } 2295 }
2293 pSesInfo->linux_uid = volume_info.linux_uid; 2296 pSesInfo->linux_uid = volume_info->linux_uid;
2294 pSesInfo->overrideSecFlg = volume_info.secFlg; 2297 pSesInfo->overrideSecFlg = volume_info->secFlg;
2295 down(&pSesInfo->sesSem); 2298 down(&pSesInfo->sesSem);
2296 2299
2297 /* BB FIXME need to pass vol->secFlgs BB */ 2300 /* BB FIXME need to pass vol->secFlgs BB */
@@ -2302,14 +2305,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2302 2305
2303 /* search for existing tcon to this server share */ 2306 /* search for existing tcon to this server share */
2304 if (!rc) { 2307 if (!rc) {
2305 setup_cifs_sb(&volume_info, cifs_sb); 2308 setup_cifs_sb(volume_info, cifs_sb);
2306 2309
2307 tcon = cifs_find_tcon(pSesInfo, volume_info.UNC); 2310 tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
2308 if (tcon) { 2311 if (tcon) {
2309 cFYI(1, ("Found match on UNC path")); 2312 cFYI(1, ("Found match on UNC path"));
2310 /* existing tcon already has a reference */ 2313 /* existing tcon already has a reference */
2311 cifs_put_smb_ses(pSesInfo); 2314 cifs_put_smb_ses(pSesInfo);
2312 if (tcon->seal != volume_info.seal) 2315 if (tcon->seal != volume_info->seal)
2313 cERROR(1, ("transport encryption setting " 2316 cERROR(1, ("transport encryption setting "
2314 "conflicts with existing tid")); 2317 "conflicts with existing tid"));
2315 } else { 2318 } else {
@@ -2321,8 +2324,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2321 tcon->ses = pSesInfo; 2324 tcon->ses = pSesInfo;
2322 2325
2323 /* check for null share name ie connect to dfs root */ 2326 /* check for null share name ie connect to dfs root */
2324 if ((strchr(volume_info.UNC + 3, '\\') == NULL) 2327 if ((strchr(volume_info->UNC + 3, '\\') == NULL)
2325 && (strchr(volume_info.UNC + 3, '/') == NULL)) { 2328 && (strchr(volume_info->UNC + 3, '/') == NULL)) {
2326 /* rc = connect_to_dfs_path(...) */ 2329 /* rc = connect_to_dfs_path(...) */
2327 cFYI(1, ("DFS root not supported")); 2330 cFYI(1, ("DFS root not supported"));
2328 rc = -ENODEV; 2331 rc = -ENODEV;
@@ -2331,10 +2334,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2331 /* BB Do we need to wrap sesSem around 2334 /* BB Do we need to wrap sesSem around
2332 * this TCon call and Unix SetFS as 2335 * this TCon call and Unix SetFS as
2333 * we do on SessSetup and reconnect? */ 2336 * we do on SessSetup and reconnect? */
2334 rc = CIFSTCon(xid, pSesInfo, volume_info.UNC, 2337 rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
2335 tcon, cifs_sb->local_nls); 2338 tcon, cifs_sb->local_nls);
2336 cFYI(1, ("CIFS Tcon rc = %d", rc)); 2339 cFYI(1, ("CIFS Tcon rc = %d", rc));
2337 if (volume_info.nodfs) { 2340 if (volume_info->nodfs) {
2338 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; 2341 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2339 cFYI(1, ("DFS disabled (%d)", 2342 cFYI(1, ("DFS disabled (%d)",
2340 tcon->Flags)); 2343 tcon->Flags));
@@ -2342,7 +2345,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2342 } 2345 }
2343 if (rc) 2346 if (rc)
2344 goto mount_fail_check; 2347 goto mount_fail_check;
2345 tcon->seal = volume_info.seal; 2348 tcon->seal = volume_info->seal;
2346 write_lock(&cifs_tcp_ses_lock); 2349 write_lock(&cifs_tcp_ses_lock);
2347 list_add(&tcon->tcon_list, &pSesInfo->tcon_list); 2350 list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
2348 write_unlock(&cifs_tcp_ses_lock); 2351 write_unlock(&cifs_tcp_ses_lock);
@@ -2352,9 +2355,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2352 to a share so for resources mounted more than once 2355 to a share so for resources mounted more than once
2353 to the same server share the last value passed in 2356 to the same server share the last value passed in
2354 for the retry flag is used */ 2357 for the retry flag is used */
2355 tcon->retry = volume_info.retry; 2358 tcon->retry = volume_info->retry;
2356 tcon->nocase = volume_info.nocase; 2359 tcon->nocase = volume_info->nocase;
2357 tcon->local_lease = volume_info.local_lease; 2360 tcon->local_lease = volume_info->local_lease;
2358 } 2361 }
2359 if (pSesInfo) { 2362 if (pSesInfo) {
2360 if (pSesInfo->capabilities & CAP_LARGE_FILES) { 2363 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
@@ -2391,7 +2394,7 @@ mount_fail_check:
2391 if (tcon->ses->capabilities & CAP_UNIX) 2394 if (tcon->ses->capabilities & CAP_UNIX)
2392 /* reset of caps checks mount to see if unix extensions 2395 /* reset of caps checks mount to see if unix extensions
2393 disabled for just this mount */ 2396 disabled for just this mount */
2394 reset_cifs_unix_caps(xid, tcon, sb, &volume_info); 2397 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2395 else 2398 else
2396 tcon->unix_ext = 0; /* server does not support them */ 2399 tcon->unix_ext = 0; /* server does not support them */
2397 2400
@@ -2410,18 +2413,22 @@ mount_fail_check:
2410 cifs_sb->rsize = min(cifs_sb->rsize, 2413 cifs_sb->rsize = min(cifs_sb->rsize,
2411 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); 2414 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2412 2415
2413 /* volume_info.password is freed above when existing session found 2416 /* volume_info->password is freed above when existing session found
2414 (in which case it is not needed anymore) but when new sesion is created 2417 (in which case it is not needed anymore) but when new sesion is created
2415 the password ptr is put in the new session structure (in which case the 2418 the password ptr is put in the new session structure (in which case the
2416 password will be freed at unmount time) */ 2419 password will be freed at unmount time) */
2417out: 2420out:
2418 /* zero out password before freeing */ 2421 /* zero out password before freeing */
2419 if (volume_info.password != NULL) { 2422 if (volume_info) {
2420 memset(volume_info.password, 0, strlen(volume_info.password)); 2423 if (volume_info->password != NULL) {
2421 kfree(volume_info.password); 2424 memset(volume_info->password, 0,
2425 strlen(volume_info->password));
2426 kfree(volume_info->password);
2427 }
2428 kfree(volume_info->UNC);
2429 kfree(volume_info->prepath);
2430 kfree(volume_info);
2422 } 2431 }
2423 kfree(volume_info.UNC);
2424 kfree(volume_info.prepath);
2425 FreeXid(xid); 2432 FreeXid(xid);
2426 return rc; 2433 return rc;
2427} 2434}