diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-09-21 05:09:22 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-09-21 05:09:22 -0400 |
commit | 7cce2f4cb7f5f641f78c8e3eea4e7b1b96cb71c0 (patch) | |
tree | b064d077928cf224660ab1e1841cdab2c9fd8b08 /fs/cifs/connect.c | |
parent | e055f7e873d900925c222cf2d1ec955af4a9ca90 (diff) | |
parent | ebc79c4f8da0f92efa968e0328f32334a2ce80cf (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.c | 112 |
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 | ||
1361 | static struct TCP_Server_Info * | 1379 | static struct TCP_Server_Info * |
1362 | cifs_find_tcp_session(struct sockaddr_storage *addr) | 1380 | cifs_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, |