diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/cifs/CHANGES | 7 | ||||
| -rw-r--r-- | fs/cifs/README | 25 | ||||
| -rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 12 | ||||
| -rw-r--r-- | fs/cifs/cifs_unicode.c | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 4 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 55 | ||||
| -rw-r--r-- | fs/nilfs2/mdt.c | 4 | ||||
| -rw-r--r-- | fs/nilfs2/segment.c | 16 |
8 files changed, 91 insertions, 34 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 92888aa90749..e85b1e4389e0 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | Version 1.60 | ||
| 2 | ------------- | ||
| 3 | Fix memory leak in reconnect. Fix oops in DFS mount error path. | ||
| 4 | Set s_maxbytes to smaller (the max that vfs can handle) so that | ||
| 5 | sendfile will now work over cifs mounts again. Add noforcegid | ||
| 6 | and noforceuid mount parameters. | ||
| 7 | |||
| 1 | Version 1.59 | 8 | Version 1.59 |
| 2 | ------------ | 9 | ------------ |
| 3 | Client uses server inode numbers (which are persistent) rather than | 10 | Client uses server inode numbers (which are persistent) rather than |
diff --git a/fs/cifs/README b/fs/cifs/README index ad92921dbde4..79c1a93400be 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
| @@ -262,11 +262,11 @@ A partial list of the supported mount options follows: | |||
| 262 | mount. | 262 | mount. |
| 263 | domain Set the SMB/CIFS workgroup name prepended to the | 263 | domain Set the SMB/CIFS workgroup name prepended to the |
| 264 | username during CIFS session establishment | 264 | username during CIFS session establishment |
| 265 | forceuid Set the default uid for inodes based on the uid | 265 | forceuid Set the default uid for inodes to the uid |
| 266 | passed in. For mounts to servers | 266 | passed in on mount. For mounts to servers |
| 267 | which do support the CIFS Unix extensions, such as a | 267 | which do support the CIFS Unix extensions, such as a |
| 268 | properly configured Samba server, the server provides | 268 | properly configured Samba server, the server provides |
| 269 | the uid, gid and mode so this parameter should not be | 269 | the uid, gid and mode so this parameter should not be |
| 270 | specified unless the server and clients uid and gid | 270 | specified unless the server and clients uid and gid |
| 271 | numbering differ. If the server and client are in the | 271 | numbering differ. If the server and client are in the |
| 272 | same domain (e.g. running winbind or nss_ldap) and | 272 | same domain (e.g. running winbind or nss_ldap) and |
| @@ -278,11 +278,7 @@ A partial list of the supported mount options follows: | |||
| 278 | of existing files will be the uid (gid) of the person | 278 | of existing files will be the uid (gid) of the person |
| 279 | who executed the mount (root, except when mount.cifs | 279 | who executed the mount (root, except when mount.cifs |
| 280 | is configured setuid for user mounts) unless the "uid=" | 280 | is configured setuid for user mounts) unless the "uid=" |
| 281 | (gid) mount option is specified. For the uid (gid) of newly | 281 | (gid) mount option is specified. Also note that permission |
| 282 | created files and directories, ie files created since | ||
| 283 | the last mount of the server share, the expected uid | ||
| 284 | (gid) is cached as long as the inode remains in | ||
| 285 | memory on the client. Also note that permission | ||
| 286 | checks (authorization checks) on accesses to a file occur | 282 | checks (authorization checks) on accesses to a file occur |
| 287 | at the server, but there are cases in which an administrator | 283 | at the server, but there are cases in which an administrator |
| 288 | may want to restrict at the client as well. For those | 284 | may want to restrict at the client as well. For those |
| @@ -290,12 +286,15 @@ A partial list of the supported mount options follows: | |||
| 290 | (such as Windows), permissions can also be checked at the | 286 | (such as Windows), permissions can also be checked at the |
| 291 | client, and a crude form of client side permission checking | 287 | client, and a crude form of client side permission checking |
| 292 | can be enabled by specifying file_mode and dir_mode on | 288 | can be enabled by specifying file_mode and dir_mode on |
| 293 | the client. Note that the mount.cifs helper must be | 289 | the client. (default) |
| 294 | at version 1.10 or higher to support specifying the uid | 290 | forcegid (similar to above but for the groupid instead of uid) (default) |
| 295 | (or gid) in non-numeric form. | 291 | noforceuid Fill in file owner information (uid) by requesting it from |
| 296 | forcegid (similar to above but for the groupid instead of uid) | 292 | the server if possible. With this option, the value given in |
| 293 | the uid= option (on mount) will only be used if the server | ||
| 294 | can not support returning uids on inodes. | ||
| 295 | noforcegid (similar to above but for the group owner, gid, instead of uid) | ||
| 297 | uid Set the default uid for inodes, and indicate to the | 296 | uid Set the default uid for inodes, and indicate to the |
| 298 | cifs kernel driver which local user mounted . If the server | 297 | cifs kernel driver which local user mounted. If the server |
| 299 | supports the unix extensions the default uid is | 298 | supports the unix extensions the default uid is |
| 300 | not used to fill in the owner fields of inodes (files) | 299 | not used to fill in the owner fields of inodes (files) |
| 301 | unless the "forceuid" parameter is specified. | 300 | unless the "forceuid" parameter is specified. |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 3bb11be8b6a8..606912d8f2a8 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
| @@ -55,7 +55,7 @@ void cifs_dfs_release_automount_timer(void) | |||
| 55 | * i.e. strips from UNC trailing path that is not part of share | 55 | * i.e. strips from UNC trailing path that is not part of share |
| 56 | * name and fixup missing '\' in the begining of DFS node refferal | 56 | * name and fixup missing '\' in the begining of DFS node refferal |
| 57 | * if neccessary. | 57 | * if neccessary. |
| 58 | * Returns pointer to share name on success or NULL on error. | 58 | * Returns pointer to share name on success or ERR_PTR on error. |
| 59 | * Caller is responsible for freeing returned string. | 59 | * Caller is responsible for freeing returned string. |
| 60 | */ | 60 | */ |
| 61 | static char *cifs_get_share_name(const char *node_name) | 61 | static char *cifs_get_share_name(const char *node_name) |
| @@ -68,7 +68,7 @@ static char *cifs_get_share_name(const char *node_name) | |||
| 68 | UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */, | 68 | UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */, |
| 69 | GFP_KERNEL); | 69 | GFP_KERNEL); |
| 70 | if (!UNC) | 70 | if (!UNC) |
| 71 | return NULL; | 71 | return ERR_PTR(-ENOMEM); |
| 72 | 72 | ||
| 73 | /* get share name and server name */ | 73 | /* get share name and server name */ |
| 74 | if (node_name[1] != '\\') { | 74 | if (node_name[1] != '\\') { |
| @@ -87,7 +87,7 @@ static char *cifs_get_share_name(const char *node_name) | |||
| 87 | cERROR(1, ("%s: no server name end in node name: %s", | 87 | cERROR(1, ("%s: no server name end in node name: %s", |
| 88 | __func__, node_name)); | 88 | __func__, node_name)); |
| 89 | kfree(UNC); | 89 | kfree(UNC); |
| 90 | return NULL; | 90 | return ERR_PTR(-EINVAL); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /* find sharename end */ | 93 | /* find sharename end */ |
| @@ -133,6 +133,12 @@ char *cifs_compose_mount_options(const char *sb_mountdata, | |||
| 133 | return ERR_PTR(-EINVAL); | 133 | return ERR_PTR(-EINVAL); |
| 134 | 134 | ||
| 135 | *devname = cifs_get_share_name(ref->node_name); | 135 | *devname = cifs_get_share_name(ref->node_name); |
| 136 | if (IS_ERR(*devname)) { | ||
| 137 | rc = PTR_ERR(*devname); | ||
| 138 | *devname = NULL; | ||
| 139 | goto compose_mount_options_err; | ||
| 140 | } | ||
| 141 | |||
| 136 | rc = dns_resolve_server_name_to_ip(*devname, &srvIP); | 142 | rc = dns_resolve_server_name_to_ip(*devname, &srvIP); |
| 137 | if (rc != 0) { | 143 | if (rc != 0) { |
| 138 | cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d", | 144 | cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d", |
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 60e3c4253de0..714a542cbafc 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
| @@ -44,7 +44,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes, | |||
| 44 | int maxwords = maxbytes / 2; | 44 | int maxwords = maxbytes / 2; |
| 45 | char tmp[NLS_MAX_CHARSET_SIZE]; | 45 | char tmp[NLS_MAX_CHARSET_SIZE]; |
| 46 | 46 | ||
| 47 | for (i = 0; from[i] && i < maxwords; i++) { | 47 | for (i = 0; i < maxwords && from[i]; i++) { |
| 48 | charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp, | 48 | charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp, |
| 49 | NLS_MAX_CHARSET_SIZE); | 49 | NLS_MAX_CHARSET_SIZE); |
| 50 | if (charlen > 0) | 50 | if (charlen > 0) |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 44f30504b82d..84b75253b05a 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -376,10 +376,14 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
| 376 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | 376 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); |
| 377 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | 377 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
| 378 | seq_printf(s, ",forceuid"); | 378 | seq_printf(s, ",forceuid"); |
| 379 | else | ||
| 380 | seq_printf(s, ",noforceuid"); | ||
| 379 | 381 | ||
| 380 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | 382 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); |
| 381 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | 383 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) |
| 382 | seq_printf(s, ",forcegid"); | 384 | seq_printf(s, ",forcegid"); |
| 385 | else | ||
| 386 | seq_printf(s, ",noforcegid"); | ||
| 383 | 387 | ||
| 384 | cifs_show_address(s, tcon->ses->server); | 388 | cifs_show_address(s, tcon->ses->server); |
| 385 | 389 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index fc44d316d0bb..1f3345d7fa79 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,6 +1361,18 @@ 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 | ||
| @@ -2544,11 +2562,20 @@ remote_path_check: | |||
| 2544 | 2562 | ||
| 2545 | if (mount_data != mount_data_global) | 2563 | if (mount_data != mount_data_global) |
| 2546 | kfree(mount_data); | 2564 | kfree(mount_data); |
| 2565 | |||
| 2547 | mount_data = cifs_compose_mount_options( | 2566 | mount_data = cifs_compose_mount_options( |
| 2548 | cifs_sb->mountdata, full_path + 1, | 2567 | cifs_sb->mountdata, full_path + 1, |
| 2549 | referrals, &fake_devname); | 2568 | referrals, &fake_devname); |
| 2550 | kfree(fake_devname); | 2569 | |
| 2551 | free_dfs_info_array(referrals, num_referrals); | 2570 | free_dfs_info_array(referrals, num_referrals); |
| 2571 | kfree(fake_devname); | ||
| 2572 | kfree(full_path); | ||
| 2573 | |||
| 2574 | if (IS_ERR(mount_data)) { | ||
| 2575 | rc = PTR_ERR(mount_data); | ||
| 2576 | mount_data = NULL; | ||
| 2577 | goto mount_fail_check; | ||
| 2578 | } | ||
| 2552 | 2579 | ||
| 2553 | if (tcon) | 2580 | if (tcon) |
| 2554 | cifs_put_tcon(tcon); | 2581 | cifs_put_tcon(tcon); |
| @@ -2556,8 +2583,6 @@ remote_path_check: | |||
| 2556 | cifs_put_smb_ses(pSesInfo); | 2583 | cifs_put_smb_ses(pSesInfo); |
| 2557 | 2584 | ||
| 2558 | cleanup_volume_info(&volume_info); | 2585 | cleanup_volume_info(&volume_info); |
| 2559 | FreeXid(xid); | ||
| 2560 | kfree(full_path); | ||
| 2561 | referral_walks_count++; | 2586 | referral_walks_count++; |
| 2562 | goto try_mount_again; | 2587 | goto try_mount_again; |
| 2563 | } | 2588 | } |
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 3d3ddb3f5177..2dfd47714ae5 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
| @@ -412,8 +412,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
| 412 | return 0; /* Do not request flush for shadow page cache */ | 412 | return 0; /* Do not request flush for shadow page cache */ |
| 413 | if (!sb) { | 413 | if (!sb) { |
| 414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); | 414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); |
| 415 | if (!writer) | 415 | if (!writer) { |
| 416 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | ||
| 416 | return -EROFS; | 417 | return -EROFS; |
| 418 | } | ||
| 417 | sb = writer->s_super; | 419 | sb = writer->s_super; |
| 418 | } | 420 | } |
| 419 | 421 | ||
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 8b5e4778cf28..51ff3d0a4ee2 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -1859,12 +1859,26 @@ static void nilfs_end_page_io(struct page *page, int err) | |||
| 1859 | if (!page) | 1859 | if (!page) |
| 1860 | return; | 1860 | return; |
| 1861 | 1861 | ||
| 1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) | 1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) { |
| 1863 | /* | 1863 | /* |
| 1864 | * For b-tree node pages, this function may be called twice | 1864 | * For b-tree node pages, this function may be called twice |
| 1865 | * or more because they might be split in a segment. | 1865 | * or more because they might be split in a segment. |
| 1866 | */ | 1866 | */ |
| 1867 | if (PageDirty(page)) { | ||
| 1868 | /* | ||
| 1869 | * For pages holding split b-tree node buffers, dirty | ||
| 1870 | * flag on the buffers may be cleared discretely. | ||
| 1871 | * In that case, the page is once redirtied for | ||
| 1872 | * remaining buffers, and it must be cancelled if | ||
| 1873 | * all the buffers get cleaned later. | ||
| 1874 | */ | ||
| 1875 | lock_page(page); | ||
| 1876 | if (nilfs_page_buffers_clean(page)) | ||
| 1877 | __nilfs_clear_page_dirty(page); | ||
| 1878 | unlock_page(page); | ||
| 1879 | } | ||
| 1867 | return; | 1880 | return; |
| 1881 | } | ||
| 1868 | 1882 | ||
| 1869 | __nilfs_end_page_io(page, err); | 1883 | __nilfs_end_page_io(page, err); |
| 1870 | } | 1884 | } |
