aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2009-05-22 04:40:59 -0400
committerJames Morris <jmorris@namei.org>2009-05-22 04:40:59 -0400
commit2c9e703c618106f5383226fbb1f526cb11034f8a (patch)
tree87d7548001ea82f655fede0640466fc16aabcdf7 /fs
parent6470c077cae12227318f40f3e6d756caadcce4b0 (diff)
parent5805977e63a36ad56594a623f3bd2bebcb7db233 (diff)
Merge branch 'master' into next
Conflicts: fs/exec.c Removed IMA changes (the IMA checks are now performed via may_open()). Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_super.c12
-rw-r--r--fs/affs/super.c3
-rw-r--r--fs/afs/super.c7
-rw-r--r--fs/btrfs/ctree.c39
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/btrfs/ioctl.c4
-rw-r--r--fs/btrfs/super.c16
-rw-r--r--fs/cifs/CHANGES13
-rw-r--r--fs/cifs/README10
-rw-r--r--fs/cifs/cifs_dfs_ref.c32
-rw-r--r--fs/cifs/cifs_unicode.c198
-rw-r--r--fs/cifs/cifs_unicode.h23
-rw-r--r--fs/cifs/cifsfs.c6
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h16
-rw-r--r--fs/cifs/cifsproto.h5
-rw-r--r--fs/cifs/cifssmb.c215
-rw-r--r--fs/cifs/connect.c1190
-rw-r--r--fs/cifs/dir.c15
-rw-r--r--fs/cifs/file.c14
-rw-r--r--fs/cifs/inode.c21
-rw-r--r--fs/cifs/link.c162
-rw-r--r--fs/cifs/misc.c71
-rw-r--r--fs/cifs/netmisc.c2
-rw-r--r--fs/cifs/nterr.h9
-rw-r--r--fs/cifs/ntlmssp.h68
-rw-r--r--fs/cifs/readdir.c72
-rw-r--r--fs/cifs/sess.c340
-rw-r--r--fs/cifs/smberr.h1
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/devpts/inode.c23
-rw-r--r--fs/ecryptfs/main.c5
-rw-r--r--fs/eventpoll.c2
-rw-r--r--fs/exec.c80
-rw-r--r--fs/ext4/extents.c19
-rw-r--r--fs/ext4/inode.c26
-rw-r--r--fs/fcntl.c6
-rw-r--r--fs/fuse/inode.c4
-rw-r--r--fs/gfs2/glock.c1
-rw-r--r--fs/gfs2/ops_fstype.c8
-rw-r--r--fs/hpfs/super.c3
-rw-r--r--fs/hugetlbfs/inode.c11
-rw-r--r--fs/inode.c81
-rw-r--r--fs/libfs.c3
-rw-r--r--fs/lockd/svc.c15
-rw-r--r--fs/namei.c13
-rw-r--r--fs/namespace.c23
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/super.c22
-rw-r--r--fs/nfsd/nfs4recover.c4
-rw-r--r--fs/nfsd/nfs4state.c1
-rw-r--r--fs/nfsd/nfs4xdr.c16
-rw-r--r--fs/nilfs2/ioctl.c281
-rw-r--r--fs/nilfs2/mdt.c15
-rw-r--r--fs/nilfs2/nilfs.h3
-rw-r--r--fs/nilfs2/page.c3
-rw-r--r--fs/nilfs2/recovery.c6
-rw-r--r--fs/nilfs2/segment.c5
-rw-r--r--fs/nilfs2/segment.h3
-rw-r--r--fs/ocfs2/symlink.c77
-rw-r--r--fs/open.c2
-rw-r--r--fs/proc/root.c3
-rw-r--r--fs/reiserfs/dir.c24
-rw-r--r--fs/reiserfs/namei.c17
-rw-r--r--fs/reiserfs/super.c11
-rw-r--r--fs/reiserfs/xattr.c260
-rw-r--r--fs/reiserfs/xattr_security.c12
-rw-r--r--fs/romfs/super.c3
-rw-r--r--fs/squashfs/Makefile1
-rw-r--r--fs/squashfs/cache.c1
-rw-r--r--fs/squashfs/super.c10
-rw-r--r--fs/super.c48
-rw-r--r--fs/ubifs/super.c3
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--fs/ufs/file.c2
-rw-r--r--fs/ufs/ufs.h2
78 files changed, 1489 insertions, 2248 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 5f8ab8adb5f5..ab5547ff29a1 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -37,6 +37,7 @@
37#include <linux/mount.h> 37#include <linux/mount.h>
38#include <linux/idr.h> 38#include <linux/idr.h>
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/smp_lock.h>
40#include <net/9p/9p.h> 41#include <net/9p/9p.h>
41#include <net/9p/client.h> 42#include <net/9p/client.h>
42 43
@@ -155,6 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
155 156
156 root = d_alloc_root(inode); 157 root = d_alloc_root(inode);
157 if (!root) { 158 if (!root) {
159 iput(inode);
158 retval = -ENOMEM; 160 retval = -ENOMEM;
159 goto release_sb; 161 goto release_sb;
160 } 162 }
@@ -173,10 +175,7 @@ P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
173 return 0; 175 return 0;
174 176
175release_sb: 177release_sb:
176 if (sb) { 178 deactivate_locked_super(sb);
177 up_write(&sb->s_umount);
178 deactivate_super(sb);
179 }
180 179
181free_stat: 180free_stat:
182 kfree(st); 181 kfree(st);
@@ -230,9 +229,12 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
230static void 229static void
231v9fs_umount_begin(struct super_block *sb) 230v9fs_umount_begin(struct super_block *sb)
232{ 231{
233 struct v9fs_session_info *v9ses = sb->s_fs_info; 232 struct v9fs_session_info *v9ses;
234 233
234 lock_kernel();
235 v9ses = sb->s_fs_info;
235 v9fs_session_cancel(v9ses); 236 v9fs_session_cancel(v9ses);
237 unlock_kernel();
236} 238}
237 239
238static const struct super_operations v9fs_super_ops = { 240static const struct super_operations v9fs_super_ops = {
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 5ce695e707fe..63f5183f263b 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -507,8 +507,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
507 kfree(new_opts); 507 kfree(new_opts);
508 return -EINVAL; 508 return -EINVAL;
509 } 509 }
510 kfree(sb->s_options); 510 replace_mount_options(sb, new_opts);
511 sb->s_options = new_opts;
512 511
513 sbi->s_flags = mount_flags; 512 sbi->s_flags = mount_flags;
514 sbi->s_mode = mode; 513 sbi->s_mode = mode;
diff --git a/fs/afs/super.c b/fs/afs/super.c
index aee239a048cb..76828e5f8a39 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -405,21 +405,20 @@ static int afs_get_sb(struct file_system_type *fs_type,
405 sb->s_flags = flags; 405 sb->s_flags = flags;
406 ret = afs_fill_super(sb, &params); 406 ret = afs_fill_super(sb, &params);
407 if (ret < 0) { 407 if (ret < 0) {
408 up_write(&sb->s_umount); 408 deactivate_locked_super(sb);
409 deactivate_super(sb);
410 goto error; 409 goto error;
411 } 410 }
412 sb->s_options = new_opts; 411 save_mount_options(sb, new_opts);
413 sb->s_flags |= MS_ACTIVE; 412 sb->s_flags |= MS_ACTIVE;
414 } else { 413 } else {
415 _debug("reuse"); 414 _debug("reuse");
416 kfree(new_opts);
417 ASSERTCMP(sb->s_flags, &, MS_ACTIVE); 415 ASSERTCMP(sb->s_flags, &, MS_ACTIVE);
418 } 416 }
419 417
420 simple_set_mnt(mnt, sb); 418 simple_set_mnt(mnt, sb);
421 afs_put_volume(params.volume); 419 afs_put_volume(params.volume);
422 afs_put_cell(params.cell); 420 afs_put_cell(params.cell);
421 kfree(new_opts);
423 _leave(" = 0 [%p]", sb); 422 _leave(" = 0 [%p]", sb);
424 return 0; 423 return 0;
425 424
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a99f1c2a710d..fedf8b9f03a2 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1469,6 +1469,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
1469 u32 blocksize; 1469 u32 blocksize;
1470 struct extent_buffer *b = *eb_ret; 1470 struct extent_buffer *b = *eb_ret;
1471 struct extent_buffer *tmp; 1471 struct extent_buffer *tmp;
1472 int ret;
1472 1473
1473 blocknr = btrfs_node_blockptr(b, slot); 1474 blocknr = btrfs_node_blockptr(b, slot);
1474 gen = btrfs_node_ptr_generation(b, slot); 1475 gen = btrfs_node_ptr_generation(b, slot);
@@ -1476,6 +1477,10 @@ read_block_for_search(struct btrfs_trans_handle *trans,
1476 1477
1477 tmp = btrfs_find_tree_block(root, blocknr, blocksize); 1478 tmp = btrfs_find_tree_block(root, blocknr, blocksize);
1478 if (tmp && btrfs_buffer_uptodate(tmp, gen)) { 1479 if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
1480 /*
1481 * we found an up to date block without sleeping, return
1482 * right away
1483 */
1479 *eb_ret = tmp; 1484 *eb_ret = tmp;
1480 return 0; 1485 return 0;
1481 } 1486 }
@@ -1483,7 +1488,9 @@ read_block_for_search(struct btrfs_trans_handle *trans,
1483 /* 1488 /*
1484 * reduce lock contention at high levels 1489 * reduce lock contention at high levels
1485 * of the btree by dropping locks before 1490 * of the btree by dropping locks before
1486 * we read. 1491 * we read. Don't release the lock on the current
1492 * level because we need to walk this node to figure
1493 * out which blocks to read.
1487 */ 1494 */
1488 btrfs_unlock_up_safe(p, level + 1); 1495 btrfs_unlock_up_safe(p, level + 1);
1489 btrfs_set_path_blocking(p); 1496 btrfs_set_path_blocking(p);
@@ -1494,10 +1501,21 @@ read_block_for_search(struct btrfs_trans_handle *trans,
1494 reada_for_search(root, p, level, slot, key->objectid); 1501 reada_for_search(root, p, level, slot, key->objectid);
1495 1502
1496 btrfs_release_path(NULL, p); 1503 btrfs_release_path(NULL, p);
1504
1505 ret = -EAGAIN;
1497 tmp = read_tree_block(root, blocknr, blocksize, gen); 1506 tmp = read_tree_block(root, blocknr, blocksize, gen);
1498 if (tmp) 1507 if (tmp) {
1508 /*
1509 * If the read above didn't mark this buffer up to date,
1510 * it will never end up being up to date. Set ret to EIO now
1511 * and give up so that our caller doesn't loop forever
1512 * on our EAGAINs.
1513 */
1514 if (!btrfs_buffer_uptodate(tmp, 0))
1515 ret = -EIO;
1499 free_extent_buffer(tmp); 1516 free_extent_buffer(tmp);
1500 return -EAGAIN; 1517 }
1518 return ret;
1501} 1519}
1502 1520
1503/* 1521/*
@@ -1696,6 +1714,9 @@ cow_done:
1696 if (ret == -EAGAIN) 1714 if (ret == -EAGAIN)
1697 goto again; 1715 goto again;
1698 1716
1717 if (ret == -EIO)
1718 goto done;
1719
1699 if (!p->skip_locking) { 1720 if (!p->skip_locking) {
1700 int lret; 1721 int lret;
1701 1722
@@ -1738,6 +1759,8 @@ done:
1738 */ 1759 */
1739 if (!p->leave_spinning) 1760 if (!p->leave_spinning)
1740 btrfs_set_path_blocking(p); 1761 btrfs_set_path_blocking(p);
1762 if (ret < 0)
1763 btrfs_release_path(root, p);
1741 return ret; 1764 return ret;
1742} 1765}
1743 1766
@@ -4212,6 +4235,11 @@ again:
4212 if (ret == -EAGAIN) 4235 if (ret == -EAGAIN)
4213 goto again; 4236 goto again;
4214 4237
4238 if (ret < 0) {
4239 btrfs_release_path(root, path);
4240 goto done;
4241 }
4242
4215 if (!path->skip_locking) { 4243 if (!path->skip_locking) {
4216 ret = btrfs_try_spin_lock(next); 4244 ret = btrfs_try_spin_lock(next);
4217 if (!ret) { 4245 if (!ret) {
@@ -4246,6 +4274,11 @@ again:
4246 if (ret == -EAGAIN) 4274 if (ret == -EAGAIN)
4247 goto again; 4275 goto again;
4248 4276
4277 if (ret < 0) {
4278 btrfs_release_path(root, path);
4279 goto done;
4280 }
4281
4249 if (!path->skip_locking) { 4282 if (!path->skip_locking) {
4250 btrfs_assert_tree_locked(path->nodes[level]); 4283 btrfs_assert_tree_locked(path->nodes[level]);
4251 ret = btrfs_try_spin_lock(next); 4284 ret = btrfs_try_spin_lock(next);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 0ff16d3331da..4b0ea0b80c23 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -848,8 +848,6 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
848 848
849 if (ret == 0) 849 if (ret == 0)
850 set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); 850 set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags);
851 else
852 WARN_ON(1);
853 return buf; 851 return buf;
854 852
855} 853}
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e4966444811b..3e2c7c738f23 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -312,7 +312,7 @@ btrfs_lookup_first_block_group(struct btrfs_fs_info *info, u64 bytenr)
312} 312}
313 313
314/* 314/*
315 * return the block group that contains teh given bytenr 315 * return the block group that contains the given bytenr
316 */ 316 */
317struct btrfs_block_group_cache *btrfs_lookup_block_group( 317struct btrfs_block_group_cache *btrfs_lookup_block_group(
318 struct btrfs_fs_info *info, 318 struct btrfs_fs_info *info,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 90c23eb28829..1c8b0190d031 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3122,6 +3122,7 @@ static noinline void init_btrfs_i(struct inode *inode)
3122 bi->flags = 0; 3122 bi->flags = 0;
3123 bi->index_cnt = (u64)-1; 3123 bi->index_cnt = (u64)-1;
3124 bi->last_unlink_trans = 0; 3124 bi->last_unlink_trans = 0;
3125 bi->ordered_data_close = 0;
3125 extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); 3126 extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS);
3126 extent_io_tree_init(&BTRFS_I(inode)->io_tree, 3127 extent_io_tree_init(&BTRFS_I(inode)->io_tree,
3127 inode->i_mapping, GFP_NOFS); 3128 inode->i_mapping, GFP_NOFS);
@@ -4295,7 +4296,6 @@ out:
4295 } 4296 }
4296 if (err) { 4297 if (err) {
4297 free_extent_map(em); 4298 free_extent_map(em);
4298 WARN_ON(1);
4299 return ERR_PTR(err); 4299 return ERR_PTR(err);
4300 } 4300 }
4301 return em; 4301 return em;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 5e94ea6e1cbe..2624b53ea783 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -437,10 +437,6 @@ out_unlock:
437 return 0; 437 return 0;
438} 438}
439 439
440/*
441 * Called inside transaction, so use GFP_NOFS
442 */
443
444static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) 440static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
445{ 441{
446 u64 new_size; 442 u64 new_size;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3536bdb2d7cb..2ff7cd2db25f 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -436,9 +436,9 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
436 if (btrfs_test_opt(root, SSD)) 436 if (btrfs_test_opt(root, SSD))
437 seq_puts(seq, ",ssd"); 437 seq_puts(seq, ",ssd");
438 if (btrfs_test_opt(root, NOTREELOG)) 438 if (btrfs_test_opt(root, NOTREELOG))
439 seq_puts(seq, ",no-treelog"); 439 seq_puts(seq, ",notreelog");
440 if (btrfs_test_opt(root, FLUSHONCOMMIT)) 440 if (btrfs_test_opt(root, FLUSHONCOMMIT))
441 seq_puts(seq, ",flush-on-commit"); 441 seq_puts(seq, ",flushoncommit");
442 if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) 442 if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
443 seq_puts(seq, ",noacl"); 443 seq_puts(seq, ",noacl");
444 return 0; 444 return 0;
@@ -502,8 +502,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
502 502
503 if (s->s_root) { 503 if (s->s_root) {
504 if ((flags ^ s->s_flags) & MS_RDONLY) { 504 if ((flags ^ s->s_flags) & MS_RDONLY) {
505 up_write(&s->s_umount); 505 deactivate_locked_super(s);
506 deactivate_super(s);
507 error = -EBUSY; 506 error = -EBUSY;
508 goto error_close_devices; 507 goto error_close_devices;
509 } 508 }
@@ -517,8 +516,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
517 error = btrfs_fill_super(s, fs_devices, data, 516 error = btrfs_fill_super(s, fs_devices, data,
518 flags & MS_SILENT ? 1 : 0); 517 flags & MS_SILENT ? 1 : 0);
519 if (error) { 518 if (error) {
520 up_write(&s->s_umount); 519 deactivate_locked_super(s);
521 deactivate_super(s);
522 goto error_free_subvol_name; 520 goto error_free_subvol_name;
523 } 521 }
524 522
@@ -535,15 +533,13 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
535 mutex_unlock(&s->s_root->d_inode->i_mutex); 533 mutex_unlock(&s->s_root->d_inode->i_mutex);
536 534
537 if (IS_ERR(root)) { 535 if (IS_ERR(root)) {
538 up_write(&s->s_umount); 536 deactivate_locked_super(s);
539 deactivate_super(s);
540 error = PTR_ERR(root); 537 error = PTR_ERR(root);
541 goto error_free_subvol_name; 538 goto error_free_subvol_name;
542 } 539 }
543 if (!root->d_inode) { 540 if (!root->d_inode) {
544 dput(root); 541 dput(root);
545 up_write(&s->s_umount); 542 deactivate_locked_super(s);
546 deactivate_super(s);
547 error = -ENXIO; 543 error = -ENXIO;
548 goto error_free_subvol_name; 544 goto error_free_subvol_name;
549 } 545 }
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 9d1fb6ec8a5a..f20c4069c220 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,16 @@
1Version 1.58
2------------
3Guard against buffer overruns in various UCS-2 to UTF-8 string conversions
4when the UTF-8 string is composed of unusually long (more than 4 byte) converted
5characters. Add support for mounting root of a share which redirects immediately
6to DFS target. Convert string conversion functions from Unicode to more
7accurately mark string length before allocating memory (which may help the
8rare cases where a UTF-8 string is much larger than the UCS2 string that
9we converted from). Fix endianness of the vcnum field used during
10session setup to distinguish multiple mounts to same server from different
11userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental
12flag to be set to 2, and mount must enable krb5 to turn on extended security).
13
1Version 1.57 14Version 1.57
2------------ 15------------
3Improve support for multiple security contexts to the same server. We 16Improve support for multiple security contexts to the same server. We
diff --git a/fs/cifs/README b/fs/cifs/README
index 07434181623b..db208ddb9899 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -651,7 +651,15 @@ Experimental When set to 1 used to enable certain experimental
651 signing turned on in case buffer was modified 651 signing turned on in case buffer was modified
652 just before it was sent, also this flag will 652 just before it was sent, also this flag will
653 be used to use the new experimental directory change 653 be used to use the new experimental directory change
654 notification code). 654 notification code). When set to 2 enables
655 an additional experimental feature, "raw ntlmssp"
656 session establishment support (which allows
657 specifying "sec=ntlmssp" on mount). The Linux cifs
658 module will use ntlmv2 authentication encapsulated
659 in "raw ntlmssp" (not using SPNEGO) when
660 "sec=ntlmssp" is specified on mount.
661 This support also requires building cifs with
662 the CONFIG_CIFS_EXPERIMENTAL configuration flag.
655 663
656These experimental features and tracing can be enabled by changing flags in 664These experimental features and tracing can be enabled by changing flags in
657/proc/fs/cifs (after the cifs module has been installed or built into the 665/proc/fs/cifs (after the cifs module has been installed or built into the
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 5fdbf8a14472..83d62759c7c7 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -340,28 +340,24 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
340 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 340 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
341 341
342 for (i = 0; i < num_referrals; i++) { 342 for (i = 0; i < num_referrals; i++) {
343 int len;
343 dump_referral(referrals+i); 344 dump_referral(referrals+i);
344 /* connect to a storage node */ 345 /* connect to a node */
345 if (referrals[i].flags & DFSREF_STORAGE_SERVER) { 346 len = strlen(referrals[i].node_name);
346 int len; 347 if (len < 2) {
347 len = strlen(referrals[i].node_name); 348 cERROR(1, ("%s: Net Address path too short: %s",
348 if (len < 2) {
349 cERROR(1, ("%s: Net Address path too short: %s",
350 __func__, referrals[i].node_name)); 349 __func__, referrals[i].node_name));
351 rc = -EINVAL; 350 rc = -EINVAL;
352 goto out_err; 351 goto out_err;
353 } 352 }
354 mnt = cifs_dfs_do_refmount(nd->path.mnt, 353 mnt = cifs_dfs_do_refmount(nd->path.mnt,
355 nd->path.dentry, 354 nd->path.dentry, referrals + i);
356 referrals + i); 355 cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
357 cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p",
358 __func__,
359 referrals[i].node_name, mnt)); 356 referrals[i].node_name, mnt));
360 357
361 /* complete mount procedure if we accured submount */ 358 /* complete mount procedure if we accured submount */
362 if (!IS_ERR(mnt)) 359 if (!IS_ERR(mnt))
363 break; 360 break;
364 }
365 } 361 }
366 362
367 /* we need it cause for() above could exit without valid submount */ 363 /* we need it cause for() above could exit without valid submount */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 7d75272a6b3f..60e3c4253de0 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifs_unicode.c 2 * fs/cifs/cifs_unicode.c
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2000,2005 4 * Copyright (c) International Business Machines Corp., 2000,2009
5 * Modified by Steve French (sfrench@us.ibm.com) 5 * Modified by Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -26,31 +26,157 @@
26#include "cifs_debug.h" 26#include "cifs_debug.h"
27 27
28/* 28/*
29 * NAME: cifs_strfromUCS() 29 * cifs_ucs2_bytes - how long will a string be after conversion?
30 * 30 * @ucs - pointer to input string
31 * FUNCTION: Convert little-endian unicode string to character string 31 * @maxbytes - don't go past this many bytes of input string
32 * @codepage - destination codepage
32 * 33 *
34 * Walk a ucs2le string and return the number of bytes that the string will
35 * be after being converted to the given charset, not including any null
36 * termination required. Don't walk past maxbytes in the source buffer.
33 */ 37 */
34int 38int
35cifs_strfromUCS_le(char *to, const __le16 *from, 39cifs_ucs2_bytes(const __le16 *from, int maxbytes,
36 int len, const struct nls_table *codepage) 40 const struct nls_table *codepage)
37{ 41{
38 int i; 42 int i;
39 int outlen = 0; 43 int charlen, outlen = 0;
44 int maxwords = maxbytes / 2;
45 char tmp[NLS_MAX_CHARSET_SIZE];
40 46
41 for (i = 0; (i < len) && from[i]; i++) { 47 for (i = 0; from[i] && i < maxwords; i++) {
42 int charlen; 48 charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp,
43 /* 2.4.0 kernel or greater */ 49 NLS_MAX_CHARSET_SIZE);
44 charlen = 50 if (charlen > 0)
45 codepage->uni2char(le16_to_cpu(from[i]), &to[outlen],
46 NLS_MAX_CHARSET_SIZE);
47 if (charlen > 0) {
48 outlen += charlen; 51 outlen += charlen;
49 } else { 52 else
50 to[outlen++] = '?'; 53 outlen++;
54 }
55
56 return outlen;
57}
58
59/*
60 * cifs_mapchar - convert a little-endian char to proper char in codepage
61 * @target - where converted character should be copied
62 * @src_char - 2 byte little-endian source character
63 * @cp - codepage to which character should be converted
64 * @mapchar - should character be mapped according to mapchars mount option?
65 *
66 * This function handles the conversion of a single character. It is the
67 * responsibility of the caller to ensure that the target buffer is large
68 * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).
69 */
70static int
71cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
72 bool mapchar)
73{
74 int len = 1;
75
76 if (!mapchar)
77 goto cp_convert;
78
79 /*
80 * BB: Cannot handle remapping UNI_SLASH until all the calls to
81 * build_path_from_dentry are modified, as they use slash as
82 * separator.
83 */
84 switch (le16_to_cpu(src_char)) {
85 case UNI_COLON:
86 *target = ':';
87 break;
88 case UNI_ASTERIK:
89 *target = '*';
90 break;
91 case UNI_QUESTION:
92 *target = '?';
93 break;
94 case UNI_PIPE:
95 *target = '|';
96 break;
97 case UNI_GRTRTHAN:
98 *target = '>';
99 break;
100 case UNI_LESSTHAN:
101 *target = '<';
102 break;
103 default:
104 goto cp_convert;
105 }
106
107out:
108 return len;
109
110cp_convert:
111 len = cp->uni2char(le16_to_cpu(src_char), target,
112 NLS_MAX_CHARSET_SIZE);
113 if (len <= 0) {
114 *target = '?';
115 len = 1;
116 }
117 goto out;
118}
119
120/*
121 * cifs_from_ucs2 - convert utf16le string to local charset
122 * @to - destination buffer
123 * @from - source buffer
124 * @tolen - destination buffer size (in bytes)
125 * @fromlen - source buffer size (in bytes)
126 * @codepage - codepage to which characters should be converted
127 * @mapchar - should characters be remapped according to the mapchars option?
128 *
129 * Convert a little-endian ucs2le string (as sent by the server) to a string
130 * in the provided codepage. The tolen and fromlen parameters are to ensure
131 * that the code doesn't walk off of the end of the buffer (which is always
132 * a danger if the alignment of the source buffer is off). The destination
133 * string is always properly null terminated and fits in the destination
134 * buffer. Returns the length of the destination string in bytes (including
135 * null terminator).
136 *
137 * Note that some windows versions actually send multiword UTF-16 characters
138 * instead of straight UCS-2. The linux nls routines however aren't able to
139 * deal with those characters properly. In the event that we get some of
140 * those characters, they won't be translated properly.
141 */
142int
143cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
144 const struct nls_table *codepage, bool mapchar)
145{
146 int i, charlen, safelen;
147 int outlen = 0;
148 int nullsize = nls_nullsize(codepage);
149 int fromwords = fromlen / 2;
150 char tmp[NLS_MAX_CHARSET_SIZE];
151
152 /*
153 * because the chars can be of varying widths, we need to take care
154 * not to overflow the destination buffer when we get close to the
155 * end of it. Until we get to this offset, we don't need to check
156 * for overflow however.
157 */
158 safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);
159
160 for (i = 0; i < fromwords && from[i]; i++) {
161 /*
162 * check to see if converting this character might make the
163 * conversion bleed into the null terminator
164 */
165 if (outlen >= safelen) {
166 charlen = cifs_mapchar(tmp, from[i], codepage, mapchar);
167 if ((outlen + charlen) > (tolen - nullsize))
168 break;
51 } 169 }
170
171 /* put converted char into 'to' buffer */
172 charlen = cifs_mapchar(&to[outlen], from[i], codepage, mapchar);
173 outlen += charlen;
52 } 174 }
53 to[outlen] = 0; 175
176 /* properly null-terminate string */
177 for (i = 0; i < nullsize; i++)
178 to[outlen++] = 0;
179
54 return outlen; 180 return outlen;
55} 181}
56 182
@@ -88,3 +214,41 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
88 return i; 214 return i;
89} 215}
90 216
217/*
218 * cifs_strndup_from_ucs - copy a string from wire format to the local codepage
219 * @src - source string
220 * @maxlen - don't walk past this many bytes in the source string
221 * @is_unicode - is this a unicode string?
222 * @codepage - destination codepage
223 *
224 * Take a string given by the server, convert it to the local codepage and
225 * put it in a new buffer. Returns a pointer to the new string or NULL on
226 * error.
227 */
228char *
229cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
230 const struct nls_table *codepage)
231{
232 int len;
233 char *dst;
234
235 if (is_unicode) {
236 len = cifs_ucs2_bytes((__le16 *) src, maxlen, codepage);
237 len += nls_nullsize(codepage);
238 dst = kmalloc(len, GFP_KERNEL);
239 if (!dst)
240 return NULL;
241 cifs_from_ucs2(dst, (__le16 *) src, len, maxlen, codepage,
242 false);
243 } else {
244 len = strnlen(src, maxlen);
245 len++;
246 dst = kmalloc(len, GFP_KERNEL);
247 if (!dst)
248 return NULL;
249 strlcpy(dst, src, len);
250 }
251
252 return dst;
253}
254
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 14eb9a2395d3..650638275a6f 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -5,7 +5,7 @@
5 * Convert a unicode character to upper or lower case using 5 * Convert a unicode character to upper or lower case using
6 * compressed tables. 6 * compressed tables.
7 * 7 *
8 * Copyright (c) International Business Machines Corp., 2000,2007 8 * Copyright (c) International Business Machines Corp., 2000,2009
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -37,6 +37,19 @@
37 37
38#define UNIUPR_NOLOWER /* Example to not expand lower case tables */ 38#define UNIUPR_NOLOWER /* Example to not expand lower case tables */
39 39
40/*
41 * Windows maps these to the user defined 16 bit Unicode range since they are
42 * reserved symbols (along with \ and /), otherwise illegal to store
43 * in filenames in NTFS
44 */
45#define UNI_ASTERIK (__u16) ('*' + 0xF000)
46#define UNI_QUESTION (__u16) ('?' + 0xF000)
47#define UNI_COLON (__u16) (':' + 0xF000)
48#define UNI_GRTRTHAN (__u16) ('>' + 0xF000)
49#define UNI_LESSTHAN (__u16) ('<' + 0xF000)
50#define UNI_PIPE (__u16) ('|' + 0xF000)
51#define UNI_SLASH (__u16) ('\\' + 0xF000)
52
40/* Just define what we want from uniupr.h. We don't want to define the tables 53/* Just define what we want from uniupr.h. We don't want to define the tables
41 * in each source file. 54 * in each source file.
42 */ 55 */
@@ -59,8 +72,14 @@ extern struct UniCaseRange UniLowerRange[];
59#endif /* UNIUPR_NOLOWER */ 72#endif /* UNIUPR_NOLOWER */
60 73
61#ifdef __KERNEL__ 74#ifdef __KERNEL__
62int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *); 75int cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
76 const struct nls_table *codepage, bool mapchar);
77int cifs_ucs2_bytes(const __le16 *from, int maxbytes,
78 const struct nls_table *codepage);
63int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); 79int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
80char *cifs_strndup_from_ucs(const char *src, const int maxlen,
81 const bool is_unicode,
82 const struct nls_table *codepage);
64#endif 83#endif
65 84
66/* 85/*
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 0d6d8b573652..5e6d35804d73 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -35,6 +35,7 @@
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/kthread.h> 36#include <linux/kthread.h>
37#include <linux/freezer.h> 37#include <linux/freezer.h>
38#include <linux/smp_lock.h>
38#include "cifsfs.h" 39#include "cifsfs.h"
39#include "cifspdu.h" 40#include "cifspdu.h"
40#define DECLARE_GLOBALS_HERE 41#define DECLARE_GLOBALS_HERE
@@ -530,6 +531,7 @@ static void cifs_umount_begin(struct super_block *sb)
530 if (tcon == NULL) 531 if (tcon == NULL)
531 return; 532 return;
532 533
534 lock_kernel();
533 read_lock(&cifs_tcp_ses_lock); 535 read_lock(&cifs_tcp_ses_lock);
534 if (tcon->tc_count == 1) 536 if (tcon->tc_count == 1)
535 tcon->tidStatus = CifsExiting; 537 tcon->tidStatus = CifsExiting;
@@ -548,6 +550,7 @@ static void cifs_umount_begin(struct super_block *sb)
548 } 550 }
549/* BB FIXME - finish add checks for tidStatus BB */ 551/* BB FIXME - finish add checks for tidStatus BB */
550 552
553 unlock_kernel();
551 return; 554 return;
552} 555}
553 556
@@ -599,8 +602,7 @@ cifs_get_sb(struct file_system_type *fs_type,
599 602
600 rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0); 603 rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
601 if (rc) { 604 if (rc) {
602 up_write(&sb->s_umount); 605 deactivate_locked_super(sb);
603 deactivate_super(sb);
604 return rc; 606 return rc;
605 } 607 }
606 sb->s_flags |= MS_ACTIVE; 608 sb->s_flags |= MS_ACTIVE;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 77e190dc2883..051b71cfdea9 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
100extern const struct export_operations cifs_export_ops; 100extern const struct export_operations cifs_export_ops;
101#endif /* EXPERIMENTAL */ 101#endif /* EXPERIMENTAL */
102 102
103#define CIFS_VERSION "1.57" 103#define CIFS_VERSION "1.58"
104#endif /* _CIFSFS_H */ 104#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index df40ab64cd95..a61ab772c6f6 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -82,8 +82,8 @@ enum securityEnum {
82 LANMAN, /* Legacy LANMAN auth */ 82 LANMAN, /* Legacy LANMAN auth */
83 NTLM, /* Legacy NTLM012 auth with NTLM hash */ 83 NTLM, /* Legacy NTLM012 auth with NTLM hash */
84 NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ 84 NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
85 RawNTLMSSP, /* NTLMSSP without SPNEGO */ 85 RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
86 NTLMSSP, /* NTLMSSP via SPNEGO */ 86 NTLMSSP, /* NTLMSSP via SPNEGO, NTLMv2 hash */
87 Kerberos, /* Kerberos via SPNEGO */ 87 Kerberos, /* Kerberos via SPNEGO */
88 MSKerberos, /* MS Kerberos via SPNEGO */ 88 MSKerberos, /* MS Kerberos via SPNEGO */
89}; 89};
@@ -531,6 +531,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
531#define CIFSSEC_MAY_PLNTXT 0 531#define CIFSSEC_MAY_PLNTXT 0
532#endif /* weak passwords */ 532#endif /* weak passwords */
533#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ 533#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */
534#define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */
534 535
535#define CIFSSEC_MUST_SIGN 0x01001 536#define CIFSSEC_MUST_SIGN 0x01001
536/* note that only one of the following can be set so the 537/* note that only one of the following can be set so the
@@ -543,22 +544,23 @@ require use of the stronger protocol */
543#define CIFSSEC_MUST_LANMAN 0x10010 544#define CIFSSEC_MUST_LANMAN 0x10010
544#define CIFSSEC_MUST_PLNTXT 0x20020 545#define CIFSSEC_MUST_PLNTXT 0x20020
545#ifdef CONFIG_CIFS_UPCALL 546#ifdef CONFIG_CIFS_UPCALL
546#define CIFSSEC_MASK 0x3F03F /* allows weak security but also krb5 */ 547#define CIFSSEC_MASK 0xAF0AF /* allows weak security but also krb5 */
547#else 548#else
548#define CIFSSEC_MASK 0x37037 /* current flags supported if weak */ 549#define CIFSSEC_MASK 0xA70A7 /* current flags supported if weak */
549#endif /* UPCALL */ 550#endif /* UPCALL */
550#else /* do not allow weak pw hash */ 551#else /* do not allow weak pw hash */
551#ifdef CONFIG_CIFS_UPCALL 552#ifdef CONFIG_CIFS_UPCALL
552#define CIFSSEC_MASK 0x0F00F /* flags supported if no weak allowed */ 553#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */
553#else 554#else
554#define CIFSSEC_MASK 0x07007 /* flags supported if no weak allowed */ 555#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */
555#endif /* UPCALL */ 556#endif /* UPCALL */
556#endif /* WEAK_PW_HASH */ 557#endif /* WEAK_PW_HASH */
557#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ 558#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
559#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
558 560
559#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2) 561#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2)
560#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2) 562#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
561#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5) 563#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
562/* 564/*
563 ***************************************************************** 565 *****************************************************************
564 * All constants go here 566 * All constants go here
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 4167716d32f2..fae083930eee 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -260,8 +260,7 @@ extern int CIFSUnixCreateSymLink(const int xid,
260 const struct nls_table *nls_codepage); 260 const struct nls_table *nls_codepage);
261extern int CIFSSMBUnixQuerySymLink(const int xid, 261extern int CIFSSMBUnixQuerySymLink(const int xid,
262 struct cifsTconInfo *tcon, 262 struct cifsTconInfo *tcon,
263 const unsigned char *searchName, 263 const unsigned char *searchName, char **syminfo,
264 char *syminfo, const int buflen,
265 const struct nls_table *nls_codepage); 264 const struct nls_table *nls_codepage);
266extern int CIFSSMBQueryReparseLinkInfo(const int xid, 265extern int CIFSSMBQueryReparseLinkInfo(const int xid,
267 struct cifsTconInfo *tcon, 266 struct cifsTconInfo *tcon,
@@ -307,8 +306,6 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
307 const unsigned char *searchName, __u64 *inode_number, 306 const unsigned char *searchName, __u64 *inode_number,
308 const struct nls_table *nls_codepage, 307 const struct nls_table *nls_codepage,
309 int remap_special_chars); 308 int remap_special_chars);
310extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
311 const struct nls_table *codepage);
312extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen, 309extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
313 const struct nls_table *cp, int mapChars); 310 const struct nls_table *cp, int mapChars);
314 311
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a0845dc7b8a9..d06260251c30 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifssmb.c 2 * fs/cifs/cifssmb.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2008 4 * Copyright (C) International Business Machines Corp., 2002,2009
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Contains the routines for constructing the SMB PDUs themselves 7 * Contains the routines for constructing the SMB PDUs themselves
@@ -81,41 +81,6 @@ static struct {
81#endif /* CONFIG_CIFS_WEAK_PW_HASH */ 81#endif /* CONFIG_CIFS_WEAK_PW_HASH */
82#endif /* CIFS_POSIX */ 82#endif /* CIFS_POSIX */
83 83
84/* Allocates buffer into dst and copies smb string from src to it.
85 * caller is responsible for freeing dst if function returned 0.
86 * returns:
87 * on success - 0
88 * on failure - errno
89 */
90static int
91cifs_strncpy_to_host(char **dst, const char *src, const int maxlen,
92 const bool is_unicode, const struct nls_table *nls_codepage)
93{
94 int plen;
95
96 if (is_unicode) {
97 plen = UniStrnlen((wchar_t *)src, maxlen);
98 *dst = kmalloc(plen + 2, GFP_KERNEL);
99 if (!*dst)
100 goto cifs_strncpy_to_host_ErrExit;
101 cifs_strfromUCS_le(*dst, (__le16 *)src, plen, nls_codepage);
102 } else {
103 plen = strnlen(src, maxlen);
104 *dst = kmalloc(plen + 2, GFP_KERNEL);
105 if (!*dst)
106 goto cifs_strncpy_to_host_ErrExit;
107 strncpy(*dst, src, plen);
108 }
109 (*dst)[plen] = 0;
110 (*dst)[plen+1] = 0; /* harmless for ASCII case, needed for Unicode */
111 return 0;
112
113cifs_strncpy_to_host_ErrExit:
114 cERROR(1, ("Failed to allocate buffer for string\n"));
115 return -ENOMEM;
116}
117
118
119/* Mark as invalid, all open files on tree connections since they 84/* Mark as invalid, all open files on tree connections since they
120 were closed when session to server was lost */ 85 were closed when session to server was lost */
121static void mark_open_files_invalid(struct cifsTconInfo *pTcon) 86static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
@@ -484,6 +449,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
484 cFYI(1, ("Kerberos only mechanism, enable extended security")); 449 cFYI(1, ("Kerberos only mechanism, enable extended security"));
485 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 450 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
486 } 451 }
452#ifdef CONFIG_CIFS_EXPERIMENTAL
453 else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
454 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
455 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
456 cFYI(1, ("NTLMSSP only mechanism, enable extended security"));
457 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
458 }
459#endif
487 460
488 count = 0; 461 count = 0;
489 for (i = 0; i < CIFS_NUM_PROT; i++) { 462 for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -620,6 +593,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
620 server->secType = NTLMv2; 593 server->secType = NTLMv2;
621 else if (secFlags & CIFSSEC_MAY_KRB5) 594 else if (secFlags & CIFSSEC_MAY_KRB5)
622 server->secType = Kerberos; 595 server->secType = Kerberos;
596 else if (secFlags & CIFSSEC_MAY_NTLMSSP)
597 server->secType = NTLMSSP;
623 else if (secFlags & CIFSSEC_MAY_LANMAN) 598 else if (secFlags & CIFSSEC_MAY_LANMAN)
624 server->secType = LANMAN; 599 server->secType = LANMAN;
625/* #ifdef CONFIG_CIFS_EXPERIMENTAL 600/* #ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -2417,8 +2392,7 @@ winCreateHardLinkRetry:
2417 2392
2418int 2393int
2419CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, 2394CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
2420 const unsigned char *searchName, 2395 const unsigned char *searchName, char **symlinkinfo,
2421 char *symlinkinfo, const int buflen,
2422 const struct nls_table *nls_codepage) 2396 const struct nls_table *nls_codepage)
2423{ 2397{
2424/* SMB_QUERY_FILE_UNIX_LINK */ 2398/* SMB_QUERY_FILE_UNIX_LINK */
@@ -2428,6 +2402,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
2428 int bytes_returned; 2402 int bytes_returned;
2429 int name_len; 2403 int name_len;
2430 __u16 params, byte_count; 2404 __u16 params, byte_count;
2405 char *data_start;
2431 2406
2432 cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName)); 2407 cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName));
2433 2408
@@ -2482,30 +2457,26 @@ querySymLinkRetry:
2482 /* decode response */ 2457 /* decode response */
2483 2458
2484 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2459 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2485 if (rc || (pSMBr->ByteCount < 2))
2486 /* BB also check enough total bytes returned */ 2460 /* BB also check enough total bytes returned */
2487 rc = -EIO; /* bad smb */ 2461 if (rc || (pSMBr->ByteCount < 2))
2462 rc = -EIO;
2488 else { 2463 else {
2489 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2464 bool is_unicode;
2490 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2465 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2466
2467 data_start = ((char *) &pSMBr->hdr.Protocol) +
2468 le16_to_cpu(pSMBr->t2.DataOffset);
2469
2470 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2471 is_unicode = true;
2472 else
2473 is_unicode = false;
2491 2474
2492 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2493 name_len = UniStrnlen((wchar_t *) ((char *)
2494 &pSMBr->hdr.Protocol + data_offset),
2495 min_t(const int, buflen, count) / 2);
2496 /* BB FIXME investigate remapping reserved chars here */ 2475 /* BB FIXME investigate remapping reserved chars here */
2497 cifs_strfromUCS_le(symlinkinfo, 2476 *symlinkinfo = cifs_strndup_from_ucs(data_start, count,
2498 (__le16 *) ((char *)&pSMBr->hdr.Protocol 2477 is_unicode, nls_codepage);
2499 + data_offset), 2478 if (!*symlinkinfo)
2500 name_len, nls_codepage); 2479 rc = -ENOMEM;
2501 } else {
2502 strncpy(symlinkinfo,
2503 (char *) &pSMBr->hdr.Protocol +
2504 data_offset,
2505 min_t(const int, buflen, count));
2506 }
2507 symlinkinfo[buflen] = 0;
2508 /* just in case so calling code does not go off the end of buffer */
2509 } 2480 }
2510 } 2481 }
2511 cifs_buf_release(pSMB); 2482 cifs_buf_release(pSMB);
@@ -2603,7 +2574,6 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
2603 *pparmlen = parm_count; 2574 *pparmlen = parm_count;
2604 return 0; 2575 return 0;
2605} 2576}
2606#endif /* CIFS_EXPERIMENTAL */
2607 2577
2608int 2578int
2609CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2579CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
@@ -2613,7 +2583,6 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2613{ 2583{
2614 int rc = 0; 2584 int rc = 0;
2615 int bytes_returned; 2585 int bytes_returned;
2616 int name_len;
2617 struct smb_com_transaction_ioctl_req *pSMB; 2586 struct smb_com_transaction_ioctl_req *pSMB;
2618 struct smb_com_transaction_ioctl_rsp *pSMBr; 2587 struct smb_com_transaction_ioctl_rsp *pSMBr;
2619 2588
@@ -2650,59 +2619,55 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2650 } else { /* decode response */ 2619 } else { /* decode response */
2651 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset); 2620 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
2652 __u32 data_count = le32_to_cpu(pSMBr->DataCount); 2621 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
2653 if ((pSMBr->ByteCount < 2) || (data_offset > 512)) 2622 if ((pSMBr->ByteCount < 2) || (data_offset > 512)) {
2654 /* BB also check enough total bytes returned */ 2623 /* BB also check enough total bytes returned */
2655 rc = -EIO; /* bad smb */ 2624 rc = -EIO; /* bad smb */
2656 else { 2625 goto qreparse_out;
2657 if (data_count && (data_count < 2048)) { 2626 }
2658 char *end_of_smb = 2 /* sizeof byte count */ + 2627 if (data_count && (data_count < 2048)) {
2659 pSMBr->ByteCount + 2628 char *end_of_smb = 2 /* sizeof byte count */ +
2660 (char *)&pSMBr->ByteCount; 2629 pSMBr->ByteCount + (char *)&pSMBr->ByteCount;
2661 2630
2662 struct reparse_data *reparse_buf = 2631 struct reparse_data *reparse_buf =
2663 (struct reparse_data *) 2632 (struct reparse_data *)
2664 ((char *)&pSMBr->hdr.Protocol 2633 ((char *)&pSMBr->hdr.Protocol
2665 + data_offset); 2634 + data_offset);
2666 if ((char *)reparse_buf >= end_of_smb) { 2635 if ((char *)reparse_buf >= end_of_smb) {
2667 rc = -EIO; 2636 rc = -EIO;
2668 goto qreparse_out; 2637 goto qreparse_out;
2669 } 2638 }
2670 if ((reparse_buf->LinkNamesBuf + 2639 if ((reparse_buf->LinkNamesBuf +
2671 reparse_buf->TargetNameOffset + 2640 reparse_buf->TargetNameOffset +
2672 reparse_buf->TargetNameLen) > 2641 reparse_buf->TargetNameLen) > end_of_smb) {
2673 end_of_smb) { 2642 cFYI(1, ("reparse buf beyond SMB"));
2674 cFYI(1, ("reparse buf beyond SMB")); 2643 rc = -EIO;
2675 rc = -EIO; 2644 goto qreparse_out;
2676 goto qreparse_out; 2645 }
2677 }
2678 2646
2679 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 2647 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2680 name_len = UniStrnlen((wchar_t *) 2648 cifs_from_ucs2(symlinkinfo, (__le16 *)
2681 (reparse_buf->LinkNamesBuf + 2649 (reparse_buf->LinkNamesBuf +
2682 reparse_buf->TargetNameOffset), 2650 reparse_buf->TargetNameOffset),
2683 min(buflen/2, 2651 buflen,
2684 reparse_buf->TargetNameLen / 2)); 2652 reparse_buf->TargetNameLen,
2685 cifs_strfromUCS_le(symlinkinfo, 2653 nls_codepage, 0);
2686 (__le16 *) (reparse_buf->LinkNamesBuf + 2654 } else { /* ASCII names */
2687 reparse_buf->TargetNameOffset), 2655 strncpy(symlinkinfo,
2688 name_len, nls_codepage); 2656 reparse_buf->LinkNamesBuf +
2689 } else { /* ASCII names */ 2657 reparse_buf->TargetNameOffset,
2690 strncpy(symlinkinfo, 2658 min_t(const int, buflen,
2691 reparse_buf->LinkNamesBuf + 2659 reparse_buf->TargetNameLen));
2692 reparse_buf->TargetNameOffset,
2693 min_t(const int, buflen,
2694 reparse_buf->TargetNameLen));
2695 }
2696 } else {
2697 rc = -EIO;
2698 cFYI(1, ("Invalid return data count on "
2699 "get reparse info ioctl"));
2700 } 2660 }
2701 symlinkinfo[buflen] = 0; /* just in case so the caller 2661 } else {
2702 does not go off the end of the buffer */ 2662 rc = -EIO;
2703 cFYI(1, ("readlink result - %s", symlinkinfo)); 2663 cFYI(1, ("Invalid return data count on "
2664 "get reparse info ioctl"));
2704 } 2665 }
2666 symlinkinfo[buflen] = 0; /* just in case so the caller
2667 does not go off the end of the buffer */
2668 cFYI(1, ("readlink result - %s", symlinkinfo));
2705 } 2669 }
2670
2706qreparse_out: 2671qreparse_out:
2707 cifs_buf_release(pSMB); 2672 cifs_buf_release(pSMB);
2708 2673
@@ -2711,6 +2676,7 @@ qreparse_out:
2711 2676
2712 return rc; 2677 return rc;
2713} 2678}
2679#endif /* CIFS_EXPERIMENTAL */
2714 2680
2715#ifdef CONFIG_CIFS_POSIX 2681#ifdef CONFIG_CIFS_POSIX
2716 2682
@@ -3928,27 +3894,6 @@ GetInodeNumOut:
3928 return rc; 3894 return rc;
3929} 3895}
3930 3896
3931/* computes length of UCS string converted to host codepage
3932 * @src: UCS string
3933 * @maxlen: length of the input string in UCS characters
3934 * (not in bytes)
3935 *
3936 * return: size of input string in host codepage
3937 */
3938static int hostlen_fromUCS(const __le16 *src, const int maxlen,
3939 const struct nls_table *nls_codepage) {
3940 int i;
3941 int hostlen = 0;
3942 char to[4];
3943 int charlen;
3944 for (i = 0; (i < maxlen) && src[i]; ++i) {
3945 charlen = nls_codepage->uni2char(le16_to_cpu(src[i]),
3946 to, NLS_MAX_CHARSET_SIZE);
3947 hostlen += charlen > 0 ? charlen : 1;
3948 }
3949 return hostlen;
3950}
3951
3952/* parses DFS refferal V3 structure 3897/* parses DFS refferal V3 structure
3953 * caller is responsible for freeing target_nodes 3898 * caller is responsible for freeing target_nodes
3954 * returns: 3899 * returns:
@@ -3994,7 +3939,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
3994 3939
3995 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n", 3940 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n",
3996 *num_of_nodes, 3941 *num_of_nodes,
3997 le16_to_cpu(pSMBr->DFSFlags))); 3942 le32_to_cpu(pSMBr->DFSFlags)));
3998 3943
3999 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) * 3944 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4000 *num_of_nodes, GFP_KERNEL); 3945 *num_of_nodes, GFP_KERNEL);
@@ -4010,14 +3955,14 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4010 int max_len; 3955 int max_len;
4011 struct dfs_info3_param *node = (*target_nodes)+i; 3956 struct dfs_info3_param *node = (*target_nodes)+i;
4012 3957
4013 node->flags = le16_to_cpu(pSMBr->DFSFlags); 3958 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4014 if (is_unicode) { 3959 if (is_unicode) {
4015 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2, 3960 __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4016 GFP_KERNEL); 3961 GFP_KERNEL);
4017 cifsConvertToUCS((__le16 *) tmp, searchName, 3962 cifsConvertToUCS((__le16 *) tmp, searchName,
4018 PATH_MAX, nls_codepage, remap); 3963 PATH_MAX, nls_codepage, remap);
4019 node->path_consumed = hostlen_fromUCS(tmp, 3964 node->path_consumed = cifs_ucs2_bytes(tmp,
4020 le16_to_cpu(pSMBr->PathConsumed)/2, 3965 le16_to_cpu(pSMBr->PathConsumed),
4021 nls_codepage); 3966 nls_codepage);
4022 kfree(tmp); 3967 kfree(tmp);
4023 } else 3968 } else
@@ -4029,20 +3974,20 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4029 /* copy DfsPath */ 3974 /* copy DfsPath */
4030 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset); 3975 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4031 max_len = data_end - temp; 3976 max_len = data_end - temp;
4032 rc = cifs_strncpy_to_host(&(node->path_name), temp, 3977 node->path_name = cifs_strndup_from_ucs(temp, max_len,
4033 max_len, is_unicode, nls_codepage); 3978 is_unicode, nls_codepage);
4034 if (rc) 3979 if (!node->path_name) {
3980 rc = -ENOMEM;
4035 goto parse_DFS_referrals_exit; 3981 goto parse_DFS_referrals_exit;
3982 }
4036 3983
4037 /* copy link target UNC */ 3984 /* copy link target UNC */
4038 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset); 3985 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4039 max_len = data_end - temp; 3986 max_len = data_end - temp;
4040 rc = cifs_strncpy_to_host(&(node->node_name), temp, 3987 node->node_name = cifs_strndup_from_ucs(temp, max_len,
4041 max_len, is_unicode, nls_codepage); 3988 is_unicode, nls_codepage);
4042 if (rc) 3989 if (!node->node_name)
4043 goto parse_DFS_referrals_exit; 3990 rc = -ENOMEM;
4044
4045 ref += le16_to_cpu(ref->Size);
4046 } 3991 }
4047 3992
4048parse_DFS_referrals_exit: 3993parse_DFS_referrals_exit:
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index bacdef1546b7..4aa81a507b74 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2008 4 * Copyright (C) International Business Machines Corp., 2002,2009
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -32,6 +32,7 @@
32#include <linux/kthread.h> 32#include <linux/kthread.h>
33#include <linux/pagevec.h> 33#include <linux/pagevec.h>
34#include <linux/freezer.h> 34#include <linux/freezer.h>
35#include <linux/namei.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36#include <asm/processor.h> 37#include <asm/processor.h>
37#include <net/ipv6.h> 38#include <net/ipv6.h>
@@ -978,6 +979,13 @@ cifs_parse_mount_options(char *options, const char *devname,
978 return 1; 979 return 1;
979 } else if (strnicmp(value, "krb5", 4) == 0) { 980 } else if (strnicmp(value, "krb5", 4) == 0) {
980 vol->secFlg |= CIFSSEC_MAY_KRB5; 981 vol->secFlg |= CIFSSEC_MAY_KRB5;
982#ifdef CONFIG_CIFS_EXPERIMENTAL
983 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
984 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
985 CIFSSEC_MUST_SIGN;
986 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
987 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
988#endif
981 } else if (strnicmp(value, "ntlmv2i", 7) == 0) { 989 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
982 vol->secFlg |= CIFSSEC_MAY_NTLMV2 | 990 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
983 CIFSSEC_MUST_SIGN; 991 CIFSSEC_MUST_SIGN;
@@ -2278,6 +2286,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2278#ifdef CONFIG_CIFS_DFS_UPCALL 2286#ifdef CONFIG_CIFS_DFS_UPCALL
2279 struct dfs_info3_param *referrals = NULL; 2287 struct dfs_info3_param *referrals = NULL;
2280 unsigned int num_referrals = 0; 2288 unsigned int num_referrals = 0;
2289 int referral_walks_count = 0;
2281try_mount_again: 2290try_mount_again:
2282#endif 2291#endif
2283 full_path = NULL; 2292 full_path = NULL;
@@ -2525,6 +2534,16 @@ remote_path_check:
2525 /* get referral if needed */ 2534 /* get referral if needed */
2526 if (rc == -EREMOTE) { 2535 if (rc == -EREMOTE) {
2527#ifdef CONFIG_CIFS_DFS_UPCALL 2536#ifdef CONFIG_CIFS_DFS_UPCALL
2537 if (referral_walks_count > MAX_NESTED_LINKS) {
2538 /*
2539 * BB: when we implement proper loop detection,
2540 * we will remove this check. But now we need it
2541 * to prevent an indefinite loop if 'DFS tree' is
2542 * misconfigured (i.e. has loops).
2543 */
2544 rc = -ELOOP;
2545 goto mount_fail_check;
2546 }
2528 /* convert forward to back slashes in prepath here if needed */ 2547 /* convert forward to back slashes in prepath here if needed */
2529 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) 2548 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2530 convert_delimiter(cifs_sb->prepath, 2549 convert_delimiter(cifs_sb->prepath,
@@ -2558,6 +2577,7 @@ remote_path_check:
2558 cleanup_volume_info(&volume_info); 2577 cleanup_volume_info(&volume_info);
2559 FreeXid(xid); 2578 FreeXid(xid);
2560 kfree(full_path); 2579 kfree(full_path);
2580 referral_walks_count++;
2561 goto try_mount_again; 2581 goto try_mount_again;
2562 } 2582 }
2563#else /* No DFS support, return error on mount */ 2583#else /* No DFS support, return error on mount */
@@ -2592,1041 +2612,6 @@ out:
2592 return rc; 2612 return rc;
2593} 2613}
2594 2614
2595static int
2596CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2597 char session_key[CIFS_SESS_KEY_SIZE],
2598 const struct nls_table *nls_codepage)
2599{
2600 struct smb_hdr *smb_buffer;
2601 struct smb_hdr *smb_buffer_response;
2602 SESSION_SETUP_ANDX *pSMB;
2603 SESSION_SETUP_ANDX *pSMBr;
2604 char *bcc_ptr;
2605 char *user;
2606 char *domain;
2607 int rc = 0;
2608 int remaining_words = 0;
2609 int bytes_returned = 0;
2610 int len;
2611 __u32 capabilities;
2612 __u16 count;
2613
2614 cFYI(1, ("In sesssetup"));
2615 if (ses == NULL)
2616 return -EINVAL;
2617 user = ses->userName;
2618 domain = ses->domainName;
2619 smb_buffer = cifs_buf_get();
2620
2621 if (smb_buffer == NULL)
2622 return -ENOMEM;
2623
2624 smb_buffer_response = smb_buffer;
2625 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2626
2627 /* send SMBsessionSetup here */
2628 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2629 NULL /* no tCon exists yet */ , 13 /* wct */ );
2630
2631 smb_buffer->Mid = GetNextMid(ses->server);
2632 pSMB->req_no_secext.AndXCommand = 0xFF;
2633 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2634 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2635
2636 if (ses->server->secMode &
2637 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2638 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2639
2640 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2641 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2642 if (ses->capabilities & CAP_UNICODE) {
2643 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2644 capabilities |= CAP_UNICODE;
2645 }
2646 if (ses->capabilities & CAP_STATUS32) {
2647 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2648 capabilities |= CAP_STATUS32;
2649 }
2650 if (ses->capabilities & CAP_DFS) {
2651 smb_buffer->Flags2 |= SMBFLG2_DFS;
2652 capabilities |= CAP_DFS;
2653 }
2654 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2655
2656 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2657 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2658
2659 pSMB->req_no_secext.CaseSensitivePasswordLength =
2660 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2661 bcc_ptr = pByteArea(smb_buffer);
2662 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2663 bcc_ptr += CIFS_SESS_KEY_SIZE;
2664 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2665 bcc_ptr += CIFS_SESS_KEY_SIZE;
2666
2667 if (ses->capabilities & CAP_UNICODE) {
2668 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2669 *bcc_ptr = 0;
2670 bcc_ptr++;
2671 }
2672 if (user == NULL)
2673 bytes_returned = 0; /* skip null user */
2674 else
2675 bytes_returned =
2676 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2677 nls_codepage);
2678 /* convert number of 16 bit words to bytes */
2679 bcc_ptr += 2 * bytes_returned;
2680 bcc_ptr += 2; /* trailing null */
2681 if (domain == NULL)
2682 bytes_returned =
2683 cifs_strtoUCS((__le16 *) bcc_ptr,
2684 "CIFS_LINUX_DOM", 32, nls_codepage);
2685 else
2686 bytes_returned =
2687 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2688 nls_codepage);
2689 bcc_ptr += 2 * bytes_returned;
2690 bcc_ptr += 2;
2691 bytes_returned =
2692 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2693 32, nls_codepage);
2694 bcc_ptr += 2 * bytes_returned;
2695 bytes_returned =
2696 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2697 32, nls_codepage);
2698 bcc_ptr += 2 * bytes_returned;
2699 bcc_ptr += 2;
2700 bytes_returned =
2701 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2702 64, nls_codepage);
2703 bcc_ptr += 2 * bytes_returned;
2704 bcc_ptr += 2;
2705 } else {
2706 if (user != NULL) {
2707 strncpy(bcc_ptr, user, 200);
2708 bcc_ptr += strnlen(user, 200);
2709 }
2710 *bcc_ptr = 0;
2711 bcc_ptr++;
2712 if (domain == NULL) {
2713 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2714 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2715 } else {
2716 strncpy(bcc_ptr, domain, 64);
2717 bcc_ptr += strnlen(domain, 64);
2718 *bcc_ptr = 0;
2719 bcc_ptr++;
2720 }
2721 strcpy(bcc_ptr, "Linux version ");
2722 bcc_ptr += strlen("Linux version ");
2723 strcpy(bcc_ptr, utsname()->release);
2724 bcc_ptr += strlen(utsname()->release) + 1;
2725 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2726 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2727 }
2728 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2729 smb_buffer->smb_buf_length += count;
2730 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2731
2732 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2733 &bytes_returned, CIFS_LONG_OP);
2734 if (rc) {
2735/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2736 } else if ((smb_buffer_response->WordCount == 3)
2737 || (smb_buffer_response->WordCount == 4)) {
2738 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2739 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2740 if (action & GUEST_LOGIN)
2741 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
2742 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2743 (little endian) */
2744 cFYI(1, ("UID = %d ", ses->Suid));
2745 /* response can have either 3 or 4 word count - Samba sends 3 */
2746 bcc_ptr = pByteArea(smb_buffer_response);
2747 if ((pSMBr->resp.hdr.WordCount == 3)
2748 || ((pSMBr->resp.hdr.WordCount == 4)
2749 && (blob_len < pSMBr->resp.ByteCount))) {
2750 if (pSMBr->resp.hdr.WordCount == 4)
2751 bcc_ptr += blob_len;
2752
2753 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2754 if ((long) (bcc_ptr) % 2) {
2755 remaining_words =
2756 (BCC(smb_buffer_response) - 1) / 2;
2757 /* Unicode strings must be word
2758 aligned */
2759 bcc_ptr++;
2760 } else {
2761 remaining_words =
2762 BCC(smb_buffer_response) / 2;
2763 }
2764 len =
2765 UniStrnlen((wchar_t *) bcc_ptr,
2766 remaining_words - 1);
2767/* We look for obvious messed up bcc or strings in response so we do not go off
2768 the end since (at least) WIN2K and Windows XP have a major bug in not null
2769 terminating last Unicode string in response */
2770 kfree(ses->serverOS);
2771 ses->serverOS = kzalloc(2 * (len + 1),
2772 GFP_KERNEL);
2773 if (ses->serverOS == NULL)
2774 goto sesssetup_nomem;
2775 cifs_strfromUCS_le(ses->serverOS,
2776 (__le16 *)bcc_ptr,
2777 len, nls_codepage);
2778 bcc_ptr += 2 * (len + 1);
2779 remaining_words -= len + 1;
2780 ses->serverOS[2 * len] = 0;
2781 ses->serverOS[1 + (2 * len)] = 0;
2782 if (remaining_words > 0) {
2783 len = UniStrnlen((wchar_t *)bcc_ptr,
2784 remaining_words-1);
2785 kfree(ses->serverNOS);
2786 ses->serverNOS = kzalloc(2 * (len + 1),
2787 GFP_KERNEL);
2788 if (ses->serverNOS == NULL)
2789 goto sesssetup_nomem;
2790 cifs_strfromUCS_le(ses->serverNOS,
2791 (__le16 *)bcc_ptr,
2792 len, nls_codepage);
2793 bcc_ptr += 2 * (len + 1);
2794 ses->serverNOS[2 * len] = 0;
2795 ses->serverNOS[1 + (2 * len)] = 0;
2796 if (strncmp(ses->serverNOS,
2797 "NT LAN Manager 4", 16) == 0) {
2798 cFYI(1, ("NT4 server"));
2799 ses->flags |= CIFS_SES_NT4;
2800 }
2801 remaining_words -= len + 1;
2802 if (remaining_words > 0) {
2803 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2804 /* last string is not always null terminated
2805 (for e.g. for Windows XP & 2000) */
2806 kfree(ses->serverDomain);
2807 ses->serverDomain =
2808 kzalloc(2*(len+1),
2809 GFP_KERNEL);
2810 if (ses->serverDomain == NULL)
2811 goto sesssetup_nomem;
2812 cifs_strfromUCS_le(ses->serverDomain,
2813 (__le16 *)bcc_ptr,
2814 len, nls_codepage);
2815 bcc_ptr += 2 * (len + 1);
2816 ses->serverDomain[2*len] = 0;
2817 ses->serverDomain[1+(2*len)] = 0;
2818 } else { /* else no more room so create
2819 dummy domain string */
2820 kfree(ses->serverDomain);
2821 ses->serverDomain =
2822 kzalloc(2, GFP_KERNEL);
2823 }
2824 } else { /* no room so create dummy domain
2825 and NOS string */
2826
2827 /* if these kcallocs fail not much we
2828 can do, but better to not fail the
2829 sesssetup itself */
2830 kfree(ses->serverDomain);
2831 ses->serverDomain =
2832 kzalloc(2, GFP_KERNEL);
2833 kfree(ses->serverNOS);
2834 ses->serverNOS =
2835 kzalloc(2, GFP_KERNEL);
2836 }
2837 } else { /* ASCII */
2838 len = strnlen(bcc_ptr, 1024);
2839 if (((long) bcc_ptr + len) - (long)
2840 pByteArea(smb_buffer_response)
2841 <= BCC(smb_buffer_response)) {
2842 kfree(ses->serverOS);
2843 ses->serverOS = kzalloc(len + 1,
2844 GFP_KERNEL);
2845 if (ses->serverOS == NULL)
2846 goto sesssetup_nomem;
2847 strncpy(ses->serverOS, bcc_ptr, len);
2848
2849 bcc_ptr += len;
2850 /* null terminate the string */
2851 bcc_ptr[0] = 0;
2852 bcc_ptr++;
2853
2854 len = strnlen(bcc_ptr, 1024);
2855 kfree(ses->serverNOS);
2856 ses->serverNOS = kzalloc(len + 1,
2857 GFP_KERNEL);
2858 if (ses->serverNOS == NULL)
2859 goto sesssetup_nomem;
2860 strncpy(ses->serverNOS, bcc_ptr, len);
2861 bcc_ptr += len;
2862 bcc_ptr[0] = 0;
2863 bcc_ptr++;
2864
2865 len = strnlen(bcc_ptr, 1024);
2866 kfree(ses->serverDomain);
2867 ses->serverDomain = kzalloc(len + 1,
2868 GFP_KERNEL);
2869 if (ses->serverDomain == NULL)
2870 goto sesssetup_nomem;
2871 strncpy(ses->serverDomain, bcc_ptr,
2872 len);
2873 bcc_ptr += len;
2874 bcc_ptr[0] = 0;
2875 bcc_ptr++;
2876 } else
2877 cFYI(1,
2878 ("Variable field of length %d "
2879 "extends beyond end of smb ",
2880 len));
2881 }
2882 } else {
2883 cERROR(1, ("Security Blob Length extends beyond "
2884 "end of SMB"));
2885 }
2886 } else {
2887 cERROR(1, ("Invalid Word count %d: ",
2888 smb_buffer_response->WordCount));
2889 rc = -EIO;
2890 }
2891sesssetup_nomem: /* do not return an error on nomem for the info strings,
2892 since that could make reconnection harder, and
2893 reconnection might be needed to free memory */
2894 cifs_buf_release(smb_buffer);
2895
2896 return rc;
2897}
2898
2899static int
2900CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2901 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2902 const struct nls_table *nls_codepage)
2903{
2904 struct smb_hdr *smb_buffer;
2905 struct smb_hdr *smb_buffer_response;
2906 SESSION_SETUP_ANDX *pSMB;
2907 SESSION_SETUP_ANDX *pSMBr;
2908 char *bcc_ptr;
2909 char *domain;
2910 int rc = 0;
2911 int remaining_words = 0;
2912 int bytes_returned = 0;
2913 int len;
2914 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2915 PNEGOTIATE_MESSAGE SecurityBlob;
2916 PCHALLENGE_MESSAGE SecurityBlob2;
2917 __u32 negotiate_flags, capabilities;
2918 __u16 count;
2919
2920 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2921 if (ses == NULL)
2922 return -EINVAL;
2923 domain = ses->domainName;
2924 *pNTLMv2_flag = false;
2925 smb_buffer = cifs_buf_get();
2926 if (smb_buffer == NULL) {
2927 return -ENOMEM;
2928 }
2929 smb_buffer_response = smb_buffer;
2930 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2931 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2932
2933 /* send SMBsessionSetup here */
2934 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2935 NULL /* no tCon exists yet */ , 12 /* wct */ );
2936
2937 smb_buffer->Mid = GetNextMid(ses->server);
2938 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2939 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2940
2941 pSMB->req.AndXCommand = 0xFF;
2942 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2943 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2944
2945 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2946 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2947
2948 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2949 CAP_EXTENDED_SECURITY;
2950 if (ses->capabilities & CAP_UNICODE) {
2951 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2952 capabilities |= CAP_UNICODE;
2953 }
2954 if (ses->capabilities & CAP_STATUS32) {
2955 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2956 capabilities |= CAP_STATUS32;
2957 }
2958 if (ses->capabilities & CAP_DFS) {
2959 smb_buffer->Flags2 |= SMBFLG2_DFS;
2960 capabilities |= CAP_DFS;
2961 }
2962 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2963
2964 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2965 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2966 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2967 SecurityBlob->MessageType = NtLmNegotiate;
2968 negotiate_flags =
2969 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2970 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2971 NTLMSSP_NEGOTIATE_56 |
2972 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2973 if (sign_CIFS_PDUs)
2974 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2975/* if (ntlmv2_support)
2976 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2977 /* setup pointers to domain name and workstation name */
2978 bcc_ptr += SecurityBlobLength;
2979
2980 SecurityBlob->WorkstationName.Buffer = 0;
2981 SecurityBlob->WorkstationName.Length = 0;
2982 SecurityBlob->WorkstationName.MaximumLength = 0;
2983
2984 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2985 along with username on auth request (ie the response to challenge) */
2986 SecurityBlob->DomainName.Buffer = 0;
2987 SecurityBlob->DomainName.Length = 0;
2988 SecurityBlob->DomainName.MaximumLength = 0;
2989 if (ses->capabilities & CAP_UNICODE) {
2990 if ((long) bcc_ptr % 2) {
2991 *bcc_ptr = 0;
2992 bcc_ptr++;
2993 }
2994
2995 bytes_returned =
2996 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2997 32, nls_codepage);
2998 bcc_ptr += 2 * bytes_returned;
2999 bytes_returned =
3000 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3001 nls_codepage);
3002 bcc_ptr += 2 * bytes_returned;
3003 bcc_ptr += 2; /* null terminate Linux version */
3004 bytes_returned =
3005 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3006 64, nls_codepage);
3007 bcc_ptr += 2 * bytes_returned;
3008 *(bcc_ptr + 1) = 0;
3009 *(bcc_ptr + 2) = 0;
3010 bcc_ptr += 2; /* null terminate network opsys string */
3011 *(bcc_ptr + 1) = 0;
3012 *(bcc_ptr + 2) = 0;
3013 bcc_ptr += 2; /* null domain */
3014 } else { /* ASCII */
3015 strcpy(bcc_ptr, "Linux version ");
3016 bcc_ptr += strlen("Linux version ");
3017 strcpy(bcc_ptr, utsname()->release);
3018 bcc_ptr += strlen(utsname()->release) + 1;
3019 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3020 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3021 bcc_ptr++; /* empty domain field */
3022 *bcc_ptr = 0;
3023 }
3024 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3025 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3026 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3027 smb_buffer->smb_buf_length += count;
3028 pSMB->req.ByteCount = cpu_to_le16(count);
3029
3030 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3031 &bytes_returned, CIFS_LONG_OP);
3032
3033 if (smb_buffer_response->Status.CifsError ==
3034 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
3035 rc = 0;
3036
3037 if (rc) {
3038/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3039 } else if ((smb_buffer_response->WordCount == 3)
3040 || (smb_buffer_response->WordCount == 4)) {
3041 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3042 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3043
3044 if (action & GUEST_LOGIN)
3045 cFYI(1, ("Guest login"));
3046 /* Do we want to set anything in SesInfo struct when guest login? */
3047
3048 bcc_ptr = pByteArea(smb_buffer_response);
3049 /* response can have either 3 or 4 word count - Samba sends 3 */
3050
3051 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
3052 if (SecurityBlob2->MessageType != NtLmChallenge) {
3053 cFYI(1, ("Unexpected NTLMSSP message type received %d",
3054 SecurityBlob2->MessageType));
3055 } else if (ses) {
3056 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
3057 cFYI(1, ("UID = %d", ses->Suid));
3058 if ((pSMBr->resp.hdr.WordCount == 3)
3059 || ((pSMBr->resp.hdr.WordCount == 4)
3060 && (blob_len <
3061 pSMBr->resp.ByteCount))) {
3062
3063 if (pSMBr->resp.hdr.WordCount == 4) {
3064 bcc_ptr += blob_len;
3065 cFYI(1, ("Security Blob Length %d",
3066 blob_len));
3067 }
3068
3069 cFYI(1, ("NTLMSSP Challenge rcvd"));
3070
3071 memcpy(ses->server->cryptKey,
3072 SecurityBlob2->Challenge,
3073 CIFS_CRYPTO_KEY_SIZE);
3074 if (SecurityBlob2->NegotiateFlags &
3075 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
3076 *pNTLMv2_flag = true;
3077
3078 if ((SecurityBlob2->NegotiateFlags &
3079 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
3080 || (sign_CIFS_PDUs > 1))
3081 ses->server->secMode |=
3082 SECMODE_SIGN_REQUIRED;
3083 if ((SecurityBlob2->NegotiateFlags &
3084 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
3085 ses->server->secMode |=
3086 SECMODE_SIGN_ENABLED;
3087
3088 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3089 if ((long) (bcc_ptr) % 2) {
3090 remaining_words =
3091 (BCC(smb_buffer_response)
3092 - 1) / 2;
3093 /* Must word align unicode strings */
3094 bcc_ptr++;
3095 } else {
3096 remaining_words =
3097 BCC
3098 (smb_buffer_response) / 2;
3099 }
3100 len =
3101 UniStrnlen((wchar_t *) bcc_ptr,
3102 remaining_words - 1);
3103/* We look for obvious messed up bcc or strings in response so we do not go off
3104 the end since (at least) WIN2K and Windows XP have a major bug in not null
3105 terminating last Unicode string in response */
3106 kfree(ses->serverOS);
3107 ses->serverOS =
3108 kzalloc(2 * (len + 1), GFP_KERNEL);
3109 cifs_strfromUCS_le(ses->serverOS,
3110 (__le16 *)
3111 bcc_ptr, len,
3112 nls_codepage);
3113 bcc_ptr += 2 * (len + 1);
3114 remaining_words -= len + 1;
3115 ses->serverOS[2 * len] = 0;
3116 ses->serverOS[1 + (2 * len)] = 0;
3117 if (remaining_words > 0) {
3118 len = UniStrnlen((wchar_t *)
3119 bcc_ptr,
3120 remaining_words
3121 - 1);
3122 kfree(ses->serverNOS);
3123 ses->serverNOS =
3124 kzalloc(2 * (len + 1),
3125 GFP_KERNEL);
3126 cifs_strfromUCS_le(ses->
3127 serverNOS,
3128 (__le16 *)
3129 bcc_ptr,
3130 len,
3131 nls_codepage);
3132 bcc_ptr += 2 * (len + 1);
3133 ses->serverNOS[2 * len] = 0;
3134 ses->serverNOS[1 +
3135 (2 * len)] = 0;
3136 remaining_words -= len + 1;
3137 if (remaining_words > 0) {
3138 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3139 /* last string not always null terminated
3140 (for e.g. for Windows XP & 2000) */
3141 kfree(ses->serverDomain);
3142 ses->serverDomain =
3143 kzalloc(2 *
3144 (len +
3145 1),
3146 GFP_KERNEL);
3147 cifs_strfromUCS_le
3148 (ses->serverDomain,
3149 (__le16 *)bcc_ptr,
3150 len, nls_codepage);
3151 bcc_ptr +=
3152 2 * (len + 1);
3153 ses->serverDomain[2*len]
3154 = 0;
3155 ses->serverDomain
3156 [1 + (2 * len)]
3157 = 0;
3158 } /* else no more room so create dummy domain string */
3159 else {
3160 kfree(ses->serverDomain);
3161 ses->serverDomain =
3162 kzalloc(2,
3163 GFP_KERNEL);
3164 }
3165 } else { /* no room so create dummy domain and NOS string */
3166 kfree(ses->serverDomain);
3167 ses->serverDomain =
3168 kzalloc(2, GFP_KERNEL);
3169 kfree(ses->serverNOS);
3170 ses->serverNOS =
3171 kzalloc(2, GFP_KERNEL);
3172 }
3173 } else { /* ASCII */
3174 len = strnlen(bcc_ptr, 1024);
3175 if (((long) bcc_ptr + len) - (long)
3176 pByteArea(smb_buffer_response)
3177 <= BCC(smb_buffer_response)) {
3178 kfree(ses->serverOS);
3179 ses->serverOS =
3180 kzalloc(len + 1,
3181 GFP_KERNEL);
3182 strncpy(ses->serverOS,
3183 bcc_ptr, len);
3184
3185 bcc_ptr += len;
3186 bcc_ptr[0] = 0; /* null terminate string */
3187 bcc_ptr++;
3188
3189 len = strnlen(bcc_ptr, 1024);
3190 kfree(ses->serverNOS);
3191 ses->serverNOS =
3192 kzalloc(len + 1,
3193 GFP_KERNEL);
3194 strncpy(ses->serverNOS, bcc_ptr, len);
3195 bcc_ptr += len;
3196 bcc_ptr[0] = 0;
3197 bcc_ptr++;
3198
3199 len = strnlen(bcc_ptr, 1024);
3200 kfree(ses->serverDomain);
3201 ses->serverDomain =
3202 kzalloc(len + 1,
3203 GFP_KERNEL);
3204 strncpy(ses->serverDomain,
3205 bcc_ptr, len);
3206 bcc_ptr += len;
3207 bcc_ptr[0] = 0;
3208 bcc_ptr++;
3209 } else
3210 cFYI(1,
3211 ("field of length %d "
3212 "extends beyond end of smb",
3213 len));
3214 }
3215 } else {
3216 cERROR(1, ("Security Blob Length extends beyond"
3217 " end of SMB"));
3218 }
3219 } else {
3220 cERROR(1, ("No session structure passed in."));
3221 }
3222 } else {
3223 cERROR(1, ("Invalid Word count %d:",
3224 smb_buffer_response->WordCount));
3225 rc = -EIO;
3226 }
3227
3228 cifs_buf_release(smb_buffer);
3229
3230 return rc;
3231}
3232static int
3233CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3234 char *ntlm_session_key, bool ntlmv2_flag,
3235 const struct nls_table *nls_codepage)
3236{
3237 struct smb_hdr *smb_buffer;
3238 struct smb_hdr *smb_buffer_response;
3239 SESSION_SETUP_ANDX *pSMB;
3240 SESSION_SETUP_ANDX *pSMBr;
3241 char *bcc_ptr;
3242 char *user;
3243 char *domain;
3244 int rc = 0;
3245 int remaining_words = 0;
3246 int bytes_returned = 0;
3247 int len;
3248 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
3249 PAUTHENTICATE_MESSAGE SecurityBlob;
3250 __u32 negotiate_flags, capabilities;
3251 __u16 count;
3252
3253 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
3254 if (ses == NULL)
3255 return -EINVAL;
3256 user = ses->userName;
3257 domain = ses->domainName;
3258 smb_buffer = cifs_buf_get();
3259 if (smb_buffer == NULL) {
3260 return -ENOMEM;
3261 }
3262 smb_buffer_response = smb_buffer;
3263 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
3264 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
3265
3266 /* send SMBsessionSetup here */
3267 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3268 NULL /* no tCon exists yet */ , 12 /* wct */ );
3269
3270 smb_buffer->Mid = GetNextMid(ses->server);
3271 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3272 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3273 pSMB->req.AndXCommand = 0xFF;
3274 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3275 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3276
3277 pSMB->req.hdr.Uid = ses->Suid;
3278
3279 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3280 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3281
3282 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
3283 CAP_EXTENDED_SECURITY;
3284 if (ses->capabilities & CAP_UNICODE) {
3285 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3286 capabilities |= CAP_UNICODE;
3287 }
3288 if (ses->capabilities & CAP_STATUS32) {
3289 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3290 capabilities |= CAP_STATUS32;
3291 }
3292 if (ses->capabilities & CAP_DFS) {
3293 smb_buffer->Flags2 |= SMBFLG2_DFS;
3294 capabilities |= CAP_DFS;
3295 }
3296 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3297
3298 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3299 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3300 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3301 SecurityBlob->MessageType = NtLmAuthenticate;
3302 bcc_ptr += SecurityBlobLength;
3303 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3304 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3305 0x80000000 | NTLMSSP_NEGOTIATE_128;
3306 if (sign_CIFS_PDUs)
3307 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3308 if (ntlmv2_flag)
3309 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3310
3311/* setup pointers to domain name and workstation name */
3312
3313 SecurityBlob->WorkstationName.Buffer = 0;
3314 SecurityBlob->WorkstationName.Length = 0;
3315 SecurityBlob->WorkstationName.MaximumLength = 0;
3316 SecurityBlob->SessionKey.Length = 0;
3317 SecurityBlob->SessionKey.MaximumLength = 0;
3318 SecurityBlob->SessionKey.Buffer = 0;
3319
3320 SecurityBlob->LmChallengeResponse.Length = 0;
3321 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3322 SecurityBlob->LmChallengeResponse.Buffer = 0;
3323
3324 SecurityBlob->NtChallengeResponse.Length =
3325 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3326 SecurityBlob->NtChallengeResponse.MaximumLength =
3327 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3328 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3329 SecurityBlob->NtChallengeResponse.Buffer =
3330 cpu_to_le32(SecurityBlobLength);
3331 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3332 bcc_ptr += CIFS_SESS_KEY_SIZE;
3333
3334 if (ses->capabilities & CAP_UNICODE) {
3335 if (domain == NULL) {
3336 SecurityBlob->DomainName.Buffer = 0;
3337 SecurityBlob->DomainName.Length = 0;
3338 SecurityBlob->DomainName.MaximumLength = 0;
3339 } else {
3340 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3341 nls_codepage);
3342 ln *= 2;
3343 SecurityBlob->DomainName.MaximumLength =
3344 cpu_to_le16(ln);
3345 SecurityBlob->DomainName.Buffer =
3346 cpu_to_le32(SecurityBlobLength);
3347 bcc_ptr += ln;
3348 SecurityBlobLength += ln;
3349 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3350 }
3351 if (user == NULL) {
3352 SecurityBlob->UserName.Buffer = 0;
3353 SecurityBlob->UserName.Length = 0;
3354 SecurityBlob->UserName.MaximumLength = 0;
3355 } else {
3356 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3357 nls_codepage);
3358 ln *= 2;
3359 SecurityBlob->UserName.MaximumLength =
3360 cpu_to_le16(ln);
3361 SecurityBlob->UserName.Buffer =
3362 cpu_to_le32(SecurityBlobLength);
3363 bcc_ptr += ln;
3364 SecurityBlobLength += ln;
3365 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3366 }
3367
3368 /* SecurityBlob->WorkstationName.Length =
3369 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3370 SecurityBlob->WorkstationName.Length *= 2;
3371 SecurityBlob->WorkstationName.MaximumLength =
3372 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3373 SecurityBlob->WorkstationName.Buffer =
3374 cpu_to_le32(SecurityBlobLength);
3375 bcc_ptr += SecurityBlob->WorkstationName.Length;
3376 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3377 SecurityBlob->WorkstationName.Length =
3378 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3379
3380 if ((long) bcc_ptr % 2) {
3381 *bcc_ptr = 0;
3382 bcc_ptr++;
3383 }
3384 bytes_returned =
3385 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3386 32, nls_codepage);
3387 bcc_ptr += 2 * bytes_returned;
3388 bytes_returned =
3389 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3390 nls_codepage);
3391 bcc_ptr += 2 * bytes_returned;
3392 bcc_ptr += 2; /* null term version string */
3393 bytes_returned =
3394 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3395 64, nls_codepage);
3396 bcc_ptr += 2 * bytes_returned;
3397 *(bcc_ptr + 1) = 0;
3398 *(bcc_ptr + 2) = 0;
3399 bcc_ptr += 2; /* null terminate network opsys string */
3400 *(bcc_ptr + 1) = 0;
3401 *(bcc_ptr + 2) = 0;
3402 bcc_ptr += 2; /* null domain */
3403 } else { /* ASCII */
3404 if (domain == NULL) {
3405 SecurityBlob->DomainName.Buffer = 0;
3406 SecurityBlob->DomainName.Length = 0;
3407 SecurityBlob->DomainName.MaximumLength = 0;
3408 } else {
3409 __u16 ln;
3410 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3411 strncpy(bcc_ptr, domain, 63);
3412 ln = strnlen(domain, 64);
3413 SecurityBlob->DomainName.MaximumLength =
3414 cpu_to_le16(ln);
3415 SecurityBlob->DomainName.Buffer =
3416 cpu_to_le32(SecurityBlobLength);
3417 bcc_ptr += ln;
3418 SecurityBlobLength += ln;
3419 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3420 }
3421 if (user == NULL) {
3422 SecurityBlob->UserName.Buffer = 0;
3423 SecurityBlob->UserName.Length = 0;
3424 SecurityBlob->UserName.MaximumLength = 0;
3425 } else {
3426 __u16 ln;
3427 strncpy(bcc_ptr, user, 63);
3428 ln = strnlen(user, 64);
3429 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3430 SecurityBlob->UserName.Buffer =
3431 cpu_to_le32(SecurityBlobLength);
3432 bcc_ptr += ln;
3433 SecurityBlobLength += ln;
3434 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3435 }
3436 /* BB fill in our workstation name if known BB */
3437
3438 strcpy(bcc_ptr, "Linux version ");
3439 bcc_ptr += strlen("Linux version ");
3440 strcpy(bcc_ptr, utsname()->release);
3441 bcc_ptr += strlen(utsname()->release) + 1;
3442 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3443 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3444 bcc_ptr++; /* null domain */
3445 *bcc_ptr = 0;
3446 }
3447 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3448 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3449 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3450 smb_buffer->smb_buf_length += count;
3451 pSMB->req.ByteCount = cpu_to_le16(count);
3452
3453 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3454 &bytes_returned, CIFS_LONG_OP);
3455 if (rc) {
3456/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3457 } else if ((smb_buffer_response->WordCount == 3) ||
3458 (smb_buffer_response->WordCount == 4)) {
3459 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3460 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3461 if (action & GUEST_LOGIN)
3462 cFYI(1, ("Guest login")); /* BB Should we set anything
3463 in SesInfo struct ? */
3464/* if (SecurityBlob2->MessageType != NtLm??) {
3465 cFYI("Unexpected message type on auth response is %d"));
3466 } */
3467
3468 if (ses) {
3469 cFYI(1,
3470 ("Check challenge UID %d vs auth response UID %d",
3471 ses->Suid, smb_buffer_response->Uid));
3472 /* UID left in wire format */
3473 ses->Suid = smb_buffer_response->Uid;
3474 bcc_ptr = pByteArea(smb_buffer_response);
3475 /* response can have either 3 or 4 word count - Samba sends 3 */
3476 if ((pSMBr->resp.hdr.WordCount == 3)
3477 || ((pSMBr->resp.hdr.WordCount == 4)
3478 && (blob_len <
3479 pSMBr->resp.ByteCount))) {
3480 if (pSMBr->resp.hdr.WordCount == 4) {
3481 bcc_ptr +=
3482 blob_len;
3483 cFYI(1,
3484 ("Security Blob Length %d ",
3485 blob_len));
3486 }
3487
3488 cFYI(1,
3489 ("NTLMSSP response to Authenticate "));
3490
3491 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3492 if ((long) (bcc_ptr) % 2) {
3493 remaining_words =
3494 (BCC(smb_buffer_response)
3495 - 1) / 2;
3496 bcc_ptr++; /* Unicode strings must be word aligned */
3497 } else {
3498 remaining_words = BCC(smb_buffer_response) / 2;
3499 }
3500 len = UniStrnlen((wchar_t *) bcc_ptr,
3501 remaining_words - 1);
3502/* We look for obvious messed up bcc or strings in response so we do not go off
3503 the end since (at least) WIN2K and Windows XP have a major bug in not null
3504 terminating last Unicode string in response */
3505 kfree(ses->serverOS);
3506 ses->serverOS =
3507 kzalloc(2 * (len + 1), GFP_KERNEL);
3508 cifs_strfromUCS_le(ses->serverOS,
3509 (__le16 *)
3510 bcc_ptr, len,
3511 nls_codepage);
3512 bcc_ptr += 2 * (len + 1);
3513 remaining_words -= len + 1;
3514 ses->serverOS[2 * len] = 0;
3515 ses->serverOS[1 + (2 * len)] = 0;
3516 if (remaining_words > 0) {
3517 len = UniStrnlen((wchar_t *)
3518 bcc_ptr,
3519 remaining_words
3520 - 1);
3521 kfree(ses->serverNOS);
3522 ses->serverNOS =
3523 kzalloc(2 * (len + 1),
3524 GFP_KERNEL);
3525 cifs_strfromUCS_le(ses->
3526 serverNOS,
3527 (__le16 *)
3528 bcc_ptr,
3529 len,
3530 nls_codepage);
3531 bcc_ptr += 2 * (len + 1);
3532 ses->serverNOS[2 * len] = 0;
3533 ses->serverNOS[1+(2*len)] = 0;
3534 remaining_words -= len + 1;
3535 if (remaining_words > 0) {
3536 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3537 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3538 kfree(ses->serverDomain);
3539 ses->serverDomain =
3540 kzalloc(2 *
3541 (len +
3542 1),
3543 GFP_KERNEL);
3544 cifs_strfromUCS_le
3545 (ses->
3546 serverDomain,
3547 (__le16 *)
3548 bcc_ptr, len,
3549 nls_codepage);
3550 bcc_ptr +=
3551 2 * (len + 1);
3552 ses->
3553 serverDomain[2
3554 * len]
3555 = 0;
3556 ses->
3557 serverDomain[1
3558 +
3559 (2
3560 *
3561 len)]
3562 = 0;
3563 } /* else no more room so create dummy domain string */
3564 else {
3565 kfree(ses->serverDomain);
3566 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3567 }
3568 } else { /* no room so create dummy domain and NOS string */
3569 kfree(ses->serverDomain);
3570 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3571 kfree(ses->serverNOS);
3572 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3573 }
3574 } else { /* ASCII */
3575 len = strnlen(bcc_ptr, 1024);
3576 if (((long) bcc_ptr + len) -
3577 (long) pByteArea(smb_buffer_response)
3578 <= BCC(smb_buffer_response)) {
3579 kfree(ses->serverOS);
3580 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3581 strncpy(ses->serverOS,bcc_ptr, len);
3582
3583 bcc_ptr += len;
3584 bcc_ptr[0] = 0; /* null terminate the string */
3585 bcc_ptr++;
3586
3587 len = strnlen(bcc_ptr, 1024);
3588 kfree(ses->serverNOS);
3589 ses->serverNOS = kzalloc(len+1,
3590 GFP_KERNEL);
3591 strncpy(ses->serverNOS,
3592 bcc_ptr, len);
3593 bcc_ptr += len;
3594 bcc_ptr[0] = 0;
3595 bcc_ptr++;
3596
3597 len = strnlen(bcc_ptr, 1024);
3598 kfree(ses->serverDomain);
3599 ses->serverDomain =
3600 kzalloc(len+1,
3601 GFP_KERNEL);
3602 strncpy(ses->serverDomain,
3603 bcc_ptr, len);
3604 bcc_ptr += len;
3605 bcc_ptr[0] = 0;
3606 bcc_ptr++;
3607 } else
3608 cFYI(1, ("field of length %d "
3609 "extends beyond end of smb ",
3610 len));
3611 }
3612 } else {
3613 cERROR(1, ("Security Blob extends beyond end "
3614 "of SMB"));
3615 }
3616 } else {
3617 cERROR(1, ("No session structure passed in."));
3618 }
3619 } else {
3620 cERROR(1, ("Invalid Word count %d: ",
3621 smb_buffer_response->WordCount));
3622 rc = -EIO;
3623 }
3624
3625 cifs_buf_release(smb_buffer);
3626
3627 return rc;
3628}
3629
3630int 2615int
3631CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 2616CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3632 const char *tree, struct cifsTconInfo *tcon, 2617 const char *tree, struct cifsTconInfo *tcon,
@@ -3638,7 +2623,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3638 TCONX_RSP *pSMBr; 2623 TCONX_RSP *pSMBr;
3639 unsigned char *bcc_ptr; 2624 unsigned char *bcc_ptr;
3640 int rc = 0; 2625 int rc = 0;
3641 int length; 2626 int length, bytes_left;
3642 __u16 count; 2627 __u16 count;
3643 2628
3644 if (ses == NULL) 2629 if (ses == NULL)
@@ -3726,14 +2711,22 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3726 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 2711 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3727 CIFS_STD_OP); 2712 CIFS_STD_OP);
3728 2713
3729 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3730 /* above now done in SendReceive */ 2714 /* above now done in SendReceive */
3731 if ((rc == 0) && (tcon != NULL)) { 2715 if ((rc == 0) && (tcon != NULL)) {
2716 bool is_unicode;
2717
3732 tcon->tidStatus = CifsGood; 2718 tcon->tidStatus = CifsGood;
3733 tcon->need_reconnect = false; 2719 tcon->need_reconnect = false;
3734 tcon->tid = smb_buffer_response->Tid; 2720 tcon->tid = smb_buffer_response->Tid;
3735 bcc_ptr = pByteArea(smb_buffer_response); 2721 bcc_ptr = pByteArea(smb_buffer_response);
3736 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); 2722 bytes_left = BCC(smb_buffer_response);
2723 length = strnlen(bcc_ptr, bytes_left - 2);
2724 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
2725 is_unicode = true;
2726 else
2727 is_unicode = false;
2728
2729
3737 /* skip service field (NB: this field is always ASCII) */ 2730 /* skip service field (NB: this field is always ASCII) */
3738 if (length == 3) { 2731 if (length == 3) {
3739 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') && 2732 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
@@ -3748,39 +2741,16 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3748 } 2741 }
3749 } 2742 }
3750 bcc_ptr += length + 1; 2743 bcc_ptr += length + 1;
2744 bytes_left -= (length + 1);
3751 strncpy(tcon->treeName, tree, MAX_TREE_SIZE); 2745 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3752 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 2746
3753 length = UniStrnlen((wchar_t *) bcc_ptr, 512); 2747 /* mostly informational -- no need to fail on error here */
3754 if ((bcc_ptr + (2 * length)) - 2748 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
3755 pByteArea(smb_buffer_response) <= 2749 bytes_left, is_unicode,
3756 BCC(smb_buffer_response)) { 2750 nls_codepage);
3757 kfree(tcon->nativeFileSystem); 2751
3758 tcon->nativeFileSystem = 2752 cFYI(1, ("nativeFileSystem=%s", tcon->nativeFileSystem));
3759 kzalloc((4 * length) + 2, GFP_KERNEL); 2753
3760 if (tcon->nativeFileSystem) {
3761 cifs_strfromUCS_le(
3762 tcon->nativeFileSystem,
3763 (__le16 *) bcc_ptr,
3764 length, nls_codepage);
3765 cFYI(1, ("nativeFileSystem=%s",
3766 tcon->nativeFileSystem));
3767 }
3768 }
3769 /* else do not bother copying these information fields*/
3770 } else {
3771 length = strnlen(bcc_ptr, 1024);
3772 if ((bcc_ptr + length) -
3773 pByteArea(smb_buffer_response) <=
3774 BCC(smb_buffer_response)) {
3775 kfree(tcon->nativeFileSystem);
3776 tcon->nativeFileSystem =
3777 kzalloc(length + 1, GFP_KERNEL);
3778 if (tcon->nativeFileSystem)
3779 strncpy(tcon->nativeFileSystem, bcc_ptr,
3780 length);
3781 }
3782 /* else do not bother copying these information fields*/
3783 }
3784 if ((smb_buffer_response->WordCount == 3) || 2754 if ((smb_buffer_response->WordCount == 3) ||
3785 (smb_buffer_response->WordCount == 7)) 2755 (smb_buffer_response->WordCount == 7))
3786 /* field is in same location */ 2756 /* field is in same location */
@@ -3819,8 +2789,6 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3819 struct nls_table *nls_info) 2789 struct nls_table *nls_info)
3820{ 2790{
3821 int rc = 0; 2791 int rc = 0;
3822 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3823 bool ntlmv2_flag = false;
3824 int first_time = 0; 2792 int first_time = 0;
3825 struct TCP_Server_Info *server = pSesInfo->server; 2793 struct TCP_Server_Info *server = pSesInfo->server;
3826 2794
@@ -3852,83 +2820,19 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3852 pSesInfo->capabilities = server->capabilities; 2820 pSesInfo->capabilities = server->capabilities;
3853 if (linuxExtEnabled == 0) 2821 if (linuxExtEnabled == 0)
3854 pSesInfo->capabilities &= (~CAP_UNIX); 2822 pSesInfo->capabilities &= (~CAP_UNIX);
3855 /* pSesInfo->sequence_number = 0;*/ 2823
3856 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 2824 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3857 server->secMode, server->capabilities, server->timeAdj)); 2825 server->secMode, server->capabilities, server->timeAdj));
3858 2826
3859 if (experimEnabled < 2) 2827 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3860 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3861 else if (extended_security
3862 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3863 && (server->secType == NTLMSSP)) {
3864 rc = -EOPNOTSUPP;
3865 } else if (extended_security
3866 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3867 && (server->secType == RawNTLMSSP)) {
3868 cFYI(1, ("NTLMSSP sesssetup"));
3869 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3870 nls_info);
3871 if (!rc) {
3872 if (ntlmv2_flag) {
3873 char *v2_response;
3874 cFYI(1, ("more secure NTLM ver2 hash"));
3875 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3876 nls_info)) {
3877 rc = -ENOMEM;
3878 goto ss_err_exit;
3879 } else
3880 v2_response = kmalloc(16 + 64 /* blob*/,
3881 GFP_KERNEL);
3882 if (v2_response) {
3883 CalcNTLMv2_response(pSesInfo,
3884 v2_response);
3885 /* if (first_time)
3886 cifs_calculate_ntlmv2_mac_key */
3887 kfree(v2_response);
3888 /* BB Put dummy sig in SessSetup PDU? */
3889 } else {
3890 rc = -ENOMEM;
3891 goto ss_err_exit;
3892 }
3893
3894 } else {
3895 SMBNTencrypt(pSesInfo->password,
3896 server->cryptKey,
3897 ntlm_session_key);
3898
3899 if (first_time)
3900 cifs_calculate_mac_key(
3901 &server->mac_signing_key,
3902 ntlm_session_key,
3903 pSesInfo->password);
3904 }
3905 /* for better security the weaker lanman hash not sent
3906 in AuthSessSetup so we no longer calculate it */
3907
3908 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3909 ntlm_session_key,
3910 ntlmv2_flag,
3911 nls_info);
3912 }
3913 } else { /* old style NTLM 0.12 session setup */
3914 SMBNTencrypt(pSesInfo->password, server->cryptKey,
3915 ntlm_session_key);
3916
3917 if (first_time)
3918 cifs_calculate_mac_key(&server->mac_signing_key,
3919 ntlm_session_key,
3920 pSesInfo->password);
3921
3922 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3923 }
3924 if (rc) { 2828 if (rc) {
3925 cERROR(1, ("Send error in SessSetup = %d", rc)); 2829 cERROR(1, ("Send error in SessSetup = %d", rc));
3926 } else { 2830 } else {
3927 cFYI(1, ("CIFS Session Established successfully")); 2831 cFYI(1, ("CIFS Session Established successfully"));
3928 spin_lock(&GlobalMid_Lock); 2832 spin_lock(&GlobalMid_Lock);
3929 pSesInfo->status = CifsGood; 2833 pSesInfo->status = CifsGood;
3930 pSesInfo->need_reconnect = false; 2834 pSesInfo->need_reconnect = false;
3931 spin_unlock(&GlobalMid_Lock); 2835 spin_unlock(&GlobalMid_Lock);
3932 } 2836 }
3933 2837
3934ss_err_exit: 2838ss_err_exit:
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 461750e01364..11431ed72a7f 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -281,6 +281,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
281 int create_options = CREATE_NOT_DIR; 281 int create_options = CREATE_NOT_DIR;
282 int oplock = 0; 282 int oplock = 0;
283 int oflags; 283 int oflags;
284 bool posix_create = false;
284 /* 285 /*
285 * BB below access is probably too much for mknod to request 286 * BB below access is probably too much for mknod to request
286 * but we have to do query and setpathinfo so requesting 287 * but we have to do query and setpathinfo so requesting
@@ -328,11 +329,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
328 negotation. EREMOTE indicates DFS junction, which is not 329 negotation. EREMOTE indicates DFS junction, which is not
329 handled in posix open */ 330 handled in posix open */
330 331
331 if ((rc == 0) && (newinode == NULL)) 332 if (rc == 0) {
332 goto cifs_create_get_file_info; /* query inode info */ 333 posix_create = true;
333 else if (rc == 0) /* success, no need to query */ 334 if (newinode == NULL) /* query inode info */
334 goto cifs_create_set_dentry; 335 goto cifs_create_get_file_info;
335 else if ((rc != -EIO) && (rc != -EREMOTE) && 336 else /* success, no need to query */
337 goto cifs_create_set_dentry;
338 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
336 (rc != -EOPNOTSUPP)) /* path not found or net err */ 339 (rc != -EOPNOTSUPP)) /* path not found or net err */
337 goto cifs_create_out; 340 goto cifs_create_out;
338 /* else fallthrough to retry, using older open call, this is 341 /* else fallthrough to retry, using older open call, this is
@@ -464,7 +467,7 @@ cifs_create_set_dentry:
464 if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { 467 if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) {
465 /* mknod case - do not leave file open */ 468 /* mknod case - do not leave file open */
466 CIFSSMBClose(xid, tcon, fileHandle); 469 CIFSSMBClose(xid, tcon, fileHandle);
467 } else if (newinode) { 470 } else if (!(posix_create) && (newinode)) {
468 cifs_fill_fileinfo(newinode, fileHandle, 471 cifs_fill_fileinfo(newinode, fileHandle,
469 cifs_sb->tcon, write_only); 472 cifs_sb->tcon, write_only);
470 } 473 }
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 50ca088d8860..38c06f826575 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -129,15 +129,12 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode,
129 struct file *file, struct cifsInodeInfo *pCifsInode, 129 struct file *file, struct cifsInodeInfo *pCifsInode,
130 struct cifsFileInfo *pCifsFile, int oplock, u16 netfid) 130 struct cifsFileInfo *pCifsFile, int oplock, u16 netfid)
131{ 131{
132 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
133/* struct timespec temp; */ /* BB REMOVEME BB */
134 132
135 file->private_data = kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 133 file->private_data = kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
136 if (file->private_data == NULL) 134 if (file->private_data == NULL)
137 return -ENOMEM; 135 return -ENOMEM;
138 pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); 136 pCifsFile = cifs_init_private(file->private_data, inode, file, netfid);
139 write_lock(&GlobalSMBSeslock); 137 write_lock(&GlobalSMBSeslock);
140 list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList);
141 138
142 pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 139 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
143 if (pCifsInode == NULL) { 140 if (pCifsInode == NULL) {
@@ -145,17 +142,6 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode,
145 return -EINVAL; 142 return -EINVAL;
146 } 143 }
147 144
148 /* want handles we can use to read with first
149 in the list so we do not have to walk the
150 list to search for one in write_begin */
151 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
152 list_add_tail(&pCifsFile->flist,
153 &pCifsInode->openFileList);
154 } else {
155 list_add(&pCifsFile->flist,
156 &pCifsInode->openFileList);
157 }
158
159 if (pCifsInode->clientCanCacheRead) { 145 if (pCifsInode->clientCanCacheRead) {
160 /* we have the inode open somewhere else 146 /* we have the inode open somewhere else
161 no need to discard cache data */ 147 no need to discard cache data */
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index f36b4e40e443..9c869a6dcba1 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -962,13 +962,21 @@ undo_setattr:
962 goto out_close; 962 goto out_close;
963} 963}
964 964
965
966/*
967 * If dentry->d_inode is null (usually meaning the cached dentry
968 * is a negative dentry) then we would attempt a standard SMB delete, but
969 * if that fails we can not attempt the fall back mechanisms on EACESS
970 * but will return the EACESS to the caller. Note that the VFS does not call
971 * unlink on negative dentries currently.
972 */
965int cifs_unlink(struct inode *dir, struct dentry *dentry) 973int cifs_unlink(struct inode *dir, struct dentry *dentry)
966{ 974{
967 int rc = 0; 975 int rc = 0;
968 int xid; 976 int xid;
969 char *full_path = NULL; 977 char *full_path = NULL;
970 struct inode *inode = dentry->d_inode; 978 struct inode *inode = dentry->d_inode;
971 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 979 struct cifsInodeInfo *cifs_inode;
972 struct super_block *sb = dir->i_sb; 980 struct super_block *sb = dir->i_sb;
973 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 981 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
974 struct cifsTconInfo *tcon = cifs_sb->tcon; 982 struct cifsTconInfo *tcon = cifs_sb->tcon;
@@ -1012,7 +1020,7 @@ psx_del_no_retry:
1012 rc = cifs_rename_pending_delete(full_path, dentry, xid); 1020 rc = cifs_rename_pending_delete(full_path, dentry, xid);
1013 if (rc == 0) 1021 if (rc == 0)
1014 drop_nlink(inode); 1022 drop_nlink(inode);
1015 } else if (rc == -EACCES && dosattr == 0) { 1023 } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
1016 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); 1024 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1017 if (attrs == NULL) { 1025 if (attrs == NULL) {
1018 rc = -ENOMEM; 1026 rc = -ENOMEM;
@@ -1020,7 +1028,8 @@ psx_del_no_retry:
1020 } 1028 }
1021 1029
1022 /* try to reset dos attributes */ 1030 /* try to reset dos attributes */
1023 origattr = cifsInode->cifsAttrs; 1031 cifs_inode = CIFS_I(inode);
1032 origattr = cifs_inode->cifsAttrs;
1024 if (origattr == 0) 1033 if (origattr == 0)
1025 origattr |= ATTR_NORMAL; 1034 origattr |= ATTR_NORMAL;
1026 dosattr = origattr & ~ATTR_READONLY; 1035 dosattr = origattr & ~ATTR_READONLY;
@@ -1041,13 +1050,13 @@ psx_del_no_retry:
1041 1050
1042out_reval: 1051out_reval:
1043 if (inode) { 1052 if (inode) {
1044 cifsInode = CIFS_I(inode); 1053 cifs_inode = CIFS_I(inode);
1045 cifsInode->time = 0; /* will force revalidate to get info 1054 cifs_inode->time = 0; /* will force revalidate to get info
1046 when needed */ 1055 when needed */
1047 inode->i_ctime = current_fs_time(sb); 1056 inode->i_ctime = current_fs_time(sb);
1048 } 1057 }
1049 dir->i_ctime = dir->i_mtime = current_fs_time(sb); 1058 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1050 cifsInode = CIFS_I(dir); 1059 cifs_inode = CIFS_I(dir);
1051 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ 1060 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
1052 1061
1053 kfree(full_path); 1062 kfree(full_path);
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 63f644000ce5..cd83c53fcbb5 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -107,63 +107,51 @@ void *
107cifs_follow_link(struct dentry *direntry, struct nameidata *nd) 107cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
108{ 108{
109 struct inode *inode = direntry->d_inode; 109 struct inode *inode = direntry->d_inode;
110 int rc = -EACCES; 110 int rc = -ENOMEM;
111 int xid; 111 int xid;
112 char *full_path = NULL; 112 char *full_path = NULL;
113 char *target_path = ERR_PTR(-ENOMEM); 113 char *target_path = NULL;
114 struct cifs_sb_info *cifs_sb; 114 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
115 struct cifsTconInfo *pTcon; 115 struct cifsTconInfo *tcon = cifs_sb->tcon;
116 116
117 xid = GetXid(); 117 xid = GetXid();
118 118
119 full_path = build_path_from_dentry(direntry); 119 /*
120 120 * For now, we just handle symlinks with unix extensions enabled.
121 if (!full_path) 121 * Eventually we should handle NTFS reparse points, and MacOS
122 goto out_no_free; 122 * symlink support. For instance...
123 123 *
124 cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); 124 * rc = CIFSSMBQueryReparseLinkInfo(...)
125 cifs_sb = CIFS_SB(inode->i_sb); 125 *
126 pTcon = cifs_sb->tcon; 126 * For now, just return -EACCES when the server doesn't support posix
127 target_path = kmalloc(PATH_MAX, GFP_KERNEL); 127 * extensions. Note that we still allow querying symlinks when posix
128 if (!target_path) { 128 * extensions are manually disabled. We could disable these as well
129 target_path = ERR_PTR(-ENOMEM); 129 * but there doesn't seem to be any harm in allowing the client to
130 * read them.
131 */
132 if (!(tcon->ses->capabilities & CAP_UNIX)) {
133 rc = -EACCES;
130 goto out; 134 goto out;
131 } 135 }
132 136
133 /* We could change this to: 137 full_path = build_path_from_dentry(direntry);
134 if (pTcon->unix_ext) 138 if (!full_path)
135 but there does not seem any point in refusing to 139 goto out;
136 get symlink info if we can, even if unix extensions
137 turned off for this mount */
138
139 if (pTcon->ses->capabilities & CAP_UNIX)
140 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
141 target_path,
142 PATH_MAX-1,
143 cifs_sb->local_nls);
144 else {
145 /* BB add read reparse point symlink code here */
146 /* rc = CIFSSMBQueryReparseLinkInfo */
147 /* BB Add code to Query ReparsePoint info */
148 /* BB Add MAC style xsymlink check here if enabled */
149 }
150
151 if (rc == 0) {
152 140
153/* BB Add special case check for Samba DFS symlinks */ 141 cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
154 142
155 target_path[PATH_MAX-1] = 0; 143 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
156 } else { 144 cifs_sb->local_nls);
145 kfree(full_path);
146out:
147 if (rc != 0) {
157 kfree(target_path); 148 kfree(target_path);
158 target_path = ERR_PTR(rc); 149 target_path = ERR_PTR(rc);
159 } 150 }
160 151
161out:
162 kfree(full_path);
163out_no_free:
164 FreeXid(xid); 152 FreeXid(xid);
165 nd_set_link(nd, target_path); 153 nd_set_link(nd, target_path);
166 return NULL; /* No cookie */ 154 return NULL;
167} 155}
168 156
169int 157int
@@ -224,98 +212,6 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
224 return rc; 212 return rc;
225} 213}
226 214
227int
228cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
229{
230 struct inode *inode = direntry->d_inode;
231 int rc = -EACCES;
232 int xid;
233 int oplock = 0;
234 struct cifs_sb_info *cifs_sb;
235 struct cifsTconInfo *pTcon;
236 char *full_path = NULL;
237 char *tmpbuffer;
238 int len;
239 __u16 fid;
240
241 xid = GetXid();
242 cifs_sb = CIFS_SB(inode->i_sb);
243 pTcon = cifs_sb->tcon;
244
245/* BB would it be safe against deadlock to grab this sem
246 even though rename itself grabs the sem and calls lookup? */
247/* mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/
248 full_path = build_path_from_dentry(direntry);
249/* mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/
250
251 if (full_path == NULL) {
252 FreeXid(xid);
253 return -ENOMEM;
254 }
255
256 cFYI(1,
257 ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d",
258 full_path, inode, pBuffer, buflen));
259 if (buflen > PATH_MAX)
260 len = PATH_MAX;
261 else
262 len = buflen;
263 tmpbuffer = kmalloc(len, GFP_KERNEL);
264 if (tmpbuffer == NULL) {
265 kfree(full_path);
266 FreeXid(xid);
267 return -ENOMEM;
268 }
269
270/* BB add read reparse point symlink code and
271 Unix extensions symlink code here BB */
272/* We could disable this based on pTcon->unix_ext flag instead ... but why? */
273 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
274 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
275 tmpbuffer,
276 len - 1,
277 cifs_sb->local_nls);
278 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
279 cERROR(1, ("SFU style symlinks not implemented yet"));
280 /* add open and read as in fs/cifs/inode.c */
281 } else {
282 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
283 OPEN_REPARSE_POINT, &fid, &oplock, NULL,
284 cifs_sb->local_nls,
285 cifs_sb->mnt_cifs_flags &
286 CIFS_MOUNT_MAP_SPECIAL_CHR);
287 if (!rc) {
288 rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
289 tmpbuffer,
290 len - 1,
291 fid,
292 cifs_sb->local_nls);
293 if (CIFSSMBClose(xid, pTcon, fid)) {
294 cFYI(1, ("Error closing junction point "
295 "(open for ioctl)"));
296 }
297 /* If it is a DFS junction earlier we would have gotten
298 PATH_NOT_COVERED returned from server so we do
299 not need to request the DFS info here */
300 }
301 }
302 /* BB Anything else to do to handle recursive links? */
303 /* BB Should we be using page ops here? */
304
305 /* BB null terminate returned string in pBuffer? BB */
306 if (rc == 0) {
307 rc = vfs_readlink(direntry, pBuffer, len, tmpbuffer);
308 cFYI(1,
309 ("vfs_readlink called from cifs_readlink returned %d",
310 rc));
311 }
312
313 kfree(tmpbuffer);
314 kfree(full_path);
315 FreeXid(xid);
316 return rc;
317}
318
319void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie) 215void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
320{ 216{
321 char *p = nd_get_link(nd); 217 char *p = nd_get_link(nd);
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 4c89c572891a..e079a9190ec4 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -635,77 +635,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
635 return; 635 return;
636} 636}
637 637
638/* Windows maps these to the user defined 16 bit Unicode range since they are
639 reserved symbols (along with \ and /), otherwise illegal to store
640 in filenames in NTFS */
641#define UNI_ASTERIK (__u16) ('*' + 0xF000)
642#define UNI_QUESTION (__u16) ('?' + 0xF000)
643#define UNI_COLON (__u16) (':' + 0xF000)
644#define UNI_GRTRTHAN (__u16) ('>' + 0xF000)
645#define UNI_LESSTHAN (__u16) ('<' + 0xF000)
646#define UNI_PIPE (__u16) ('|' + 0xF000)
647#define UNI_SLASH (__u16) ('\\' + 0xF000)
648
649/* Convert 16 bit Unicode pathname from wire format to string in current code
650 page. Conversion may involve remapping up the seven characters that are
651 only legal in POSIX-like OS (if they are present in the string). Path
652 names are little endian 16 bit Unicode on the wire */
653int
654cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
655 const struct nls_table *cp)
656{
657 int i, j, len;
658 __u16 src_char;
659
660 for (i = 0, j = 0; i < maxlen; i++) {
661 src_char = le16_to_cpu(source[i]);
662 switch (src_char) {
663 case 0:
664 goto cUCS_out; /* BB check this BB */
665 case UNI_COLON:
666 target[j] = ':';
667 break;
668 case UNI_ASTERIK:
669 target[j] = '*';
670 break;
671 case UNI_QUESTION:
672 target[j] = '?';
673 break;
674 /* BB We can not handle remapping slash until
675 all the calls to build_path_from_dentry
676 are modified, as they use slash as separator BB */
677 /* case UNI_SLASH:
678 target[j] = '\\';
679 break;*/
680 case UNI_PIPE:
681 target[j] = '|';
682 break;
683 case UNI_GRTRTHAN:
684 target[j] = '>';
685 break;
686 case UNI_LESSTHAN:
687 target[j] = '<';
688 break;
689 default:
690 len = cp->uni2char(src_char, &target[j],
691 NLS_MAX_CHARSET_SIZE);
692 if (len > 0) {
693 j += len;
694 continue;
695 } else {
696 target[j] = '?';
697 }
698 }
699 j++;
700 /* make sure we do not overrun callers allocated temp buffer */
701 if (j >= (2 * NAME_MAX))
702 break;
703 }
704cUCS_out:
705 target[j] = 0;
706 return j;
707}
708
709/* Convert 16 bit Unicode pathname to wire format from string in current code 638/* Convert 16 bit Unicode pathname to wire format from string in current code
710 page. Conversion may involve remapping up the seven characters that are 639 page. Conversion may involve remapping up the seven characters that are
711 only legal in POSIX-like OS (if they are present in the string). Path 640 only legal in POSIX-like OS (if they are present in the string). Path
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 8703d68f5b20..e2fe998989a3 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -79,6 +79,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
79 {ErrQuota, -EDQUOT}, 79 {ErrQuota, -EDQUOT},
80 {ErrNotALink, -ENOLINK}, 80 {ErrNotALink, -ENOLINK},
81 {ERRnetlogonNotStarted, -ENOPROTOOPT}, 81 {ERRnetlogonNotStarted, -ENOPROTOOPT},
82 {ERRsymlink, -EOPNOTSUPP},
82 {ErrTooManyLinks, -EMLINK}, 83 {ErrTooManyLinks, -EMLINK},
83 {0, 0} 84 {0, 0}
84}; 85};
@@ -714,6 +715,7 @@ static const struct {
714 ERRDOS, ERRnoaccess, 0xc000028f}, { 715 ERRDOS, ERRnoaccess, 0xc000028f}, {
715 ERRDOS, ERRnoaccess, 0xc0000290}, { 716 ERRDOS, ERRnoaccess, 0xc0000290}, {
716 ERRDOS, ERRbadfunc, 0xc000029c}, { 717 ERRDOS, ERRbadfunc, 0xc000029c}, {
718 ERRDOS, ERRsymlink, NT_STATUS_STOPPED_ON_SYMLINK}, {
717 ERRDOS, ERRinvlevel, 0x007c0001}, }; 719 ERRDOS, ERRinvlevel, 0x007c0001}, };
718 720
719/***************************************************************************** 721/*****************************************************************************
diff --git a/fs/cifs/nterr.h b/fs/cifs/nterr.h
index 588abbb9d08c..257267367d41 100644
--- a/fs/cifs/nterr.h
+++ b/fs/cifs/nterr.h
@@ -35,8 +35,6 @@ struct nt_err_code_struct {
35extern const struct nt_err_code_struct nt_errs[]; 35extern const struct nt_err_code_struct nt_errs[];
36 36
37/* Win32 Status codes. */ 37/* Win32 Status codes. */
38
39#define STATUS_BUFFER_OVERFLOW 0x80000005
40#define STATUS_MORE_ENTRIES 0x0105 38#define STATUS_MORE_ENTRIES 0x0105
41#define ERROR_INVALID_PARAMETER 0x0057 39#define ERROR_INVALID_PARAMETER 0x0057
42#define ERROR_INSUFFICIENT_BUFFER 0x007a 40#define ERROR_INSUFFICIENT_BUFFER 0x007a
@@ -50,6 +48,13 @@ extern const struct nt_err_code_struct nt_errs[];
50#define STATUS_SOME_UNMAPPED 0x0107 48#define STATUS_SOME_UNMAPPED 0x0107
51#define STATUS_BUFFER_OVERFLOW 0x80000005 49#define STATUS_BUFFER_OVERFLOW 0x80000005
52#define NT_STATUS_NO_MORE_ENTRIES 0x8000001a 50#define NT_STATUS_NO_MORE_ENTRIES 0x8000001a
51#define NT_STATUS_MEDIA_CHANGED 0x8000001c
52#define NT_STATUS_END_OF_MEDIA 0x8000001e
53#define NT_STATUS_MEDIA_CHECK 0x80000020
54#define NT_STATUS_NO_DATA_DETECTED 0x8000001c
55#define NT_STATUS_STOPPED_ON_SYMLINK 0x8000002d
56#define NT_STATUS_DEVICE_REQUIRES_CLEANING 0x80000288
57#define NT_STATUS_DEVICE_DOOR_OPEN 0x80000288
53#define NT_STATUS_UNSUCCESSFUL 0xC0000000 | 0x0001 58#define NT_STATUS_UNSUCCESSFUL 0xC0000000 | 0x0001
54#define NT_STATUS_NOT_IMPLEMENTED 0xC0000000 | 0x0002 59#define NT_STATUS_NOT_IMPLEMENTED 0xC0000000 | 0x0002
55#define NT_STATUS_INVALID_INFO_CLASS 0xC0000000 | 0x0003 60#define NT_STATUS_INVALID_INFO_CLASS 0xC0000000 | 0x0003
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index c377d8065d99..49c9a4e75319 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -27,29 +27,39 @@
27#define UnknownMessage cpu_to_le32(8) 27#define UnknownMessage cpu_to_le32(8)
28 28
29/* Negotiate Flags */ 29/* Negotiate Flags */
30#define NTLMSSP_NEGOTIATE_UNICODE 0x01 /* Text strings are in unicode */ 30#define NTLMSSP_NEGOTIATE_UNICODE 0x01 /* Text strings are unicode */
31#define NTLMSSP_NEGOTIATE_OEM 0x02 /* Text strings are in OEM */ 31#define NTLMSSP_NEGOTIATE_OEM 0x02 /* Text strings are in OEM */
32#define NTLMSSP_REQUEST_TARGET 0x04 /* Server return its auth realm */ 32#define NTLMSSP_REQUEST_TARGET 0x04 /* Srv returns its auth realm */
33#define NTLMSSP_NEGOTIATE_SIGN 0x0010 /* Request signature capability */ 33/* define reserved9 0x08 */
34#define NTLMSSP_NEGOTIATE_SEAL 0x0020 /* Request confidentiality */ 34#define NTLMSSP_NEGOTIATE_SIGN 0x0010 /* Request signing capability */
35#define NTLMSSP_NEGOTIATE_DGRAM 0x0040 35#define NTLMSSP_NEGOTIATE_SEAL 0x0020 /* Request confidentiality */
36#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 /* Sign/seal use LM session key */ 36#define NTLMSSP_NEGOTIATE_DGRAM 0x0040
37#define NTLMSSP_NEGOTIATE_NTLM 0x0200 /* NTLM authentication */ 37#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 /* Use LM session key */
38#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000 38/* defined reserved 8 0x0100 */
39#define NTLMSSP_NEGOTIATE_NTLM 0x0200 /* NTLM authentication */
40#define NTLMSSP_NEGOTIATE_NT_ONLY 0x0400 /* Lanman not allowed */
41#define NTLMSSP_ANONYMOUS 0x0800
42#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000 /* reserved6 */
39#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000 43#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000
40#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 /* client/server on same machine */ 44#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 /* client/server same machine */
41#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 /* Sign for all security levels */ 45#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 /* Sign. All security levels */
42#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000 46#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000
43#define NTLMSSP_TARGET_TYPE_SERVER 0x20000 47#define NTLMSSP_TARGET_TYPE_SERVER 0x20000
44#define NTLMSSP_TARGET_TYPE_SHARE 0x40000 48#define NTLMSSP_TARGET_TYPE_SHARE 0x40000
45#define NTLMSSP_NEGOTIATE_NTLMV2 0x80000 49#define NTLMSSP_NEGOTIATE_EXTENDED_SEC 0x80000 /* NB:not related to NTLMv2 pwd*/
46#define NTLMSSP_REQUEST_INIT_RESP 0x100000 50/* #define NTLMSSP_REQUEST_INIT_RESP 0x100000 */
47#define NTLMSSP_REQUEST_ACCEPT_RESP 0x200000 51#define NTLMSSP_NEGOTIATE_IDENTIFY 0x100000
48#define NTLMSSP_REQUEST_NOT_NT_KEY 0x400000 52#define NTLMSSP_REQUEST_ACCEPT_RESP 0x200000 /* reserved5 */
53#define NTLMSSP_REQUEST_NON_NT_KEY 0x400000
49#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x800000 54#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x800000
50#define NTLMSSP_NEGOTIATE_128 0x20000000 55/* #define reserved4 0x1000000 */
51#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 56#define NTLMSSP_NEGOTIATE_VERSION 0x2000000 /* we do not set */
52#define NTLMSSP_NEGOTIATE_56 0x80000000 57/* #define reserved3 0x4000000 */
58/* #define reserved2 0x8000000 */
59/* #define reserved1 0x10000000 */
60#define NTLMSSP_NEGOTIATE_128 0x20000000
61#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
62#define NTLMSSP_NEGOTIATE_56 0x80000000
53 63
54/* Although typedefs are not commonly used for structure definitions */ 64/* Although typedefs are not commonly used for structure definitions */
55/* in the Linux kernel, in this particular case they are useful */ 65/* in the Linux kernel, in this particular case they are useful */
@@ -60,32 +70,36 @@
60typedef struct _SECURITY_BUFFER { 70typedef struct _SECURITY_BUFFER {
61 __le16 Length; 71 __le16 Length;
62 __le16 MaximumLength; 72 __le16 MaximumLength;
63 __le32 Buffer; /* offset to buffer */ 73 __le32 BufferOffset; /* offset to buffer */
64} __attribute__((packed)) SECURITY_BUFFER; 74} __attribute__((packed)) SECURITY_BUFFER;
65 75
66typedef struct _NEGOTIATE_MESSAGE { 76typedef struct _NEGOTIATE_MESSAGE {
67 __u8 Signature[sizeof(NTLMSSP_SIGNATURE)]; 77 __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
68 __le32 MessageType; /* 1 */ 78 __le32 MessageType; /* NtLmNegotiate = 1 */
69 __le32 NegotiateFlags; 79 __le32 NegotiateFlags;
70 SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */ 80 SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */
71 SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */ 81 SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */
82 /* SECURITY_BUFFER for version info not present since we
83 do not set the version is present flag */
72 char DomainString[0]; 84 char DomainString[0];
73 /* followed by WorkstationString */ 85 /* followed by WorkstationString */
74} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE; 86} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
75 87
76typedef struct _CHALLENGE_MESSAGE { 88typedef struct _CHALLENGE_MESSAGE {
77 __u8 Signature[sizeof(NTLMSSP_SIGNATURE)]; 89 __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
78 __le32 MessageType; /* 2 */ 90 __le32 MessageType; /* NtLmChallenge = 2 */
79 SECURITY_BUFFER TargetName; 91 SECURITY_BUFFER TargetName;
80 __le32 NegotiateFlags; 92 __le32 NegotiateFlags;
81 __u8 Challenge[CIFS_CRYPTO_KEY_SIZE]; 93 __u8 Challenge[CIFS_CRYPTO_KEY_SIZE];
82 __u8 Reserved[8]; 94 __u8 Reserved[8];
83 SECURITY_BUFFER TargetInfoArray; 95 SECURITY_BUFFER TargetInfoArray;
96 /* SECURITY_BUFFER for version info not present since we
97 do not set the version is present flag */
84} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE; 98} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
85 99
86typedef struct _AUTHENTICATE_MESSAGE { 100typedef struct _AUTHENTICATE_MESSAGE {
87 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; 101 __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
88 __le32 MessageType; /* 3 */ 102 __le32 MessageType; /* NtLmsAuthenticate = 3 */
89 SECURITY_BUFFER LmChallengeResponse; 103 SECURITY_BUFFER LmChallengeResponse;
90 SECURITY_BUFFER NtChallengeResponse; 104 SECURITY_BUFFER NtChallengeResponse;
91 SECURITY_BUFFER DomainName; 105 SECURITY_BUFFER DomainName;
@@ -93,5 +107,7 @@ typedef struct _AUTHENTICATE_MESSAGE {
93 SECURITY_BUFFER WorkstationName; 107 SECURITY_BUFFER WorkstationName;
94 SECURITY_BUFFER SessionKey; 108 SECURITY_BUFFER SessionKey;
95 __le32 NegotiateFlags; 109 __le32 NegotiateFlags;
110 /* SECURITY_BUFFER for version info not present since we
111 do not set the version is present flag */
96 char UserString[0]; 112 char UserString[0];
97} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE; 113} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 1a8be6228333..964e097c8203 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -31,6 +31,13 @@
31#include "cifs_fs_sb.h" 31#include "cifs_fs_sb.h"
32#include "cifsfs.h" 32#include "cifsfs.h"
33 33
34/*
35 * To be safe - for UCS to UTF-8 with strings loaded with the rare long
36 * characters alloc more to account for such multibyte target UTF-8
37 * characters.
38 */
39#define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2)
40
34#ifdef CONFIG_CIFS_DEBUG2 41#ifdef CONFIG_CIFS_DEBUG2
35static void dump_cifs_file_struct(struct file *file, char *label) 42static void dump_cifs_file_struct(struct file *file, char *label)
36{ 43{
@@ -438,6 +445,38 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
438 } 445 }
439} 446}
440 447
448/* BB eventually need to add the following helper function to
449 resolve NT_STATUS_STOPPED_ON_SYMLINK return code when
450 we try to do FindFirst on (NTFS) directory symlinks */
451/*
452int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
453 int xid)
454{
455 __u16 fid;
456 int len;
457 int oplock = 0;
458 int rc;
459 struct cifsTconInfo *ptcon = cifs_sb->tcon;
460 char *tmpbuffer;
461
462 rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
463 OPEN_REPARSE_POINT, &fid, &oplock, NULL,
464 cifs_sb->local_nls,
465 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
466 if (!rc) {
467 tmpbuffer = kmalloc(maxpath);
468 rc = CIFSSMBQueryReparseLinkInfo(xid, ptcon, full_path,
469 tmpbuffer,
470 maxpath -1,
471 fid,
472 cifs_sb->local_nls);
473 if (CIFSSMBClose(xid, ptcon, fid)) {
474 cFYI(1, ("Error closing temporary reparsepoint open)"));
475 }
476 }
477}
478 */
479
441static int initiate_cifs_search(const int xid, struct file *file) 480static int initiate_cifs_search(const int xid, struct file *file)
442{ 481{
443 int rc = 0; 482 int rc = 0;
@@ -493,7 +532,10 @@ ffirst_retry:
493 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); 532 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
494 if (rc == 0) 533 if (rc == 0)
495 cifsFile->invalidHandle = false; 534 cifsFile->invalidHandle = false;
496 if ((rc == -EOPNOTSUPP) && 535 /* BB add following call to handle readdir on new NTFS symlink errors
536 else if STATUS_STOPPED_ON_SYMLINK
537 call get_symlink_reparse_path and retry with new path */
538 else if ((rc == -EOPNOTSUPP) &&
497 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { 539 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
498 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; 540 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
499 goto ffirst_retry; 541 goto ffirst_retry;
@@ -822,7 +864,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
822/* inode num, inode type and filename returned */ 864/* inode num, inode type and filename returned */
823static int cifs_get_name_from_search_buf(struct qstr *pqst, 865static int cifs_get_name_from_search_buf(struct qstr *pqst,
824 char *current_entry, __u16 level, unsigned int unicode, 866 char *current_entry, __u16 level, unsigned int unicode,
825 struct cifs_sb_info *cifs_sb, int max_len, __u64 *pinum) 867 struct cifs_sb_info *cifs_sb, unsigned int max_len, __u64 *pinum)
826{ 868{
827 int rc = 0; 869 int rc = 0;
828 unsigned int len = 0; 870 unsigned int len = 0;
@@ -881,14 +923,12 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
881 } 923 }
882 924
883 if (unicode) { 925 if (unicode) {
884 /* BB fixme - test with long names */ 926 pqst->len = cifs_from_ucs2((char *) pqst->name,
885 /* Note converted filename can be longer than in unicode */ 927 (__le16 *) filename,
886 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) 928 UNICODE_NAME_MAX,
887 pqst->len = cifs_convertUCSpath((char *)pqst->name, 929 min(len, max_len), nlt,
888 (__le16 *)filename, len/2, nlt); 930 cifs_sb->mnt_cifs_flags &
889 else 931 CIFS_MOUNT_MAP_SPECIAL_CHR);
890 pqst->len = cifs_strfromUCS_le((char *)pqst->name,
891 (__le16 *)filename, len/2, nlt);
892 } else { 932 } else {
893 pqst->name = filename; 933 pqst->name = filename;
894 pqst->len = len; 934 pqst->len = len;
@@ -898,8 +938,8 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
898 return rc; 938 return rc;
899} 939}
900 940
901static int cifs_filldir(char *pfindEntry, struct file *file, 941static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
902 filldir_t filldir, void *direntry, char *scratch_buf, int max_len) 942 void *direntry, char *scratch_buf, unsigned int max_len)
903{ 943{
904 int rc = 0; 944 int rc = 0;
905 struct qstr qstring; 945 struct qstr qstring;
@@ -996,7 +1036,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
996 int num_to_fill = 0; 1036 int num_to_fill = 0;
997 char *tmp_buf = NULL; 1037 char *tmp_buf = NULL;
998 char *end_of_smb; 1038 char *end_of_smb;
999 int max_len; 1039 unsigned int max_len;
1000 1040
1001 xid = GetXid(); 1041 xid = GetXid();
1002 1042
@@ -1070,11 +1110,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1070 cifsFile->srch_inf.ntwrk_buf_start); 1110 cifsFile->srch_inf.ntwrk_buf_start);
1071 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len; 1111 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
1072 1112
1073 /* To be safe - for UCS to UTF-8 with strings loaded 1113 tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
1074 with the rare long characters alloc more to account for
1075 such multibyte target UTF-8 characters. cifs_unicode.c,
1076 which actually does the conversion, has the same limit */
1077 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
1078 for (i = 0; (i < num_to_fill) && (rc == 0); i++) { 1114 for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
1079 if (current_entry == NULL) { 1115 if (current_entry == NULL) {
1080 /* evaluate whether this case is an error */ 1116 /* evaluate whether this case is an error */
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index c652c73760dd..897a052270f9 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * SMB/CIFS session setup handling routines 4 * SMB/CIFS session setup handling routines
5 * 5 *
6 * Copyright (c) International Business Machines Corp., 2006, 2007 6 * Copyright (c) International Business Machines Corp., 2006, 2009
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
9 * This library is free software; you can redistribute it and/or modify 9 * This library is free software; you can redistribute it and/or modify
@@ -111,7 +111,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
111get_vc_num_exit: 111get_vc_num_exit:
112 write_unlock(&cifs_tcp_ses_lock); 112 write_unlock(&cifs_tcp_ses_lock);
113 113
114 return le16_to_cpu(vcnum); 114 return cpu_to_le16(vcnum);
115} 115}
116 116
117static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) 117static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
@@ -277,12 +277,11 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
277 *pbcc_area = bcc_ptr; 277 *pbcc_area = bcc_ptr;
278} 278}
279 279
280static int decode_unicode_ssetup(char **pbcc_area, int bleft, 280static void
281 struct cifsSesInfo *ses, 281decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
282 const struct nls_table *nls_cp) 282 const struct nls_table *nls_cp)
283{ 283{
284 int rc = 0; 284 int len;
285 int words_left, len;
286 char *data = *pbcc_area; 285 char *data = *pbcc_area;
287 286
288 cFYI(1, ("bleft %d", bleft)); 287 cFYI(1, ("bleft %d", bleft));
@@ -300,63 +299,29 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
300 ++bleft; 299 ++bleft;
301 } 300 }
302 301
303 words_left = bleft / 2;
304
305 /* save off server operating system */
306 len = UniStrnlen((wchar_t *) data, words_left);
307
308 if (len >= words_left)
309 return rc;
310
311 kfree(ses->serverOS); 302 kfree(ses->serverOS);
312 /* UTF-8 string will not grow more than four times as big as UCS-16 */ 303 ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
313 ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); 304 cFYI(1, ("serverOS=%s", ses->serverOS));
314 if (ses->serverOS != NULL) { 305 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
315 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); 306 data += len;
316 cFYI(1, ("serverOS=%s", ses->serverOS)); 307 bleft -= len;
317 } 308 if (bleft <= 0)
318 data += 2 * (len + 1); 309 return;
319 words_left -= len + 1;
320
321 /* save off server network operating system */
322 len = UniStrnlen((wchar_t *) data, words_left);
323
324 if (len >= words_left)
325 return rc;
326 310
327 kfree(ses->serverNOS); 311 kfree(ses->serverNOS);
328 ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); 312 ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
329 if (ses->serverNOS != NULL) { 313 cFYI(1, ("serverNOS=%s", ses->serverNOS));
330 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 314 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
331 nls_cp); 315 data += len;
332 cFYI(1, ("serverNOS=%s", ses->serverNOS)); 316 bleft -= len;
333 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) { 317 if (bleft <= 0)
334 cFYI(1, ("NT4 server")); 318 return;
335 ses->flags |= CIFS_SES_NT4;
336 }
337 }
338 data += 2 * (len + 1);
339 words_left -= len + 1;
340
341 /* save off server domain */
342 len = UniStrnlen((wchar_t *) data, words_left);
343
344 if (len > words_left)
345 return rc;
346 319
347 kfree(ses->serverDomain); 320 kfree(ses->serverDomain);
348 ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL); 321 ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
349 if (ses->serverDomain != NULL) { 322 cFYI(1, ("serverDomain=%s", ses->serverDomain));
350 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
351 nls_cp);
352 cFYI(1, ("serverDomain=%s", ses->serverDomain));
353 }
354 data += 2 * (len + 1);
355 words_left -= len + 1;
356
357 cFYI(1, ("words left: %d", words_left));
358 323
359 return rc; 324 return;
360} 325}
361 326
362static int decode_ascii_ssetup(char **pbcc_area, int bleft, 327static int decode_ascii_ssetup(char **pbcc_area, int bleft,
@@ -413,6 +378,186 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
413 return rc; 378 return rc;
414} 379}
415 380
381static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
382 struct cifsSesInfo *ses)
383{
384 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
385
386 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
387 cERROR(1, ("challenge blob len %d too small", blob_len));
388 return -EINVAL;
389 }
390
391 if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
392 cERROR(1, ("blob signature incorrect %s", pblob->Signature));
393 return -EINVAL;
394 }
395 if (pblob->MessageType != NtLmChallenge) {
396 cERROR(1, ("Incorrect message type %d", pblob->MessageType));
397 return -EINVAL;
398 }
399
400 memcpy(ses->server->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
401 /* BB we could decode pblob->NegotiateFlags; some may be useful */
402 /* In particular we can examine sign flags */
403 /* BB spec says that if AvId field of MsvAvTimestamp is populated then
404 we must set the MIC field of the AUTHENTICATE_MESSAGE */
405
406 return 0;
407}
408
409#ifdef CONFIG_CIFS_EXPERIMENTAL
410/* BB Move to ntlmssp.c eventually */
411
412/* We do not malloc the blob, it is passed in pbuffer, because
413 it is fixed size, and small, making this approach cleaner */
414static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
415 struct cifsSesInfo *ses)
416{
417 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
418 __u32 flags;
419
420 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
421 sec_blob->MessageType = NtLmNegotiate;
422
423 /* BB is NTLMV2 session security format easier to use here? */
424 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
425 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
426 NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
427 if (ses->server->secMode &
428 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
429 flags |= NTLMSSP_NEGOTIATE_SIGN;
430 if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
431 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
432
433 sec_blob->NegotiateFlags |= cpu_to_le32(flags);
434
435 sec_blob->WorkstationName.BufferOffset = 0;
436 sec_blob->WorkstationName.Length = 0;
437 sec_blob->WorkstationName.MaximumLength = 0;
438
439 /* Domain name is sent on the Challenge not Negotiate NTLMSSP request */
440 sec_blob->DomainName.BufferOffset = 0;
441 sec_blob->DomainName.Length = 0;
442 sec_blob->DomainName.MaximumLength = 0;
443}
444
445/* We do not malloc the blob, it is passed in pbuffer, because its
446 maximum possible size is fixed and small, making this approach cleaner.
447 This function returns the length of the data in the blob */
448static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
449 struct cifsSesInfo *ses,
450 const struct nls_table *nls_cp, int first)
451{
452 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
453 __u32 flags;
454 unsigned char *tmp;
455 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
456
457 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
458 sec_blob->MessageType = NtLmAuthenticate;
459
460 flags = NTLMSSP_NEGOTIATE_56 |
461 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
462 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
463 NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
464 if (ses->server->secMode &
465 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
466 flags |= NTLMSSP_NEGOTIATE_SIGN;
467 if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
468 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
469
470 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
471 sec_blob->NegotiateFlags |= cpu_to_le32(flags);
472
473 sec_blob->LmChallengeResponse.BufferOffset =
474 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
475 sec_blob->LmChallengeResponse.Length = 0;
476 sec_blob->LmChallengeResponse.MaximumLength = 0;
477
478 /* calculate session key, BB what about adding similar ntlmv2 path? */
479 SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
480 if (first)
481 cifs_calculate_mac_key(&ses->server->mac_signing_key,
482 ntlm_session_key, ses->password);
483
484 memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
485 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
486 sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);
487 sec_blob->NtChallengeResponse.MaximumLength =
488 cpu_to_le16(CIFS_SESS_KEY_SIZE);
489
490 tmp += CIFS_SESS_KEY_SIZE;
491
492 if (ses->domainName == NULL) {
493 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
494 sec_blob->DomainName.Length = 0;
495 sec_blob->DomainName.MaximumLength = 0;
496 tmp += 2;
497 } else {
498 int len;
499 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
500 MAX_USERNAME_SIZE, nls_cp);
501 len *= 2; /* unicode is 2 bytes each */
502 len += 2; /* trailing null */
503 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
504 sec_blob->DomainName.Length = cpu_to_le16(len);
505 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
506 tmp += len;
507 }
508
509 if (ses->userName == NULL) {
510 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
511 sec_blob->UserName.Length = 0;
512 sec_blob->UserName.MaximumLength = 0;
513 tmp += 2;
514 } else {
515 int len;
516 len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
517 MAX_USERNAME_SIZE, nls_cp);
518 len *= 2; /* unicode is 2 bytes each */
519 len += 2; /* trailing null */
520 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
521 sec_blob->UserName.Length = cpu_to_le16(len);
522 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
523 tmp += len;
524 }
525
526 sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
527 sec_blob->WorkstationName.Length = 0;
528 sec_blob->WorkstationName.MaximumLength = 0;
529 tmp += 2;
530
531 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
532 sec_blob->SessionKey.Length = 0;
533 sec_blob->SessionKey.MaximumLength = 0;
534 return tmp - pbuffer;
535}
536
537
538static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
539 struct cifsSesInfo *ses)
540{
541 build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
542 pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
543
544 return;
545}
546
547static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
548 struct cifsSesInfo *ses,
549 const struct nls_table *nls, int first_time)
550{
551 int bloblen;
552
553 bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls,
554 first_time);
555 pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);
556
557 return bloblen;
558}
559#endif
560
416int 561int
417CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 562CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
418 const struct nls_table *nls_cp) 563 const struct nls_table *nls_cp)
@@ -431,6 +576,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
431 __u16 action; 576 __u16 action;
432 int bytes_remaining; 577 int bytes_remaining;
433 struct key *spnego_key = NULL; 578 struct key *spnego_key = NULL;
579 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
434 580
435 if (ses == NULL) 581 if (ses == NULL)
436 return -EINVAL; 582 return -EINVAL;
@@ -438,6 +584,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
438 type = ses->server->secType; 584 type = ses->server->secType;
439 585
440 cFYI(1, ("sess setup type %d", type)); 586 cFYI(1, ("sess setup type %d", type));
587ssetup_ntlmssp_authenticate:
588 if (phase == NtLmChallenge)
589 phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
590
441 if (type == LANMAN) { 591 if (type == LANMAN) {
442#ifndef CONFIG_CIFS_WEAK_PW_HASH 592#ifndef CONFIG_CIFS_WEAK_PW_HASH
443 /* LANMAN and plaintext are less secure and off by default. 593 /* LANMAN and plaintext are less secure and off by default.
@@ -651,9 +801,53 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
651 goto ssetup_exit; 801 goto ssetup_exit;
652#endif /* CONFIG_CIFS_UPCALL */ 802#endif /* CONFIG_CIFS_UPCALL */
653 } else { 803 } else {
804#ifdef CONFIG_CIFS_EXPERIMENTAL
805 if ((experimEnabled > 1) && (type == RawNTLMSSP)) {
806 if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
807 cERROR(1, ("NTLMSSP requires Unicode support"));
808 rc = -ENOSYS;
809 goto ssetup_exit;
810 }
811
812 cFYI(1, ("ntlmssp session setup phase %d", phase));
813 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
814 capabilities |= CAP_EXTENDED_SECURITY;
815 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
816 if (phase == NtLmNegotiate) {
817 setup_ntlmssp_neg_req(pSMB, ses);
818 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
819 } else if (phase == NtLmAuthenticate) {
820 int blob_len;
821 blob_len = setup_ntlmssp_auth_req(pSMB, ses,
822 nls_cp,
823 first_time);
824 iov[1].iov_len = blob_len;
825 /* Make sure that we tell the server that we
826 are using the uid that it just gave us back
827 on the response (challenge) */
828 smb_buf->Uid = ses->Suid;
829 } else {
830 cERROR(1, ("invalid phase %d", phase));
831 rc = -ENOSYS;
832 goto ssetup_exit;
833 }
834 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
835 /* unicode strings must be word aligned */
836 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
837 *bcc_ptr = 0;
838 bcc_ptr++;
839 }
840 unicode_oslm_strings(&bcc_ptr, nls_cp);
841 } else {
842 cERROR(1, ("secType %d not supported!", type));
843 rc = -ENOSYS;
844 goto ssetup_exit;
845 }
846#else
654 cERROR(1, ("secType %d not supported!", type)); 847 cERROR(1, ("secType %d not supported!", type));
655 rc = -ENOSYS; 848 rc = -ENOSYS;
656 goto ssetup_exit; 849 goto ssetup_exit;
850#endif
657 } 851 }
658 852
659 iov[2].iov_base = str_area; 853 iov[2].iov_base = str_area;
@@ -669,12 +863,23 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
669 /* SMB request buf freed in SendReceive2 */ 863 /* SMB request buf freed in SendReceive2 */
670 864
671 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); 865 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
672 if (rc)
673 goto ssetup_exit;
674 866
675 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; 867 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
676 smb_buf = (struct smb_hdr *)iov[0].iov_base; 868 smb_buf = (struct smb_hdr *)iov[0].iov_base;
677 869
870 if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
871 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
872 if (phase != NtLmNegotiate) {
873 cERROR(1, ("Unexpected more processing error"));
874 goto ssetup_exit;
875 }
876 /* NTLMSSP Negotiate sent now processing challenge (response) */
877 phase = NtLmChallenge; /* process ntlmssp challenge */
878 rc = 0; /* MORE_PROC rc is not an error here, but expected */
879 }
880 if (rc)
881 goto ssetup_exit;
882
678 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) { 883 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
679 rc = -EIO; 884 rc = -EIO;
680 cERROR(1, ("bad word count %d", smb_buf->WordCount)); 885 cERROR(1, ("bad word count %d", smb_buf->WordCount));
@@ -693,12 +898,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
693 if (smb_buf->WordCount == 4) { 898 if (smb_buf->WordCount == 4) {
694 __u16 blob_len; 899 __u16 blob_len;
695 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); 900 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
696 bcc_ptr += blob_len;
697 if (blob_len > bytes_remaining) { 901 if (blob_len > bytes_remaining) {
698 cERROR(1, ("bad security blob length %d", blob_len)); 902 cERROR(1, ("bad security blob length %d", blob_len));
699 rc = -EINVAL; 903 rc = -EINVAL;
700 goto ssetup_exit; 904 goto ssetup_exit;
701 } 905 }
906 if (phase == NtLmChallenge) {
907 rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
908 /* now goto beginning for ntlmssp authenticate phase */
909 if (rc)
910 goto ssetup_exit;
911 }
912 bcc_ptr += blob_len;
702 bytes_remaining -= blob_len; 913 bytes_remaining -= blob_len;
703 } 914 }
704 915
@@ -709,8 +920,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
709 ++bcc_ptr; 920 ++bcc_ptr;
710 --bytes_remaining; 921 --bytes_remaining;
711 } 922 }
712 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 923 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
713 ses, nls_cp);
714 } else { 924 } else {
715 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, 925 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
716 ses, nls_cp); 926 ses, nls_cp);
@@ -728,5 +938,9 @@ ssetup_exit:
728 } else if (resp_buf_type == CIFS_LARGE_BUFFER) 938 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
729 cifs_buf_release(iov[0].iov_base); 939 cifs_buf_release(iov[0].iov_base);
730 940
941 /* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
942 if ((phase == NtLmChallenge) && (rc == 0))
943 goto ssetup_ntlmssp_authenticate;
944
731 return rc; 945 return rc;
732} 946}
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h
index 7f50e8577c1c..c5084d27db7c 100644
--- a/fs/cifs/smberr.h
+++ b/fs/cifs/smberr.h
@@ -110,6 +110,7 @@
110 110
111/* Below errors are used internally (do not come over the wire) for passthrough 111/* Below errors are used internally (do not come over the wire) for passthrough
112 from STATUS codes to POSIX only */ 112 from STATUS codes to POSIX only */
113#define ERRsymlink 0xFFFD
113#define ErrTooManyLinks 0xFFFE 114#define ErrTooManyLinks 0xFFFE
114 115
115/* Following error codes may be generated with the ERRSRV error class.*/ 116/* Following error codes may be generated with the ERRSRV error class.*/
diff --git a/fs/dcache.c b/fs/dcache.c
index 1fcffebfb44f..75659a6fd1f8 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -481,7 +481,7 @@ restart:
481 if ((flags & DCACHE_REFERENCED) 481 if ((flags & DCACHE_REFERENCED)
482 && (dentry->d_flags & DCACHE_REFERENCED)) { 482 && (dentry->d_flags & DCACHE_REFERENCED)) {
483 dentry->d_flags &= ~DCACHE_REFERENCED; 483 dentry->d_flags &= ~DCACHE_REFERENCED;
484 list_move_tail(&dentry->d_lru, &referenced); 484 list_move(&dentry->d_lru, &referenced);
485 spin_unlock(&dentry->d_lock); 485 spin_unlock(&dentry->d_lock);
486 } else { 486 } else {
487 list_move_tail(&dentry->d_lru, &tmp); 487 list_move_tail(&dentry->d_lru, &tmp);
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 63a4a59e4148..c68edb969441 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -90,6 +90,15 @@ static inline struct super_block *pts_sb_from_inode(struct inode *inode)
90#define PARSE_MOUNT 0 90#define PARSE_MOUNT 0
91#define PARSE_REMOUNT 1 91#define PARSE_REMOUNT 1
92 92
93/*
94 * parse_mount_options():
95 * Set @opts to mount options specified in @data. If an option is not
96 * specified in @data, set it to its default value. The exception is
97 * 'newinstance' option which can only be set/cleared on a mount (i.e.
98 * cannot be changed during remount).
99 *
100 * Note: @data may be NULL (in which case all options are set to default).
101 */
93static int parse_mount_options(char *data, int op, struct pts_mount_opts *opts) 102static int parse_mount_options(char *data, int op, struct pts_mount_opts *opts)
94{ 103{
95 char *p; 104 char *p;
@@ -355,12 +364,9 @@ static int devpts_get_sb(struct file_system_type *fs_type,
355 struct pts_mount_opts opts; 364 struct pts_mount_opts opts;
356 struct super_block *s; 365 struct super_block *s;
357 366
358 memset(&opts, 0, sizeof(opts)); 367 error = parse_mount_options(data, PARSE_MOUNT, &opts);
359 if (data) { 368 if (error)
360 error = parse_mount_options(data, PARSE_MOUNT, &opts); 369 return error;
361 if (error)
362 return error;
363 }
364 370
365 if (opts.newinstance) 371 if (opts.newinstance)
366 s = sget(fs_type, NULL, set_anon_super, NULL); 372 s = sget(fs_type, NULL, set_anon_super, NULL);
@@ -389,11 +395,10 @@ static int devpts_get_sb(struct file_system_type *fs_type,
389 return 0; 395 return 0;
390 396
391out_dput: 397out_dput:
392 dput(s->s_root); 398 dput(s->s_root); /* undo dget() in simple_set_mnt() */
393 399
394out_undo_sget: 400out_undo_sget:
395 up_write(&s->s_umount); 401 deactivate_locked_super(s);
396 deactivate_super(s);
397 return error; 402 return error;
398} 403}
399 404
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index ccabd5faa04d..9f0aa9883c28 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -614,9 +614,8 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
614 } 614 }
615 goto out; 615 goto out;
616out_abort: 616out_abort:
617 dput(sb->s_root); 617 dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */
618 up_write(&sb->s_umount); 618 deactivate_locked_super(sb);
619 deactivate_super(sb);
620out: 619out:
621 return rc; 620 return rc;
622} 621}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index a89f370fadb5..5458e80fc558 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -1212,7 +1212,7 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
1212 1212
1213SYSCALL_DEFINE1(epoll_create, int, size) 1213SYSCALL_DEFINE1(epoll_create, int, size)
1214{ 1214{
1215 if (size < 0) 1215 if (size <= 0)
1216 return -EINVAL; 1216 return -EINVAL;
1217 1217
1218 return sys_epoll_create1(0); 1218 return sys_epoll_create1(0);
diff --git a/fs/exec.c b/fs/exec.c
index 618d6d1e2c52..a7fcd975c6b2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -105,41 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
105SYSCALL_DEFINE1(uselib, const char __user *, library) 105SYSCALL_DEFINE1(uselib, const char __user *, library)
106{ 106{
107 struct file *file; 107 struct file *file;
108 struct nameidata nd;
109 char *tmp = getname(library); 108 char *tmp = getname(library);
110 int error = PTR_ERR(tmp); 109 int error = PTR_ERR(tmp);
111 110
112 if (!IS_ERR(tmp)) { 111 if (IS_ERR(tmp))
113 error = path_lookup_open(AT_FDCWD, tmp, 112 goto out;
114 LOOKUP_FOLLOW, &nd, 113
115 FMODE_READ|FMODE_EXEC); 114 file = do_filp_open(AT_FDCWD, tmp,
116 putname(tmp); 115 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
117 } 116 MAY_READ | MAY_EXEC | MAY_OPEN);
118 if (error) 117 putname(tmp);
118 error = PTR_ERR(file);
119 if (IS_ERR(file))
119 goto out; 120 goto out;
120 121
121 error = -EINVAL; 122 error = -EINVAL;
122 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 123 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
123 goto exit; 124 goto exit;
124 125
125 error = -EACCES; 126 error = -EACCES;
126 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 127 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
127 goto exit;
128
129 error = inode_permission(nd.path.dentry->d_inode,
130 MAY_READ | MAY_EXEC | MAY_OPEN);
131 if (error)
132 goto exit;
133 error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN,
134 IMA_COUNT_UPDATE);
135 if (error)
136 goto exit; 128 goto exit;
137 129
138 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
139 error = PTR_ERR(file);
140 if (IS_ERR(file))
141 goto out;
142
143 fsnotify_open(file->f_path.dentry); 130 fsnotify_open(file->f_path.dentry);
144 131
145 error = -ENOEXEC; 132 error = -ENOEXEC;
@@ -161,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
161 } 148 }
162 read_unlock(&binfmt_lock); 149 read_unlock(&binfmt_lock);
163 } 150 }
151exit:
164 fput(file); 152 fput(file);
165out: 153out:
166 return error; 154 return error;
167exit:
168 release_open_intent(&nd);
169 path_put(&nd.path);
170 goto out;
171} 155}
172 156
173#ifdef CONFIG_MMU 157#ifdef CONFIG_MMU
@@ -662,47 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);
662 646
663struct file *open_exec(const char *name) 647struct file *open_exec(const char *name)
664{ 648{
665 struct nameidata nd;
666 struct file *file; 649 struct file *file;
667 int err; 650 int err;
668 651
669 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, 652 file = do_filp_open(AT_FDCWD, name,
670 FMODE_READ|FMODE_EXEC); 653 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
671 if (err) 654 MAY_EXEC | MAY_OPEN);
655 if (IS_ERR(file))
672 goto out; 656 goto out;
673 657
674 err = -EACCES; 658 err = -EACCES;
675 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 659 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
676 goto out_path_put; 660 goto exit;
677
678 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
679 goto out_path_put;
680
681 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
682 if (err)
683 goto out_path_put;
684 err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN, IMA_COUNT_UPDATE);
685 if (err)
686 goto out_path_put;
687 661
688 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 662 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
689 if (IS_ERR(file)) 663 goto exit;
690 return file;
691 664
692 fsnotify_open(file->f_path.dentry); 665 fsnotify_open(file->f_path.dentry);
693 666
694 err = deny_write_access(file); 667 err = deny_write_access(file);
695 if (err) { 668 if (err)
696 fput(file); 669 goto exit;
697 goto out;
698 }
699 670
671out:
700 return file; 672 return file;
701 673
702 out_path_put: 674exit:
703 release_open_intent(&nd); 675 fput(file);
704 path_put(&nd.path);
705 out:
706 return ERR_PTR(err); 676 return ERR_PTR(err);
707} 677}
708EXPORT_SYMBOL(open_exec); 678EXPORT_SYMBOL(open_exec);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index e40332158340..e3a55eb8b26a 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1841,11 +1841,13 @@ ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block,
1841{ 1841{
1842 struct ext4_ext_cache *cex; 1842 struct ext4_ext_cache *cex;
1843 BUG_ON(len == 0); 1843 BUG_ON(len == 0);
1844 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1844 cex = &EXT4_I(inode)->i_cached_extent; 1845 cex = &EXT4_I(inode)->i_cached_extent;
1845 cex->ec_type = type; 1846 cex->ec_type = type;
1846 cex->ec_block = block; 1847 cex->ec_block = block;
1847 cex->ec_len = len; 1848 cex->ec_len = len;
1848 cex->ec_start = start; 1849 cex->ec_start = start;
1850 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1849} 1851}
1850 1852
1851/* 1853/*
@@ -1902,12 +1904,17 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
1902 struct ext4_extent *ex) 1904 struct ext4_extent *ex)
1903{ 1905{
1904 struct ext4_ext_cache *cex; 1906 struct ext4_ext_cache *cex;
1907 int ret = EXT4_EXT_CACHE_NO;
1905 1908
1909 /*
1910 * We borrow i_block_reservation_lock to protect i_cached_extent
1911 */
1912 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1906 cex = &EXT4_I(inode)->i_cached_extent; 1913 cex = &EXT4_I(inode)->i_cached_extent;
1907 1914
1908 /* has cache valid data? */ 1915 /* has cache valid data? */
1909 if (cex->ec_type == EXT4_EXT_CACHE_NO) 1916 if (cex->ec_type == EXT4_EXT_CACHE_NO)
1910 return EXT4_EXT_CACHE_NO; 1917 goto errout;
1911 1918
1912 BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP && 1919 BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&
1913 cex->ec_type != EXT4_EXT_CACHE_EXTENT); 1920 cex->ec_type != EXT4_EXT_CACHE_EXTENT);
@@ -1918,11 +1925,11 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
1918 ext_debug("%u cached by %u:%u:%llu\n", 1925 ext_debug("%u cached by %u:%u:%llu\n",
1919 block, 1926 block,
1920 cex->ec_block, cex->ec_len, cex->ec_start); 1927 cex->ec_block, cex->ec_len, cex->ec_start);
1921 return cex->ec_type; 1928 ret = cex->ec_type;
1922 } 1929 }
1923 1930errout:
1924 /* not in cache */ 1931 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1925 return EXT4_EXT_CACHE_NO; 1932 return ret;
1926} 1933}
1927 1934
1928/* 1935/*
@@ -2875,6 +2882,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2875 if (allocated > max_blocks) 2882 if (allocated > max_blocks)
2876 allocated = max_blocks; 2883 allocated = max_blocks;
2877 set_buffer_unwritten(bh_result); 2884 set_buffer_unwritten(bh_result);
2885 bh_result->b_bdev = inode->i_sb->s_bdev;
2886 bh_result->b_blocknr = newblock;
2878 goto out2; 2887 goto out2;
2879 } 2888 }
2880 2889
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index e91f978c7f12..2a9ffd528dd1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1149,6 +1149,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
1149 int retval; 1149 int retval;
1150 1150
1151 clear_buffer_mapped(bh); 1151 clear_buffer_mapped(bh);
1152 clear_buffer_unwritten(bh);
1152 1153
1153 /* 1154 /*
1154 * Try to see if we can get the block without requesting 1155 * Try to see if we can get the block without requesting
@@ -1179,6 +1180,18 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
1179 return retval; 1180 return retval;
1180 1181
1181 /* 1182 /*
1183 * When we call get_blocks without the create flag, the
1184 * BH_Unwritten flag could have gotten set if the blocks
1185 * requested were part of a uninitialized extent. We need to
1186 * clear this flag now that we are committed to convert all or
1187 * part of the uninitialized extent to be an initialized
1188 * extent. This is because we need to avoid the combination
1189 * of BH_Unwritten and BH_Mapped flags being simultaneously
1190 * set on the buffer_head.
1191 */
1192 clear_buffer_unwritten(bh);
1193
1194 /*
1182 * New blocks allocate and/or writing to uninitialized extent 1195 * New blocks allocate and/or writing to uninitialized extent
1183 * will possibly result in updating i_data, so we take 1196 * will possibly result in updating i_data, so we take
1184 * the write lock of i_data_sem, and call get_blocks() 1197 * the write lock of i_data_sem, and call get_blocks()
@@ -2297,6 +2310,10 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
2297 struct buffer_head *bh_result, int create) 2310 struct buffer_head *bh_result, int create)
2298{ 2311{
2299 int ret = 0; 2312 int ret = 0;
2313 sector_t invalid_block = ~((sector_t) 0xffff);
2314
2315 if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es))
2316 invalid_block = ~0;
2300 2317
2301 BUG_ON(create == 0); 2318 BUG_ON(create == 0);
2302 BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize); 2319 BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize);
@@ -2318,11 +2335,18 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
2318 /* not enough space to reserve */ 2335 /* not enough space to reserve */
2319 return ret; 2336 return ret;
2320 2337
2321 map_bh(bh_result, inode->i_sb, 0); 2338 map_bh(bh_result, inode->i_sb, invalid_block);
2322 set_buffer_new(bh_result); 2339 set_buffer_new(bh_result);
2323 set_buffer_delay(bh_result); 2340 set_buffer_delay(bh_result);
2324 } else if (ret > 0) { 2341 } else if (ret > 0) {
2325 bh_result->b_size = (ret << inode->i_blkbits); 2342 bh_result->b_size = (ret << inode->i_blkbits);
2343 /*
2344 * With sub-block writes into unwritten extents
2345 * we also need to mark the buffer as new so that
2346 * the unwritten parts of the buffer gets correctly zeroed.
2347 */
2348 if (buffer_unwritten(bh_result))
2349 set_buffer_new(bh_result);
2326 ret = 0; 2350 ret = 0;
2327 } 2351 }
2328 2352
diff --git a/fs/fcntl.c b/fs/fcntl.c
index cc8e4de2fee5..1ad703150dee 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -117,11 +117,13 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
117{ 117{
118 if (unlikely(newfd == oldfd)) { /* corner case */ 118 if (unlikely(newfd == oldfd)) { /* corner case */
119 struct files_struct *files = current->files; 119 struct files_struct *files = current->files;
120 int retval = oldfd;
121
120 rcu_read_lock(); 122 rcu_read_lock();
121 if (!fcheck_files(files, oldfd)) 123 if (!fcheck_files(files, oldfd))
122 oldfd = -EBADF; 124 retval = -EBADF;
123 rcu_read_unlock(); 125 rcu_read_unlock();
124 return oldfd; 126 return retval;
125 } 127 }
126 return sys_dup3(oldfd, newfd, 0); 128 return sys_dup3(oldfd, newfd, 0);
127} 129}
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 459b73dd45e1..91f7c85f1ffd 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -19,6 +19,7 @@
19#include <linux/random.h> 19#include <linux/random.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/exportfs.h> 21#include <linux/exportfs.h>
22#include <linux/smp_lock.h>
22 23
23MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); 24MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
24MODULE_DESCRIPTION("Filesystem in Userspace"); 25MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -259,7 +260,9 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
259 260
260static void fuse_umount_begin(struct super_block *sb) 261static void fuse_umount_begin(struct super_block *sb)
261{ 262{
263 lock_kernel();
262 fuse_abort_conn(get_fuse_conn_super(sb)); 264 fuse_abort_conn(get_fuse_conn_super(sb));
265 unlock_kernel();
263} 266}
264 267
265static void fuse_send_destroy(struct fuse_conn *fc) 268static void fuse_send_destroy(struct fuse_conn *fc)
@@ -908,6 +911,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
908 err_put_root: 911 err_put_root:
909 dput(root_dentry); 912 dput(root_dentry);
910 err_put_conn: 913 err_put_conn:
914 bdi_destroy(&fc->bdi);
911 fuse_conn_put(fc); 915 fuse_conn_put(fc);
912 err_fput: 916 err_fput:
913 fput(file); 917 fput(file);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1afd9f26bcb1..ff4981090489 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1304,6 +1304,7 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
1304 nr--; 1304 nr--;
1305 if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) 1305 if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
1306 gfs2_glock_put(gl); 1306 gfs2_glock_put(gl);
1307 got_ref = 0;
1307 } 1308 }
1308 spin_lock(&lru_lock); 1309 spin_lock(&lru_lock);
1309 if (may_demote) 1310 if (may_demote)
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 650a730707b7..1ff9473ea753 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1282,21 +1282,21 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
1282static struct super_block *get_gfs2_sb(const char *dev_name) 1282static struct super_block *get_gfs2_sb(const char *dev_name)
1283{ 1283{
1284 struct super_block *sb; 1284 struct super_block *sb;
1285 struct nameidata nd; 1285 struct path path;
1286 int error; 1286 int error;
1287 1287
1288 error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); 1288 error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
1289 if (error) { 1289 if (error) {
1290 printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n", 1290 printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
1291 dev_name, error); 1291 dev_name, error);
1292 return NULL; 1292 return NULL;
1293 } 1293 }
1294 sb = nd.path.dentry->d_inode->i_sb; 1294 sb = path.dentry->d_inode->i_sb;
1295 if (sb && (sb->s_type == &gfs2_fs_type)) 1295 if (sb && (sb->s_type == &gfs2_fs_type))
1296 atomic_inc(&sb->s_active); 1296 atomic_inc(&sb->s_active);
1297 else 1297 else
1298 sb = NULL; 1298 sb = NULL;
1299 path_put(&nd.path); 1299 path_put(&path);
1300 return sb; 1300 return sb;
1301} 1301}
1302 1302
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index fecf402d7b8a..fc77965be841 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -423,8 +423,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
423 423
424 if (!(*flags & MS_RDONLY)) mark_dirty(s); 424 if (!(*flags & MS_RDONLY)) mark_dirty(s);
425 425
426 kfree(s->s_options); 426 replace_mount_options(s, new_opts);
427 s->s_options = new_opts;
428 427
429 return 0; 428 return 0;
430 429
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index ccc62de96df8..941c8425c10b 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -313,16 +313,6 @@ out:
313 return retval; 313 return retval;
314} 314}
315 315
316/*
317 * Read a page. Again trivial. If it didn't already exist
318 * in the page cache, it is zero-filled.
319 */
320static int hugetlbfs_readpage(struct file *file, struct page * page)
321{
322 unlock_page(page);
323 return -EINVAL;
324}
325
326static int hugetlbfs_write_begin(struct file *file, 316static int hugetlbfs_write_begin(struct file *file,
327 struct address_space *mapping, 317 struct address_space *mapping,
328 loff_t pos, unsigned len, unsigned flags, 318 loff_t pos, unsigned len, unsigned flags,
@@ -702,7 +692,6 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
702} 692}
703 693
704static const struct address_space_operations hugetlbfs_aops = { 694static const struct address_space_operations hugetlbfs_aops = {
705 .readpage = hugetlbfs_readpage,
706 .write_begin = hugetlbfs_write_begin, 695 .write_begin = hugetlbfs_write_begin,
707 .write_end = hugetlbfs_write_end, 696 .write_end = hugetlbfs_write_end,
708 .set_page_dirty = hugetlbfs_set_page_dirty, 697 .set_page_dirty = hugetlbfs_set_page_dirty,
diff --git a/fs/inode.c b/fs/inode.c
index 6ad14a1cd8c9..0571983755dc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -99,7 +99,7 @@ static DEFINE_MUTEX(iprune_mutex);
99 */ 99 */
100struct inodes_stat_t inodes_stat; 100struct inodes_stat_t inodes_stat;
101 101
102static struct kmem_cache * inode_cachep __read_mostly; 102static struct kmem_cache *inode_cachep __read_mostly;
103 103
104static void wake_up_inode(struct inode *inode) 104static void wake_up_inode(struct inode *inode)
105{ 105{
@@ -124,7 +124,7 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
124 static struct inode_operations empty_iops; 124 static struct inode_operations empty_iops;
125 static const struct file_operations empty_fops; 125 static const struct file_operations empty_fops;
126 126
127 struct address_space * const mapping = &inode->i_data; 127 struct address_space *const mapping = &inode->i_data;
128 128
129 inode->i_sb = sb; 129 inode->i_sb = sb;
130 inode->i_blkbits = sb->s_blocksize_bits; 130 inode->i_blkbits = sb->s_blocksize_bits;
@@ -216,7 +216,7 @@ static struct inode *alloc_inode(struct super_block *sb)
216 return NULL; 216 return NULL;
217} 217}
218 218
219void destroy_inode(struct inode *inode) 219void destroy_inode(struct inode *inode)
220{ 220{
221 BUG_ON(inode_has_buffers(inode)); 221 BUG_ON(inode_has_buffers(inode));
222 security_inode_free(inode); 222 security_inode_free(inode);
@@ -252,12 +252,11 @@ void inode_init_once(struct inode *inode)
252 mutex_init(&inode->inotify_mutex); 252 mutex_init(&inode->inotify_mutex);
253#endif 253#endif
254} 254}
255
256EXPORT_SYMBOL(inode_init_once); 255EXPORT_SYMBOL(inode_init_once);
257 256
258static void init_once(void *foo) 257static void init_once(void *foo)
259{ 258{
260 struct inode * inode = (struct inode *) foo; 259 struct inode *inode = (struct inode *) foo;
261 260
262 inode_init_once(inode); 261 inode_init_once(inode);
263} 262}
@@ -265,7 +264,7 @@ static void init_once(void *foo)
265/* 264/*
266 * inode_lock must be held 265 * inode_lock must be held
267 */ 266 */
268void __iget(struct inode * inode) 267void __iget(struct inode *inode)
269{ 268{
270 if (atomic_read(&inode->i_count)) { 269 if (atomic_read(&inode->i_count)) {
271 atomic_inc(&inode->i_count); 270 atomic_inc(&inode->i_count);
@@ -289,7 +288,7 @@ void clear_inode(struct inode *inode)
289{ 288{
290 might_sleep(); 289 might_sleep();
291 invalidate_inode_buffers(inode); 290 invalidate_inode_buffers(inode);
292 291
293 BUG_ON(inode->i_data.nrpages); 292 BUG_ON(inode->i_data.nrpages);
294 BUG_ON(!(inode->i_state & I_FREEING)); 293 BUG_ON(!(inode->i_state & I_FREEING));
295 BUG_ON(inode->i_state & I_CLEAR); 294 BUG_ON(inode->i_state & I_CLEAR);
@@ -303,7 +302,6 @@ void clear_inode(struct inode *inode)
303 cd_forget(inode); 302 cd_forget(inode);
304 inode->i_state = I_CLEAR; 303 inode->i_state = I_CLEAR;
305} 304}
306
307EXPORT_SYMBOL(clear_inode); 305EXPORT_SYMBOL(clear_inode);
308 306
309/* 307/*
@@ -351,8 +349,8 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
351 349
352 next = head->next; 350 next = head->next;
353 for (;;) { 351 for (;;) {
354 struct list_head * tmp = next; 352 struct list_head *tmp = next;
355 struct inode * inode; 353 struct inode *inode;
356 354
357 /* 355 /*
358 * We can reschedule here without worrying about the list's 356 * We can reschedule here without worrying about the list's
@@ -391,7 +389,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
391 * fails because there are busy inodes then a non zero value is returned. 389 * fails because there are busy inodes then a non zero value is returned.
392 * If the discard is successful all the inodes have been discarded. 390 * If the discard is successful all the inodes have been discarded.
393 */ 391 */
394int invalidate_inodes(struct super_block * sb) 392int invalidate_inodes(struct super_block *sb)
395{ 393{
396 int busy; 394 int busy;
397 LIST_HEAD(throw_away); 395 LIST_HEAD(throw_away);
@@ -407,7 +405,6 @@ int invalidate_inodes(struct super_block * sb)
407 405
408 return busy; 406 return busy;
409} 407}
410
411EXPORT_SYMBOL(invalidate_inodes); 408EXPORT_SYMBOL(invalidate_inodes);
412 409
413static int can_unuse(struct inode *inode) 410static int can_unuse(struct inode *inode)
@@ -504,7 +501,7 @@ static int shrink_icache_memory(int nr, gfp_t gfp_mask)
504 * Nasty deadlock avoidance. We may hold various FS locks, 501 * Nasty deadlock avoidance. We may hold various FS locks,
505 * and we don't want to recurse into the FS that called us 502 * and we don't want to recurse into the FS that called us
506 * in clear_inode() and friends.. 503 * in clear_inode() and friends..
507 */ 504 */
508 if (!(gfp_mask & __GFP_FS)) 505 if (!(gfp_mask & __GFP_FS))
509 return -1; 506 return -1;
510 prune_icache(nr); 507 prune_icache(nr);
@@ -524,10 +521,13 @@ static void __wait_on_freeing_inode(struct inode *inode);
524 * by hand after calling find_inode now! This simplifies iunique and won't 521 * by hand after calling find_inode now! This simplifies iunique and won't
525 * add any additional branch in the common code. 522 * add any additional branch in the common code.
526 */ 523 */
527static struct inode * find_inode(struct super_block * sb, struct hlist_head *head, int (*test)(struct inode *, void *), void *data) 524static struct inode *find_inode(struct super_block *sb,
525 struct hlist_head *head,
526 int (*test)(struct inode *, void *),
527 void *data)
528{ 528{
529 struct hlist_node *node; 529 struct hlist_node *node;
530 struct inode * inode = NULL; 530 struct inode *inode = NULL;
531 531
532repeat: 532repeat:
533 hlist_for_each_entry(inode, node, head, i_hash) { 533 hlist_for_each_entry(inode, node, head, i_hash) {
@@ -548,10 +548,11 @@ repeat:
548 * find_inode_fast is the fast path version of find_inode, see the comment at 548 * find_inode_fast is the fast path version of find_inode, see the comment at
549 * iget_locked for details. 549 * iget_locked for details.
550 */ 550 */
551static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head *head, unsigned long ino) 551static struct inode *find_inode_fast(struct super_block *sb,
552 struct hlist_head *head, unsigned long ino)
552{ 553{
553 struct hlist_node *node; 554 struct hlist_node *node;
554 struct inode * inode = NULL; 555 struct inode *inode = NULL;
555 556
556repeat: 557repeat:
557 hlist_for_each_entry(inode, node, head, i_hash) { 558 hlist_for_each_entry(inode, node, head, i_hash) {
@@ -631,10 +632,10 @@ struct inode *new_inode(struct super_block *sb)
631 * here to attempt to avoid that. 632 * here to attempt to avoid that.
632 */ 633 */
633 static unsigned int last_ino; 634 static unsigned int last_ino;
634 struct inode * inode; 635 struct inode *inode;
635 636
636 spin_lock_prefetch(&inode_lock); 637 spin_lock_prefetch(&inode_lock);
637 638
638 inode = alloc_inode(sb); 639 inode = alloc_inode(sb);
639 if (inode) { 640 if (inode) {
640 spin_lock(&inode_lock); 641 spin_lock(&inode_lock);
@@ -645,7 +646,6 @@ struct inode *new_inode(struct super_block *sb)
645 } 646 }
646 return inode; 647 return inode;
647} 648}
648
649EXPORT_SYMBOL(new_inode); 649EXPORT_SYMBOL(new_inode);
650 650
651void unlock_new_inode(struct inode *inode) 651void unlock_new_inode(struct inode *inode)
@@ -674,7 +674,6 @@ void unlock_new_inode(struct inode *inode)
674 inode->i_state &= ~(I_LOCK|I_NEW); 674 inode->i_state &= ~(I_LOCK|I_NEW);
675 wake_up_inode(inode); 675 wake_up_inode(inode);
676} 676}
677
678EXPORT_SYMBOL(unlock_new_inode); 677EXPORT_SYMBOL(unlock_new_inode);
679 678
680/* 679/*
@@ -683,13 +682,17 @@ EXPORT_SYMBOL(unlock_new_inode);
683 * We no longer cache the sb_flags in i_flags - see fs.h 682 * We no longer cache the sb_flags in i_flags - see fs.h
684 * -- rmk@arm.uk.linux.org 683 * -- rmk@arm.uk.linux.org
685 */ 684 */
686static struct inode * get_new_inode(struct super_block *sb, struct hlist_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data) 685static struct inode *get_new_inode(struct super_block *sb,
686 struct hlist_head *head,
687 int (*test)(struct inode *, void *),
688 int (*set)(struct inode *, void *),
689 void *data)
687{ 690{
688 struct inode * inode; 691 struct inode *inode;
689 692
690 inode = alloc_inode(sb); 693 inode = alloc_inode(sb);
691 if (inode) { 694 if (inode) {
692 struct inode * old; 695 struct inode *old;
693 696
694 spin_lock(&inode_lock); 697 spin_lock(&inode_lock);
695 /* We released the lock, so.. */ 698 /* We released the lock, so.. */
@@ -731,13 +734,14 @@ set_failed:
731 * get_new_inode_fast is the fast path version of get_new_inode, see the 734 * get_new_inode_fast is the fast path version of get_new_inode, see the
732 * comment at iget_locked for details. 735 * comment at iget_locked for details.
733 */ 736 */
734static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_head *head, unsigned long ino) 737static struct inode *get_new_inode_fast(struct super_block *sb,
738 struct hlist_head *head, unsigned long ino)
735{ 739{
736 struct inode * inode; 740 struct inode *inode;
737 741
738 inode = alloc_inode(sb); 742 inode = alloc_inode(sb);
739 if (inode) { 743 if (inode) {
740 struct inode * old; 744 struct inode *old;
741 745
742 spin_lock(&inode_lock); 746 spin_lock(&inode_lock);
743 /* We released the lock, so.. */ 747 /* We released the lock, so.. */
@@ -823,7 +827,6 @@ struct inode *igrab(struct inode *inode)
823 spin_unlock(&inode_lock); 827 spin_unlock(&inode_lock);
824 return inode; 828 return inode;
825} 829}
826
827EXPORT_SYMBOL(igrab); 830EXPORT_SYMBOL(igrab);
828 831
829/** 832/**
@@ -924,7 +927,6 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
924 927
925 return ifind(sb, head, test, data, 0); 928 return ifind(sb, head, test, data, 0);
926} 929}
927
928EXPORT_SYMBOL(ilookup5_nowait); 930EXPORT_SYMBOL(ilookup5_nowait);
929 931
930/** 932/**
@@ -953,7 +955,6 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
953 955
954 return ifind(sb, head, test, data, 1); 956 return ifind(sb, head, test, data, 1);
955} 957}
956
957EXPORT_SYMBOL(ilookup5); 958EXPORT_SYMBOL(ilookup5);
958 959
959/** 960/**
@@ -976,7 +977,6 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
976 977
977 return ifind_fast(sb, head, ino); 978 return ifind_fast(sb, head, ino);
978} 979}
979
980EXPORT_SYMBOL(ilookup); 980EXPORT_SYMBOL(ilookup);
981 981
982/** 982/**
@@ -1015,7 +1015,6 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
1015 */ 1015 */
1016 return get_new_inode(sb, head, test, set, data); 1016 return get_new_inode(sb, head, test, set, data);
1017} 1017}
1018
1019EXPORT_SYMBOL(iget5_locked); 1018EXPORT_SYMBOL(iget5_locked);
1020 1019
1021/** 1020/**
@@ -1047,7 +1046,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
1047 */ 1046 */
1048 return get_new_inode_fast(sb, head, ino); 1047 return get_new_inode_fast(sb, head, ino);
1049} 1048}
1050
1051EXPORT_SYMBOL(iget_locked); 1049EXPORT_SYMBOL(iget_locked);
1052 1050
1053int insert_inode_locked(struct inode *inode) 1051int insert_inode_locked(struct inode *inode)
@@ -1076,7 +1074,6 @@ int insert_inode_locked(struct inode *inode)
1076 iput(old); 1074 iput(old);
1077 } 1075 }
1078} 1076}
1079
1080EXPORT_SYMBOL(insert_inode_locked); 1077EXPORT_SYMBOL(insert_inode_locked);
1081 1078
1082int insert_inode_locked4(struct inode *inode, unsigned long hashval, 1079int insert_inode_locked4(struct inode *inode, unsigned long hashval,
@@ -1106,7 +1103,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
1106 iput(old); 1103 iput(old);
1107 } 1104 }
1108} 1105}
1109
1110EXPORT_SYMBOL(insert_inode_locked4); 1106EXPORT_SYMBOL(insert_inode_locked4);
1111 1107
1112/** 1108/**
@@ -1124,7 +1120,6 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval)
1124 hlist_add_head(&inode->i_hash, head); 1120 hlist_add_head(&inode->i_hash, head);
1125 spin_unlock(&inode_lock); 1121 spin_unlock(&inode_lock);
1126} 1122}
1127
1128EXPORT_SYMBOL(__insert_inode_hash); 1123EXPORT_SYMBOL(__insert_inode_hash);
1129 1124
1130/** 1125/**
@@ -1139,7 +1134,6 @@ void remove_inode_hash(struct inode *inode)
1139 hlist_del_init(&inode->i_hash); 1134 hlist_del_init(&inode->i_hash);
1140 spin_unlock(&inode_lock); 1135 spin_unlock(&inode_lock);
1141} 1136}
1142
1143EXPORT_SYMBOL(remove_inode_hash); 1137EXPORT_SYMBOL(remove_inode_hash);
1144 1138
1145/* 1139/*
@@ -1187,7 +1181,6 @@ void generic_delete_inode(struct inode *inode)
1187 BUG_ON(inode->i_state != I_CLEAR); 1181 BUG_ON(inode->i_state != I_CLEAR);
1188 destroy_inode(inode); 1182 destroy_inode(inode);
1189} 1183}
1190
1191EXPORT_SYMBOL(generic_delete_inode); 1184EXPORT_SYMBOL(generic_delete_inode);
1192 1185
1193static void generic_forget_inode(struct inode *inode) 1186static void generic_forget_inode(struct inode *inode)
@@ -1237,12 +1230,11 @@ void generic_drop_inode(struct inode *inode)
1237 else 1230 else
1238 generic_forget_inode(inode); 1231 generic_forget_inode(inode);
1239} 1232}
1240
1241EXPORT_SYMBOL_GPL(generic_drop_inode); 1233EXPORT_SYMBOL_GPL(generic_drop_inode);
1242 1234
1243/* 1235/*
1244 * Called when we're dropping the last reference 1236 * Called when we're dropping the last reference
1245 * to an inode. 1237 * to an inode.
1246 * 1238 *
1247 * Call the FS "drop()" function, defaulting to 1239 * Call the FS "drop()" function, defaulting to
1248 * the legacy UNIX filesystem behaviour.. 1240 * the legacy UNIX filesystem behaviour..
@@ -1262,7 +1254,7 @@ static inline void iput_final(struct inode *inode)
1262} 1254}
1263 1255
1264/** 1256/**
1265 * iput - put an inode 1257 * iput - put an inode
1266 * @inode: inode to put 1258 * @inode: inode to put
1267 * 1259 *
1268 * Puts an inode, dropping its usage count. If the inode use count hits 1260 * Puts an inode, dropping its usage count. If the inode use count hits
@@ -1279,7 +1271,6 @@ void iput(struct inode *inode)
1279 iput_final(inode); 1271 iput_final(inode);
1280 } 1272 }
1281} 1273}
1282
1283EXPORT_SYMBOL(iput); 1274EXPORT_SYMBOL(iput);
1284 1275
1285/** 1276/**
@@ -1290,10 +1281,10 @@ EXPORT_SYMBOL(iput);
1290 * Returns the block number on the device holding the inode that 1281 * Returns the block number on the device holding the inode that
1291 * is the disk block number for the block of the file requested. 1282 * is the disk block number for the block of the file requested.
1292 * That is, asked for block 4 of inode 1 the function will return the 1283 * That is, asked for block 4 of inode 1 the function will return the
1293 * disk block relative to the disk start that holds that block of the 1284 * disk block relative to the disk start that holds that block of the
1294 * file. 1285 * file.
1295 */ 1286 */
1296sector_t bmap(struct inode * inode, sector_t block) 1287sector_t bmap(struct inode *inode, sector_t block)
1297{ 1288{
1298 sector_t res = 0; 1289 sector_t res = 0;
1299 if (inode->i_mapping->a_ops->bmap) 1290 if (inode->i_mapping->a_ops->bmap)
@@ -1425,7 +1416,6 @@ void file_update_time(struct file *file)
1425 mark_inode_dirty_sync(inode); 1416 mark_inode_dirty_sync(inode);
1426 mnt_drop_write(file->f_path.mnt); 1417 mnt_drop_write(file->f_path.mnt);
1427} 1418}
1428
1429EXPORT_SYMBOL(file_update_time); 1419EXPORT_SYMBOL(file_update_time);
1430 1420
1431int inode_needs_sync(struct inode *inode) 1421int inode_needs_sync(struct inode *inode)
@@ -1436,7 +1426,6 @@ int inode_needs_sync(struct inode *inode)
1436 return 1; 1426 return 1;
1437 return 0; 1427 return 0;
1438} 1428}
1439
1440EXPORT_SYMBOL(inode_needs_sync); 1429EXPORT_SYMBOL(inode_needs_sync);
1441 1430
1442int inode_wait(void *word) 1431int inode_wait(void *word)
diff --git a/fs/libfs.c b/fs/libfs.c
index cd223190c4e9..80046ddf5063 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -246,8 +246,7 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
246 return 0; 246 return 0;
247 247
248Enomem: 248Enomem:
249 up_write(&s->s_umount); 249 deactivate_locked_super(s);
250 deactivate_super(s);
251 return -ENOMEM; 250 return -ENOMEM;
252} 251}
253 252
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index abf83881f68a..1a54ae14a192 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -104,6 +104,16 @@ static void set_grace_period(void)
104 schedule_delayed_work(&grace_period_end, grace_period); 104 schedule_delayed_work(&grace_period_end, grace_period);
105} 105}
106 106
107static void restart_grace(void)
108{
109 if (nlmsvc_ops) {
110 cancel_delayed_work_sync(&grace_period_end);
111 locks_end_grace(&lockd_manager);
112 nlmsvc_invalidate_all();
113 set_grace_period();
114 }
115}
116
107/* 117/*
108 * This is the lockd kernel thread 118 * This is the lockd kernel thread
109 */ 119 */
@@ -149,10 +159,7 @@ lockd(void *vrqstp)
149 159
150 if (signalled()) { 160 if (signalled()) {
151 flush_signals(current); 161 flush_signals(current);
152 if (nlmsvc_ops) { 162 restart_grace();
153 nlmsvc_invalidate_all();
154 set_grace_period();
155 }
156 continue; 163 continue;
157 } 164 }
158 165
diff --git a/fs/namei.c b/fs/namei.c
index b05a2b1dea64..c82805d088e1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1131,8 +1131,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1131 * @nd: pointer to nameidata 1131 * @nd: pointer to nameidata
1132 * @open_flags: open intent flags 1132 * @open_flags: open intent flags
1133 */ 1133 */
1134int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags, 1134static int path_lookup_open(int dfd, const char *name,
1135 struct nameidata *nd, int open_flags) 1135 unsigned int lookup_flags, struct nameidata *nd, int open_flags)
1136{ 1136{
1137 struct file *filp = get_empty_filp(); 1137 struct file *filp = get_empty_filp();
1138 int err; 1138 int err;
@@ -1639,18 +1639,19 @@ static int open_will_write_to_fs(int flag, struct inode *inode)
1639 * open_to_namei_flags() for more details. 1639 * open_to_namei_flags() for more details.
1640 */ 1640 */
1641struct file *do_filp_open(int dfd, const char *pathname, 1641struct file *do_filp_open(int dfd, const char *pathname,
1642 int open_flag, int mode) 1642 int open_flag, int mode, int acc_mode)
1643{ 1643{
1644 struct file *filp; 1644 struct file *filp;
1645 struct nameidata nd; 1645 struct nameidata nd;
1646 int acc_mode, error; 1646 int error;
1647 struct path path; 1647 struct path path;
1648 struct dentry *dir; 1648 struct dentry *dir;
1649 int count = 0; 1649 int count = 0;
1650 int will_write; 1650 int will_write;
1651 int flag = open_to_namei_flags(open_flag); 1651 int flag = open_to_namei_flags(open_flag);
1652 1652
1653 acc_mode = MAY_OPEN | ACC_MODE(flag); 1653 if (!acc_mode)
1654 acc_mode = MAY_OPEN | ACC_MODE(flag);
1654 1655
1655 /* O_TRUNC implies we need access checks for write permissions */ 1656 /* O_TRUNC implies we need access checks for write permissions */
1656 if (flag & O_TRUNC) 1657 if (flag & O_TRUNC)
@@ -1871,7 +1872,7 @@ do_link:
1871 */ 1872 */
1872struct file *filp_open(const char *filename, int flags, int mode) 1873struct file *filp_open(const char *filename, int flags, int mode)
1873{ 1874{
1874 return do_filp_open(AT_FDCWD, filename, flags, mode); 1875 return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
1875} 1876}
1876EXPORT_SYMBOL(filp_open); 1877EXPORT_SYMBOL(filp_open);
1877 1878
diff --git a/fs/namespace.c b/fs/namespace.c
index 41196209a906..134d494158d9 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -695,12 +695,16 @@ static inline void mangle(struct seq_file *m, const char *s)
695 */ 695 */
696int generic_show_options(struct seq_file *m, struct vfsmount *mnt) 696int generic_show_options(struct seq_file *m, struct vfsmount *mnt)
697{ 697{
698 const char *options = mnt->mnt_sb->s_options; 698 const char *options;
699
700 rcu_read_lock();
701 options = rcu_dereference(mnt->mnt_sb->s_options);
699 702
700 if (options != NULL && options[0]) { 703 if (options != NULL && options[0]) {
701 seq_putc(m, ','); 704 seq_putc(m, ',');
702 mangle(m, options); 705 mangle(m, options);
703 } 706 }
707 rcu_read_unlock();
704 708
705 return 0; 709 return 0;
706} 710}
@@ -721,11 +725,22 @@ EXPORT_SYMBOL(generic_show_options);
721 */ 725 */
722void save_mount_options(struct super_block *sb, char *options) 726void save_mount_options(struct super_block *sb, char *options)
723{ 727{
724 kfree(sb->s_options); 728 BUG_ON(sb->s_options);
725 sb->s_options = kstrdup(options, GFP_KERNEL); 729 rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL));
726} 730}
727EXPORT_SYMBOL(save_mount_options); 731EXPORT_SYMBOL(save_mount_options);
728 732
733void replace_mount_options(struct super_block *sb, char *options)
734{
735 char *old = sb->s_options;
736 rcu_assign_pointer(sb->s_options, options);
737 if (old) {
738 synchronize_rcu();
739 kfree(old);
740 }
741}
742EXPORT_SYMBOL(replace_mount_options);
743
729#ifdef CONFIG_PROC_FS 744#ifdef CONFIG_PROC_FS
730/* iterator */ 745/* iterator */
731static void *m_start(struct seq_file *m, loff_t *pos) 746static void *m_start(struct seq_file *m, loff_t *pos)
@@ -1073,9 +1088,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
1073 */ 1088 */
1074 1089
1075 if (flags & MNT_FORCE && sb->s_op->umount_begin) { 1090 if (flags & MNT_FORCE && sb->s_op->umount_begin) {
1076 lock_kernel();
1077 sb->s_op->umount_begin(sb); 1091 sb->s_op->umount_begin(sb);
1078 unlock_kernel();
1079 } 1092 }
1080 1093
1081 /* 1094 /*
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 370b190a09d1..89f98e9a024b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1943,7 +1943,8 @@ int nfs_permission(struct inode *inode, int mask)
1943 case S_IFREG: 1943 case S_IFREG:
1944 /* NFSv4 has atomic_open... */ 1944 /* NFSv4 has atomic_open... */
1945 if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) 1945 if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
1946 && (mask & MAY_OPEN)) 1946 && (mask & MAY_OPEN)
1947 && !(mask & MAY_EXEC))
1947 goto out; 1948 goto out;
1948 break; 1949 break;
1949 case S_IFDIR: 1950 case S_IFDIR:
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 6717200923fe..d2d67781c579 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -683,9 +683,12 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
683 */ 683 */
684static void nfs_umount_begin(struct super_block *sb) 684static void nfs_umount_begin(struct super_block *sb)
685{ 685{
686 struct nfs_server *server = NFS_SB(sb); 686 struct nfs_server *server;
687 struct rpc_clnt *rpc; 687 struct rpc_clnt *rpc;
688 688
689 lock_kernel();
690
691 server = NFS_SB(sb);
689 /* -EIO all pending I/O */ 692 /* -EIO all pending I/O */
690 rpc = server->client_acl; 693 rpc = server->client_acl;
691 if (!IS_ERR(rpc)) 694 if (!IS_ERR(rpc))
@@ -693,6 +696,8 @@ static void nfs_umount_begin(struct super_block *sb)
693 rpc = server->client; 696 rpc = server->client;
694 if (!IS_ERR(rpc)) 697 if (!IS_ERR(rpc))
695 rpc_killall_tasks(rpc); 698 rpc_killall_tasks(rpc);
699
700 unlock_kernel();
696} 701}
697 702
698/* 703/*
@@ -2106,8 +2111,7 @@ out_err_nosb:
2106error_splat_root: 2111error_splat_root:
2107 dput(mntroot); 2112 dput(mntroot);
2108error_splat_super: 2113error_splat_super:
2109 up_write(&s->s_umount); 2114 deactivate_locked_super(s);
2110 deactivate_super(s);
2111 goto out; 2115 goto out;
2112} 2116}
2113 2117
@@ -2203,8 +2207,7 @@ out_err_noserver:
2203 return error; 2207 return error;
2204 2208
2205error_splat_super: 2209error_splat_super:
2206 up_write(&s->s_umount); 2210 deactivate_locked_super(s);
2207 deactivate_super(s);
2208 dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); 2211 dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
2209 return error; 2212 return error;
2210} 2213}
@@ -2464,8 +2467,7 @@ out_free:
2464error_splat_root: 2467error_splat_root:
2465 dput(mntroot); 2468 dput(mntroot);
2466error_splat_super: 2469error_splat_super:
2467 up_write(&s->s_umount); 2470 deactivate_locked_super(s);
2468 deactivate_super(s);
2469 goto out; 2471 goto out;
2470} 2472}
2471 2473
@@ -2559,8 +2561,7 @@ out_err_noserver:
2559 return error; 2561 return error;
2560 2562
2561error_splat_super: 2563error_splat_super:
2562 up_write(&s->s_umount); 2564 deactivate_locked_super(s);
2563 deactivate_super(s);
2564 dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); 2565 dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
2565 return error; 2566 return error;
2566} 2567}
@@ -2644,8 +2645,7 @@ out_err_noserver:
2644 return error; 2645 return error;
2645 2646
2646error_splat_super: 2647error_splat_super:
2647 up_write(&s->s_umount); 2648 deactivate_locked_super(s);
2648 deactivate_super(s);
2649 dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); 2649 dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
2650 return error; 2650 return error;
2651} 2651}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 5275097a7565..b5348405046b 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -229,7 +229,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
229 goto out; 229 goto out;
230 status = vfs_readdir(filp, nfsd4_build_namelist, &names); 230 status = vfs_readdir(filp, nfsd4_build_namelist, &names);
231 fput(filp); 231 fput(filp);
232 mutex_lock(&dir->d_inode->i_mutex); 232 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
233 while (!list_empty(&names)) { 233 while (!list_empty(&names)) {
234 entry = list_entry(names.next, struct name_list, list); 234 entry = list_entry(names.next, struct name_list, list);
235 235
@@ -264,7 +264,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
264 264
265 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); 265 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
266 266
267 mutex_lock(&rec_dir.dentry->d_inode->i_mutex); 267 mutex_lock_nested(&rec_dir.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
268 dentry = lookup_one_len(name, rec_dir.dentry, namlen); 268 dentry = lookup_one_len(name, rec_dir.dentry, namlen);
269 if (IS_ERR(dentry)) { 269 if (IS_ERR(dentry)) {
270 status = PTR_ERR(dentry); 270 status = PTR_ERR(dentry);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c65a27b76a9d..3b711f5147a7 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -580,7 +580,6 @@ free_session(struct kref *kref)
580 struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry; 580 struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry;
581 nfsd4_release_respages(e->ce_respages, e->ce_resused); 581 nfsd4_release_respages(e->ce_respages, e->ce_resused);
582 } 582 }
583 kfree(ses->se_slots);
584 kfree(ses); 583 kfree(ses);
585} 584}
586 585
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b820c311931c..b73549d293be 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2214,6 +2214,15 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2214 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); 2214 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
2215 if (IS_ERR(dentry)) 2215 if (IS_ERR(dentry))
2216 return nfserrno(PTR_ERR(dentry)); 2216 return nfserrno(PTR_ERR(dentry));
2217 if (!dentry->d_inode) {
2218 /*
2219 * nfsd_buffered_readdir drops the i_mutex between
2220 * readdir and calling this callback, leaving a window
2221 * where this directory entry could have gone away.
2222 */
2223 dput(dentry);
2224 return nfserr_noent;
2225 }
2217 2226
2218 exp_get(exp); 2227 exp_get(exp);
2219 /* 2228 /*
@@ -2276,6 +2285,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2276 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); 2285 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2277 int buflen; 2286 int buflen;
2278 __be32 *p = cd->buffer; 2287 __be32 *p = cd->buffer;
2288 __be32 *cookiep;
2279 __be32 nfserr = nfserr_toosmall; 2289 __be32 nfserr = nfserr_toosmall;
2280 2290
2281 /* In nfsv4, "." and ".." never make it onto the wire.. */ 2291 /* In nfsv4, "." and ".." never make it onto the wire.. */
@@ -2292,7 +2302,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2292 goto fail; 2302 goto fail;
2293 2303
2294 *p++ = xdr_one; /* mark entry present */ 2304 *p++ = xdr_one; /* mark entry present */
2295 cd->offset = p; /* remember pointer */ 2305 cookiep = p;
2296 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ 2306 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
2297 p = xdr_encode_array(p, name, namlen); /* name length & name */ 2307 p = xdr_encode_array(p, name, namlen); /* name length & name */
2298 2308
@@ -2306,6 +2316,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2306 goto fail; 2316 goto fail;
2307 case nfserr_dropit: 2317 case nfserr_dropit:
2308 goto fail; 2318 goto fail;
2319 case nfserr_noent:
2320 goto skip_entry;
2309 default: 2321 default:
2310 /* 2322 /*
2311 * If the client requested the RDATTR_ERROR attribute, 2323 * If the client requested the RDATTR_ERROR attribute,
@@ -2324,6 +2336,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2324 } 2336 }
2325 cd->buflen -= (p - cd->buffer); 2337 cd->buflen -= (p - cd->buffer);
2326 cd->buffer = p; 2338 cd->buffer = p;
2339 cd->offset = cookiep;
2340skip_entry:
2327 cd->common.err = nfs_ok; 2341 cd->common.err = nfs_ok;
2328 return 0; 2342 return 0;
2329fail: 2343fail:
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 108d281ebca5..50ff3f2cdf24 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -25,6 +25,7 @@
25#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */ 25#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */
26#include <linux/capability.h> /* capable() */ 26#include <linux/capability.h> /* capable() */
27#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */ 27#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
28#include <linux/vmalloc.h>
28#include <linux/nilfs2_fs.h> 29#include <linux/nilfs2_fs.h>
29#include "nilfs.h" 30#include "nilfs.h"
30#include "segment.h" 31#include "segment.h"
@@ -147,29 +148,12 @@ static ssize_t
147nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, 148nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
148 void *buf, size_t size, size_t nmembs) 149 void *buf, size_t size, size_t nmembs)
149{ 150{
150 return nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
151 nmembs);
152}
153
154static int nilfs_ioctl_get_cpinfo(struct inode *inode, struct file *filp,
155 unsigned int cmd, void __user *argp)
156{
157 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
158 struct nilfs_argv argv;
159 int ret; 151 int ret;
160 152
161 if (copy_from_user(&argv, argp, sizeof(argv)))
162 return -EFAULT;
163
164 down_read(&nilfs->ns_segctor_sem); 153 down_read(&nilfs->ns_segctor_sem);
165 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 154 ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
166 nilfs_ioctl_do_get_cpinfo); 155 nmembs);
167 up_read(&nilfs->ns_segctor_sem); 156 up_read(&nilfs->ns_segctor_sem);
168 if (ret < 0)
169 return ret;
170
171 if (copy_to_user(argp, &argv, sizeof(argv)))
172 ret = -EFAULT;
173 return ret; 157 return ret;
174} 158}
175 159
@@ -195,28 +179,11 @@ static ssize_t
195nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, 179nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
196 void *buf, size_t size, size_t nmembs) 180 void *buf, size_t size, size_t nmembs)
197{ 181{
198 return nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
199}
200
201static int nilfs_ioctl_get_suinfo(struct inode *inode, struct file *filp,
202 unsigned int cmd, void __user *argp)
203{
204 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
205 struct nilfs_argv argv;
206 int ret; 182 int ret;
207 183
208 if (copy_from_user(&argv, argp, sizeof(argv)))
209 return -EFAULT;
210
211 down_read(&nilfs->ns_segctor_sem); 184 down_read(&nilfs->ns_segctor_sem);
212 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 185 ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
213 nilfs_ioctl_do_get_suinfo);
214 up_read(&nilfs->ns_segctor_sem); 186 up_read(&nilfs->ns_segctor_sem);
215 if (ret < 0)
216 return ret;
217
218 if (copy_to_user(argp, &argv, sizeof(argv)))
219 ret = -EFAULT;
220 return ret; 187 return ret;
221} 188}
222 189
@@ -242,28 +209,11 @@ static ssize_t
242nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, 209nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
243 void *buf, size_t size, size_t nmembs) 210 void *buf, size_t size, size_t nmembs)
244{ 211{
245 return nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
246}
247
248static int nilfs_ioctl_get_vinfo(struct inode *inode, struct file *filp,
249 unsigned int cmd, void __user *argp)
250{
251 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
252 struct nilfs_argv argv;
253 int ret; 212 int ret;
254 213
255 if (copy_from_user(&argv, argp, sizeof(argv)))
256 return -EFAULT;
257
258 down_read(&nilfs->ns_segctor_sem); 214 down_read(&nilfs->ns_segctor_sem);
259 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 215 ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
260 nilfs_ioctl_do_get_vinfo);
261 up_read(&nilfs->ns_segctor_sem); 216 up_read(&nilfs->ns_segctor_sem);
262 if (ret < 0)
263 return ret;
264
265 if (copy_to_user(argp, &argv, sizeof(argv)))
266 ret = -EFAULT;
267 return ret; 217 return ret;
268} 218}
269 219
@@ -276,17 +226,21 @@ nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
276 struct nilfs_bdesc *bdescs = buf; 226 struct nilfs_bdesc *bdescs = buf;
277 int ret, i; 227 int ret, i;
278 228
229 down_read(&nilfs->ns_segctor_sem);
279 for (i = 0; i < nmembs; i++) { 230 for (i = 0; i < nmembs; i++) {
280 ret = nilfs_bmap_lookup_at_level(bmap, 231 ret = nilfs_bmap_lookup_at_level(bmap,
281 bdescs[i].bd_offset, 232 bdescs[i].bd_offset,
282 bdescs[i].bd_level + 1, 233 bdescs[i].bd_level + 1,
283 &bdescs[i].bd_blocknr); 234 &bdescs[i].bd_blocknr);
284 if (ret < 0) { 235 if (ret < 0) {
285 if (ret != -ENOENT) 236 if (ret != -ENOENT) {
237 up_read(&nilfs->ns_segctor_sem);
286 return ret; 238 return ret;
239 }
287 bdescs[i].bd_blocknr = 0; 240 bdescs[i].bd_blocknr = 0;
288 } 241 }
289 } 242 }
243 up_read(&nilfs->ns_segctor_sem);
290 return nmembs; 244 return nmembs;
291} 245}
292 246
@@ -300,10 +254,11 @@ static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
300 if (copy_from_user(&argv, argp, sizeof(argv))) 254 if (copy_from_user(&argv, argp, sizeof(argv)))
301 return -EFAULT; 255 return -EFAULT;
302 256
303 down_read(&nilfs->ns_segctor_sem); 257 if (argv.v_size != sizeof(struct nilfs_bdesc))
258 return -EINVAL;
259
304 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 260 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
305 nilfs_ioctl_do_get_bdescs); 261 nilfs_ioctl_do_get_bdescs);
306 up_read(&nilfs->ns_segctor_sem);
307 if (ret < 0) 262 if (ret < 0)
308 return ret; 263 return ret;
309 264
@@ -346,10 +301,10 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode,
346 return 0; 301 return 0;
347} 302}
348 303
349static ssize_t 304static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
350nilfs_ioctl_do_move_blocks(struct the_nilfs *nilfs, __u64 *posp, int flags, 305 struct nilfs_argv *argv, void *buf)
351 void *buf, size_t size, size_t nmembs)
352{ 306{
307 size_t nmembs = argv->v_nmembs;
353 struct inode *inode; 308 struct inode *inode;
354 struct nilfs_vdesc *vdesc; 309 struct nilfs_vdesc *vdesc;
355 struct buffer_head *bh, *n; 310 struct buffer_head *bh, *n;
@@ -410,19 +365,10 @@ nilfs_ioctl_do_move_blocks(struct the_nilfs *nilfs, __u64 *posp, int flags,
410 return ret; 365 return ret;
411} 366}
412 367
413static inline int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs, 368static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
414 struct nilfs_argv *argv, 369 struct nilfs_argv *argv, void *buf)
415 int dir)
416{
417 return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
418 nilfs_ioctl_do_move_blocks);
419}
420
421static ssize_t
422nilfs_ioctl_do_delete_checkpoints(struct the_nilfs *nilfs, __u64 *posp,
423 int flags, void *buf, size_t size,
424 size_t nmembs)
425{ 370{
371 size_t nmembs = argv->v_nmembs;
426 struct inode *cpfile = nilfs->ns_cpfile; 372 struct inode *cpfile = nilfs->ns_cpfile;
427 struct nilfs_period *periods = buf; 373 struct nilfs_period *periods = buf;
428 int ret, i; 374 int ret, i;
@@ -436,36 +382,21 @@ nilfs_ioctl_do_delete_checkpoints(struct the_nilfs *nilfs, __u64 *posp,
436 return nmembs; 382 return nmembs;
437} 383}
438 384
439static inline int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs, 385static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
440 struct nilfs_argv *argv, 386 struct nilfs_argv *argv, void *buf)
441 int dir)
442{ 387{
443 return nilfs_ioctl_wrap_copy(nilfs, argv, dir, 388 size_t nmembs = argv->v_nmembs;
444 nilfs_ioctl_do_delete_checkpoints); 389 int ret;
445}
446 390
447static ssize_t 391 ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
448nilfs_ioctl_do_free_vblocknrs(struct the_nilfs *nilfs, __u64 *posp, int flags,
449 void *buf, size_t size, size_t nmembs)
450{
451 int ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
452 392
453 return (ret < 0) ? ret : nmembs; 393 return (ret < 0) ? ret : nmembs;
454} 394}
455 395
456static inline int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs, 396static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
457 struct nilfs_argv *argv, 397 struct nilfs_argv *argv, void *buf)
458 int dir)
459{
460 return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
461 nilfs_ioctl_do_free_vblocknrs);
462}
463
464static ssize_t
465nilfs_ioctl_do_mark_blocks_dirty(struct the_nilfs *nilfs, __u64 *posp,
466 int flags, void *buf, size_t size,
467 size_t nmembs)
468{ 398{
399 size_t nmembs = argv->v_nmembs;
469 struct inode *dat = nilfs_dat_inode(nilfs); 400 struct inode *dat = nilfs_dat_inode(nilfs);
470 struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap; 401 struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap;
471 struct nilfs_bdesc *bdescs = buf; 402 struct nilfs_bdesc *bdescs = buf;
@@ -504,55 +435,37 @@ nilfs_ioctl_do_mark_blocks_dirty(struct the_nilfs *nilfs, __u64 *posp,
504 return nmembs; 435 return nmembs;
505} 436}
506 437
507static inline int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs, 438static int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
508 struct nilfs_argv *argv, 439 struct nilfs_argv *argv, void *buf)
509 int dir)
510{ 440{
511 return nilfs_ioctl_wrap_copy(nilfs, argv, dir, 441 size_t nmembs = argv->v_nmembs;
512 nilfs_ioctl_do_mark_blocks_dirty); 442 struct nilfs_sb_info *sbi = nilfs->ns_writer;
513}
514
515static ssize_t
516nilfs_ioctl_do_free_segments(struct the_nilfs *nilfs, __u64 *posp, int flags,
517 void *buf, size_t size, size_t nmembs)
518{
519 struct nilfs_sb_info *sbi = nilfs_get_writer(nilfs);
520 int ret; 443 int ret;
521 444
522 if (unlikely(!sbi)) 445 if (unlikely(!sbi)) {
446 /* never happens because called for a writable mount */
447 WARN_ON(1);
523 return -EROFS; 448 return -EROFS;
449 }
524 ret = nilfs_segctor_add_segments_to_be_freed( 450 ret = nilfs_segctor_add_segments_to_be_freed(
525 NILFS_SC(sbi), buf, nmembs); 451 NILFS_SC(sbi), buf, nmembs);
526 nilfs_put_writer(nilfs);
527 452
528 return (ret < 0) ? ret : nmembs; 453 return (ret < 0) ? ret : nmembs;
529} 454}
530 455
531static inline int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
532 struct nilfs_argv *argv,
533 int dir)
534{
535 return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
536 nilfs_ioctl_do_free_segments);
537}
538
539int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, 456int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
540 void __user *argp) 457 struct nilfs_argv *argv, void **kbufs)
541{ 458{
542 struct nilfs_argv argv[5];
543 const char *msg; 459 const char *msg;
544 int dir, ret; 460 int ret;
545
546 if (copy_from_user(argv, argp, sizeof(argv)))
547 return -EFAULT;
548 461
549 dir = _IOC_WRITE; 462 ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]);
550 ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], dir);
551 if (ret < 0) { 463 if (ret < 0) {
552 msg = "cannot read source blocks"; 464 msg = "cannot read source blocks";
553 goto failed; 465 goto failed;
554 } 466 }
555 ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], dir); 467
468 ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
556 if (ret < 0) { 469 if (ret < 0) {
557 /* 470 /*
558 * can safely abort because checkpoints can be removed 471 * can safely abort because checkpoints can be removed
@@ -561,7 +474,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
561 msg = "cannot delete checkpoints"; 474 msg = "cannot delete checkpoints";
562 goto failed; 475 goto failed;
563 } 476 }
564 ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], dir); 477 ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
565 if (ret < 0) { 478 if (ret < 0) {
566 /* 479 /*
567 * can safely abort because DAT file is updated atomically 480 * can safely abort because DAT file is updated atomically
@@ -570,7 +483,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
570 msg = "cannot delete virtual blocks from DAT file"; 483 msg = "cannot delete virtual blocks from DAT file";
571 goto failed; 484 goto failed;
572 } 485 }
573 ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], dir); 486 ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
574 if (ret < 0) { 487 if (ret < 0) {
575 /* 488 /*
576 * can safely abort because the operation is nondestructive. 489 * can safely abort because the operation is nondestructive.
@@ -578,7 +491,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
578 msg = "cannot mark copying blocks dirty"; 491 msg = "cannot mark copying blocks dirty";
579 goto failed; 492 goto failed;
580 } 493 }
581 ret = nilfs_ioctl_free_segments(nilfs, &argv[4], dir); 494 ret = nilfs_ioctl_free_segments(nilfs, &argv[4], kbufs[4]);
582 if (ret < 0) { 495 if (ret < 0) {
583 /* 496 /*
584 * can safely abort because this operation is atomic. 497 * can safely abort because this operation is atomic.
@@ -598,9 +511,75 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
598static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, 511static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
599 unsigned int cmd, void __user *argp) 512 unsigned int cmd, void __user *argp)
600{ 513{
514 struct nilfs_argv argv[5];
515 const static size_t argsz[5] = {
516 sizeof(struct nilfs_vdesc),
517 sizeof(struct nilfs_period),
518 sizeof(__u64),
519 sizeof(struct nilfs_bdesc),
520 sizeof(__u64),
521 };
522 void __user *base;
523 void *kbufs[5];
524 struct the_nilfs *nilfs;
525 size_t len, nsegs;
526 int n, ret;
527
601 if (!capable(CAP_SYS_ADMIN)) 528 if (!capable(CAP_SYS_ADMIN))
602 return -EPERM; 529 return -EPERM;
603 return nilfs_clean_segments(inode->i_sb, argp); 530
531 if (copy_from_user(argv, argp, sizeof(argv)))
532 return -EFAULT;
533
534 nsegs = argv[4].v_nmembs;
535 if (argv[4].v_size != argsz[4])
536 return -EINVAL;
537 /*
538 * argv[4] points to segment numbers this ioctl cleans. We
539 * use kmalloc() for its buffer because memory used for the
540 * segment numbers is enough small.
541 */
542 kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
543 nsegs * sizeof(__u64));
544 if (IS_ERR(kbufs[4]))
545 return PTR_ERR(kbufs[4]);
546
547 nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
548
549 for (n = 0; n < 4; n++) {
550 ret = -EINVAL;
551 if (argv[n].v_size != argsz[n])
552 goto out_free;
553
554 if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
555 goto out_free;
556
557 len = argv[n].v_size * argv[n].v_nmembs;
558 base = (void __user *)(unsigned long)argv[n].v_base;
559 if (len == 0) {
560 kbufs[n] = NULL;
561 continue;
562 }
563
564 kbufs[n] = vmalloc(len);
565 if (!kbufs[n]) {
566 ret = -ENOMEM;
567 goto out_free;
568 }
569 if (copy_from_user(kbufs[n], base, len)) {
570 ret = -EFAULT;
571 vfree(kbufs[n]);
572 goto out_free;
573 }
574 }
575
576 ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
577
578 out_free:
579 while (--n > 0)
580 vfree(kbufs[n]);
581 kfree(kbufs[4]);
582 return ret;
604} 583}
605 584
606static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, 585static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
@@ -621,6 +600,33 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
621 return 0; 600 return 0;
622} 601}
623 602
603static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
604 unsigned int cmd, void __user *argp,
605 size_t membsz,
606 ssize_t (*dofunc)(struct the_nilfs *,
607 __u64 *, int,
608 void *, size_t, size_t))
609
610{
611 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
612 struct nilfs_argv argv;
613 int ret;
614
615 if (copy_from_user(&argv, argp, sizeof(argv)))
616 return -EFAULT;
617
618 if (argv.v_size != membsz)
619 return -EINVAL;
620
621 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
622 if (ret < 0)
623 return ret;
624
625 if (copy_to_user(argp, &argv, sizeof(argv)))
626 ret = -EFAULT;
627 return ret;
628}
629
624long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 630long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
625{ 631{
626 struct inode *inode = filp->f_dentry->d_inode; 632 struct inode *inode = filp->f_dentry->d_inode;
@@ -632,16 +638,21 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
632 case NILFS_IOCTL_DELETE_CHECKPOINT: 638 case NILFS_IOCTL_DELETE_CHECKPOINT:
633 return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp); 639 return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
634 case NILFS_IOCTL_GET_CPINFO: 640 case NILFS_IOCTL_GET_CPINFO:
635 return nilfs_ioctl_get_cpinfo(inode, filp, cmd, argp); 641 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
642 sizeof(struct nilfs_cpinfo),
643 nilfs_ioctl_do_get_cpinfo);
636 case NILFS_IOCTL_GET_CPSTAT: 644 case NILFS_IOCTL_GET_CPSTAT:
637 return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp); 645 return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
638 case NILFS_IOCTL_GET_SUINFO: 646 case NILFS_IOCTL_GET_SUINFO:
639 return nilfs_ioctl_get_suinfo(inode, filp, cmd, argp); 647 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
648 sizeof(struct nilfs_suinfo),
649 nilfs_ioctl_do_get_suinfo);
640 case NILFS_IOCTL_GET_SUSTAT: 650 case NILFS_IOCTL_GET_SUSTAT:
641 return nilfs_ioctl_get_sustat(inode, filp, cmd, argp); 651 return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
642 case NILFS_IOCTL_GET_VINFO: 652 case NILFS_IOCTL_GET_VINFO:
643 /* XXX: rename to ??? */ 653 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
644 return nilfs_ioctl_get_vinfo(inode, filp, cmd, argp); 654 sizeof(struct nilfs_vinfo),
655 nilfs_ioctl_do_get_vinfo);
645 case NILFS_IOCTL_GET_BDESCS: 656 case NILFS_IOCTL_GET_BDESCS:
646 return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp); 657 return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
647 case NILFS_IOCTL_CLEAN_SEGMENTS: 658 case NILFS_IOCTL_CLEAN_SEGMENTS:
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 47dd815433fd..bb78745a0e30 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -77,19 +77,22 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
77 void *)) 77 void *))
78{ 78{
79 struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs; 79 struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs;
80 struct nilfs_sb_info *writer = NULL;
81 struct super_block *sb = inode->i_sb; 80 struct super_block *sb = inode->i_sb;
82 struct nilfs_transaction_info ti; 81 struct nilfs_transaction_info ti;
83 struct buffer_head *bh; 82 struct buffer_head *bh;
84 int err; 83 int err;
85 84
86 if (!sb) { 85 if (!sb) {
87 writer = nilfs_get_writer(nilfs); 86 /*
88 if (!writer) { 87 * Make sure this function is not called from any
88 * read-only context.
89 */
90 if (!nilfs->ns_writer) {
91 WARN_ON(1);
89 err = -EROFS; 92 err = -EROFS;
90 goto out; 93 goto out;
91 } 94 }
92 sb = writer->s_super; 95 sb = nilfs->ns_writer->s_super;
93 } 96 }
94 97
95 nilfs_transaction_begin(sb, &ti, 0); 98 nilfs_transaction_begin(sb, &ti, 0);
@@ -127,8 +130,6 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
127 err = nilfs_transaction_commit(sb); 130 err = nilfs_transaction_commit(sb);
128 else 131 else
129 nilfs_transaction_abort(sb); 132 nilfs_transaction_abort(sb);
130 if (writer)
131 nilfs_put_writer(nilfs);
132 out: 133 out:
133 return err; 134 return err;
134} 135}
@@ -299,7 +300,7 @@ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
299 int err; 300 int err;
300 301
301 err = nilfs_bmap_delete(ii->i_bmap, block); 302 err = nilfs_bmap_delete(ii->i_bmap, block);
302 if (likely(!err)) { 303 if (!err || err == -ENOENT) {
303 nilfs_mdt_mark_dirty(inode); 304 nilfs_mdt_mark_dirty(inode);
304 nilfs_mdt_forget_block(inode, block); 305 nilfs_mdt_forget_block(inode, block);
305 } 306 }
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 3d0c18a16db1..da6fc0bba2e5 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -236,7 +236,8 @@ extern int nilfs_sync_file(struct file *, struct dentry *, int);
236 236
237/* ioctl.c */ 237/* ioctl.c */
238long nilfs_ioctl(struct file *, unsigned int, unsigned long); 238long nilfs_ioctl(struct file *, unsigned int, unsigned long);
239int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, void __user *); 239int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *,
240 void **);
240 241
241/* inode.c */ 242/* inode.c */
242extern struct inode *nilfs_new_inode(struct inode *, int); 243extern struct inode *nilfs_new_inode(struct inode *, int);
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 1bfbba9c0e9a..a2692bbc7b50 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -128,7 +128,8 @@ void nilfs_forget_buffer(struct buffer_head *bh)
128 128
129 lock_buffer(bh); 129 lock_buffer(bh);
130 clear_buffer_nilfs_volatile(bh); 130 clear_buffer_nilfs_volatile(bh);
131 if (test_clear_buffer_dirty(bh) && nilfs_page_buffers_clean(page)) 131 clear_buffer_dirty(bh);
132 if (nilfs_page_buffers_clean(page))
132 __nilfs_clear_page_dirty(page); 133 __nilfs_clear_page_dirty(page);
133 134
134 clear_buffer_uptodate(bh); 135 clear_buffer_uptodate(bh);
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 4fc081e47d70..57afa9d24061 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -407,6 +407,7 @@ void nilfs_dispose_segment_list(struct list_head *head)
407} 407}
408 408
409static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, 409static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
410 struct nilfs_sb_info *sbi,
410 struct nilfs_recovery_info *ri) 411 struct nilfs_recovery_info *ri)
411{ 412{
412 struct list_head *head = &ri->ri_used_segments; 413 struct list_head *head = &ri->ri_used_segments;
@@ -421,6 +422,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
421 segnum[2] = ri->ri_segnum; 422 segnum[2] = ri->ri_segnum;
422 segnum[3] = ri->ri_nextnum; 423 segnum[3] = ri->ri_nextnum;
423 424
425 nilfs_attach_writer(nilfs, sbi);
424 /* 426 /*
425 * Releasing the next segment of the latest super root. 427 * Releasing the next segment of the latest super root.
426 * The next segment is invalidated by this recovery. 428 * The next segment is invalidated by this recovery.
@@ -459,10 +461,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
459 nilfs->ns_pseg_offset = 0; 461 nilfs->ns_pseg_offset = 0;
460 nilfs->ns_seg_seq = ri->ri_seq + 2; 462 nilfs->ns_seg_seq = ri->ri_seq + 2;
461 nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0]; 463 nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0];
462 return 0;
463 464
464 failed: 465 failed:
465 /* No need to recover sufile because it will be destroyed on error */ 466 /* No need to recover sufile because it will be destroyed on error */
467 nilfs_detach_writer(nilfs, sbi);
466 return err; 468 return err;
467} 469}
468 470
@@ -728,7 +730,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
728 goto failed; 730 goto failed;
729 731
730 if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) { 732 if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) {
731 err = nilfs_prepare_segment_for_recovery(nilfs, ri); 733 err = nilfs_prepare_segment_for_recovery(nilfs, sbi, ri);
732 if (unlikely(err)) { 734 if (unlikely(err)) {
733 printk(KERN_ERR "NILFS: Error preparing segments for " 735 printk(KERN_ERR "NILFS: Error preparing segments for "
734 "recovery.\n"); 736 "recovery.\n");
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index fb70ec3be20e..22c7f65c2403 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2589,7 +2589,8 @@ nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head)
2589 } 2589 }
2590} 2590}
2591 2591
2592int nilfs_clean_segments(struct super_block *sb, void __user *argp) 2592int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
2593 void **kbufs)
2593{ 2594{
2594 struct nilfs_sb_info *sbi = NILFS_SB(sb); 2595 struct nilfs_sb_info *sbi = NILFS_SB(sb);
2595 struct nilfs_sc_info *sci = NILFS_SC(sbi); 2596 struct nilfs_sc_info *sci = NILFS_SC(sbi);
@@ -2606,7 +2607,7 @@ int nilfs_clean_segments(struct super_block *sb, void __user *argp)
2606 err = nilfs_init_gcdat_inode(nilfs); 2607 err = nilfs_init_gcdat_inode(nilfs);
2607 if (unlikely(err)) 2608 if (unlikely(err))
2608 goto out_unlock; 2609 goto out_unlock;
2609 err = nilfs_ioctl_prepare_clean_segments(nilfs, argp); 2610 err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
2610 if (unlikely(err)) 2611 if (unlikely(err))
2611 goto out_unlock; 2612 goto out_unlock;
2612 2613
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index a98fc1ed0bbb..476bdd5df5be 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -222,7 +222,8 @@ extern int nilfs_construct_segment(struct super_block *);
222extern int nilfs_construct_dsync_segment(struct super_block *, struct inode *, 222extern int nilfs_construct_dsync_segment(struct super_block *, struct inode *,
223 loff_t, loff_t); 223 loff_t, loff_t);
224extern void nilfs_flush_segment(struct super_block *, ino_t); 224extern void nilfs_flush_segment(struct super_block *, ino_t);
225extern int nilfs_clean_segments(struct super_block *, void __user *); 225extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
226 void **);
226 227
227extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *, 228extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
228 __u64 *, size_t); 229 __u64 *, size_t);
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index ed0a0cfd68d2..579dd1b1110f 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -39,6 +39,7 @@
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/pagemap.h> 40#include <linux/pagemap.h>
41#include <linux/utsname.h> 41#include <linux/utsname.h>
42#include <linux/namei.h>
42 43
43#define MLOG_MASK_PREFIX ML_NAMEI 44#define MLOG_MASK_PREFIX ML_NAMEI
44#include <cluster/masklog.h> 45#include <cluster/masklog.h>
@@ -54,26 +55,6 @@
54 55
55#include "buffer_head_io.h" 56#include "buffer_head_io.h"
56 57
57static char *ocfs2_page_getlink(struct dentry * dentry,
58 struct page **ppage);
59static char *ocfs2_fast_symlink_getlink(struct inode *inode,
60 struct buffer_head **bh);
61
62/* get the link contents into pagecache */
63static char *ocfs2_page_getlink(struct dentry * dentry,
64 struct page **ppage)
65{
66 struct page * page;
67 struct address_space *mapping = dentry->d_inode->i_mapping;
68 page = read_mapping_page(mapping, 0, NULL);
69 if (IS_ERR(page))
70 goto sync_fail;
71 *ppage = page;
72 return kmap(page);
73
74sync_fail:
75 return (char*)page;
76}
77 58
78static char *ocfs2_fast_symlink_getlink(struct inode *inode, 59static char *ocfs2_fast_symlink_getlink(struct inode *inode,
79 struct buffer_head **bh) 60 struct buffer_head **bh)
@@ -128,40 +109,55 @@ out:
128 return ret; 109 return ret;
129} 110}
130 111
131static void *ocfs2_follow_link(struct dentry *dentry, 112static void *ocfs2_fast_follow_link(struct dentry *dentry,
132 struct nameidata *nd) 113 struct nameidata *nd)
133{ 114{
134 int status; 115 int status = 0;
135 char *link; 116 int len;
117 char *target, *link = ERR_PTR(-ENOMEM);
136 struct inode *inode = dentry->d_inode; 118 struct inode *inode = dentry->d_inode;
137 struct page *page = NULL;
138 struct buffer_head *bh = NULL; 119 struct buffer_head *bh = NULL;
139 120
140 if (ocfs2_inode_is_fast_symlink(inode)) 121 mlog_entry_void();
141 link = ocfs2_fast_symlink_getlink(inode, &bh); 122
142 else 123 BUG_ON(!ocfs2_inode_is_fast_symlink(inode));
143 link = ocfs2_page_getlink(dentry, &page); 124 target = ocfs2_fast_symlink_getlink(inode, &bh);
144 if (IS_ERR(link)) { 125 if (IS_ERR(target)) {
145 status = PTR_ERR(link); 126 status = PTR_ERR(target);
146 mlog_errno(status); 127 mlog_errno(status);
147 goto bail; 128 goto bail;
148 } 129 }
149 130
150 status = vfs_follow_link(nd, link); 131 /* Fast symlinks can't be large */
132 len = strlen(target);
133 link = kzalloc(len + 1, GFP_NOFS);
134 if (!link) {
135 status = -ENOMEM;
136 mlog_errno(status);
137 goto bail;
138 }
139
140 memcpy(link, target, len);
141 nd_set_link(nd, link);
151 142
152bail: 143bail:
153 if (page) {
154 kunmap(page);
155 page_cache_release(page);
156 }
157 brelse(bh); 144 brelse(bh);
158 145
159 return ERR_PTR(status); 146 mlog_exit(status);
147 return status ? ERR_PTR(status) : link;
148}
149
150static void ocfs2_fast_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
151{
152 char *link = cookie;
153
154 kfree(link);
160} 155}
161 156
162const struct inode_operations ocfs2_symlink_inode_operations = { 157const struct inode_operations ocfs2_symlink_inode_operations = {
163 .readlink = page_readlink, 158 .readlink = page_readlink,
164 .follow_link = ocfs2_follow_link, 159 .follow_link = page_follow_link_light,
160 .put_link = page_put_link,
165 .getattr = ocfs2_getattr, 161 .getattr = ocfs2_getattr,
166 .setattr = ocfs2_setattr, 162 .setattr = ocfs2_setattr,
167 .setxattr = generic_setxattr, 163 .setxattr = generic_setxattr,
@@ -171,7 +167,8 @@ const struct inode_operations ocfs2_symlink_inode_operations = {
171}; 167};
172const struct inode_operations ocfs2_fast_symlink_inode_operations = { 168const struct inode_operations ocfs2_fast_symlink_inode_operations = {
173 .readlink = ocfs2_readlink, 169 .readlink = ocfs2_readlink,
174 .follow_link = ocfs2_follow_link, 170 .follow_link = ocfs2_fast_follow_link,
171 .put_link = ocfs2_fast_put_link,
175 .getattr = ocfs2_getattr, 172 .getattr = ocfs2_getattr,
176 .setattr = ocfs2_setattr, 173 .setattr = ocfs2_setattr,
177 .setxattr = generic_setxattr, 174 .setxattr = generic_setxattr,
diff --git a/fs/open.c b/fs/open.c
index 377eb25b6abf..bdfbf03615a4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1033,7 +1033,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
1033 if (!IS_ERR(tmp)) { 1033 if (!IS_ERR(tmp)) {
1034 fd = get_unused_fd_flags(flags); 1034 fd = get_unused_fd_flags(flags);
1035 if (fd >= 0) { 1035 if (fd >= 0) {
1036 struct file *f = do_filp_open(dfd, tmp, flags, mode); 1036 struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
1037 if (IS_ERR(f)) { 1037 if (IS_ERR(f)) {
1038 put_unused_fd(fd); 1038 put_unused_fd(fd);
1039 fd = PTR_ERR(f); 1039 fd = PTR_ERR(f);
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 1e15a2b176e8..b080b791d9e3 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -67,8 +67,7 @@ static int proc_get_sb(struct file_system_type *fs_type,
67 sb->s_flags = flags; 67 sb->s_flags = flags;
68 err = proc_fill_super(sb); 68 err = proc_fill_super(sb);
69 if (err) { 69 if (err) {
70 up_write(&sb->s_umount); 70 deactivate_locked_super(sb);
71 deactivate_super(sb);
72 return err; 71 return err;
73 } 72 }
74 73
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 67a80d7e59e2..45ee3d357c70 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -41,6 +41,18 @@ static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
41 41
42#define store_ih(where,what) copy_item_head (where, what) 42#define store_ih(where,what) copy_item_head (where, what)
43 43
44static inline bool is_privroot_deh(struct dentry *dir,
45 struct reiserfs_de_head *deh)
46{
47 int ret = 0;
48#ifdef CONFIG_REISERFS_FS_XATTR
49 struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root;
50 ret = (dir == dir->d_parent && privroot->d_inode &&
51 deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid);
52#endif
53 return ret;
54}
55
44int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, 56int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,
45 filldir_t filldir, loff_t *pos) 57 filldir_t filldir, loff_t *pos)
46{ 58{
@@ -138,18 +150,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,
138 } 150 }
139 151
140 /* Ignore the .reiserfs_priv entry */ 152 /* Ignore the .reiserfs_priv entry */
141 if (reiserfs_xattrs(inode->i_sb) && 153 if (is_privroot_deh(dentry, deh))
142 !old_format_only(inode->i_sb) &&
143 dentry == inode->i_sb->s_root &&
144 REISERFS_SB(inode->i_sb)->priv_root &&
145 REISERFS_SB(inode->i_sb)->priv_root->d_inode
146 && deh_objectid(deh) ==
147 le32_to_cpu(INODE_PKEY
148 (REISERFS_SB(inode->i_sb)->
149 priv_root->d_inode)->
150 k_objectid)) {
151 continue; 154 continue;
152 }
153 155
154 d_off = deh_offset(deh); 156 d_off = deh_offset(deh);
155 *pos = d_off; 157 *pos = d_off;
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index efd4d720718e..271579128634 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -338,21 +338,8 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
338 &path_to_entry, &de); 338 &path_to_entry, &de);
339 pathrelse(&path_to_entry); 339 pathrelse(&path_to_entry);
340 if (retval == NAME_FOUND) { 340 if (retval == NAME_FOUND) {
341 /* Hide the .reiserfs_priv directory */ 341 inode = reiserfs_iget(dir->i_sb,
342 if (reiserfs_xattrs(dir->i_sb) && 342 (struct cpu_key *)&(de.de_dir_id));
343 !old_format_only(dir->i_sb) &&
344 REISERFS_SB(dir->i_sb)->priv_root &&
345 REISERFS_SB(dir->i_sb)->priv_root->d_inode &&
346 de.de_objectid ==
347 le32_to_cpu(INODE_PKEY
348 (REISERFS_SB(dir->i_sb)->priv_root->d_inode)->
349 k_objectid)) {
350 reiserfs_write_unlock(dir->i_sb);
351 return ERR_PTR(-EACCES);
352 }
353
354 inode =
355 reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
356 if (!inode || IS_ERR(inode)) { 343 if (!inode || IS_ERR(inode)) {
357 reiserfs_write_unlock(dir->i_sb); 344 reiserfs_write_unlock(dir->i_sb);
358 return ERR_PTR(-EACCES); 345 return ERR_PTR(-EACCES);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 0ae6486d9046..3567fb9e3fb1 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -448,13 +448,11 @@ int remove_save_link(struct inode *inode, int truncate)
448static void reiserfs_kill_sb(struct super_block *s) 448static void reiserfs_kill_sb(struct super_block *s)
449{ 449{
450 if (REISERFS_SB(s)) { 450 if (REISERFS_SB(s)) {
451#ifdef CONFIG_REISERFS_FS_XATTR
452 if (REISERFS_SB(s)->xattr_root) { 451 if (REISERFS_SB(s)->xattr_root) {
453 d_invalidate(REISERFS_SB(s)->xattr_root); 452 d_invalidate(REISERFS_SB(s)->xattr_root);
454 dput(REISERFS_SB(s)->xattr_root); 453 dput(REISERFS_SB(s)->xattr_root);
455 REISERFS_SB(s)->xattr_root = NULL; 454 REISERFS_SB(s)->xattr_root = NULL;
456 } 455 }
457#endif
458 if (REISERFS_SB(s)->priv_root) { 456 if (REISERFS_SB(s)->priv_root) {
459 d_invalidate(REISERFS_SB(s)->priv_root); 457 d_invalidate(REISERFS_SB(s)->priv_root);
460 dput(REISERFS_SB(s)->priv_root); 458 dput(REISERFS_SB(s)->priv_root);
@@ -1316,8 +1314,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1316 } 1314 }
1317 1315
1318out_ok: 1316out_ok:
1319 kfree(s->s_options); 1317 replace_mount_options(s, new_opts);
1320 s->s_options = new_opts;
1321 return 0; 1318 return 0;
1322 1319
1323out_err: 1320out_err:
@@ -1842,7 +1839,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1842 goto error; 1839 goto error;
1843 } 1840 }
1844 1841
1845 if ((errval = reiserfs_xattr_init(s, s->s_flags))) { 1842 if ((errval = reiserfs_lookup_privroot(s)) ||
1843 (errval = reiserfs_xattr_init(s, s->s_flags))) {
1846 dput(s->s_root); 1844 dput(s->s_root);
1847 s->s_root = NULL; 1845 s->s_root = NULL;
1848 goto error; 1846 goto error;
@@ -1855,7 +1853,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1855 reiserfs_info(s, "using 3.5.x disk format\n"); 1853 reiserfs_info(s, "using 3.5.x disk format\n");
1856 } 1854 }
1857 1855
1858 if ((errval = reiserfs_xattr_init(s, s->s_flags))) { 1856 if ((errval = reiserfs_lookup_privroot(s)) ||
1857 (errval = reiserfs_xattr_init(s, s->s_flags))) {
1859 dput(s->s_root); 1858 dput(s->s_root);
1860 s->s_root = NULL; 1859 s->s_root = NULL;
1861 goto error; 1860 goto error;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index f83f52bae390..8e7deb0e6964 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -113,41 +113,30 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)
113 113
114#define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) 114#define xattr_may_create(flags) (!flags || flags & XATTR_CREATE)
115 115
116/* Returns and possibly creates the xattr dir. */ 116static struct dentry *open_xa_root(struct super_block *sb, int flags)
117static struct dentry *lookup_or_create_dir(struct dentry *parent,
118 const char *name, int flags)
119{ 117{
120 struct dentry *dentry; 118 struct dentry *privroot = REISERFS_SB(sb)->priv_root;
121 BUG_ON(!parent); 119 struct dentry *xaroot;
122 120 if (!privroot->d_inode)
123 dentry = lookup_one_len(name, parent, strlen(name)); 121 return ERR_PTR(-ENODATA);
124 if (IS_ERR(dentry))
125 return dentry;
126 else if (!dentry->d_inode) {
127 int err = -ENODATA;
128 122
129 if (xattr_may_create(flags)) { 123 mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR);
130 mutex_lock_nested(&parent->d_inode->i_mutex,
131 I_MUTEX_XATTR);
132 err = xattr_mkdir(parent->d_inode, dentry, 0700);
133 mutex_unlock(&parent->d_inode->i_mutex);
134 }
135 124
125 xaroot = dget(REISERFS_SB(sb)->xattr_root);
126 if (!xaroot)
127 xaroot = ERR_PTR(-ENODATA);
128 else if (!xaroot->d_inode) {
129 int err = -ENODATA;
130 if (xattr_may_create(flags))
131 err = xattr_mkdir(privroot->d_inode, xaroot, 0700);
136 if (err) { 132 if (err) {
137 dput(dentry); 133 dput(xaroot);
138 dentry = ERR_PTR(err); 134 xaroot = ERR_PTR(err);
139 } 135 }
140 } 136 }
141 137
142 return dentry; 138 mutex_unlock(&privroot->d_inode->i_mutex);
143} 139 return xaroot;
144
145static struct dentry *open_xa_root(struct super_block *sb, int flags)
146{
147 struct dentry *privroot = REISERFS_SB(sb)->priv_root;
148 if (!privroot)
149 return ERR_PTR(-ENODATA);
150 return lookup_or_create_dir(privroot, XAROOT_NAME, flags);
151} 140}
152 141
153static struct dentry *open_xa_dir(const struct inode *inode, int flags) 142static struct dentry *open_xa_dir(const struct inode *inode, int flags)
@@ -163,10 +152,22 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
163 le32_to_cpu(INODE_PKEY(inode)->k_objectid), 152 le32_to_cpu(INODE_PKEY(inode)->k_objectid),
164 inode->i_generation); 153 inode->i_generation);
165 154
166 xadir = lookup_or_create_dir(xaroot, namebuf, flags); 155 mutex_lock_nested(&xaroot->d_inode->i_mutex, I_MUTEX_XATTR);
156
157 xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf));
158 if (!IS_ERR(xadir) && !xadir->d_inode) {
159 int err = -ENODATA;
160 if (xattr_may_create(flags))
161 err = xattr_mkdir(xaroot->d_inode, xadir, 0700);
162 if (err) {
163 dput(xadir);
164 xadir = ERR_PTR(err);
165 }
166 }
167
168 mutex_unlock(&xaroot->d_inode->i_mutex);
167 dput(xaroot); 169 dput(xaroot);
168 return xadir; 170 return xadir;
169
170} 171}
171 172
172/* The following are side effects of other operations that aren't explicitly 173/* The following are side effects of other operations that aren't explicitly
@@ -184,6 +185,7 @@ fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset,
184{ 185{
185 struct reiserfs_dentry_buf *dbuf = buf; 186 struct reiserfs_dentry_buf *dbuf = buf;
186 struct dentry *dentry; 187 struct dentry *dentry;
188 WARN_ON_ONCE(!mutex_is_locked(&dbuf->xadir->d_inode->i_mutex));
187 189
188 if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) 190 if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
189 return -ENOSPC; 191 return -ENOSPC;
@@ -349,6 +351,7 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
349 if (IS_ERR(xadir)) 351 if (IS_ERR(xadir))
350 return ERR_CAST(xadir); 352 return ERR_CAST(xadir);
351 353
354 mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
352 xafile = lookup_one_len(name, xadir, strlen(name)); 355 xafile = lookup_one_len(name, xadir, strlen(name));
353 if (IS_ERR(xafile)) { 356 if (IS_ERR(xafile)) {
354 err = PTR_ERR(xafile); 357 err = PTR_ERR(xafile);
@@ -360,18 +363,15 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
360 363
361 if (!xafile->d_inode) { 364 if (!xafile->d_inode) {
362 err = -ENODATA; 365 err = -ENODATA;
363 if (xattr_may_create(flags)) { 366 if (xattr_may_create(flags))
364 mutex_lock_nested(&xadir->d_inode->i_mutex,
365 I_MUTEX_XATTR);
366 err = xattr_create(xadir->d_inode, xafile, 367 err = xattr_create(xadir->d_inode, xafile,
367 0700|S_IFREG); 368 0700|S_IFREG);
368 mutex_unlock(&xadir->d_inode->i_mutex);
369 }
370 } 369 }
371 370
372 if (err) 371 if (err)
373 dput(xafile); 372 dput(xafile);
374out: 373out:
374 mutex_unlock(&xadir->d_inode->i_mutex);
375 dput(xadir); 375 dput(xadir);
376 if (err) 376 if (err)
377 return ERR_PTR(err); 377 return ERR_PTR(err);
@@ -435,6 +435,7 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
435 if (IS_ERR(xadir)) 435 if (IS_ERR(xadir))
436 return PTR_ERR(xadir); 436 return PTR_ERR(xadir);
437 437
438 mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
438 dentry = lookup_one_len(name, xadir, strlen(name)); 439 dentry = lookup_one_len(name, xadir, strlen(name));
439 if (IS_ERR(dentry)) { 440 if (IS_ERR(dentry)) {
440 err = PTR_ERR(dentry); 441 err = PTR_ERR(dentry);
@@ -442,14 +443,13 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
442 } 443 }
443 444
444 if (dentry->d_inode) { 445 if (dentry->d_inode) {
445 mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
446 err = xattr_unlink(xadir->d_inode, dentry); 446 err = xattr_unlink(xadir->d_inode, dentry);
447 mutex_unlock(&xadir->d_inode->i_mutex);
448 update_ctime(inode); 447 update_ctime(inode);
449 } 448 }
450 449
451 dput(dentry); 450 dput(dentry);
452out_dput: 451out_dput:
452 mutex_unlock(&xadir->d_inode->i_mutex);
453 dput(xadir); 453 dput(xadir);
454 return err; 454 return err;
455} 455}
@@ -687,20 +687,6 @@ out:
687 return err; 687 return err;
688} 688}
689 689
690/* Actual operations that are exported to VFS-land */
691struct xattr_handler *reiserfs_xattr_handlers[] = {
692 &reiserfs_xattr_user_handler,
693 &reiserfs_xattr_trusted_handler,
694#ifdef CONFIG_REISERFS_FS_SECURITY
695 &reiserfs_xattr_security_handler,
696#endif
697#ifdef CONFIG_REISERFS_FS_POSIX_ACL
698 &reiserfs_posix_acl_access_handler,
699 &reiserfs_posix_acl_default_handler,
700#endif
701 NULL
702};
703
704/* 690/*
705 * In order to implement different sets of xattr operations for each xattr 691 * In order to implement different sets of xattr operations for each xattr
706 * prefix with the generic xattr API, a filesystem should create a 692 * prefix with the generic xattr API, a filesystem should create a
@@ -843,7 +829,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
843 if (!dentry->d_inode) 829 if (!dentry->d_inode)
844 return -EINVAL; 830 return -EINVAL;
845 831
846 if (!reiserfs_xattrs(dentry->d_sb) || 832 if (!dentry->d_sb->s_xattr ||
847 get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) 833 get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
848 return -EOPNOTSUPP; 834 return -EOPNOTSUPP;
849 835
@@ -885,42 +871,50 @@ static int reiserfs_check_acl(struct inode *inode, int mask)
885 return error; 871 return error;
886} 872}
887 873
888int reiserfs_permission(struct inode *inode, int mask)
889{
890 /*
891 * We don't do permission checks on the internal objects.
892 * Permissions are determined by the "owning" object.
893 */
894 if (IS_PRIVATE(inode))
895 return 0;
896 /*
897 * Stat data v1 doesn't support ACLs.
898 */
899 if (get_inode_sd_version(inode) == STAT_DATA_V1)
900 return generic_permission(inode, mask, NULL);
901 else
902 return generic_permission(inode, mask, reiserfs_check_acl);
903}
904
905static int create_privroot(struct dentry *dentry) 874static int create_privroot(struct dentry *dentry)
906{ 875{
907 int err; 876 int err;
908 struct inode *inode = dentry->d_parent->d_inode; 877 struct inode *inode = dentry->d_parent->d_inode;
909 mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); 878 WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
879
910 err = xattr_mkdir(inode, dentry, 0700); 880 err = xattr_mkdir(inode, dentry, 0700);
911 mutex_unlock(&inode->i_mutex); 881 if (err || !dentry->d_inode) {
912 if (err) { 882 reiserfs_warning(dentry->d_sb, "jdm-20006",
913 dput(dentry); 883 "xattrs/ACLs enabled and couldn't "
914 dentry = NULL; 884 "find/create .reiserfs_priv. "
885 "Failing mount.");
886 return -EOPNOTSUPP;
915 } 887 }
916 888
917 if (dentry && dentry->d_inode) 889 dentry->d_inode->i_flags |= S_PRIVATE;
918 reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " 890 reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
919 "storage.\n", PRIVROOT_NAME); 891 "storage.\n", PRIVROOT_NAME);
920 892
921 return err; 893 return 0;
922} 894}
923 895
896#else
897int __init reiserfs_xattr_register_handlers(void) { return 0; }
898void reiserfs_xattr_unregister_handlers(void) {}
899static int create_privroot(struct dentry *dentry) { return 0; }
900#endif
901
902/* Actual operations that are exported to VFS-land */
903struct xattr_handler *reiserfs_xattr_handlers[] = {
904#ifdef CONFIG_REISERFS_FS_XATTR
905 &reiserfs_xattr_user_handler,
906 &reiserfs_xattr_trusted_handler,
907#endif
908#ifdef CONFIG_REISERFS_FS_SECURITY
909 &reiserfs_xattr_security_handler,
910#endif
911#ifdef CONFIG_REISERFS_FS_POSIX_ACL
912 &reiserfs_posix_acl_access_handler,
913 &reiserfs_posix_acl_default_handler,
914#endif
915 NULL
916};
917
924static int xattr_mount_check(struct super_block *s) 918static int xattr_mount_check(struct super_block *s)
925{ 919{
926 /* We need generation numbers to ensure that the oid mapping is correct 920 /* We need generation numbers to ensure that the oid mapping is correct
@@ -940,21 +934,33 @@ static int xattr_mount_check(struct super_block *s)
940 return 0; 934 return 0;
941} 935}
942 936
943#else 937int reiserfs_permission(struct inode *inode, int mask)
944int __init reiserfs_xattr_register_handlers(void) { return 0; } 938{
945void reiserfs_xattr_unregister_handlers(void) {} 939 /*
940 * We don't do permission checks on the internal objects.
941 * Permissions are determined by the "owning" object.
942 */
943 if (IS_PRIVATE(inode))
944 return 0;
945
946#ifdef CONFIG_REISERFS_FS_XATTR
947 /*
948 * Stat data v1 doesn't support ACLs.
949 */
950 if (get_inode_sd_version(inode) != STAT_DATA_V1)
951 return generic_permission(inode, mask, reiserfs_check_acl);
946#endif 952#endif
953 return generic_permission(inode, mask, NULL);
954}
947 955
948/* This will catch lookups from the fs root to .reiserfs_priv */ 956/* This will catch lookups from the fs root to .reiserfs_priv */
949static int 957static int
950xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) 958xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
951{ 959{
952 struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; 960 struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
953 if (name->len == priv_root->d_name.len && 961 if (container_of(q1, struct dentry, d_name) == priv_root)
954 name->hash == priv_root->d_name.hash &&
955 !memcmp(name->name, priv_root->d_name.name, name->len)) {
956 return -ENOENT; 962 return -ENOENT;
957 } else if (q1->len == name->len && 963 if (q1->len == name->len &&
958 !memcmp(q1->name, name->name, name->len)) 964 !memcmp(q1->name, name->name, name->len))
959 return 0; 965 return 0;
960 return 1; 966 return 1;
@@ -964,73 +970,71 @@ static const struct dentry_operations xattr_lookup_poison_ops = {
964 .d_compare = xattr_lookup_poison, 970 .d_compare = xattr_lookup_poison,
965}; 971};
966 972
973int reiserfs_lookup_privroot(struct super_block *s)
974{
975 struct dentry *dentry;
976 int err = 0;
977
978 /* If we don't have the privroot located yet - go find it */
979 mutex_lock(&s->s_root->d_inode->i_mutex);
980 dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
981 strlen(PRIVROOT_NAME));
982 if (!IS_ERR(dentry)) {
983 REISERFS_SB(s)->priv_root = dentry;
984 s->s_root->d_op = &xattr_lookup_poison_ops;
985 if (dentry->d_inode)
986 dentry->d_inode->i_flags |= S_PRIVATE;
987 } else
988 err = PTR_ERR(dentry);
989 mutex_unlock(&s->s_root->d_inode->i_mutex);
990
991 return err;
992}
993
967/* We need to take a copy of the mount flags since things like 994/* We need to take a copy of the mount flags since things like
968 * MS_RDONLY don't get set until *after* we're called. 995 * MS_RDONLY don't get set until *after* we're called.
969 * mount_flags != mount_options */ 996 * mount_flags != mount_options */
970int reiserfs_xattr_init(struct super_block *s, int mount_flags) 997int reiserfs_xattr_init(struct super_block *s, int mount_flags)
971{ 998{
972 int err = 0; 999 int err = 0;
1000 struct dentry *privroot = REISERFS_SB(s)->priv_root;
973 1001
974#ifdef CONFIG_REISERFS_FS_XATTR
975 err = xattr_mount_check(s); 1002 err = xattr_mount_check(s);
976 if (err) 1003 if (err)
977 goto error; 1004 goto error;
978#endif
979 1005
980 /* If we don't have the privroot located yet - go find it */ 1006 if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) {
981 if (!REISERFS_SB(s)->priv_root) { 1007 mutex_lock(&s->s_root->d_inode->i_mutex);
982 struct dentry *dentry; 1008 err = create_privroot(REISERFS_SB(s)->priv_root);
983 dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, 1009 mutex_unlock(&s->s_root->d_inode->i_mutex);
984 strlen(PRIVROOT_NAME));
985 if (!IS_ERR(dentry)) {
986#ifdef CONFIG_REISERFS_FS_XATTR
987 if (!(mount_flags & MS_RDONLY) && !dentry->d_inode)
988 err = create_privroot(dentry);
989#endif
990 if (!dentry->d_inode) {
991 dput(dentry);
992 dentry = NULL;
993 }
994 } else
995 err = PTR_ERR(dentry);
996
997 if (!err && dentry) {
998 s->s_root->d_op = &xattr_lookup_poison_ops;
999 dentry->d_inode->i_flags |= S_PRIVATE;
1000 REISERFS_SB(s)->priv_root = dentry;
1001#ifdef CONFIG_REISERFS_FS_XATTR
1002 /* xattrs are unavailable */
1003 } else if (!(mount_flags & MS_RDONLY)) {
1004 /* If we're read-only it just means that the dir
1005 * hasn't been created. Not an error -- just no
1006 * xattrs on the fs. We'll check again if we
1007 * go read-write */
1008 reiserfs_warning(s, "jdm-20006",
1009 "xattrs/ACLs enabled and couldn't "
1010 "find/create .reiserfs_priv. "
1011 "Failing mount.");
1012 err = -EOPNOTSUPP;
1013#endif
1014 }
1015 } 1010 }
1016 1011
1017#ifdef CONFIG_REISERFS_FS_XATTR 1012 if (privroot->d_inode) {
1018 if (!err)
1019 s->s_xattr = reiserfs_xattr_handlers; 1013 s->s_xattr = reiserfs_xattr_handlers;
1014 mutex_lock(&privroot->d_inode->i_mutex);
1015 if (!REISERFS_SB(s)->xattr_root) {
1016 struct dentry *dentry;
1017 dentry = lookup_one_len(XAROOT_NAME, privroot,
1018 strlen(XAROOT_NAME));
1019 if (!IS_ERR(dentry))
1020 REISERFS_SB(s)->xattr_root = dentry;
1021 else
1022 err = PTR_ERR(dentry);
1023 }
1024 mutex_unlock(&privroot->d_inode->i_mutex);
1025 }
1020 1026
1021error: 1027error:
1022 if (err) { 1028 if (err) {
1023 clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); 1029 clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
1024 clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); 1030 clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
1025 } 1031 }
1026#endif
1027 1032
1028 /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ 1033 /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
1029 s->s_flags = s->s_flags & ~MS_POSIXACL;
1030#ifdef CONFIG_REISERFS_FS_POSIX_ACL
1031 if (reiserfs_posixacl(s)) 1034 if (reiserfs_posixacl(s))
1032 s->s_flags |= MS_POSIXACL; 1035 s->s_flags |= MS_POSIXACL;
1033#endif 1036 else
1037 s->s_flags &= ~MS_POSIXACL;
1034 1038
1035 return err; 1039 return err;
1036} 1040}
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index 4d3c20e787c3..a92c8792c0f6 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -55,8 +55,16 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
55 struct reiserfs_security_handle *sec) 55 struct reiserfs_security_handle *sec)
56{ 56{
57 int blocks = 0; 57 int blocks = 0;
58 int error = security_inode_init_security(inode, dir, &sec->name, 58 int error;
59 &sec->value, &sec->length); 59
60 sec->name = NULL;
61
62 /* Don't add selinux attributes on xattrs - they'll never get used */
63 if (IS_PRIVATE(dir))
64 return 0;
65
66 error = security_inode_init_security(inode, dir, &sec->name,
67 &sec->value, &sec->length);
60 if (error) { 68 if (error) {
61 if (error == -EOPNOTSUPP) 69 if (error == -EOPNOTSUPP)
62 error = 0; 70 error = 0;
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index c53b5ef8a02f..4ab3c03d8f95 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -298,7 +298,8 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos)
298 struct romfs_inode ri; 298 struct romfs_inode ri;
299 struct inode *i; 299 struct inode *i;
300 unsigned long nlen; 300 unsigned long nlen;
301 unsigned nextfh, ret; 301 unsigned nextfh;
302 int ret;
302 umode_t mode; 303 umode_t mode;
303 304
304 /* we might have to traverse a chain of "hard link" file entries to get 305 /* we might have to traverse a chain of "hard link" file entries to get
diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile
index 8258cf9a0317..70e3244fa30f 100644
--- a/fs/squashfs/Makefile
+++ b/fs/squashfs/Makefile
@@ -5,4 +5,3 @@
5obj-$(CONFIG_SQUASHFS) += squashfs.o 5obj-$(CONFIG_SQUASHFS) += squashfs.o
6squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o 6squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
7squashfs-y += namei.o super.o symlink.o 7squashfs-y += namei.o super.o symlink.o
8#squashfs-y += squashfs2_0.o
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 1c4739e33af6..40c98fa6b5d6 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -252,6 +252,7 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries,
252 cache->entries = entries; 252 cache->entries = entries;
253 cache->block_size = block_size; 253 cache->block_size = block_size;
254 cache->pages = block_size >> PAGE_CACHE_SHIFT; 254 cache->pages = block_size >> PAGE_CACHE_SHIFT;
255 cache->pages = cache->pages ? cache->pages : 1;
255 cache->name = name; 256 cache->name = name;
256 cache->num_waiters = 0; 257 cache->num_waiters = 0;
257 spin_lock_init(&cache->lock); 258 spin_lock_init(&cache->lock);
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index ffa6edcd2d0c..0adc624c956f 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -157,6 +157,16 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
157 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE) 157 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
158 goto failed_mount; 158 goto failed_mount;
159 159
160 /*
161 * Check the system page size is not larger than the filesystem
162 * block size (by default 128K). This is currently not supported.
163 */
164 if (PAGE_CACHE_SIZE > msblk->block_size) {
165 ERROR("Page size > filesystem block size (%d). This is "
166 "currently not supported!\n", msblk->block_size);
167 goto failed_mount;
168 }
169
160 msblk->block_log = le16_to_cpu(sblk->block_log); 170 msblk->block_log = le16_to_cpu(sblk->block_log);
161 if (msblk->block_log > SQUASHFS_FILE_MAX_LOG) 171 if (msblk->block_log > SQUASHFS_FILE_MAX_LOG)
162 goto failed_mount; 172 goto failed_mount;
diff --git a/fs/super.c b/fs/super.c
index 786fe7d72790..1943fdf655fa 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -208,6 +208,34 @@ void deactivate_super(struct super_block *s)
208EXPORT_SYMBOL(deactivate_super); 208EXPORT_SYMBOL(deactivate_super);
209 209
210/** 210/**
211 * deactivate_locked_super - drop an active reference to superblock
212 * @s: superblock to deactivate
213 *
214 * Equivalent of up_write(&s->s_umount); deactivate_super(s);, except that
215 * it does not unlock it until it's all over. As the result, it's safe to
216 * use to dispose of new superblock on ->get_sb() failure exits - nobody
217 * will see the sucker until it's all over. Equivalent using up_write +
218 * deactivate_super is safe for that purpose only if superblock is either
219 * safe to use or has NULL ->s_root when we unlock.
220 */
221void deactivate_locked_super(struct super_block *s)
222{
223 struct file_system_type *fs = s->s_type;
224 if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
225 s->s_count -= S_BIAS-1;
226 spin_unlock(&sb_lock);
227 vfs_dq_off(s, 0);
228 fs->kill_sb(s);
229 put_filesystem(fs);
230 put_super(s);
231 } else {
232 up_write(&s->s_umount);
233 }
234}
235
236EXPORT_SYMBOL(deactivate_locked_super);
237
238/**
211 * grab_super - acquire an active reference 239 * grab_super - acquire an active reference
212 * @s: reference we are trying to make active 240 * @s: reference we are trying to make active
213 * 241 *
@@ -797,8 +825,7 @@ int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
797 sb->s_flags = flags; 825 sb->s_flags = flags;
798 err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); 826 err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
799 if (err) { 827 if (err) {
800 up_write(&sb->s_umount); 828 deactivate_locked_super(sb);
801 deactivate_super(sb);
802 return err; 829 return err;
803 } 830 }
804 831
@@ -854,8 +881,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
854 881
855 if (s->s_root) { 882 if (s->s_root) {
856 if ((flags ^ s->s_flags) & MS_RDONLY) { 883 if ((flags ^ s->s_flags) & MS_RDONLY) {
857 up_write(&s->s_umount); 884 deactivate_locked_super(s);
858 deactivate_super(s);
859 error = -EBUSY; 885 error = -EBUSY;
860 goto error_bdev; 886 goto error_bdev;
861 } 887 }
@@ -870,8 +896,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
870 sb_set_blocksize(s, block_size(bdev)); 896 sb_set_blocksize(s, block_size(bdev));
871 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 897 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
872 if (error) { 898 if (error) {
873 up_write(&s->s_umount); 899 deactivate_locked_super(s);
874 deactivate_super(s);
875 goto error; 900 goto error;
876 } 901 }
877 902
@@ -897,7 +922,7 @@ void kill_block_super(struct super_block *sb)
897 struct block_device *bdev = sb->s_bdev; 922 struct block_device *bdev = sb->s_bdev;
898 fmode_t mode = sb->s_mode; 923 fmode_t mode = sb->s_mode;
899 924
900 bdev->bd_super = 0; 925 bdev->bd_super = NULL;
901 generic_shutdown_super(sb); 926 generic_shutdown_super(sb);
902 sync_blockdev(bdev); 927 sync_blockdev(bdev);
903 close_bdev_exclusive(bdev, mode); 928 close_bdev_exclusive(bdev, mode);
@@ -921,8 +946,7 @@ int get_sb_nodev(struct file_system_type *fs_type,
921 946
922 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 947 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
923 if (error) { 948 if (error) {
924 up_write(&s->s_umount); 949 deactivate_locked_super(s);
925 deactivate_super(s);
926 return error; 950 return error;
927 } 951 }
928 s->s_flags |= MS_ACTIVE; 952 s->s_flags |= MS_ACTIVE;
@@ -952,8 +976,7 @@ int get_sb_single(struct file_system_type *fs_type,
952 s->s_flags = flags; 976 s->s_flags = flags;
953 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 977 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
954 if (error) { 978 if (error) {
955 up_write(&s->s_umount); 979 deactivate_locked_super(s);
956 deactivate_super(s);
957 return error; 980 return error;
958 } 981 }
959 s->s_flags |= MS_ACTIVE; 982 s->s_flags |= MS_ACTIVE;
@@ -1006,8 +1029,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
1006 return mnt; 1029 return mnt;
1007out_sb: 1030out_sb:
1008 dput(mnt->mnt_root); 1031 dput(mnt->mnt_root);
1009 up_write(&mnt->mnt_sb->s_umount); 1032 deactivate_locked_super(mnt->mnt_sb);
1010 deactivate_super(mnt->mnt_sb);
1011out_free_secdata: 1033out_free_secdata:
1012 free_secdata(secdata); 1034 free_secdata(secdata);
1013out_mnt: 1035out_mnt:
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index faa44f90608a..e9f7a754c4f7 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2055,8 +2055,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
2055 return 0; 2055 return 0;
2056 2056
2057out_deact: 2057out_deact:
2058 up_write(&sb->s_umount); 2058 deactivate_locked_super(sb);
2059 deactivate_super(sb);
2060out_close: 2059out_close:
2061 ubi_close_volume(ubi); 2060 ubi_close_volume(ubi);
2062 return err; 2061 return err;
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index dbbbc4668769..6321b797061b 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -666,6 +666,6 @@ not_empty:
666const struct file_operations ufs_dir_operations = { 666const struct file_operations ufs_dir_operations = {
667 .read = generic_read_dir, 667 .read = generic_read_dir,
668 .readdir = ufs_readdir, 668 .readdir = ufs_readdir,
669 .fsync = file_fsync, 669 .fsync = ufs_sync_file,
670 .llseek = generic_file_llseek, 670 .llseek = generic_file_llseek,
671}; 671};
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 625ef17c6f83..2bd3a1615714 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -30,7 +30,7 @@
30#include "ufs.h" 30#include "ufs.h"
31 31
32 32
33static int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync) 33int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
34{ 34{
35 struct inode *inode = dentry->d_inode; 35 struct inode *inode = dentry->d_inode;
36 int err; 36 int err;
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 69b3427d7885..d0c4acd4f1f3 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -98,8 +98,8 @@ extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
98/* file.c */ 98/* file.c */
99extern const struct inode_operations ufs_file_inode_operations; 99extern const struct inode_operations ufs_file_inode_operations;
100extern const struct file_operations ufs_file_operations; 100extern const struct file_operations ufs_file_operations;
101
102extern const struct address_space_operations ufs_aops; 101extern const struct address_space_operations ufs_aops;
102extern int ufs_sync_file(struct file *, struct dentry *, int);
103 103
104/* ialloc.c */ 104/* ialloc.c */
105extern void ufs_free_inode (struct inode *inode); 105extern void ufs_free_inode (struct inode *inode);