aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-09-21 05:09:22 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-09-21 05:09:22 -0400
commit7cce2f4cb7f5f641f78c8e3eea4e7b1b96cb71c0 (patch)
treeb064d077928cf224660ab1e1841cdab2c9fd8b08 /fs/cifs/connect.c
parente055f7e873d900925c222cf2d1ec955af4a9ca90 (diff)
parentebc79c4f8da0f92efa968e0328f32334a2ce80cf (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into linux-next
Conflicts: fs/ubifs/super.c Merge the upstream tree in order to resolve a conflict with the per-bdi writeback changes from the linux-2.6-block tree.
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c112
1 files changed, 79 insertions, 33 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9bb5c8750736..d49682433c20 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -803,6 +803,10 @@ cifs_parse_mount_options(char *options, const char *devname,
803 char *data; 803 char *data;
804 unsigned int temp_len, i, j; 804 unsigned int temp_len, i, j;
805 char separator[2]; 805 char separator[2];
806 short int override_uid = -1;
807 short int override_gid = -1;
808 bool uid_specified = false;
809 bool gid_specified = false;
806 810
807 separator[0] = ','; 811 separator[0] = ',';
808 separator[1] = 0; 812 separator[1] = 0;
@@ -1093,18 +1097,20 @@ cifs_parse_mount_options(char *options, const char *devname,
1093 "too long.\n"); 1097 "too long.\n");
1094 return 1; 1098 return 1;
1095 } 1099 }
1096 } else if (strnicmp(data, "uid", 3) == 0) { 1100 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1097 if (value && *value) 1101 vol->linux_uid = simple_strtoul(value, &value, 0);
1098 vol->linux_uid = 1102 uid_specified = true;
1099 simple_strtoul(value, &value, 0); 1103 } else if (!strnicmp(data, "forceuid", 8)) {
1100 } else if (strnicmp(data, "forceuid", 8) == 0) { 1104 override_uid = 1;
1101 vol->override_uid = 1; 1105 } else if (!strnicmp(data, "noforceuid", 10)) {
1102 } else if (strnicmp(data, "gid", 3) == 0) { 1106 override_uid = 0;
1103 if (value && *value) 1107 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1104 vol->linux_gid = 1108 vol->linux_gid = simple_strtoul(value, &value, 0);
1105 simple_strtoul(value, &value, 0); 1109 gid_specified = true;
1106 } else if (strnicmp(data, "forcegid", 8) == 0) { 1110 } else if (!strnicmp(data, "forcegid", 8)) {
1107 vol->override_gid = 1; 1111 override_gid = 1;
1112 } else if (!strnicmp(data, "noforcegid", 10)) {
1113 override_gid = 0;
1108 } else if (strnicmp(data, "file_mode", 4) == 0) { 1114 } else if (strnicmp(data, "file_mode", 4) == 0) {
1109 if (value && *value) { 1115 if (value && *value) {
1110 vol->file_mode = 1116 vol->file_mode =
@@ -1355,11 +1361,23 @@ cifs_parse_mount_options(char *options, const char *devname,
1355 if (vol->UNCip == NULL) 1361 if (vol->UNCip == NULL)
1356 vol->UNCip = &vol->UNC[2]; 1362 vol->UNCip = &vol->UNC[2];
1357 1363
1364 if (uid_specified)
1365 vol->override_uid = override_uid;
1366 else if (override_uid == 1)
1367 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1368 "specified with no uid= option.\n");
1369
1370 if (gid_specified)
1371 vol->override_gid = override_gid;
1372 else if (override_gid == 1)
1373 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1374 "specified with no gid= option.\n");
1375
1358 return 0; 1376 return 0;
1359} 1377}
1360 1378
1361static struct TCP_Server_Info * 1379static struct TCP_Server_Info *
1362cifs_find_tcp_session(struct sockaddr_storage *addr) 1380cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port)
1363{ 1381{
1364 struct list_head *tmp; 1382 struct list_head *tmp;
1365 struct TCP_Server_Info *server; 1383 struct TCP_Server_Info *server;
@@ -1379,16 +1397,37 @@ cifs_find_tcp_session(struct sockaddr_storage *addr)
1379 if (server->tcpStatus == CifsNew) 1397 if (server->tcpStatus == CifsNew)
1380 continue; 1398 continue;
1381 1399
1382 if (addr->ss_family == AF_INET && 1400 switch (addr->ss_family) {
1383 (addr4->sin_addr.s_addr != 1401 case AF_INET:
1384 server->addr.sockAddr.sin_addr.s_addr)) 1402 if (addr4->sin_addr.s_addr ==
1385 continue; 1403 server->addr.sockAddr.sin_addr.s_addr) {
1386 else if (addr->ss_family == AF_INET6 && 1404 addr4->sin_port = htons(port);
1387 (!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, 1405 /* user overrode default port? */
1388 &addr6->sin6_addr) || 1406 if (addr4->sin_port) {
1389 server->addr.sockAddr6.sin6_scope_id != 1407 if (addr4->sin_port !=
1390 addr6->sin6_scope_id)) 1408 server->addr.sockAddr.sin_port)
1391 continue; 1409 continue;
1410 }
1411 break;
1412 } else
1413 continue;
1414
1415 case AF_INET6:
1416 if (ipv6_addr_equal(&addr6->sin6_addr,
1417 &server->addr.sockAddr6.sin6_addr) &&
1418 (addr6->sin6_scope_id ==
1419 server->addr.sockAddr6.sin6_scope_id)) {
1420 addr6->sin6_port = htons(port);
1421 /* user overrode default port? */
1422 if (addr6->sin6_port) {
1423 if (addr6->sin6_port !=
1424 server->addr.sockAddr6.sin6_port)
1425 continue;
1426 }
1427 break;
1428 } else
1429 continue;
1430 }
1392 1431
1393 ++server->srv_count; 1432 ++server->srv_count;
1394 write_unlock(&cifs_tcp_ses_lock); 1433 write_unlock(&cifs_tcp_ses_lock);
@@ -1457,7 +1496,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1457 } 1496 }
1458 1497
1459 /* see if we already have a matching tcp_ses */ 1498 /* see if we already have a matching tcp_ses */
1460 tcp_ses = cifs_find_tcp_session(&addr); 1499 tcp_ses = cifs_find_tcp_session(&addr, volume_info->port);
1461 if (tcp_ses) 1500 if (tcp_ses)
1462 return tcp_ses; 1501 return tcp_ses;
1463 1502
@@ -2452,10 +2491,10 @@ try_mount_again:
2452 tcon->local_lease = volume_info->local_lease; 2491 tcon->local_lease = volume_info->local_lease;
2453 } 2492 }
2454 if (pSesInfo) { 2493 if (pSesInfo) {
2455 if (pSesInfo->capabilities & CAP_LARGE_FILES) { 2494 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2456 sb->s_maxbytes = (u64) 1 << 63; 2495 sb->s_maxbytes = MAX_LFS_FILESIZE;
2457 } else 2496 else
2458 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */ 2497 sb->s_maxbytes = MAX_NON_LFS;
2459 } 2498 }
2460 2499
2461 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 2500 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
@@ -2544,11 +2583,20 @@ remote_path_check:
2544 2583
2545 if (mount_data != mount_data_global) 2584 if (mount_data != mount_data_global)
2546 kfree(mount_data); 2585 kfree(mount_data);
2586
2547 mount_data = cifs_compose_mount_options( 2587 mount_data = cifs_compose_mount_options(
2548 cifs_sb->mountdata, full_path + 1, 2588 cifs_sb->mountdata, full_path + 1,
2549 referrals, &fake_devname); 2589 referrals, &fake_devname);
2550 kfree(fake_devname); 2590
2551 free_dfs_info_array(referrals, num_referrals); 2591 free_dfs_info_array(referrals, num_referrals);
2592 kfree(fake_devname);
2593 kfree(full_path);
2594
2595 if (IS_ERR(mount_data)) {
2596 rc = PTR_ERR(mount_data);
2597 mount_data = NULL;
2598 goto mount_fail_check;
2599 }
2552 2600
2553 if (tcon) 2601 if (tcon)
2554 cifs_put_tcon(tcon); 2602 cifs_put_tcon(tcon);
@@ -2556,8 +2604,6 @@ remote_path_check:
2556 cifs_put_smb_ses(pSesInfo); 2604 cifs_put_smb_ses(pSesInfo);
2557 2605
2558 cleanup_volume_info(&volume_info); 2606 cleanup_volume_info(&volume_info);
2559 FreeXid(xid);
2560 kfree(full_path);
2561 referral_walks_count++; 2607 referral_walks_count++;
2562 goto try_mount_again; 2608 goto try_mount_again;
2563 } 2609 }
@@ -2611,9 +2657,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2611 return -EIO; 2657 return -EIO;
2612 2658
2613 smb_buffer = cifs_buf_get(); 2659 smb_buffer = cifs_buf_get();
2614 if (smb_buffer == NULL) { 2660 if (smb_buffer == NULL)
2615 return -ENOMEM; 2661 return -ENOMEM;
2616 } 2662
2617 smb_buffer_response = smb_buffer; 2663 smb_buffer_response = smb_buffer;
2618 2664
2619 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, 2665 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,