aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/v9fs_vfs.h2
-rw-r--r--fs/9p/vfs_file.c4
-rw-r--r--fs/9p/vfs_inode.c18
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/Kconfig.binfmt2
-rw-r--r--fs/afs/callback.c2
-rw-r--r--fs/afs/inode.c2
-rw-r--r--fs/afs/super.c2
-rw-r--r--fs/aio.c4
-rw-r--r--fs/binfmt_elf.c3
-rw-r--r--fs/binfmt_elf_fdpic.c2
-rw-r--r--fs/binfmt_flat.c8
-rw-r--r--fs/block_dev.c16
-rw-r--r--fs/buffer.c13
-rw-r--r--fs/cifs/AUTHORS1
-rw-r--r--fs/cifs/CHANGES10
-rw-r--r--fs/cifs/README5
-rw-r--r--fs/cifs/TODO15
-rw-r--r--fs/cifs/asn1.c14
-rw-r--r--fs/cifs/cifs_dfs_ref.c49
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifs_spnego.c3
-rw-r--r--fs/cifs/cifsfs.c65
-rw-r--r--fs/cifs/cifsfs.h3
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/cifspdu.h48
-rw-r--r--fs/cifs/cifsproto.h13
-rw-r--r--fs/cifs/cifssmb.c339
-rw-r--r--fs/cifs/connect.c73
-rw-r--r--fs/cifs/dir.c34
-rw-r--r--fs/cifs/dns_resolve.c9
-rw-r--r--fs/cifs/file.c13
-rw-r--r--fs/cifs/inode.c567
-rw-r--r--fs/cifs/ioctl.c4
-rw-r--r--fs/cifs/link.c43
-rw-r--r--fs/cifs/misc.c3
-rw-r--r--fs/cifs/netmisc.c6
-rw-r--r--fs/cifs/ntlmssp.h4
-rw-r--r--fs/cifs/readdir.c84
-rw-r--r--fs/dcache.c68
-rw-r--r--fs/ecryptfs/crypto.c2
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h2
-rw-r--r--fs/ecryptfs/miscdev.c28
-rw-r--r--fs/ecryptfs/read_write.c22
-rw-r--r--fs/exec.c9
-rw-r--r--fs/ext3/resize.c3
-rw-r--r--fs/ext3/super.c4
-rw-r--r--fs/ext4/balloc.c71
-rw-r--r--fs/ext4/mballoc.c8
-rw-r--r--fs/ext4/resize.c6
-rw-r--r--fs/ext4/super.c40
-rw-r--r--fs/fat/file.c44
-rw-r--r--fs/fuse/inode.c11
-rw-r--r--fs/gfs2/bmap.c23
-rw-r--r--fs/gfs2/glops.c2
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/inode.c10
-rw-r--r--fs/gfs2/meta_io.c6
-rw-r--r--fs/gfs2/ops_fstype.c4
-rw-r--r--fs/gfs2/ops_super.c16
-rw-r--r--fs/gfs2/rgrp.c4
-rw-r--r--fs/hppfs/Makefile5
-rw-r--r--fs/jbd2/commit.c1
-rw-r--r--fs/jbd2/recovery.c12
-rw-r--r--fs/libfs.c46
-rw-r--r--fs/locks.c6
-rw-r--r--fs/namei.c26
-rw-r--r--fs/nfs/mount_clnt.c5
-rw-r--r--fs/nfs/super.c76
-rw-r--r--fs/nfs/write.c7
-rw-r--r--fs/nfsd/nfs4callback.c2
-rw-r--r--fs/ntfs/upcase.c5
-rw-r--r--fs/ocfs2/alloc.c4
-rw-r--r--fs/ocfs2/cluster/nodemanager.c74
-rw-r--r--fs/ocfs2/cluster/nodemanager.h4
-rw-r--r--fs/ocfs2/cluster/tcp.c28
-rw-r--r--fs/ocfs2/cluster/tcp.h12
-rw-r--r--fs/ocfs2/cluster/tcp_internal.h32
-rw-r--r--fs/ocfs2/dlm/dlmdebug.h12
-rw-r--r--fs/ocfs2/stack_o2cb.c41
-rw-r--r--fs/ocfs2/stack_user.c37
-rw-r--r--fs/ocfs2/stackglue.c119
-rw-r--r--fs/ocfs2/stackglue.h19
-rw-r--r--fs/open.c37
-rw-r--r--fs/pipe.c10
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/base.c33
-rw-r--r--fs/proc/inode.c3
-rw-r--r--fs/proc/proc_misc.c24
-rw-r--r--fs/proc/task_mmu.c175
-rw-r--r--fs/reiserfs/super.c4
-rw-r--r--fs/select.c2
-rw-r--r--fs/splice.c17
-rw-r--r--fs/sysfs/dir.c6
-rw-r--r--fs/udf/super.c57
-rw-r--r--fs/udf/udfdecl.h2
-rw-r--r--fs/utimes.c59
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c24
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h19
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c17
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h8
-rw-r--r--fs/xfs/xfs_inode.c9
-rw-r--r--fs/xfs/xfs_vnodeops.c112
-rw-r--r--fs/xfs/xfs_vnodeops.h3
104 files changed, 1699 insertions, 1371 deletions
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index fd01d90cada..57997fa14e6 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -51,4 +51,4 @@ int v9fs_dir_release(struct inode *inode, struct file *filp);
51int v9fs_file_open(struct inode *inode, struct file *file); 51int v9fs_file_open(struct inode *inode, struct file *file);
52void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat); 52void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat);
53void v9fs_dentry_release(struct dentry *); 53void v9fs_dentry_release(struct dentry *);
54int v9fs_uflags2omode(int uflags); 54int v9fs_uflags2omode(int uflags, int extended);
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 0d55affe37d..52944d2249a 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -59,7 +59,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
59 59
60 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file); 60 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file);
61 v9ses = v9fs_inode2v9ses(inode); 61 v9ses = v9fs_inode2v9ses(inode);
62 omode = v9fs_uflags2omode(file->f_flags); 62 omode = v9fs_uflags2omode(file->f_flags, v9fs_extended(v9ses));
63 fid = file->private_data; 63 fid = file->private_data;
64 if (!fid) { 64 if (!fid) {
65 fid = v9fs_fid_clone(file->f_path.dentry); 65 fid = v9fs_fid_clone(file->f_path.dentry);
@@ -75,6 +75,8 @@ int v9fs_file_open(struct inode *inode, struct file *file)
75 inode->i_size = 0; 75 inode->i_size = 0;
76 inode->i_blocks = 0; 76 inode->i_blocks = 0;
77 } 77 }
78 if ((file->f_flags & O_APPEND) && (!v9fs_extended(v9ses)))
79 generic_file_llseek(file, 0, SEEK_END);
78 } 80 }
79 81
80 file->private_data = fid; 82 file->private_data = fid;
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 40fa807bd92..c95295c6504 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -132,10 +132,10 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
132/** 132/**
133 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits 133 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
134 * @uflags: flags to convert 134 * @uflags: flags to convert
135 * 135 * @extended: if .u extensions are active
136 */ 136 */
137 137
138int v9fs_uflags2omode(int uflags) 138int v9fs_uflags2omode(int uflags, int extended)
139{ 139{
140 int ret; 140 int ret;
141 141
@@ -155,14 +155,16 @@ int v9fs_uflags2omode(int uflags)
155 break; 155 break;
156 } 156 }
157 157
158 if (uflags & O_EXCL)
159 ret |= P9_OEXCL;
160
161 if (uflags & O_TRUNC) 158 if (uflags & O_TRUNC)
162 ret |= P9_OTRUNC; 159 ret |= P9_OTRUNC;
163 160
164 if (uflags & O_APPEND) 161 if (extended) {
165 ret |= P9_OAPPEND; 162 if (uflags & O_EXCL)
163 ret |= P9_OEXCL;
164
165 if (uflags & O_APPEND)
166 ret |= P9_OAPPEND;
167 }
166 168
167 return ret; 169 return ret;
168} 170}
@@ -506,7 +508,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
506 flags = O_RDWR; 508 flags = O_RDWR;
507 509
508 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, 510 fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
509 v9fs_uflags2omode(flags)); 511 v9fs_uflags2omode(flags, v9fs_extended(v9ses)));
510 if (IS_ERR(fid)) { 512 if (IS_ERR(fid)) {
511 err = PTR_ERR(fid); 513 err = PTR_ERR(fid);
512 fid = NULL; 514 fid = NULL;
diff --git a/fs/Kconfig b/fs/Kconfig
index cf12c403b8c..2694648cbd1 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -830,7 +830,7 @@ config NTFS_FS
830 from the project web site. 830 from the project web site.
831 831
832 For more information see <file:Documentation/filesystems/ntfs.txt> 832 For more information see <file:Documentation/filesystems/ntfs.txt>
833 and <http://linux-ntfs.sourceforge.net/>. 833 and <http://www.linux-ntfs.org/>.
834 834
835 To compile this file system support as a module, choose M here: the 835 To compile this file system support as a module, choose M here: the
836 module will be called ntfs. 836 module will be called ntfs.
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 55e8ee1900a..3263084eef9 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -42,7 +42,7 @@ config BINFMT_ELF_FDPIC
42 42
43config BINFMT_FLAT 43config BINFMT_FLAT
44 bool "Kernel support for flat binaries" 44 bool "Kernel support for flat binaries"
45 depends on !MMU 45 depends on !MMU && (!FRV || BROKEN)
46 help 46 help
47 Support uClinux FLAT format binaries. 47 Support uClinux FLAT format binaries.
48 48
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index a78d5b236bb..587ef5123cd 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -8,7 +8,7 @@
8 * along with this program; if not, write to the Free Software 8 * along with this program; if not, write to the Free Software
9 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 9 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10 * 10 *
11 * Authors: David Woodhouse <dwmw2@cambridge.redhat.com> 11 * Authors: David Woodhouse <dwmw2@infradead.org>
12 * David Howells <dhowells@redhat.com> 12 * David Howells <dhowells@redhat.com>
13 * 13 *
14 */ 14 */
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 08db82e1343..bb47217f6a1 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -8,7 +8,7 @@
8 * along with this program; if not, write to the Free Software 8 * along with this program; if not, write to the Free Software
9 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 9 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10 * 10 *
11 * Authors: David Woodhouse <dwmw2@cambridge.redhat.com> 11 * Authors: David Woodhouse <dwmw2@infradead.org>
12 * David Howells <dhowells@redhat.com> 12 * David Howells <dhowells@redhat.com>
13 * 13 *
14 */ 14 */
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 4b572b801d8..7e3faeef681 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -10,7 +10,7 @@
10 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 10 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11 * 11 *
12 * Authors: David Howells <dhowells@redhat.com> 12 * Authors: David Howells <dhowells@redhat.com>
13 * David Woodhouse <dwmw2@redhat.com> 13 * David Woodhouse <dwmw2@infradead.org>
14 * 14 *
15 */ 15 */
16 16
diff --git a/fs/aio.c b/fs/aio.c
index b5253e77eb2..0fb3117ddd9 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -591,10 +591,6 @@ static void use_mm(struct mm_struct *mm)
591 atomic_inc(&mm->mm_count); 591 atomic_inc(&mm->mm_count);
592 tsk->mm = mm; 592 tsk->mm = mm;
593 tsk->active_mm = mm; 593 tsk->active_mm = mm;
594 /*
595 * Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise
596 * it won't work. Update it accordingly if you change it here
597 */
598 switch_mm(active_mm, mm, tsk); 594 switch_mm(active_mm, mm, tsk);
599 task_unlock(tsk); 595 task_unlock(tsk);
600 596
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 0fa95b198e6..d48ff5f370f 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -16,7 +16,6 @@
16#include <linux/time.h> 16#include <linux/time.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/mman.h> 18#include <linux/mman.h>
19#include <linux/a.out.h>
20#include <linux/errno.h> 19#include <linux/errno.h>
21#include <linux/signal.h> 20#include <linux/signal.h>
22#include <linux/binfmts.h> 21#include <linux/binfmts.h>
@@ -548,7 +547,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
548 struct { 547 struct {
549 struct elfhdr elf_ex; 548 struct elfhdr elf_ex;
550 struct elfhdr interp_elf_ex; 549 struct elfhdr interp_elf_ex;
551 struct exec interp_ex;
552 } *loc; 550 } *loc;
553 551
554 loc = kmalloc(sizeof(*loc), GFP_KERNEL); 552 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
@@ -680,7 +678,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
680 } 678 }
681 679
682 /* Get the exec headers */ 680 /* Get the exec headers */
683 loc->interp_ex = *((struct exec *)bprm->buf);
684 loc->interp_elf_ex = *((struct elfhdr *)bprm->buf); 681 loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
685 break; 682 break;
686 } 683 }
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index ddd35d87339..d051a32e627 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -390,7 +390,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
390 } 390 }
391 391
392 /* expand the stack mapping to use up the entire allocation granule */ 392 /* expand the stack mapping to use up the entire allocation granule */
393 fullsize = ksize((char *) current->mm->start_brk); 393 fullsize = kobjsize((char *) current->mm->start_brk);
394 if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size, 394 if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size,
395 fullsize, 0, 0))) 395 fullsize, 0, 0)))
396 stack_size = fullsize; 396 stack_size = fullsize;
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 3b40d45a3a1..2cb1acda3a8 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -548,7 +548,7 @@ static int load_flat_file(struct linux_binprm * bprm,
548 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); 548 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
549 /* Remap to use all availabe slack region space */ 549 /* Remap to use all availabe slack region space */
550 if (realdatastart && (realdatastart < (unsigned long)-4096)) { 550 if (realdatastart && (realdatastart < (unsigned long)-4096)) {
551 reallen = ksize((void *)realdatastart); 551 reallen = kobjsize((void *)realdatastart);
552 if (reallen > len) { 552 if (reallen > len) {
553 realdatastart = do_mremap(realdatastart, len, 553 realdatastart = do_mremap(realdatastart, len,
554 reallen, MREMAP_FIXED, realdatastart); 554 reallen, MREMAP_FIXED, realdatastart);
@@ -600,7 +600,7 @@ static int load_flat_file(struct linux_binprm * bprm,
600 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); 600 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
601 /* Remap to use all availabe slack region space */ 601 /* Remap to use all availabe slack region space */
602 if (textpos && (textpos < (unsigned long) -4096)) { 602 if (textpos && (textpos < (unsigned long) -4096)) {
603 reallen = ksize((void *)textpos); 603 reallen = kobjsize((void *)textpos);
604 if (reallen > len) { 604 if (reallen > len) {
605 textpos = do_mremap(textpos, len, reallen, 605 textpos = do_mremap(textpos, len, reallen,
606 MREMAP_FIXED, textpos); 606 MREMAP_FIXED, textpos);
@@ -683,7 +683,7 @@ static int load_flat_file(struct linux_binprm * bprm,
683 */ 683 */
684 current->mm->start_brk = datapos + data_len + bss_len; 684 current->mm->start_brk = datapos + data_len + bss_len;
685 current->mm->brk = (current->mm->start_brk + 3) & ~3; 685 current->mm->brk = (current->mm->start_brk + 3) & ~3;
686 current->mm->context.end_brk = memp + ksize((void *) memp) - stack_len; 686 current->mm->context.end_brk = memp + kobjsize((void *) memp) - stack_len;
687 } 687 }
688 688
689 if (flags & FLAT_FLAG_KTRACE) 689 if (flags & FLAT_FLAG_KTRACE)
@@ -790,7 +790,7 @@ static int load_flat_file(struct linux_binprm * bprm,
790 790
791 /* zero the BSS, BRK and stack areas */ 791 /* zero the BSS, BRK and stack areas */
792 memset((void*)(datapos + data_len), 0, bss_len + 792 memset((void*)(datapos + data_len), 0, bss_len +
793 (memp + ksize((void *) memp) - stack_len - /* end brk */ 793 (memp + kobjsize((void *) memp) - stack_len - /* end brk */
794 libinfo->lib_list[id].start_brk) + /* start brk */ 794 libinfo->lib_list[id].start_brk) + /* start brk */
795 stack_len); 795 stack_len);
796 796
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 7d822fae776..10d8a0aa871 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -12,6 +12,7 @@
12#include <linux/kmod.h> 12#include <linux/kmod.h>
13#include <linux/major.h> 13#include <linux/major.h>
14#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
15#include <linux/device_cgroup.h>
15#include <linux/highmem.h> 16#include <linux/highmem.h>
16#include <linux/blkdev.h> 17#include <linux/blkdev.h>
17#include <linux/module.h> 18#include <linux/module.h>
@@ -928,9 +929,22 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
928{ 929{
929 struct module *owner = NULL; 930 struct module *owner = NULL;
930 struct gendisk *disk; 931 struct gendisk *disk;
931 int ret = -ENXIO; 932 int ret;
932 int part; 933 int part;
934 int perm = 0;
935
936 if (file->f_mode & FMODE_READ)
937 perm |= MAY_READ;
938 if (file->f_mode & FMODE_WRITE)
939 perm |= MAY_WRITE;
940 /*
941 * hooks: /n/, see "layering violations".
942 */
943 ret = devcgroup_inode_permission(bdev->bd_inode, perm);
944 if (ret != 0)
945 return ret;
933 946
947 ret = -ENXIO;
934 file->f_mapping = bdev->bd_inode->i_mapping; 948 file->f_mapping = bdev->bd_inode->i_mapping;
935 lock_kernel(); 949 lock_kernel();
936 disk = get_gendisk(bdev->bd_dev, &part); 950 disk = get_gendisk(bdev->bd_dev, &part);
diff --git a/fs/buffer.c b/fs/buffer.c
index a073f3f4f01..0f51c0f7c26 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -821,7 +821,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
821 * contents - it is a noop if I/O is still in 821 * contents - it is a noop if I/O is still in
822 * flight on potentially older contents. 822 * flight on potentially older contents.
823 */ 823 */
824 ll_rw_block(SWRITE, 1, &bh); 824 ll_rw_block(SWRITE_SYNC, 1, &bh);
825 brelse(bh); 825 brelse(bh);
826 spin_lock(lock); 826 spin_lock(lock);
827 } 827 }
@@ -2940,16 +2940,19 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
2940 for (i = 0; i < nr; i++) { 2940 for (i = 0; i < nr; i++) {
2941 struct buffer_head *bh = bhs[i]; 2941 struct buffer_head *bh = bhs[i];
2942 2942
2943 if (rw == SWRITE) 2943 if (rw == SWRITE || rw == SWRITE_SYNC)
2944 lock_buffer(bh); 2944 lock_buffer(bh);
2945 else if (test_set_buffer_locked(bh)) 2945 else if (test_set_buffer_locked(bh))
2946 continue; 2946 continue;
2947 2947
2948 if (rw == WRITE || rw == SWRITE) { 2948 if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC) {
2949 if (test_clear_buffer_dirty(bh)) { 2949 if (test_clear_buffer_dirty(bh)) {
2950 bh->b_end_io = end_buffer_write_sync; 2950 bh->b_end_io = end_buffer_write_sync;
2951 get_bh(bh); 2951 get_bh(bh);
2952 submit_bh(WRITE, bh); 2952 if (rw == SWRITE_SYNC)
2953 submit_bh(WRITE_SYNC, bh);
2954 else
2955 submit_bh(WRITE, bh);
2953 continue; 2956 continue;
2954 } 2957 }
2955 } else { 2958 } else {
@@ -2978,7 +2981,7 @@ int sync_dirty_buffer(struct buffer_head *bh)
2978 if (test_clear_buffer_dirty(bh)) { 2981 if (test_clear_buffer_dirty(bh)) {
2979 get_bh(bh); 2982 get_bh(bh);
2980 bh->b_end_io = end_buffer_write_sync; 2983 bh->b_end_io = end_buffer_write_sync;
2981 ret = submit_bh(WRITE, bh); 2984 ret = submit_bh(WRITE_SYNC, bh);
2982 wait_on_buffer(bh); 2985 wait_on_buffer(bh);
2983 if (buffer_eopnotsupp(bh)) { 2986 if (buffer_eopnotsupp(bh)) {
2984 clear_buffer_eopnotsupp(bh); 2987 clear_buffer_eopnotsupp(bh);
diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS
index 8848e4dfa02..9c136d7803d 100644
--- a/fs/cifs/AUTHORS
+++ b/fs/cifs/AUTHORS
@@ -36,6 +36,7 @@ Miklos Szeredi
36Kazeon team for various fixes especially for 2.4 version. 36Kazeon team for various fixes especially for 2.4 version.
37Asser Ferno (Change Notify support) 37Asser Ferno (Change Notify support)
38Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup 38Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup
39Igor Mammedov (DFS support)
39 40
40Test case and Bug Report contributors 41Test case and Bug Report contributors
41------------------------------------- 42-------------------------------------
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 8355e918fdd..1f3465201fd 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,5 +1,12 @@
1Version 1.53 1Version 1.53
2------------ 2------------
3DFS support added (Microsoft Distributed File System client support needed
4for referrals which enable a hierarchical name space among servers).
5Disable temporary caching of mode bits to servers which do not support
6storing of mode (e.g. Windows servers, when client mounts without cifsacl
7mount option) and add new "dynperm" mount option to enable temporary caching
8of mode (enable old behavior). Fix hang on mount caused when server crashes
9tcp session during negotiate protocol.
3 10
4Version 1.52 11Version 1.52
5------------ 12------------
@@ -12,7 +19,8 @@ Add ability to modify cifs acls for handling chmod (when mounted with
12cifsacl flag). Fix prefixpath path separator so we can handle mounts 19cifsacl flag). Fix prefixpath path separator so we can handle mounts
13with prefixpaths longer than one directory (one path component) when 20with prefixpaths longer than one directory (one path component) when
14mounted to Windows servers. Fix slow file open when cifsacl 21mounted to Windows servers. Fix slow file open when cifsacl
15enabled. 22enabled. Fix memory leak in FindNext when the SMB call returns -EBADF.
23
16 24
17Version 1.51 25Version 1.51
18------------ 26------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 621aa1a8597..2bd6fe556f8 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -483,6 +483,11 @@ A partial list of the supported mount options follows:
483 sign Must use packet signing (helps avoid unwanted data modification 483 sign Must use packet signing (helps avoid unwanted data modification
484 by intermediate systems in the route). Note that signing 484 by intermediate systems in the route). Note that signing
485 does not work with lanman or plaintext authentication. 485 does not work with lanman or plaintext authentication.
486 seal Must seal (encrypt) all data on this mounted share before
487 sending on the network. Requires support for Unix Extensions.
488 Note that this differs from the sign mount option in that it
489 causes encryption of data sent over this mounted share but other
490 shares mounted to the same server are unaffected.
486 sec Security mode. Allowed values are: 491 sec Security mode. Allowed values are:
487 none attempt to connection as a null user (no name) 492 none attempt to connection as a null user (no name)
488 krb5 Use Kerberos version 5 authentication 493 krb5 Use Kerberos version 5 authentication
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 92c9feac440..5aff46c61e5 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,4 +1,4 @@
1Version 1.52 January 3, 2008 1Version 1.53 May 20, 2008
2 2
3A Partial List of Missing Features 3A Partial List of Missing Features
4================================== 4==================================
@@ -20,20 +20,21 @@ d) Cleanup now unneeded SessSetup code in
20fs/cifs/connect.c and add back in NTLMSSP code if any servers 20fs/cifs/connect.c and add back in NTLMSSP code if any servers
21need it 21need it
22 22
23e) ms-dfs and ms-dfs host name resolution cleanup 23e) fix NTLMv2 signing when two mounts with different users to same
24
25f) fix NTLMv2 signing when two mounts with different users to same
26server. 24server.
27 25
28g) Directory entry caching relies on a 1 second timer, rather than 26f) Directory entry caching relies on a 1 second timer, rather than
29using FindNotify or equivalent. - (started) 27using FindNotify or equivalent. - (started)
30 28
31h) quota support (needs minor kernel change since quota calls 29g) quota support (needs minor kernel change since quota calls
32to make it to network filesystems or deviceless filesystems) 30to make it to network filesystems or deviceless filesystems)
33 31
34i) investigate sync behavior (including syncpage) and check 32h) investigate sync behavior (including syncpage) and check
35for proper behavior of intr/nointr 33for proper behavior of intr/nointr
36 34
35i) improve support for very old servers (OS/2 and Win9x for example)
36Including support for changing the time remotely (utimes command).
37
37j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the 38j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
38extra copy in/out of the socket buffers in some cases. 39extra copy in/out of the socket buffers in some cases.
39 40
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index cb52cbbe45f..f58e41d3ba4 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -186,6 +186,11 @@ asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
186 } 186 }
187 } 187 }
188 } 188 }
189
190 /* don't trust len bigger than ctx buffer */
191 if (*len > ctx->end - ctx->pointer)
192 return 0;
193
189 return 1; 194 return 1;
190} 195}
191 196
@@ -203,6 +208,10 @@ asn1_header_decode(struct asn1_ctx *ctx,
203 if (!asn1_length_decode(ctx, &def, &len)) 208 if (!asn1_length_decode(ctx, &def, &len))
204 return 0; 209 return 0;
205 210
211 /* primitive shall be definite, indefinite shall be constructed */
212 if (*con == ASN1_PRI && !def)
213 return 0;
214
206 if (def) 215 if (def)
207 *eoc = ctx->pointer + len; 216 *eoc = ctx->pointer + len;
208 else 217 else
@@ -389,6 +398,11 @@ asn1_oid_decode(struct asn1_ctx *ctx,
389 unsigned long *optr; 398 unsigned long *optr;
390 399
391 size = eoc - ctx->pointer + 1; 400 size = eoc - ctx->pointer + 1;
401
402 /* first subid actually encodes first two subids */
403 if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
404 return 0;
405
392 *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); 406 *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
393 if (*oid == NULL) 407 if (*oid == NULL)
394 return 0; 408 return 0;
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index f6fdecf6598..d82374c9e32 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -219,53 +219,6 @@ static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent,
219 219
220} 220}
221 221
222static char *build_full_dfs_path_from_dentry(struct dentry *dentry)
223{
224 char *full_path = NULL;
225 char *search_path;
226 char *tmp_path;
227 size_t l_max_len;
228 struct cifs_sb_info *cifs_sb;
229
230 if (dentry->d_inode == NULL)
231 return NULL;
232
233 cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
234
235 if (cifs_sb->tcon == NULL)
236 return NULL;
237
238 search_path = build_path_from_dentry(dentry);
239 if (search_path == NULL)
240 return NULL;
241
242 if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) {
243 int i;
244 /* we should use full path name for correct working with DFS */
245 l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) +
246 strnlen(search_path, MAX_PATHCONF) + 1;
247 tmp_path = kmalloc(l_max_len, GFP_KERNEL);
248 if (tmp_path == NULL) {
249 kfree(search_path);
250 return NULL;
251 }
252 strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len);
253 tmp_path[l_max_len-1] = 0;
254 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
255 for (i = 0; i < l_max_len; i++) {
256 if (tmp_path[i] == '\\')
257 tmp_path[i] = '/';
258 }
259 strncat(tmp_path, search_path, l_max_len - strlen(tmp_path));
260
261 full_path = tmp_path;
262 kfree(search_path);
263 } else {
264 full_path = search_path;
265 }
266 return full_path;
267}
268
269static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd, 222static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
270 struct list_head *mntlist) 223 struct list_head *mntlist)
271{ 224{
@@ -333,7 +286,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
333 goto out_err; 286 goto out_err;
334 } 287 }
335 288
336 full_path = build_full_dfs_path_from_dentry(dentry); 289 full_path = build_path_from_dentry(dentry);
337 if (full_path == NULL) { 290 if (full_path == NULL) {
338 rc = -ENOMEM; 291 rc = -ENOMEM;
339 goto out_err; 292 goto out_err;
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 8ad2330ba06..877c85409f1 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -30,6 +30,7 @@
30#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ 30#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */
31#define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */ 31#define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */
32#define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */ 32#define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */
33#define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */
33 34
34struct cifs_sb_info { 35struct cifs_sb_info {
35 struct cifsTconInfo *tcon; /* primary mount */ 36 struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 6653e29637a..7013aaff6ae 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -119,6 +119,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
119 dp = description + strlen(description); 119 dp = description + strlen(description);
120 sprintf(dp, ";uid=0x%x", sesInfo->linux_uid); 120 sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);
121 121
122 dp = description + strlen(description);
123 sprintf(dp, ";user=%s", sesInfo->userName);
124
122 cFYI(1, ("key description = %s", description)); 125 cFYI(1, ("key description = %s", description));
123 spnego_key = request_key(&cifs_spnego_key_type, description, ""); 126 spnego_key = request_key(&cifs_spnego_key_type, description, "");
124 127
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 427a7c69589..86b4d5f405a 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsfs.c 2 * fs/cifs/cifsfs.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2007 4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Common Internet FileSystem (CIFS) client 7 * Common Internet FileSystem (CIFS) client
@@ -97,9 +97,6 @@ cifs_read_super(struct super_block *sb, void *data,
97{ 97{
98 struct inode *inode; 98 struct inode *inode;
99 struct cifs_sb_info *cifs_sb; 99 struct cifs_sb_info *cifs_sb;
100#ifdef CONFIG_CIFS_DFS_UPCALL
101 int len;
102#endif
103 int rc = 0; 100 int rc = 0;
104 101
105 /* BB should we make this contingent on mount parm? */ 102 /* BB should we make this contingent on mount parm? */
@@ -117,15 +114,17 @@ cifs_read_super(struct super_block *sb, void *data,
117 * complex operation (mount), and in case of fail 114 * complex operation (mount), and in case of fail
118 * just exit instead of doing mount and attempting 115 * just exit instead of doing mount and attempting
119 * undo it if this copy fails?*/ 116 * undo it if this copy fails?*/
120 len = strlen(data); 117 if (data) {
121 cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); 118 int len = strlen(data);
122 if (cifs_sb->mountdata == NULL) { 119 cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
123 kfree(sb->s_fs_info); 120 if (cifs_sb->mountdata == NULL) {
124 sb->s_fs_info = NULL; 121 kfree(sb->s_fs_info);
125 return -ENOMEM; 122 sb->s_fs_info = NULL;
123 return -ENOMEM;
124 }
125 strncpy(cifs_sb->mountdata, data, len + 1);
126 cifs_sb->mountdata[len] = '\0';
126 } 127 }
127 strncpy(cifs_sb->mountdata, data, len + 1);
128 cifs_sb->mountdata[len] = '\0';
129#endif 128#endif
130 129
131 rc = cifs_mount(sb, cifs_sb, data, devname); 130 rc = cifs_mount(sb, cifs_sb, data, devname);
@@ -353,9 +352,41 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
353 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || 352 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
354 !(cifs_sb->tcon->unix_ext)) 353 !(cifs_sb->tcon->unix_ext))
355 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); 354 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
355 if (!cifs_sb->tcon->unix_ext) {
356 seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
357 cifs_sb->mnt_file_mode,
358 cifs_sb->mnt_dir_mode);
359 }
360 if (cifs_sb->tcon->seal)
361 seq_printf(s, ",seal");
362 if (cifs_sb->tcon->nocase)
363 seq_printf(s, ",nocase");
364 if (cifs_sb->tcon->retry)
365 seq_printf(s, ",hard");
356 } 366 }
357 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 367 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
358 seq_printf(s, ",posixpaths"); 368 seq_printf(s, ",posixpaths");
369 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
370 seq_printf(s, ",setuids");
371 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
372 seq_printf(s, ",serverino");
373 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
374 seq_printf(s, ",directio");
375 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
376 seq_printf(s, ",nouser_xattr");
377 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
378 seq_printf(s, ",mapchars");
379 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
380 seq_printf(s, ",sfu");
381 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
382 seq_printf(s, ",nobrl");
383 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
384 seq_printf(s, ",cifsacl");
385 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
386 seq_printf(s, ",dynperm");
387 if (m->mnt_sb->s_flags & MS_POSIXACL)
388 seq_printf(s, ",acl");
389
359 seq_printf(s, ",rsize=%d", cifs_sb->rsize); 390 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
360 seq_printf(s, ",wsize=%d", cifs_sb->wsize); 391 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
361 } 392 }
@@ -657,7 +688,7 @@ const struct file_operations cifs_file_ops = {
657 .splice_read = generic_file_splice_read, 688 .splice_read = generic_file_splice_read,
658 .llseek = cifs_llseek, 689 .llseek = cifs_llseek,
659#ifdef CONFIG_CIFS_POSIX 690#ifdef CONFIG_CIFS_POSIX
660 .ioctl = cifs_ioctl, 691 .unlocked_ioctl = cifs_ioctl,
661#endif /* CONFIG_CIFS_POSIX */ 692#endif /* CONFIG_CIFS_POSIX */
662 693
663#ifdef CONFIG_CIFS_EXPERIMENTAL 694#ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -677,7 +708,7 @@ const struct file_operations cifs_file_direct_ops = {
677 .flush = cifs_flush, 708 .flush = cifs_flush,
678 .splice_read = generic_file_splice_read, 709 .splice_read = generic_file_splice_read,
679#ifdef CONFIG_CIFS_POSIX 710#ifdef CONFIG_CIFS_POSIX
680 .ioctl = cifs_ioctl, 711 .unlocked_ioctl = cifs_ioctl,
681#endif /* CONFIG_CIFS_POSIX */ 712#endif /* CONFIG_CIFS_POSIX */
682 .llseek = cifs_llseek, 713 .llseek = cifs_llseek,
683#ifdef CONFIG_CIFS_EXPERIMENTAL 714#ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -697,7 +728,7 @@ const struct file_operations cifs_file_nobrl_ops = {
697 .splice_read = generic_file_splice_read, 728 .splice_read = generic_file_splice_read,
698 .llseek = cifs_llseek, 729 .llseek = cifs_llseek,
699#ifdef CONFIG_CIFS_POSIX 730#ifdef CONFIG_CIFS_POSIX
700 .ioctl = cifs_ioctl, 731 .unlocked_ioctl = cifs_ioctl,
701#endif /* CONFIG_CIFS_POSIX */ 732#endif /* CONFIG_CIFS_POSIX */
702 733
703#ifdef CONFIG_CIFS_EXPERIMENTAL 734#ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -716,7 +747,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
716 .flush = cifs_flush, 747 .flush = cifs_flush,
717 .splice_read = generic_file_splice_read, 748 .splice_read = generic_file_splice_read,
718#ifdef CONFIG_CIFS_POSIX 749#ifdef CONFIG_CIFS_POSIX
719 .ioctl = cifs_ioctl, 750 .unlocked_ioctl = cifs_ioctl,
720#endif /* CONFIG_CIFS_POSIX */ 751#endif /* CONFIG_CIFS_POSIX */
721 .llseek = cifs_llseek, 752 .llseek = cifs_llseek,
722#ifdef CONFIG_CIFS_EXPERIMENTAL 753#ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -731,7 +762,7 @@ const struct file_operations cifs_dir_ops = {
731#ifdef CONFIG_CIFS_EXPERIMENTAL 762#ifdef CONFIG_CIFS_EXPERIMENTAL
732 .dir_notify = cifs_dir_notify, 763 .dir_notify = cifs_dir_notify,
733#endif /* CONFIG_CIFS_EXPERIMENTAL */ 764#endif /* CONFIG_CIFS_EXPERIMENTAL */
734 .ioctl = cifs_ioctl, 765 .unlocked_ioctl = cifs_ioctl,
735}; 766};
736 767
737static void 768static void
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index cd1301a09b3..25a6cbd1552 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -95,8 +95,7 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *,
95 size_t, int); 95 size_t, int);
96extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); 96extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
97extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 97extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
98extern int cifs_ioctl(struct inode *inode, struct file *filep, 98extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
99 unsigned int command, unsigned long arg);
100 99
101#ifdef CONFIG_CIFS_EXPERIMENTAL 100#ifdef CONFIG_CIFS_EXPERIMENTAL
102extern const struct export_operations cifs_export_ops; 101extern const struct export_operations cifs_export_ops;
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b7d9f698e63..9cfcf326ead 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -281,6 +281,7 @@ struct cifsTconInfo {
281 bool ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */ 281 bool ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */
282 bool retry:1; 282 bool retry:1;
283 bool nocase:1; 283 bool nocase:1;
284 bool seal:1; /* transport encryption for this mounted share */
284 bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol 285 bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
285 for this mount even if server would support */ 286 for this mount even if server would support */
286 /* BB add field for back pointer to sb struct(s)? */ 287 /* BB add field for back pointer to sb struct(s)? */
@@ -332,7 +333,6 @@ struct cifsFileInfo {
332 bool messageMode:1; /* for pipes: message vs byte mode */ 333 bool messageMode:1; /* for pipes: message vs byte mode */
333 atomic_t wrtPending; /* handle in use - defer close */ 334 atomic_t wrtPending; /* handle in use - defer close */
334 struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 335 struct semaphore fh_sem; /* prevents reopen race after dead ses*/
335 char *search_resume_name; /* BB removeme BB */
336 struct cifs_search_info srch_inf; 336 struct cifs_search_info srch_inf;
337}; 337};
338 338
@@ -625,7 +625,7 @@ GLOBAL_EXTERN atomic_t tcpSesAllocCount;
625GLOBAL_EXTERN atomic_t tcpSesReconnectCount; 625GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
626GLOBAL_EXTERN atomic_t tconInfoReconnectCount; 626GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
627 627
628/* Various Debug counters to remove someday (BB) */ 628/* Various Debug counters */
629GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */ 629GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */
630#ifdef CONFIG_CIFS_STATS2 630#ifdef CONFIG_CIFS_STATS2
631GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */ 631GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index c43bf4b7a55..0f327c224da 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -79,6 +79,19 @@
79#define TRANS2_GET_DFS_REFERRAL 0x10 79#define TRANS2_GET_DFS_REFERRAL 0x10
80#define TRANS2_REPORT_DFS_INCOSISTENCY 0x11 80#define TRANS2_REPORT_DFS_INCOSISTENCY 0x11
81 81
82/* SMB Transact (Named Pipe) subcommand codes */
83#define TRANS_SET_NMPIPE_STATE 0x0001
84#define TRANS_RAW_READ_NMPIPE 0x0011
85#define TRANS_QUERY_NMPIPE_STATE 0x0021
86#define TRANS_QUERY_NMPIPE_INFO 0x0022
87#define TRANS_PEEK_NMPIPE 0x0023
88#define TRANS_TRANSACT_NMPIPE 0x0026
89#define TRANS_RAW_WRITE_NMPIPE 0x0031
90#define TRANS_READ_NMPIPE 0x0036
91#define TRANS_WRITE_NMPIPE 0x0037
92#define TRANS_WAIT_NMPIPE 0x0053
93#define TRANS_CALL_NMPIPE 0x0054
94
82/* NT Transact subcommand codes */ 95/* NT Transact subcommand codes */
83#define NT_TRANSACT_CREATE 0x01 96#define NT_TRANSACT_CREATE 0x01
84#define NT_TRANSACT_IOCTL 0x02 97#define NT_TRANSACT_IOCTL 0x02
@@ -328,12 +341,13 @@
328#define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */ 341#define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */
329#define CREATE_NO_EA_KNOWLEDGE 0x00000200 342#define CREATE_NO_EA_KNOWLEDGE 0x00000200
330#define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete 343#define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete
331 open for recovery flag - should 344 "open for recovery" flag - should
332 be zero */ 345 be zero in any case */
346#define CREATE_OPEN_FOR_RECOVERY 0x00000400
333#define CREATE_RANDOM_ACCESS 0x00000800 347#define CREATE_RANDOM_ACCESS 0x00000800
334#define CREATE_DELETE_ON_CLOSE 0x00001000 348#define CREATE_DELETE_ON_CLOSE 0x00001000
335#define CREATE_OPEN_BY_ID 0x00002000 349#define CREATE_OPEN_BY_ID 0x00002000
336#define CREATE_OPEN_BACKUP_INTN 0x00004000 350#define CREATE_OPEN_BACKUP_INTENT 0x00004000
337#define CREATE_NO_COMPRESSION 0x00008000 351#define CREATE_NO_COMPRESSION 0x00008000
338#define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */ 352#define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */
339#define OPEN_REPARSE_POINT 0x00200000 353#define OPEN_REPARSE_POINT 0x00200000
@@ -722,7 +736,6 @@ typedef struct smb_com_tconx_rsp_ext {
722#define SMB_CSC_CACHE_AUTO_REINT 0x0004 736#define SMB_CSC_CACHE_AUTO_REINT 0x0004
723#define SMB_CSC_CACHE_VDO 0x0008 737#define SMB_CSC_CACHE_VDO 0x0008
724#define SMB_CSC_NO_CACHING 0x000C 738#define SMB_CSC_NO_CACHING 0x000C
725
726#define SMB_UNIQUE_FILE_NAME 0x0010 739#define SMB_UNIQUE_FILE_NAME 0x0010
727#define SMB_EXTENDED_SIGNATURES 0x0020 740#define SMB_EXTENDED_SIGNATURES 0x0020
728 741
@@ -806,7 +819,7 @@ typedef struct smb_com_findclose_req {
806#define ICOUNT_MASK 0x00FF 819#define ICOUNT_MASK 0x00FF
807#define PIPE_READ_MODE 0x0100 820#define PIPE_READ_MODE 0x0100
808#define NAMED_PIPE_TYPE 0x0400 821#define NAMED_PIPE_TYPE 0x0400
809#define PIPE_END_POINT 0x0800 822#define PIPE_END_POINT 0x4000
810#define BLOCKING_NAMED_PIPE 0x8000 823#define BLOCKING_NAMED_PIPE 0x8000
811 824
812typedef struct smb_com_open_req { /* also handles create */ 825typedef struct smb_com_open_req { /* also handles create */
@@ -1904,19 +1917,26 @@ typedef struct smb_com_transaction2_get_dfs_refer_req {
1904 char RequestFileName[1]; 1917 char RequestFileName[1];
1905} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ; 1918} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
1906 1919
1920#define DFS_VERSION cpu_to_le16(0x0003)
1921
1922/* DFS server target type */
1923#define DFS_TYPE_LINK 0x0000 /* also for sysvol targets */
1924#define DFS_TYPE_ROOT 0x0001
1925
1926/* Referral Entry Flags */
1927#define DFS_NAME_LIST_REF 0x0200
1928
1907typedef struct dfs_referral_level_3 { 1929typedef struct dfs_referral_level_3 {
1908 __le16 VersionNumber; 1930 __le16 VersionNumber;
1909 __le16 ReferralSize; 1931 __le16 Size;
1910 __le16 ServerType; /* 0x0001 = CIFS server */ 1932 __le16 ServerType; /* 0x0001 = root targets; 0x0000 = link targets */
1911 __le16 ReferralFlags; /* or proximity - not clear which since it is 1933 __le16 ReferralEntryFlags; /* 0x0200 bit set only for domain
1912 always set to zero - SNIA spec says 0x01 1934 or DC referral responce */
1913 means strip off PathConsumed chars before 1935 __le32 TimeToLive;
1914 submitting RequestFileName to remote node */
1915 __le16 TimeToLive;
1916 __le16 Proximity;
1917 __le16 DfsPathOffset; 1936 __le16 DfsPathOffset;
1918 __le16 DfsAlternatePathOffset; 1937 __le16 DfsAlternatePathOffset;
1919 __le16 NetworkAddressOffset; 1938 __le16 NetworkAddressOffset; /* offset of the link target */
1939 __le16 ServiceSiteGuid;
1920} __attribute__((packed)) REFERRAL3; 1940} __attribute__((packed)) REFERRAL3;
1921 1941
1922typedef struct smb_com_transaction_get_dfs_refer_rsp { 1942typedef struct smb_com_transaction_get_dfs_refer_rsp {
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index d481f6c5a2b..b9f5e935f82 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -93,7 +93,7 @@ extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
93 93
94extern int cifs_get_inode_info(struct inode **pinode, 94extern int cifs_get_inode_info(struct inode **pinode,
95 const unsigned char *search_path, 95 const unsigned char *search_path,
96 FILE_ALL_INFO * pfile_info, 96 FILE_ALL_INFO *pfile_info,
97 struct super_block *sb, int xid, const __u16 *pfid); 97 struct super_block *sb, int xid, const __u16 *pfid);
98extern int cifs_get_inode_info_unix(struct inode **pinode, 98extern int cifs_get_inode_info_unix(struct inode **pinode,
99 const unsigned char *search_path, 99 const unsigned char *search_path,
@@ -130,7 +130,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
130 130
131extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 131extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
132 const unsigned char *searchName, 132 const unsigned char *searchName,
133 FILE_ALL_INFO * findData, 133 FILE_ALL_INFO *findData,
134 int legacy /* whether to use old info level */, 134 int legacy /* whether to use old info level */,
135 const struct nls_table *nls_codepage, int remap); 135 const struct nls_table *nls_codepage, int remap);
136extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 136extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
@@ -141,18 +141,15 @@ extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
141extern int CIFSSMBUnixQPathInfo(const int xid, 141extern int CIFSSMBUnixQPathInfo(const int xid,
142 struct cifsTconInfo *tcon, 142 struct cifsTconInfo *tcon,
143 const unsigned char *searchName, 143 const unsigned char *searchName,
144 FILE_UNIX_BASIC_INFO * pFindData, 144 FILE_UNIX_BASIC_INFO *pFindData,
145 const struct nls_table *nls_codepage, int remap); 145 const struct nls_table *nls_codepage, int remap);
146 146
147extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 147extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
148 const unsigned char *searchName, 148 const unsigned char *searchName,
149 unsigned char **targetUNCs, 149 struct dfs_info3_param **target_nodes,
150 unsigned int *number_of_UNC_in_array, 150 unsigned int *number_of_nodes_in_array,
151 const struct nls_table *nls_codepage, int remap); 151 const struct nls_table *nls_codepage, int remap);
152 152
153extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
154 const char *old_path,
155 const struct nls_table *nls_codepage, int remap);
156extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 153extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
157 const char *old_path, 154 const char *old_path,
158 const struct nls_table *nls_codepage, 155 const struct nls_table *nls_codepage,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 95fbba4ea7d..4511b708f0f 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -81,6 +81,40 @@ 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
84 118
85/* Mark as invalid, all open files on tree connections since they 119/* Mark as invalid, all open files on tree connections since they
86 were closed when session to server was lost */ 120 were closed when session to server was lost */
@@ -1166,6 +1200,20 @@ static __u16 convert_disposition(int disposition)
1166 return ofun; 1200 return ofun;
1167} 1201}
1168 1202
1203static int
1204access_flags_to_smbopen_mode(const int access_flags)
1205{
1206 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1207
1208 if (masked_flags == GENERIC_READ)
1209 return SMBOPEN_READ;
1210 else if (masked_flags == GENERIC_WRITE)
1211 return SMBOPEN_WRITE;
1212
1213 /* just go for read/write */
1214 return SMBOPEN_READWRITE;
1215}
1216
1169int 1217int
1170SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 1218SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
1171 const char *fileName, const int openDisposition, 1219 const char *fileName, const int openDisposition,
@@ -1207,13 +1255,7 @@ OldOpenRetry:
1207 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); 1255 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1208 1256
1209 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); 1257 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1210 /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ 1258 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1211 /* 0 = read
1212 1 = write
1213 2 = rw
1214 3 = execute
1215 */
1216 pSMB->Mode = cpu_to_le16(2);
1217 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ 1259 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1218 /* set file as system file if special file such 1260 /* set file as system file if special file such
1219 as fifo and server expecting SFU style and 1261 as fifo and server expecting SFU style and
@@ -1247,7 +1289,7 @@ OldOpenRetry:
1247 } else { 1289 } else {
1248 /* BB verify if wct == 15 */ 1290 /* BB verify if wct == 15 */
1249 1291
1250/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field BB */ 1292/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1251 1293
1252 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 1294 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1253 /* Let caller know file was created so we can set the mode. */ 1295 /* Let caller know file was created so we can set the mode. */
@@ -1686,7 +1728,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1686{ 1728{
1687 int rc = 0; 1729 int rc = 0;
1688 LOCK_REQ *pSMB = NULL; 1730 LOCK_REQ *pSMB = NULL;
1689 LOCK_RSP *pSMBr = NULL; 1731/* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1690 int bytes_returned; 1732 int bytes_returned;
1691 int timeout = 0; 1733 int timeout = 0;
1692 __u16 count; 1734 __u16 count;
@@ -1697,8 +1739,6 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1697 if (rc) 1739 if (rc)
1698 return rc; 1740 return rc;
1699 1741
1700 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
1701
1702 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1742 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1703 timeout = CIFS_ASYNC_OP; /* no response expected */ 1743 timeout = CIFS_ASYNC_OP; /* no response expected */
1704 pSMB->Timeout = 0; 1744 pSMB->Timeout = 0;
@@ -1732,7 +1772,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1732 1772
1733 if (waitFlag) { 1773 if (waitFlag) {
1734 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1774 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1735 (struct smb_hdr *) pSMBr, &bytes_returned); 1775 (struct smb_hdr *) pSMB, &bytes_returned);
1736 cifs_small_buf_release(pSMB); 1776 cifs_small_buf_release(pSMB);
1737 } else { 1777 } else {
1738 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB, 1778 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
@@ -1767,7 +1807,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1767 cFYI(1, ("Posix Lock")); 1807 cFYI(1, ("Posix Lock"));
1768 1808
1769 if (pLockData == NULL) 1809 if (pLockData == NULL)
1770 return EINVAL; 1810 return -EINVAL;
1771 1811
1772 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 1812 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1773 1813
@@ -1944,7 +1984,7 @@ renameRetry:
1944 /* protocol requires ASCII signature byte on Unicode string */ 1984 /* protocol requires ASCII signature byte on Unicode string */
1945 pSMB->OldFileName[name_len + 1] = 0x00; 1985 pSMB->OldFileName[name_len + 1] = 0x00;
1946 name_len2 = 1986 name_len2 =
1947 cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2], 1987 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
1948 toName, PATH_MAX, nls_codepage, remap); 1988 toName, PATH_MAX, nls_codepage, remap);
1949 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 1989 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1950 name_len2 *= 2; /* convert to bytes */ 1990 name_len2 *= 2; /* convert to bytes */
@@ -2117,8 +2157,7 @@ copyRetry:
2117 cFYI(1, ("Send error in copy = %d with %d files copied", 2157 cFYI(1, ("Send error in copy = %d with %d files copied",
2118 rc, le16_to_cpu(pSMBr->CopyCount))); 2158 rc, le16_to_cpu(pSMBr->CopyCount)));
2119 } 2159 }
2120 if (pSMB) 2160 cifs_buf_release(pSMB);
2121 cifs_buf_release(pSMB);
2122 2161
2123 if (rc == -EAGAIN) 2162 if (rc == -EAGAIN)
2124 goto copyRetry; 2163 goto copyRetry;
@@ -2207,8 +2246,7 @@ createSymLinkRetry:
2207 if (rc) 2246 if (rc)
2208 cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc)); 2247 cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc));
2209 2248
2210 if (pSMB) 2249 cifs_buf_release(pSMB);
2211 cifs_buf_release(pSMB);
2212 2250
2213 if (rc == -EAGAIN) 2251 if (rc == -EAGAIN)
2214 goto createSymLinkRetry; 2252 goto createSymLinkRetry;
@@ -2925,7 +2963,8 @@ setAclRetry:
2925 } 2963 }
2926 params = 6 + name_len; 2964 params = 6 + name_len;
2927 pSMB->MaxParameterCount = cpu_to_le16(2); 2965 pSMB->MaxParameterCount = cpu_to_le16(2);
2928 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ 2966 /* BB find max SMB size from sess */
2967 pSMB->MaxDataCount = cpu_to_le16(1000);
2929 pSMB->MaxSetupCount = 0; 2968 pSMB->MaxSetupCount = 0;
2930 pSMB->Reserved = 0; 2969 pSMB->Reserved = 0;
2931 pSMB->Flags = 0; 2970 pSMB->Flags = 0;
@@ -3322,7 +3361,8 @@ QPathInfoRetry:
3322 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 3361 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3323 pSMB->TotalDataCount = 0; 3362 pSMB->TotalDataCount = 0;
3324 pSMB->MaxParameterCount = cpu_to_le16(2); 3363 pSMB->MaxParameterCount = cpu_to_le16(2);
3325 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 3364 /* BB find exact max SMB PDU from sess structure BB */
3365 pSMB->MaxDataCount = cpu_to_le16(4000);
3326 pSMB->MaxSetupCount = 0; 3366 pSMB->MaxSetupCount = 0;
3327 pSMB->Reserved = 0; 3367 pSMB->Reserved = 0;
3328 pSMB->Flags = 0; 3368 pSMB->Flags = 0;
@@ -3388,7 +3428,7 @@ QPathInfoRetry:
3388int 3428int
3389CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, 3429CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
3390 const unsigned char *searchName, 3430 const unsigned char *searchName,
3391 FILE_UNIX_BASIC_INFO * pFindData, 3431 FILE_UNIX_BASIC_INFO *pFindData,
3392 const struct nls_table *nls_codepage, int remap) 3432 const struct nls_table *nls_codepage, int remap)
3393{ 3433{
3394/* SMB_QUERY_FILE_UNIX_BASIC */ 3434/* SMB_QUERY_FILE_UNIX_BASIC */
@@ -3679,6 +3719,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3679 if (rc) { 3719 if (rc) {
3680 if (rc == -EBADF) { 3720 if (rc == -EBADF) {
3681 psrch_inf->endOfSearch = true; 3721 psrch_inf->endOfSearch = true;
3722 cifs_buf_release(pSMB);
3682 rc = 0; /* search probably was closed at end of search*/ 3723 rc = 0; /* search probably was closed at end of search*/
3683 } else 3724 } else
3684 cFYI(1, ("FindNext returned = %d", rc)); 3725 cFYI(1, ("FindNext returned = %d", rc));
@@ -3856,25 +3897,112 @@ GetInodeNumOut:
3856 return rc; 3897 return rc;
3857} 3898}
3858 3899
3900/* parses DFS refferal V3 structure
3901 * caller is responsible for freeing target_nodes
3902 * returns:
3903 * on success - 0
3904 * on failure - errno
3905 */
3906static int
3907parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
3908 unsigned int *num_of_nodes,
3909 struct dfs_info3_param **target_nodes,
3910 const struct nls_table *nls_codepage)
3911{
3912 int i, rc = 0;
3913 char *data_end;
3914 bool is_unicode;
3915 struct dfs_referral_level_3 *ref;
3916
3917 is_unicode = pSMBr->hdr.Flags2 & SMBFLG2_UNICODE;
3918 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
3919
3920 if (*num_of_nodes < 1) {
3921 cERROR(1, ("num_referrals: must be at least > 0,"
3922 "but we get num_referrals = %d\n", *num_of_nodes));
3923 rc = -EINVAL;
3924 goto parse_DFS_referrals_exit;
3925 }
3926
3927 ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
3928 if (ref->VersionNumber != cpu_to_le16(3)) {
3929 cERROR(1, ("Referrals of V%d version are not supported,"
3930 "should be V3", le16_to_cpu(ref->VersionNumber)));
3931 rc = -EINVAL;
3932 goto parse_DFS_referrals_exit;
3933 }
3934
3935 /* get the upper boundary of the resp buffer */
3936 data_end = (char *)(&(pSMBr->PathConsumed)) +
3937 le16_to_cpu(pSMBr->t2.DataCount);
3938
3939 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n",
3940 *num_of_nodes,
3941 le16_to_cpu(pSMBr->DFSFlags)));
3942
3943 *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
3944 *num_of_nodes, GFP_KERNEL);
3945 if (*target_nodes == NULL) {
3946 cERROR(1, ("Failed to allocate buffer for target_nodes\n"));
3947 rc = -ENOMEM;
3948 goto parse_DFS_referrals_exit;
3949 }
3950
3951 /* collect neccessary data from referrals */
3952 for (i = 0; i < *num_of_nodes; i++) {
3953 char *temp;
3954 int max_len;
3955 struct dfs_info3_param *node = (*target_nodes)+i;
3956
3957 node->flags = le16_to_cpu(pSMBr->DFSFlags);
3958 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
3959 node->server_type = le16_to_cpu(ref->ServerType);
3960 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
3961
3962 /* copy DfsPath */
3963 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
3964 max_len = data_end - temp;
3965 rc = cifs_strncpy_to_host(&(node->path_name), temp,
3966 max_len, is_unicode, nls_codepage);
3967 if (rc)
3968 goto parse_DFS_referrals_exit;
3969
3970 /* copy link target UNC */
3971 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
3972 max_len = data_end - temp;
3973 rc = cifs_strncpy_to_host(&(node->node_name), temp,
3974 max_len, is_unicode, nls_codepage);
3975 if (rc)
3976 goto parse_DFS_referrals_exit;
3977
3978 ref += le16_to_cpu(ref->Size);
3979 }
3980
3981parse_DFS_referrals_exit:
3982 if (rc) {
3983 free_dfs_info_array(*target_nodes, *num_of_nodes);
3984 *target_nodes = NULL;
3985 *num_of_nodes = 0;
3986 }
3987 return rc;
3988}
3989
3859int 3990int
3860CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 3991CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
3861 const unsigned char *searchName, 3992 const unsigned char *searchName,
3862 unsigned char **targetUNCs, 3993 struct dfs_info3_param **target_nodes,
3863 unsigned int *number_of_UNC_in_array, 3994 unsigned int *num_of_nodes,
3864 const struct nls_table *nls_codepage, int remap) 3995 const struct nls_table *nls_codepage, int remap)
3865{ 3996{
3866/* TRANS2_GET_DFS_REFERRAL */ 3997/* TRANS2_GET_DFS_REFERRAL */
3867 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 3998 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
3868 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 3999 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
3869 struct dfs_referral_level_3 *referrals = NULL;
3870 int rc = 0; 4000 int rc = 0;
3871 int bytes_returned; 4001 int bytes_returned;
3872 int name_len; 4002 int name_len;
3873 unsigned int i;
3874 char *temp;
3875 __u16 params, byte_count; 4003 __u16 params, byte_count;
3876 *number_of_UNC_in_array = 0; 4004 *num_of_nodes = 0;
3877 *targetUNCs = NULL; 4005 *target_nodes = NULL;
3878 4006
3879 cFYI(1, ("In GetDFSRefer the path %s", searchName)); 4007 cFYI(1, ("In GetDFSRefer the path %s", searchName));
3880 if (ses == NULL) 4008 if (ses == NULL)
@@ -3921,7 +4049,8 @@ getDFSRetry:
3921 pSMB->DataCount = 0; 4049 pSMB->DataCount = 0;
3922 pSMB->DataOffset = 0; 4050 pSMB->DataOffset = 0;
3923 pSMB->MaxParameterCount = 0; 4051 pSMB->MaxParameterCount = 0;
3924 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 4052 /* BB find exact max SMB PDU from sess structure BB */
4053 pSMB->MaxDataCount = cpu_to_le16(4000);
3925 pSMB->MaxSetupCount = 0; 4054 pSMB->MaxSetupCount = 0;
3926 pSMB->Reserved = 0; 4055 pSMB->Reserved = 0;
3927 pSMB->Flags = 0; 4056 pSMB->Flags = 0;
@@ -3943,103 +4072,26 @@ getDFSRetry:
3943 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4072 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3944 if (rc) { 4073 if (rc) {
3945 cFYI(1, ("Send error in GetDFSRefer = %d", rc)); 4074 cFYI(1, ("Send error in GetDFSRefer = %d", rc));
3946 } else { /* decode response */ 4075 goto GetDFSRefExit;
3947/* BB Add logic to parse referrals here */ 4076 }
3948 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4077 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3949 4078
3950 /* BB Also check if enough total bytes returned? */ 4079 /* BB Also check if enough total bytes returned? */
3951 if (rc || (pSMBr->ByteCount < 17)) 4080 if (rc || (pSMBr->ByteCount < 17)) {
3952 rc = -EIO; /* bad smb */ 4081 rc = -EIO; /* bad smb */
3953 else { 4082 goto GetDFSRefExit;
3954 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4083 }
3955 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
3956 4084
3957 cFYI(1, 4085 cFYI(1, ("Decoding GetDFSRefer response BCC: %d Offset %d",
3958 ("Decoding GetDFSRefer response BCC: %d Offset %d", 4086 pSMBr->ByteCount,
3959 pSMBr->ByteCount, data_offset)); 4087 le16_to_cpu(pSMBr->t2.DataOffset)));
3960 referrals =
3961 (struct dfs_referral_level_3 *)
3962 (8 /* sizeof start of data block */ +
3963 data_offset +
3964 (char *) &pSMBr->hdr.Protocol);
3965 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
3966 "for referral one refer size: 0x%x srv "
3967 "type: 0x%x refer flags: 0x%x ttl: 0x%x",
3968 le16_to_cpu(pSMBr->NumberOfReferrals),
3969 le16_to_cpu(pSMBr->DFSFlags),
3970 le16_to_cpu(referrals->ReferralSize),
3971 le16_to_cpu(referrals->ServerType),
3972 le16_to_cpu(referrals->ReferralFlags),
3973 le16_to_cpu(referrals->TimeToLive)));
3974 /* BB This field is actually two bytes in from start of
3975 data block so we could do safety check that DataBlock
3976 begins at address of pSMBr->NumberOfReferrals */
3977 *number_of_UNC_in_array =
3978 le16_to_cpu(pSMBr->NumberOfReferrals);
3979
3980 /* BB Fix below so can return more than one referral */
3981 if (*number_of_UNC_in_array > 1)
3982 *number_of_UNC_in_array = 1;
3983
3984 /* get the length of the strings describing refs */
3985 name_len = 0;
3986 for (i = 0; i < *number_of_UNC_in_array; i++) {
3987 /* make sure that DfsPathOffset not past end */
3988 __u16 offset =
3989 le16_to_cpu(referrals->DfsPathOffset);
3990 if (offset > data_count) {
3991 /* if invalid referral, stop here and do
3992 not try to copy any more */
3993 *number_of_UNC_in_array = i;
3994 break;
3995 }
3996 temp = ((char *)referrals) + offset;
3997 4088
3998 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 4089 /* parse returned result into more usable form */
3999 name_len += UniStrnlen((wchar_t *)temp, 4090 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4000 data_count); 4091 target_nodes, nls_codepage);
4001 } else {
4002 name_len += strnlen(temp, data_count);
4003 }
4004 referrals++;
4005 /* BB add check that referral pointer does
4006 not fall off end PDU */
4007 }
4008 /* BB add check for name_len bigger than bcc */
4009 *targetUNCs =
4010 kmalloc(name_len+1+(*number_of_UNC_in_array),
4011 GFP_KERNEL);
4012 if (*targetUNCs == NULL) {
4013 rc = -ENOMEM;
4014 goto GetDFSRefExit;
4015 }
4016 /* copy the ref strings */
4017 referrals = (struct dfs_referral_level_3 *)
4018 (8 /* sizeof data hdr */ + data_offset +
4019 (char *) &pSMBr->hdr.Protocol);
4020
4021 for (i = 0; i < *number_of_UNC_in_array; i++) {
4022 temp = ((char *)referrals) +
4023 le16_to_cpu(referrals->DfsPathOffset);
4024 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
4025 cifs_strfromUCS_le(*targetUNCs,
4026 (__le16 *) temp,
4027 name_len,
4028 nls_codepage);
4029 } else {
4030 strncpy(*targetUNCs, temp, name_len);
4031 }
4032 /* BB update target_uncs pointers */
4033 referrals++;
4034 }
4035 temp = *targetUNCs;
4036 temp[name_len] = 0;
4037 }
4038 4092
4039 }
4040GetDFSRefExit: 4093GetDFSRefExit:
4041 if (pSMB) 4094 cifs_buf_release(pSMB);
4042 cifs_buf_release(pSMB);
4043 4095
4044 if (rc == -EAGAIN) 4096 if (rc == -EAGAIN)
4045 goto getDFSRetry; 4097 goto getDFSRetry;
@@ -4229,7 +4281,8 @@ QFSAttributeRetry:
4229 params = 2; /* level */ 4281 params = 2; /* level */
4230 pSMB->TotalDataCount = 0; 4282 pSMB->TotalDataCount = 0;
4231 pSMB->MaxParameterCount = cpu_to_le16(2); 4283 pSMB->MaxParameterCount = cpu_to_le16(2);
4232 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 4284 /* BB find exact max SMB PDU from sess structure BB */
4285 pSMB->MaxDataCount = cpu_to_le16(1000);
4233 pSMB->MaxSetupCount = 0; 4286 pSMB->MaxSetupCount = 0;
4234 pSMB->Reserved = 0; 4287 pSMB->Reserved = 0;
4235 pSMB->Flags = 0; 4288 pSMB->Flags = 0;
@@ -4298,7 +4351,8 @@ QFSDeviceRetry:
4298 params = 2; /* level */ 4351 params = 2; /* level */
4299 pSMB->TotalDataCount = 0; 4352 pSMB->TotalDataCount = 0;
4300 pSMB->MaxParameterCount = cpu_to_le16(2); 4353 pSMB->MaxParameterCount = cpu_to_le16(2);
4301 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 4354 /* BB find exact max SMB PDU from sess structure BB */
4355 pSMB->MaxDataCount = cpu_to_le16(1000);
4302 pSMB->MaxSetupCount = 0; 4356 pSMB->MaxSetupCount = 0;
4303 pSMB->Reserved = 0; 4357 pSMB->Reserved = 0;
4304 pSMB->Flags = 0; 4358 pSMB->Flags = 0;
@@ -4369,7 +4423,8 @@ QFSUnixRetry:
4369 pSMB->DataCount = 0; 4423 pSMB->DataCount = 0;
4370 pSMB->DataOffset = 0; 4424 pSMB->DataOffset = 0;
4371 pSMB->MaxParameterCount = cpu_to_le16(2); 4425 pSMB->MaxParameterCount = cpu_to_le16(2);
4372 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */ 4426 /* BB find exact max SMB PDU from sess structure BB */
4427 pSMB->MaxDataCount = cpu_to_le16(100);
4373 pSMB->MaxSetupCount = 0; 4428 pSMB->MaxSetupCount = 0;
4374 pSMB->Reserved = 0; 4429 pSMB->Reserved = 0;
4375 pSMB->Flags = 0; 4430 pSMB->Flags = 0;
@@ -4444,7 +4499,8 @@ SETFSUnixRetry:
4444 offset = param_offset + params; 4499 offset = param_offset + params;
4445 4500
4446 pSMB->MaxParameterCount = cpu_to_le16(4); 4501 pSMB->MaxParameterCount = cpu_to_le16(4);
4447 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */ 4502 /* BB find exact max SMB PDU from sess structure BB */
4503 pSMB->MaxDataCount = cpu_to_le16(100);
4448 pSMB->SetupCount = 1; 4504 pSMB->SetupCount = 1;
4449 pSMB->Reserved3 = 0; 4505 pSMB->Reserved3 = 0;
4450 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 4506 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
@@ -4512,7 +4568,8 @@ QFSPosixRetry:
4512 pSMB->DataCount = 0; 4568 pSMB->DataCount = 0;
4513 pSMB->DataOffset = 0; 4569 pSMB->DataOffset = 0;
4514 pSMB->MaxParameterCount = cpu_to_le16(2); 4570 pSMB->MaxParameterCount = cpu_to_le16(2);
4515 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */ 4571 /* BB find exact max SMB PDU from sess structure BB */
4572 pSMB->MaxDataCount = cpu_to_le16(100);
4516 pSMB->MaxSetupCount = 0; 4573 pSMB->MaxSetupCount = 0;
4517 pSMB->Reserved = 0; 4574 pSMB->Reserved = 0;
4518 pSMB->Flags = 0; 4575 pSMB->Flags = 0;
@@ -4702,7 +4759,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4702 4759
4703 count = sizeof(struct file_end_of_file_info); 4760 count = sizeof(struct file_end_of_file_info);
4704 pSMB->MaxParameterCount = cpu_to_le16(2); 4761 pSMB->MaxParameterCount = cpu_to_le16(2);
4705 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ 4762 /* BB find exact max SMB PDU from sess structure BB */
4763 pSMB->MaxDataCount = cpu_to_le16(1000);
4706 pSMB->SetupCount = 1; 4764 pSMB->SetupCount = 1;
4707 pSMB->Reserved3 = 0; 4765 pSMB->Reserved3 = 0;
4708 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 4766 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
@@ -4789,7 +4847,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4789 4847
4790 count = sizeof(FILE_BASIC_INFO); 4848 count = sizeof(FILE_BASIC_INFO);
4791 pSMB->MaxParameterCount = cpu_to_le16(2); 4849 pSMB->MaxParameterCount = cpu_to_le16(2);
4792 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ 4850 /* BB find max SMB PDU from sess */
4851 pSMB->MaxDataCount = cpu_to_le16(1000);
4793 pSMB->SetupCount = 1; 4852 pSMB->SetupCount = 1;
4794 pSMB->Reserved3 = 0; 4853 pSMB->Reserved3 = 0;
4795 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 4854 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
@@ -4856,7 +4915,8 @@ SetTimesRetry:
4856 params = 6 + name_len; 4915 params = 6 + name_len;
4857 count = sizeof(FILE_BASIC_INFO); 4916 count = sizeof(FILE_BASIC_INFO);
4858 pSMB->MaxParameterCount = cpu_to_le16(2); 4917 pSMB->MaxParameterCount = cpu_to_le16(2);
4859 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 4918 /* BB find max SMB PDU from sess structure BB */
4919 pSMB->MaxDataCount = cpu_to_le16(1000);
4860 pSMB->MaxSetupCount = 0; 4920 pSMB->MaxSetupCount = 0;
4861 pSMB->Reserved = 0; 4921 pSMB->Reserved = 0;
4862 pSMB->Flags = 0; 4922 pSMB->Flags = 0;
@@ -4986,7 +5046,8 @@ setPermsRetry:
4986 params = 6 + name_len; 5046 params = 6 + name_len;
4987 count = sizeof(FILE_UNIX_BASIC_INFO); 5047 count = sizeof(FILE_UNIX_BASIC_INFO);
4988 pSMB->MaxParameterCount = cpu_to_le16(2); 5048 pSMB->MaxParameterCount = cpu_to_le16(2);
4989 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 5049 /* BB find max SMB PDU from sess structure BB */
5050 pSMB->MaxDataCount = cpu_to_le16(1000);
4990 pSMB->MaxSetupCount = 0; 5051 pSMB->MaxSetupCount = 0;
4991 pSMB->Reserved = 0; 5052 pSMB->Reserved = 0;
4992 pSMB->Flags = 0; 5053 pSMB->Flags = 0;
@@ -5051,8 +5112,7 @@ setPermsRetry:
5051 if (rc) 5112 if (rc)
5052 cFYI(1, ("SetPathInfo (perms) returned %d", rc)); 5113 cFYI(1, ("SetPathInfo (perms) returned %d", rc));
5053 5114
5054 if (pSMB) 5115 cifs_buf_release(pSMB);
5055 cifs_buf_release(pSMB);
5056 if (rc == -EAGAIN) 5116 if (rc == -EAGAIN)
5057 goto setPermsRetry; 5117 goto setPermsRetry;
5058 return rc; 5118 return rc;
@@ -5169,7 +5229,8 @@ QAllEAsRetry:
5169 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 5229 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5170 pSMB->TotalDataCount = 0; 5230 pSMB->TotalDataCount = 0;
5171 pSMB->MaxParameterCount = cpu_to_le16(2); 5231 pSMB->MaxParameterCount = cpu_to_le16(2);
5172 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5232 /* BB find exact max SMB PDU from sess structure BB */
5233 pSMB->MaxDataCount = cpu_to_le16(4000);
5173 pSMB->MaxSetupCount = 0; 5234 pSMB->MaxSetupCount = 0;
5174 pSMB->Reserved = 0; 5235 pSMB->Reserved = 0;
5175 pSMB->Flags = 0; 5236 pSMB->Flags = 0;
@@ -5273,8 +5334,7 @@ QAllEAsRetry:
5273 } 5334 }
5274 } 5335 }
5275 } 5336 }
5276 if (pSMB) 5337 cifs_buf_release(pSMB);
5277 cifs_buf_release(pSMB);
5278 if (rc == -EAGAIN) 5338 if (rc == -EAGAIN)
5279 goto QAllEAsRetry; 5339 goto QAllEAsRetry;
5280 5340
@@ -5317,7 +5377,8 @@ QEARetry:
5317 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 5377 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5318 pSMB->TotalDataCount = 0; 5378 pSMB->TotalDataCount = 0;
5319 pSMB->MaxParameterCount = cpu_to_le16(2); 5379 pSMB->MaxParameterCount = cpu_to_le16(2);
5320 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5380 /* BB find exact max SMB PDU from sess structure BB */
5381 pSMB->MaxDataCount = cpu_to_le16(4000);
5321 pSMB->MaxSetupCount = 0; 5382 pSMB->MaxSetupCount = 0;
5322 pSMB->Reserved = 0; 5383 pSMB->Reserved = 0;
5323 pSMB->Flags = 0; 5384 pSMB->Flags = 0;
@@ -5422,8 +5483,7 @@ QEARetry:
5422 } 5483 }
5423 } 5484 }
5424 } 5485 }
5425 if (pSMB) 5486 cifs_buf_release(pSMB);
5426 cifs_buf_release(pSMB);
5427 if (rc == -EAGAIN) 5487 if (rc == -EAGAIN)
5428 goto QEARetry; 5488 goto QEARetry;
5429 5489
@@ -5475,7 +5535,8 @@ SetEARetry:
5475 5535
5476 count = sizeof(*parm_data) + ea_value_len + name_len; 5536 count = sizeof(*parm_data) + ea_value_len + name_len;
5477 pSMB->MaxParameterCount = cpu_to_le16(2); 5537 pSMB->MaxParameterCount = cpu_to_le16(2);
5478 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ 5538 /* BB find max SMB PDU from sess */
5539 pSMB->MaxDataCount = cpu_to_le16(1000);
5479 pSMB->MaxSetupCount = 0; 5540 pSMB->MaxSetupCount = 0;
5480 pSMB->Reserved = 0; 5541 pSMB->Reserved = 0;
5481 pSMB->Flags = 0; 5542 pSMB->Flags = 0;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f428bf3bf1a..e8fa46c7cff 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -60,7 +60,7 @@ struct smb_vol {
60 char *domainname; 60 char *domainname;
61 char *UNC; 61 char *UNC;
62 char *UNCip; 62 char *UNCip;
63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */ 63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
64 char *iocharset; /* local code page for mapping to and from Unicode */ 64 char *iocharset; /* local code page for mapping to and from Unicode */
65 char source_rfc1001_name[16]; /* netbios name of client */ 65 char source_rfc1001_name[16]; /* netbios name of client */
66 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ 66 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
@@ -75,19 +75,21 @@ struct smb_vol {
75 bool setuids:1; 75 bool setuids:1;
76 bool override_uid:1; 76 bool override_uid:1;
77 bool override_gid:1; 77 bool override_gid:1;
78 bool dynperm:1;
78 bool noperm:1; 79 bool noperm:1;
79 bool no_psx_acl:1; /* set if posix acl support should be disabled */ 80 bool no_psx_acl:1; /* set if posix acl support should be disabled */
80 bool cifs_acl:1; 81 bool cifs_acl:1;
81 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ 82 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
82 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 83 bool server_ino:1; /* use inode numbers from server ie UniqueId */
83 bool direct_io:1; 84 bool direct_io:1;
84 bool remap:1; /* set to remap seven reserved chars in filenames */ 85 bool remap:1; /* set to remap seven reserved chars in filenames */
85 bool posix_paths:1; /* unset to not ask for posix pathnames. */ 86 bool posix_paths:1; /* unset to not ask for posix pathnames. */
86 bool no_linux_ext:1; 87 bool no_linux_ext:1;
87 bool sfu_emul:1; 88 bool sfu_emul:1;
88 bool nullauth:1; /* attempt to authenticate with null user */ 89 bool nullauth:1; /* attempt to authenticate with null user */
89 unsigned nocase; /* request case insensitive filenames */ 90 bool nocase:1; /* request case insensitive filenames */
90 unsigned nobrl; /* disable sending byte range locks to srv */ 91 bool nobrl:1; /* disable sending byte range locks to srv */
92 bool seal:1; /* request transport encryption on share */
91 unsigned int rsize; 93 unsigned int rsize;
92 unsigned int wsize; 94 unsigned int wsize;
93 unsigned int sockopt; 95 unsigned int sockopt;
@@ -651,6 +653,7 @@ multi_t2_fnd:
651 spin_lock(&GlobalMid_Lock); 653 spin_lock(&GlobalMid_Lock);
652 server->tcpStatus = CifsExiting; 654 server->tcpStatus = CifsExiting;
653 spin_unlock(&GlobalMid_Lock); 655 spin_unlock(&GlobalMid_Lock);
656 wake_up_all(&server->response_q);
654 657
655 /* don't exit until kthread_stop is called */ 658 /* don't exit until kthread_stop is called */
656 set_current_state(TASK_UNINTERRUPTIBLE); 659 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1246,6 +1249,10 @@ cifs_parse_mount_options(char *options, const char *devname,
1246 vol->setuids = 1; 1249 vol->setuids = 1;
1247 } else if (strnicmp(data, "nosetuids", 9) == 0) { 1250 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1248 vol->setuids = 0; 1251 vol->setuids = 0;
1252 } else if (strnicmp(data, "dynperm", 7) == 0) {
1253 vol->dynperm = true;
1254 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1255 vol->dynperm = false;
1249 } else if (strnicmp(data, "nohard", 6) == 0) { 1256 } else if (strnicmp(data, "nohard", 6) == 0) {
1250 vol->retry = 0; 1257 vol->retry = 0;
1251 } else if (strnicmp(data, "nosoft", 6) == 0) { 1258 } else if (strnicmp(data, "nosoft", 6) == 0) {
@@ -1268,8 +1275,12 @@ cifs_parse_mount_options(char *options, const char *devname,
1268 vol->no_psx_acl = 1; 1275 vol->no_psx_acl = 1;
1269 } else if (strnicmp(data, "sign", 4) == 0) { 1276 } else if (strnicmp(data, "sign", 4) == 0) {
1270 vol->secFlg |= CIFSSEC_MUST_SIGN; 1277 vol->secFlg |= CIFSSEC_MUST_SIGN;
1271/* } else if (strnicmp(data, "seal",4) == 0) { 1278 } else if (strnicmp(data, "seal", 4) == 0) {
1272 vol->secFlg |= CIFSSEC_MUST_SEAL; */ 1279 /* we do not do the following in secFlags because seal
1280 is a per tree connection (mount) not a per socket
1281 or per-smb connection option in the protocol */
1282 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1283 vol->seal = 1;
1273 } else if (strnicmp(data, "direct", 6) == 0) { 1284 } else if (strnicmp(data, "direct", 6) == 0) {
1274 vol->direct_io = 1; 1285 vol->direct_io = 1;
1275 } else if (strnicmp(data, "forcedirectio", 13) == 0) { 1286 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
@@ -1414,34 +1425,12 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1414} 1425}
1415 1426
1416int 1427int
1417connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1418 const char *old_path, const struct nls_table *nls_codepage,
1419 int remap)
1420{
1421 struct dfs_info3_param *referrals = NULL;
1422 unsigned int num_referrals;
1423 int rc = 0;
1424
1425 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1426 &num_referrals, &referrals, remap);
1427
1428 /* BB Add in code to: if valid refrl, if not ip address contact
1429 the helper that resolves tcp names, mount to it, try to
1430 tcon to it unmount it if fail */
1431
1432 kfree(referrals);
1433
1434 return rc;
1435}
1436
1437int
1438get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 1428get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1439 const struct nls_table *nls_codepage, unsigned int *pnum_referrals, 1429 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1440 struct dfs_info3_param **preferrals, int remap) 1430 struct dfs_info3_param **preferrals, int remap)
1441{ 1431{
1442 char *temp_unc; 1432 char *temp_unc;
1443 int rc = 0; 1433 int rc = 0;
1444 unsigned char *targetUNCs;
1445 1434
1446 *pnum_referrals = 0; 1435 *pnum_referrals = 0;
1447 *preferrals = NULL; 1436 *preferrals = NULL;
@@ -1464,7 +1453,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1464 kfree(temp_unc); 1453 kfree(temp_unc);
1465 } 1454 }
1466 if (rc == 0) 1455 if (rc == 0)
1467 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &targetUNCs, 1456 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1468 pnum_referrals, nls_codepage, remap); 1457 pnum_referrals, nls_codepage, remap);
1469 /* BB map targetUNCs to dfs_info3 structures, here or 1458 /* BB map targetUNCs to dfs_info3 structures, here or
1470 in CIFSGetDFSRefer BB */ 1459 in CIFSGetDFSRefer BB */
@@ -1815,7 +1804,7 @@ convert_delimiter(char *path, char delim)
1815 if (path == NULL) 1804 if (path == NULL)
1816 return; 1805 return;
1817 1806
1818 if (delim == '/') 1807 if (delim == '/')
1819 old_delim = '\\'; 1808 old_delim = '\\';
1820 else 1809 else
1821 old_delim = '/'; 1810 old_delim = '/';
@@ -2125,11 +2114,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2125 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; 2114 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2126 if (volume_info.override_gid) 2115 if (volume_info.override_gid)
2127 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; 2116 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2117 if (volume_info.dynperm)
2118 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2128 if (volume_info.direct_io) { 2119 if (volume_info.direct_io) {
2129 cFYI(1, ("mounting share using direct i/o")); 2120 cFYI(1, ("mounting share using direct i/o"));
2130 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2121 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2131 } 2122 }
2132 2123
2124 if ((volume_info.cifs_acl) && (volume_info.dynperm))
2125 cERROR(1, ("mount option dynperm ignored if cifsacl "
2126 "mount option supported"));
2127
2133 tcon = 2128 tcon =
2134 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, 2129 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2135 volume_info.username); 2130 volume_info.username);
@@ -2141,6 +2136,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2141 for the retry flag is used */ 2136 for the retry flag is used */
2142 tcon->retry = volume_info.retry; 2137 tcon->retry = volume_info.retry;
2143 tcon->nocase = volume_info.nocase; 2138 tcon->nocase = volume_info.nocase;
2139 if (tcon->seal != volume_info.seal)
2140 cERROR(1, ("transport encryption setting "
2141 "conflicts with existing tid"));
2144 } else { 2142 } else {
2145 tcon = tconInfoAlloc(); 2143 tcon = tconInfoAlloc();
2146 if (tcon == NULL) 2144 if (tcon == NULL)
@@ -2154,10 +2152,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2154 if ((strchr(volume_info.UNC + 3, '\\') == NULL) 2152 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2155 && (strchr(volume_info.UNC + 3, '/') == 2153 && (strchr(volume_info.UNC + 3, '/') ==
2156 NULL)) { 2154 NULL)) {
2157 rc = connect_to_dfs_path(xid, pSesInfo, 2155/* rc = connect_to_dfs_path(xid, pSesInfo,
2158 "", cifs_sb->local_nls, 2156 "", cifs_sb->local_nls,
2159 cifs_sb->mnt_cifs_flags & 2157 cifs_sb->mnt_cifs_flags &
2160 CIFS_MOUNT_MAP_SPECIAL_CHR); 2158 CIFS_MOUNT_MAP_SPECIAL_CHR);*/
2159 cFYI(1, ("DFS root not supported"));
2161 rc = -ENODEV; 2160 rc = -ENODEV;
2162 goto out; 2161 goto out;
2163 } else { 2162 } else {
@@ -2173,6 +2172,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2173 atomic_inc(&pSesInfo->inUse); 2172 atomic_inc(&pSesInfo->inUse);
2174 tcon->retry = volume_info.retry; 2173 tcon->retry = volume_info.retry;
2175 tcon->nocase = volume_info.nocase; 2174 tcon->nocase = volume_info.nocase;
2175 tcon->seal = volume_info.seal;
2176 } 2176 }
2177 } 2177 }
2178 } 2178 }
@@ -2314,9 +2314,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2314 user = ses->userName; 2314 user = ses->userName;
2315 domain = ses->domainName; 2315 domain = ses->domainName;
2316 smb_buffer = cifs_buf_get(); 2316 smb_buffer = cifs_buf_get();
2317 if (smb_buffer == NULL) { 2317
2318 if (smb_buffer == NULL)
2318 return -ENOMEM; 2319 return -ENOMEM;
2319 } 2320
2320 smb_buffer_response = smb_buffer; 2321 smb_buffer_response = smb_buffer;
2321 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer; 2322 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2322 2323
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index e4e0078a052..fb69c1fa85c 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -49,18 +49,25 @@ build_path_from_dentry(struct dentry *direntry)
49 struct dentry *temp; 49 struct dentry *temp;
50 int namelen; 50 int namelen;
51 int pplen; 51 int pplen;
52 int dfsplen;
52 char *full_path; 53 char *full_path;
53 char dirsep; 54 char dirsep;
55 struct cifs_sb_info *cifs_sb;
54 56
55 if (direntry == NULL) 57 if (direntry == NULL)
56 return NULL; /* not much we can do if dentry is freed and 58 return NULL; /* not much we can do if dentry is freed and
57 we need to reopen the file after it was closed implicitly 59 we need to reopen the file after it was closed implicitly
58 when the server crashed */ 60 when the server crashed */
59 61
60 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 62 cifs_sb = CIFS_SB(direntry->d_sb);
61 pplen = CIFS_SB(direntry->d_sb)->prepathlen; 63 dirsep = CIFS_DIR_SEP(cifs_sb);
64 pplen = cifs_sb->prepathlen;
65 if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
66 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
67 else
68 dfsplen = 0;
62cifs_bp_rename_retry: 69cifs_bp_rename_retry:
63 namelen = pplen; 70 namelen = pplen + dfsplen;
64 for (temp = direntry; !IS_ROOT(temp);) { 71 for (temp = direntry; !IS_ROOT(temp);) {
65 namelen += (1 + temp->d_name.len); 72 namelen += (1 + temp->d_name.len);
66 temp = temp->d_parent; 73 temp = temp->d_parent;
@@ -91,7 +98,7 @@ cifs_bp_rename_retry:
91 return NULL; 98 return NULL;
92 } 99 }
93 } 100 }
94 if (namelen != pplen) { 101 if (namelen != pplen + dfsplen) {
95 cERROR(1, 102 cERROR(1,
96 ("did not end path lookup where expected namelen is %d", 103 ("did not end path lookup where expected namelen is %d",
97 namelen)); 104 namelen));
@@ -107,7 +114,18 @@ cifs_bp_rename_retry:
107 since the '\' is a valid posix character so we can not switch 114 since the '\' is a valid posix character so we can not switch
108 those safely to '/' if any are found in the middle of the prepath */ 115 those safely to '/' if any are found in the middle of the prepath */
109 /* BB test paths to Windows with '/' in the midst of prepath */ 116 /* BB test paths to Windows with '/' in the midst of prepath */
110 strncpy(full_path, CIFS_SB(direntry->d_sb)->prepath, pplen); 117
118 if (dfsplen) {
119 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
120 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
121 int i;
122 for (i = 0; i < dfsplen; i++) {
123 if (full_path[i] == '\\')
124 full_path[i] = '/';
125 }
126 }
127 }
128 strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
111 return full_path; 129 return full_path;
112} 130}
113 131
@@ -242,7 +260,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
242 buf, inode->i_sb, xid, 260 buf, inode->i_sb, xid,
243 &fileHandle); 261 &fileHandle);
244 if (newinode) { 262 if (newinode) {
245 newinode->i_mode = mode; 263 if (cifs_sb->mnt_cifs_flags &
264 CIFS_MOUNT_DYNPERM)
265 newinode->i_mode = mode;
246 if ((oplock & CIFS_CREATE_ACTION) && 266 if ((oplock & CIFS_CREATE_ACTION) &&
247 (cifs_sb->mnt_cifs_flags & 267 (cifs_sb->mnt_cifs_flags &
248 CIFS_MOUNT_SET_UID)) { 268 CIFS_MOUNT_SET_UID)) {
@@ -590,7 +610,7 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
590 * case take precedence. If a is not a negative dentry, this 610 * case take precedence. If a is not a negative dentry, this
591 * should have no side effects 611 * should have no side effects
592 */ 612 */
593 memcpy(a->name, b->name, a->len); 613 memcpy((void *)a->name, b->name, a->len);
594 return 0; 614 return 0;
595 } 615 }
596 return 1; 616 return 1;
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 939e256f849..f730ef35499 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -134,10 +134,6 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
134 rkey = request_key(&key_type_dns_resolver, name, ""); 134 rkey = request_key(&key_type_dns_resolver, name, "");
135 if (!IS_ERR(rkey)) { 135 if (!IS_ERR(rkey)) {
136 data = rkey->payload.data; 136 data = rkey->payload.data;
137 cFYI(1, ("%s: resolved: %s to %s", __func__,
138 rkey->description,
139 *ip_addr
140 ));
141 } else { 137 } else {
142 cERROR(1, ("%s: unable to resolve: %s", __func__, name)); 138 cERROR(1, ("%s: unable to resolve: %s", __func__, name));
143 goto out; 139 goto out;
@@ -150,6 +146,11 @@ skip_upcall:
150 if (*ip_addr) { 146 if (*ip_addr) {
151 memcpy(*ip_addr, data, len); 147 memcpy(*ip_addr, data, len);
152 (*ip_addr)[len] = '\0'; 148 (*ip_addr)[len] = '\0';
149 if (!IS_ERR(rkey))
150 cFYI(1, ("%s: resolved: %s to %s", __func__,
151 name,
152 *ip_addr
153 ));
153 rc = 0; 154 rc = 0;
154 } else { 155 } else {
155 rc = -ENOMEM; 156 rc = -ENOMEM;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 31a0a33b9d9..0aac824371a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -75,7 +75,11 @@ static inline int cifs_convert_flags(unsigned int flags)
75 return (GENERIC_READ | GENERIC_WRITE); 75 return (GENERIC_READ | GENERIC_WRITE);
76 } 76 }
77 77
78 return 0x20197; 78 return (READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES |
79 FILE_WRITE_EA | FILE_APPEND_DATA | FILE_WRITE_DATA |
80 FILE_READ_DATA);
81
82
79} 83}
80 84
81static inline int cifs_get_disposition(unsigned int flags) 85static inline int cifs_get_disposition(unsigned int flags)
@@ -542,7 +546,6 @@ int cifs_close(struct inode *inode, struct file *file)
542 msleep(timeout); 546 msleep(timeout);
543 timeout *= 8; 547 timeout *= 8;
544 } 548 }
545 kfree(pSMBFile->search_resume_name);
546 kfree(file->private_data); 549 kfree(file->private_data);
547 file->private_data = NULL; 550 file->private_data = NULL;
548 } else 551 } else
@@ -601,12 +604,6 @@ int cifs_closedir(struct inode *inode, struct file *file)
601 else 604 else
602 cifs_buf_release(ptmp); 605 cifs_buf_release(ptmp);
603 } 606 }
604 ptmp = pCFileStruct->search_resume_name;
605 if (ptmp) {
606 cFYI(1, ("closedir free resume name"));
607 pCFileStruct->search_resume_name = NULL;
608 kfree(ptmp);
609 }
610 kfree(file->private_data); 607 kfree(file->private_data);
611 file->private_data = NULL; 608 file->private_data = NULL;
612 } 609 }
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index fcbdbb6ad7b..722be543cee 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -161,118 +161,115 @@ static void cifs_unix_info_to_inode(struct inode *inode,
161 spin_unlock(&inode->i_lock); 161 spin_unlock(&inode->i_lock);
162} 162}
163 163
164static const unsigned char *cifs_get_search_path(struct cifs_sb_info *cifs_sb,
165 const char *search_path)
166{
167 int tree_len;
168 int path_len;
169 int i;
170 char *tmp_path;
171 struct cifsTconInfo *pTcon = cifs_sb->tcon;
172
173 if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS))
174 return search_path;
175
176 /* use full path name for working with DFS */
177 tree_len = strnlen(pTcon->treeName, MAX_TREE_SIZE + 1);
178 path_len = strnlen(search_path, MAX_PATHCONF);
179 164
180 tmp_path = kmalloc(tree_len+path_len+1, GFP_KERNEL); 165/*
181 if (tmp_path == NULL) 166 * Needed to setup inode data for the directory which is the
182 return search_path; 167 * junction to the new submount (ie to setup the fake directory
168 * which represents a DFS referral)
169 */
170static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat,
171 struct super_block *sb)
172{
173 struct inode *pinode = NULL;
174
175 memset(pfnd_dat, 0, sizeof(FILE_UNIX_BASIC_INFO));
176
177/* __le64 pfnd_dat->EndOfFile = cpu_to_le64(0);
178 __le64 pfnd_dat->NumOfBytes = cpu_to_le64(0);
179 __u64 UniqueId = 0; */
180 pfnd_dat->LastStatusChange =
181 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
182 pfnd_dat->LastAccessTime =
183 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
184 pfnd_dat->LastModificationTime =
185 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
186 pfnd_dat->Type = cpu_to_le32(UNIX_DIR);
187 pfnd_dat->Permissions = cpu_to_le64(S_IXUGO | S_IRWXU);
188 pfnd_dat->Nlinks = cpu_to_le64(2);
189 if (sb->s_root)
190 pinode = sb->s_root->d_inode;
191 if (pinode == NULL)
192 return;
183 193
184 strncpy(tmp_path, pTcon->treeName, tree_len); 194 /* fill in default values for the remaining based on root
185 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 195 inode since we can not query the server for this inode info */
186 for (i = 0; i < tree_len; i++) { 196 pfnd_dat->DevMajor = cpu_to_le64(MAJOR(pinode->i_rdev));
187 if (tmp_path[i] == '\\') 197 pfnd_dat->DevMinor = cpu_to_le64(MINOR(pinode->i_rdev));
188 tmp_path[i] = '/'; 198 pfnd_dat->Uid = cpu_to_le64(pinode->i_uid);
189 } 199 pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
190 strncpy(tmp_path+tree_len, search_path, path_len);
191 tmp_path[tree_len+path_len] = 0;
192 return tmp_path;
193} 200}
194 201
195int cifs_get_inode_info_unix(struct inode **pinode, 202int cifs_get_inode_info_unix(struct inode **pinode,
196 const unsigned char *search_path, struct super_block *sb, int xid) 203 const unsigned char *full_path, struct super_block *sb, int xid)
197{ 204{
198 int rc = 0; 205 int rc = 0;
199 FILE_UNIX_BASIC_INFO findData; 206 FILE_UNIX_BASIC_INFO find_data;
200 struct cifsTconInfo *pTcon; 207 struct cifsTconInfo *pTcon;
201 struct inode *inode; 208 struct inode *inode;
202 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 209 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
203 const unsigned char *full_path;
204 bool is_dfs_referral = false; 210 bool is_dfs_referral = false;
211 struct cifsInodeInfo *cifsInfo;
212 __u64 num_of_bytes;
213 __u64 end_of_file;
205 214
206 pTcon = cifs_sb->tcon; 215 pTcon = cifs_sb->tcon;
207 cFYI(1, ("Getting info on %s", search_path)); 216 cFYI(1, ("Getting info on %s", full_path));
208
209 full_path = cifs_get_search_path(cifs_sb, search_path);
210 217
211try_again_CIFSSMBUnixQPathInfo:
212 /* could have done a find first instead but this returns more info */ 218 /* could have done a find first instead but this returns more info */
213 rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &findData, 219 rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data,
214 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 220 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
215 CIFS_MOUNT_MAP_SPECIAL_CHR); 221 CIFS_MOUNT_MAP_SPECIAL_CHR);
216/* dump_mem("\nUnixQPathInfo return data", &findData,
217 sizeof(findData)); */
218 if (rc) { 222 if (rc) {
219 if (rc == -EREMOTE && !is_dfs_referral) { 223 if (rc == -EREMOTE && !is_dfs_referral) {
220 is_dfs_referral = true; 224 is_dfs_referral = true;
221 if (full_path != search_path) { 225 cFYI(DBG2, ("DFS ref"));
222 kfree(full_path); 226 /* for DFS, server does not give us real inode data */
223 full_path = search_path; 227 fill_fake_finddataunix(&find_data, sb);
224 } 228 rc = 0;
225 goto try_again_CIFSSMBUnixQPathInfo;
226 } 229 }
227 goto cgiiu_exit; 230 }
228 } else { 231 num_of_bytes = le64_to_cpu(find_data.NumOfBytes);
229 struct cifsInodeInfo *cifsInfo; 232 end_of_file = le64_to_cpu(find_data.EndOfFile);
230 __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes);
231 __u64 end_of_file = le64_to_cpu(findData.EndOfFile);
232 233
233 /* get new inode */ 234 /* get new inode */
235 if (*pinode == NULL) {
236 *pinode = new_inode(sb);
234 if (*pinode == NULL) { 237 if (*pinode == NULL) {
235 *pinode = new_inode(sb); 238 rc = -ENOMEM;
236 if (*pinode == NULL) { 239 goto cgiiu_exit;
237 rc = -ENOMEM;
238 goto cgiiu_exit;
239 }
240 /* Is an i_ino of zero legal? */
241 /* Are there sanity checks we can use to ensure that
242 the server is really filling in that field? */
243 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
244 (*pinode)->i_ino =
245 (unsigned long)findData.UniqueId;
246 } /* note ino incremented to unique num in new_inode */
247 if (sb->s_flags & MS_NOATIME)
248 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
249
250 insert_inode_hash(*pinode);
251 } 240 }
241 /* Is an i_ino of zero legal? */
242 /* note ino incremented to unique num in new_inode */
243 /* Are there sanity checks we can use to ensure that
244 the server is really filling in that field? */
245 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
246 (*pinode)->i_ino = (unsigned long)find_data.UniqueId;
252 247
253 inode = *pinode; 248 if (sb->s_flags & MS_NOATIME)
254 cifsInfo = CIFS_I(inode); 249 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
255 250
256 cFYI(1, ("Old time %ld", cifsInfo->time)); 251 insert_inode_hash(*pinode);
257 cifsInfo->time = jiffies; 252 }
258 cFYI(1, ("New time %ld", cifsInfo->time)); 253
259 /* this is ok to set on every inode revalidate */ 254 inode = *pinode;
260 atomic_set(&cifsInfo->inUse, 1); 255 cifsInfo = CIFS_I(inode);
261 256
262 cifs_unix_info_to_inode(inode, &findData, 0); 257 cFYI(1, ("Old time %ld", cifsInfo->time));
258 cifsInfo->time = jiffies;
259 cFYI(1, ("New time %ld", cifsInfo->time));
260 /* this is ok to set on every inode revalidate */
261 atomic_set(&cifsInfo->inUse, 1);
263 262
263 cifs_unix_info_to_inode(inode, &find_data, 0);
264 264
265 if (num_of_bytes < end_of_file) 265 if (num_of_bytes < end_of_file)
266 cFYI(1, ("allocation size less than end of file")); 266 cFYI(1, ("allocation size less than end of file"));
267 cFYI(1, ("Size %ld and blocks %llu", 267 cFYI(1, ("Size %ld and blocks %llu",
268 (unsigned long) inode->i_size, 268 (unsigned long) inode->i_size,
269 (unsigned long long)inode->i_blocks)); 269 (unsigned long long)inode->i_blocks));
270 270
271 cifs_set_ops(inode, is_dfs_referral); 271 cifs_set_ops(inode, is_dfs_referral);
272 }
273cgiiu_exit: 272cgiiu_exit:
274 if (full_path != search_path)
275 kfree(full_path);
276 return rc; 273 return rc;
277} 274}
278 275
@@ -379,21 +376,52 @@ static int get_sfu_mode(struct inode *inode,
379#endif 376#endif
380} 377}
381 378
379/*
380 * Needed to setup inode data for the directory which is the
381 * junction to the new submount (ie to setup the fake directory
382 * which represents a DFS referral)
383 */
384static void fill_fake_finddata(FILE_ALL_INFO *pfnd_dat,
385 struct super_block *sb)
386{
387 memset(pfnd_dat, 0, sizeof(FILE_ALL_INFO));
388
389/* __le64 pfnd_dat->AllocationSize = cpu_to_le64(0);
390 __le64 pfnd_dat->EndOfFile = cpu_to_le64(0);
391 __u8 pfnd_dat->DeletePending = 0;
392 __u8 pfnd_data->Directory = 0;
393 __le32 pfnd_dat->EASize = 0;
394 __u64 pfnd_dat->IndexNumber = 0;
395 __u64 pfnd_dat->IndexNumber1 = 0; */
396 pfnd_dat->CreationTime =
397 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
398 pfnd_dat->LastAccessTime =
399 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
400 pfnd_dat->LastWriteTime =
401 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
402 pfnd_dat->ChangeTime =
403 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
404 pfnd_dat->Attributes = cpu_to_le32(ATTR_DIRECTORY);
405 pfnd_dat->NumberOfLinks = cpu_to_le32(2);
406}
407
382int cifs_get_inode_info(struct inode **pinode, 408int cifs_get_inode_info(struct inode **pinode,
383 const unsigned char *search_path, FILE_ALL_INFO *pfindData, 409 const unsigned char *full_path, FILE_ALL_INFO *pfindData,
384 struct super_block *sb, int xid, const __u16 *pfid) 410 struct super_block *sb, int xid, const __u16 *pfid)
385{ 411{
386 int rc = 0; 412 int rc = 0;
413 __u32 attr;
414 struct cifsInodeInfo *cifsInfo;
387 struct cifsTconInfo *pTcon; 415 struct cifsTconInfo *pTcon;
388 struct inode *inode; 416 struct inode *inode;
389 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 417 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
390 const unsigned char *full_path = NULL;
391 char *buf = NULL; 418 char *buf = NULL;
392 bool adjustTZ = false; 419 bool adjustTZ = false;
393 bool is_dfs_referral = false; 420 bool is_dfs_referral = false;
421 umode_t default_mode;
394 422
395 pTcon = cifs_sb->tcon; 423 pTcon = cifs_sb->tcon;
396 cFYI(1, ("Getting info on %s", search_path)); 424 cFYI(1, ("Getting info on %s", full_path));
397 425
398 if ((pfindData == NULL) && (*pinode != NULL)) { 426 if ((pfindData == NULL) && (*pinode != NULL)) {
399 if (CIFS_I(*pinode)->clientCanCacheRead) { 427 if (CIFS_I(*pinode)->clientCanCacheRead) {
@@ -409,9 +437,6 @@ int cifs_get_inode_info(struct inode **pinode,
409 return -ENOMEM; 437 return -ENOMEM;
410 pfindData = (FILE_ALL_INFO *)buf; 438 pfindData = (FILE_ALL_INFO *)buf;
411 439
412 full_path = cifs_get_search_path(cifs_sb, search_path);
413
414try_again_CIFSSMBQPathInfo:
415 /* could do find first instead but this returns more info */ 440 /* could do find first instead but this returns more info */
416 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData, 441 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
417 0 /* not legacy */, 442 0 /* not legacy */,
@@ -429,178 +454,163 @@ try_again_CIFSSMBQPathInfo:
429 } 454 }
430 } 455 }
431 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 456 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
432 if (rc) { 457 if (rc == -EREMOTE) {
433 if (rc == -EREMOTE && !is_dfs_referral) { 458 is_dfs_referral = true;
434 is_dfs_referral = true; 459 fill_fake_finddata(pfindData, sb);
435 if (full_path != search_path) { 460 rc = 0;
436 kfree(full_path); 461 } else if (rc)
437 full_path = search_path;
438 }
439 goto try_again_CIFSSMBQPathInfo;
440 }
441 goto cgii_exit; 462 goto cgii_exit;
442 } else {
443 struct cifsInodeInfo *cifsInfo;
444 __u32 attr = le32_to_cpu(pfindData->Attributes);
445
446 /* get new inode */
447 if (*pinode == NULL) {
448 *pinode = new_inode(sb);
449 if (*pinode == NULL) {
450 rc = -ENOMEM;
451 goto cgii_exit;
452 }
453 /* Is an i_ino of zero legal? Can we use that to check
454 if the server supports returning inode numbers? Are
455 there other sanity checks we can use to ensure that
456 the server is really filling in that field? */
457
458 /* We can not use the IndexNumber field by default from
459 Windows or Samba (in ALL_INFO buf) but we can request
460 it explicitly. It may not be unique presumably if
461 the server has multiple devices mounted under one
462 share */
463 463
464 /* There may be higher info levels that work but are 464 attr = le32_to_cpu(pfindData->Attributes);
465 there Windows server or network appliances for which
466 IndexNumber field is not guaranteed unique? */
467 465
468 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 466 /* get new inode */
469 int rc1 = 0; 467 if (*pinode == NULL) {
470 __u64 inode_num; 468 *pinode = new_inode(sb);
471 469 if (*pinode == NULL) {
472 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 470 rc = -ENOMEM;
473 search_path, &inode_num, 471 goto cgii_exit;
472 }
473 /* Is an i_ino of zero legal? Can we use that to check
474 if the server supports returning inode numbers? Are
475 there other sanity checks we can use to ensure that
476 the server is really filling in that field? */
477
478 /* We can not use the IndexNumber field by default from
479 Windows or Samba (in ALL_INFO buf) but we can request
480 it explicitly. It may not be unique presumably if
481 the server has multiple devices mounted under one share */
482
483 /* There may be higher info levels that work but are
484 there Windows server or network appliances for which
485 IndexNumber field is not guaranteed unique? */
486
487 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
488 int rc1 = 0;
489 __u64 inode_num;
490
491 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
492 full_path, &inode_num,
474 cifs_sb->local_nls, 493 cifs_sb->local_nls,
475 cifs_sb->mnt_cifs_flags & 494 cifs_sb->mnt_cifs_flags &
476 CIFS_MOUNT_MAP_SPECIAL_CHR); 495 CIFS_MOUNT_MAP_SPECIAL_CHR);
477 if (rc1) { 496 if (rc1) {
478 cFYI(1, ("GetSrvInodeNum rc %d", rc1)); 497 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
479 /* BB EOPNOSUPP disable SERVER_INUM? */ 498 /* BB EOPNOSUPP disable SERVER_INUM? */
480 } else /* do we need cast or hash to ino? */ 499 } else /* do we need cast or hash to ino? */
481 (*pinode)->i_ino = inode_num; 500 (*pinode)->i_ino = inode_num;
482 } /* else ino incremented to unique num in new_inode*/ 501 } /* else ino incremented to unique num in new_inode*/
483 if (sb->s_flags & MS_NOATIME) 502 if (sb->s_flags & MS_NOATIME)
484 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 503 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
485 insert_inode_hash(*pinode); 504 insert_inode_hash(*pinode);
486 } 505 }
487 inode = *pinode; 506 inode = *pinode;
488 cifsInfo = CIFS_I(inode); 507 cifsInfo = CIFS_I(inode);
489 cifsInfo->cifsAttrs = attr; 508 cifsInfo->cifsAttrs = attr;
490 cFYI(1, ("Old time %ld", cifsInfo->time)); 509 cFYI(1, ("Old time %ld", cifsInfo->time));
491 cifsInfo->time = jiffies; 510 cifsInfo->time = jiffies;
492 cFYI(1, ("New time %ld", cifsInfo->time)); 511 cFYI(1, ("New time %ld", cifsInfo->time));
493 512
494 /* blksize needs to be multiple of two. So safer to default to 513 /* blksize needs to be multiple of two. So safer to default to
495 blksize and blkbits set in superblock so 2**blkbits and blksize 514 blksize and blkbits set in superblock so 2**blkbits and blksize
496 will match rather than setting to: 515 will match rather than setting to:
497 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 516 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
498 517
499 /* Linux can not store file creation time so ignore it */ 518 /* Linux can not store file creation time so ignore it */
500 if (pfindData->LastAccessTime) 519 if (pfindData->LastAccessTime)
501 inode->i_atime = cifs_NTtimeToUnix 520 inode->i_atime = cifs_NTtimeToUnix
502 (le64_to_cpu(pfindData->LastAccessTime)); 521 (le64_to_cpu(pfindData->LastAccessTime));
503 else /* do not need to use current_fs_time - time not stored */ 522 else /* do not need to use current_fs_time - time not stored */
504 inode->i_atime = CURRENT_TIME; 523 inode->i_atime = CURRENT_TIME;
505 inode->i_mtime = 524 inode->i_mtime =
506 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 525 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
507 inode->i_ctime = 526 inode->i_ctime =
508 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 527 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
509 cFYI(0, ("Attributes came in as 0x%x", attr)); 528 cFYI(DBG2, ("Attributes came in as 0x%x", attr));
510 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { 529 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
511 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; 530 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
512 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; 531 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
513 } 532 }
514 533
515 /* set default mode. will override for dirs below */ 534 /* get default inode mode */
516 if (atomic_read(&cifsInfo->inUse) == 0) 535 if (attr & ATTR_DIRECTORY)
517 /* new inode, can safely set these fields */ 536 default_mode = cifs_sb->mnt_dir_mode;
518 inode->i_mode = cifs_sb->mnt_file_mode; 537 else
519 else /* since we set the inode type below we need to mask off 538 default_mode = cifs_sb->mnt_file_mode;
520 to avoid strange results if type changes and both 539
521 get orred in */ 540 /* set permission bits */
541 if (atomic_read(&cifsInfo->inUse) == 0 ||
542 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
543 inode->i_mode = default_mode;
544 else {
545 /* just reenable write bits if !ATTR_READONLY */
546 if ((inode->i_mode & S_IWUGO) == 0 &&
547 (attr & ATTR_READONLY) == 0)
548 inode->i_mode |= (S_IWUGO & default_mode);
522 inode->i_mode &= ~S_IFMT; 549 inode->i_mode &= ~S_IFMT;
523/* if (attr & ATTR_REPARSE) */ 550 }
524 /* We no longer handle these as symlinks because we could not 551 /* clear write bits if ATTR_READONLY is set */
525 follow them due to the absolute path with drive letter */ 552 if (attr & ATTR_READONLY)
526 if (attr & ATTR_DIRECTORY) { 553 inode->i_mode &= ~S_IWUGO;
527 /* override default perms since we do not do byte range locking 554
528 on dirs */ 555 /* set inode type */
529 inode->i_mode = cifs_sb->mnt_dir_mode; 556 if ((attr & ATTR_SYSTEM) &&
530 inode->i_mode |= S_IFDIR; 557 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
531 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 558 /* no need to fix endianness on 0 */
532 (cifsInfo->cifsAttrs & ATTR_SYSTEM) && 559 if (pfindData->EndOfFile == 0)
533 /* No need to le64 convert size of zero */
534 (pfindData->EndOfFile == 0)) {
535 inode->i_mode = cifs_sb->mnt_file_mode;
536 inode->i_mode |= S_IFIFO; 560 inode->i_mode |= S_IFIFO;
537/* BB Finish for SFU style symlinks and devices */ 561 else if (decode_sfu_inode(inode,
538 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 562 le64_to_cpu(pfindData->EndOfFile),
539 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { 563 full_path, cifs_sb, xid))
540 if (decode_sfu_inode(inode, 564 cFYI(1, ("unknown SFU file type\n"));
541 le64_to_cpu(pfindData->EndOfFile), 565 } else {
542 search_path, 566 if (attr & ATTR_DIRECTORY)
543 cifs_sb, xid)) 567 inode->i_mode |= S_IFDIR;
544 cFYI(1, ("Unrecognized sfu inode type")); 568 else
545
546 cFYI(1, ("sfu mode 0%o", inode->i_mode));
547 } else {
548 inode->i_mode |= S_IFREG; 569 inode->i_mode |= S_IFREG;
549 /* treat the dos attribute of read-only as read-only 570 }
550 mode e.g. 555 */
551 if (cifsInfo->cifsAttrs & ATTR_READONLY)
552 inode->i_mode &= ~(S_IWUGO);
553 else if ((inode->i_mode & S_IWUGO) == 0)
554 /* the ATTR_READONLY flag may have been */
555 /* changed on server -- set any w bits */
556 /* allowed by mnt_file_mode */
557 inode->i_mode |= (S_IWUGO &
558 cifs_sb->mnt_file_mode);
559 /* BB add code here -
560 validate if device or weird share or device type? */
561 }
562 571
563 spin_lock(&inode->i_lock); 572 spin_lock(&inode->i_lock);
564 if (is_size_safe_to_change(cifsInfo, 573 if (is_size_safe_to_change(cifsInfo,
565 le64_to_cpu(pfindData->EndOfFile))) { 574 le64_to_cpu(pfindData->EndOfFile))) {
566 /* can not safely shrink the file size here if the 575 /* can not safely shrink the file size here if the
567 client is writing to it due to potential races */ 576 client is writing to it due to potential races */
568 i_size_write(inode, le64_to_cpu(pfindData->EndOfFile)); 577 i_size_write(inode, le64_to_cpu(pfindData->EndOfFile));
569 578
570 /* 512 bytes (2**9) is the fake blocksize that must be 579 /* 512 bytes (2**9) is the fake blocksize that must be
571 used for this calculation */ 580 used for this calculation */
572 inode->i_blocks = (512 - 1 + le64_to_cpu( 581 inode->i_blocks = (512 - 1 + le64_to_cpu(
573 pfindData->AllocationSize)) >> 9; 582 pfindData->AllocationSize)) >> 9;
574 } 583 }
575 spin_unlock(&inode->i_lock); 584 spin_unlock(&inode->i_lock);
576 585
577 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); 586 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
578 587
579 /* BB fill in uid and gid here? with help from winbind? 588 /* BB fill in uid and gid here? with help from winbind?
580 or retrieve from NTFS stream extended attribute */ 589 or retrieve from NTFS stream extended attribute */
581#ifdef CONFIG_CIFS_EXPERIMENTAL 590#ifdef CONFIG_CIFS_EXPERIMENTAL
582 /* fill in 0777 bits from ACL */ 591 /* fill in 0777 bits from ACL */
583 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 592 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
584 cFYI(1, ("Getting mode bits from ACL")); 593 cFYI(1, ("Getting mode bits from ACL"));
585 acl_to_uid_mode(inode, search_path, pfid); 594 acl_to_uid_mode(inode, full_path, pfid);
586 } 595 }
587#endif 596#endif
588 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 597 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
589 /* fill in remaining high mode bits e.g. SUID, VTX */ 598 /* fill in remaining high mode bits e.g. SUID, VTX */
590 get_sfu_mode(inode, search_path, cifs_sb, xid); 599 get_sfu_mode(inode, full_path, cifs_sb, xid);
591 } else if (atomic_read(&cifsInfo->inUse) == 0) { 600 } else if (atomic_read(&cifsInfo->inUse) == 0) {
592 inode->i_uid = cifs_sb->mnt_uid; 601 inode->i_uid = cifs_sb->mnt_uid;
593 inode->i_gid = cifs_sb->mnt_gid; 602 inode->i_gid = cifs_sb->mnt_gid;
594 /* set so we do not keep refreshing these fields with 603 /* set so we do not keep refreshing these fields with
595 bad data after user has changed them in memory */ 604 bad data after user has changed them in memory */
596 atomic_set(&cifsInfo->inUse, 1); 605 atomic_set(&cifsInfo->inUse, 1);
597 }
598
599 cifs_set_ops(inode, is_dfs_referral);
600 } 606 }
607
608 cifs_set_ops(inode, is_dfs_referral);
609
610
611
612
601cgii_exit: 613cgii_exit:
602 if (full_path != search_path)
603 kfree(full_path);
604 kfree(buf); 614 kfree(buf);
605 return rc; 615 return rc;
606} 616}
@@ -1005,8 +1015,11 @@ mkdir_get_info:
1005 CIFS_MOUNT_MAP_SPECIAL_CHR); 1015 CIFS_MOUNT_MAP_SPECIAL_CHR);
1006 } 1016 }
1007 if (direntry->d_inode) { 1017 if (direntry->d_inode) {
1008 direntry->d_inode->i_mode = mode; 1018 if (cifs_sb->mnt_cifs_flags &
1009 direntry->d_inode->i_mode |= S_IFDIR; 1019 CIFS_MOUNT_DYNPERM)
1020 direntry->d_inode->i_mode =
1021 (mode | S_IFDIR);
1022
1010 if (cifs_sb->mnt_cifs_flags & 1023 if (cifs_sb->mnt_cifs_flags &
1011 CIFS_MOUNT_SET_UID) { 1024 CIFS_MOUNT_SET_UID) {
1012 direntry->d_inode->i_uid = 1025 direntry->d_inode->i_uid =
@@ -1502,8 +1515,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1502 int oplock = 0; 1515 int oplock = 0;
1503 1516
1504 rc = SMBLegacyOpen(xid, pTcon, full_path, 1517 rc = SMBLegacyOpen(xid, pTcon, full_path,
1505 FILE_OPEN, 1518 FILE_OPEN, GENERIC_WRITE,
1506 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1507 CREATE_NOT_DIR, &netfid, &oplock, 1519 CREATE_NOT_DIR, &netfid, &oplock,
1508 NULL, cifs_sb->local_nls, 1520 NULL, cifs_sb->local_nls,
1509 cifs_sb->mnt_cifs_flags & 1521 cifs_sb->mnt_cifs_flags &
@@ -1534,13 +1546,26 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1534 } else 1546 } else
1535 goto cifs_setattr_exit; 1547 goto cifs_setattr_exit;
1536 } 1548 }
1537 if (attrs->ia_valid & ATTR_UID) { 1549
1538 cFYI(1, ("UID changed to %d", attrs->ia_uid)); 1550 /*
1539 uid = attrs->ia_uid; 1551 * Without unix extensions we can't send ownership changes to the
1540 } 1552 * server, so silently ignore them. This is consistent with how
1541 if (attrs->ia_valid & ATTR_GID) { 1553 * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
1542 cFYI(1, ("GID changed to %d", attrs->ia_gid)); 1554 * CIFSACL support + proper Windows to Unix idmapping, we may be
1543 gid = attrs->ia_gid; 1555 * able to support this in the future.
1556 */
1557 if (!pTcon->unix_ext &&
1558 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
1559 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1560 } else {
1561 if (attrs->ia_valid & ATTR_UID) {
1562 cFYI(1, ("UID changed to %d", attrs->ia_uid));
1563 uid = attrs->ia_uid;
1564 }
1565 if (attrs->ia_valid & ATTR_GID) {
1566 cFYI(1, ("GID changed to %d", attrs->ia_gid));
1567 gid = attrs->ia_gid;
1568 }
1544 } 1569 }
1545 1570
1546 time_buf.Attributes = 0; 1571 time_buf.Attributes = 0;
@@ -1550,7 +1575,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1550 attrs->ia_valid &= ~ATTR_MODE; 1575 attrs->ia_valid &= ~ATTR_MODE;
1551 1576
1552 if (attrs->ia_valid & ATTR_MODE) { 1577 if (attrs->ia_valid & ATTR_MODE) {
1553 cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode)); 1578 cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
1554 mode = attrs->ia_mode; 1579 mode = attrs->ia_mode;
1555 } 1580 }
1556 1581
@@ -1565,18 +1590,18 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1565#ifdef CONFIG_CIFS_EXPERIMENTAL 1590#ifdef CONFIG_CIFS_EXPERIMENTAL
1566 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) 1591 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1567 rc = mode_to_acl(inode, full_path, mode); 1592 rc = mode_to_acl(inode, full_path, mode);
1568 else if ((mode & S_IWUGO) == 0) { 1593 else
1569#else
1570 if ((mode & S_IWUGO) == 0) {
1571#endif 1594#endif
1572 /* not writeable */ 1595 if (((mode & S_IWUGO) == 0) &&
1573 if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { 1596 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1574 set_dosattr = true; 1597 set_dosattr = true;
1575 time_buf.Attributes = 1598 time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs |
1576 cpu_to_le32(cifsInode->cifsAttrs | 1599 ATTR_READONLY);
1577 ATTR_READONLY); 1600 /* fix up mode if we're not using dynperm */
1578 } 1601 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
1579 } else if (cifsInode->cifsAttrs & ATTR_READONLY) { 1602 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
1603 } else if ((mode & S_IWUGO) &&
1604 (cifsInode->cifsAttrs & ATTR_READONLY)) {
1580 /* If file is readonly on server, we would 1605 /* If file is readonly on server, we would
1581 not be able to write to it - so if any write 1606 not be able to write to it - so if any write
1582 bit is enabled for user or group or other we 1607 bit is enabled for user or group or other we
@@ -1587,6 +1612,20 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1587 /* Windows ignores set to zero */ 1612 /* Windows ignores set to zero */
1588 if (time_buf.Attributes == 0) 1613 if (time_buf.Attributes == 0)
1589 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); 1614 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1615
1616 /* reset local inode permissions to normal */
1617 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1618 attrs->ia_mode &= ~(S_IALLUGO);
1619 if (S_ISDIR(inode->i_mode))
1620 attrs->ia_mode |=
1621 cifs_sb->mnt_dir_mode;
1622 else
1623 attrs->ia_mode |=
1624 cifs_sb->mnt_file_mode;
1625 }
1626 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1627 /* ignore mode change - ATTR_READONLY hasn't changed */
1628 attrs->ia_valid &= ~ATTR_MODE;
1590 } 1629 }
1591 } 1630 }
1592 1631
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 5c792df13d6..0088a5b5256 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -30,9 +30,9 @@
30 30
31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) 31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
32 32
33int cifs_ioctl(struct inode *inode, struct file *filep, 33long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
34 unsigned int command, unsigned long arg)
35{ 34{
35 struct inode *inode = filep->f_dentry->d_inode;
36 int rc = -ENOTTY; /* strange error - but the precedent */ 36 int rc = -ENOTTY; /* strange error - but the precedent */
37 int xid; 37 int xid;
38 struct cifs_sb_info *cifs_sb; 38 struct cifs_sb_info *cifs_sb;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 1c2c3ce5020..63f644000ce 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -234,7 +234,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
234 struct cifs_sb_info *cifs_sb; 234 struct cifs_sb_info *cifs_sb;
235 struct cifsTconInfo *pTcon; 235 struct cifsTconInfo *pTcon;
236 char *full_path = NULL; 236 char *full_path = NULL;
237 char *tmp_path = NULL;
238 char *tmpbuffer; 237 char *tmpbuffer;
239 int len; 238 int len;
240 __u16 fid; 239 __u16 fid;
@@ -295,45 +294,9 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
295 cFYI(1, ("Error closing junction point " 294 cFYI(1, ("Error closing junction point "
296 "(open for ioctl)")); 295 "(open for ioctl)"));
297 } 296 }
298 /* BB unwind this long, nested function, or remove BB */ 297 /* If it is a DFS junction earlier we would have gotten
299 if (rc == -EIO) { 298 PATH_NOT_COVERED returned from server so we do
300 /* Query if DFS Junction */ 299 not need to request the DFS info here */
301 unsigned int num_referrals = 0;
302 struct dfs_info3_param *refs = NULL;
303 tmp_path =
304 kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1,
305 GFP_KERNEL);
306 if (tmp_path) {
307 strncpy(tmp_path, pTcon->treeName,
308 MAX_TREE_SIZE);
309 strncat(tmp_path, full_path,
310 MAX_PATHCONF);
311 rc = get_dfs_path(xid, pTcon->ses,
312 tmp_path,
313 cifs_sb->local_nls,
314 &num_referrals, &refs,
315 cifs_sb->mnt_cifs_flags &
316 CIFS_MOUNT_MAP_SPECIAL_CHR);
317 cFYI(1, ("Get DFS for %s rc = %d ",
318 tmp_path, rc));
319 if ((num_referrals == 0) && (rc == 0))
320 rc = -EACCES;
321 else {
322 cFYI(1, ("num referral: %d",
323 num_referrals));
324 if (refs && refs->path_name) {
325 strncpy(tmpbuffer,
326 refs->path_name,
327 len-1);
328 }
329 }
330 kfree(refs);
331 kfree(tmp_path);
332}
333 /* BB add code like else decode referrals
334 then memcpy to tmpbuffer and free referrals
335 string array BB */
336 }
337 } 300 }
338 } 301 }
339 /* BB Anything else to do to handle recursive links? */ 302 /* BB Anything else to do to handle recursive links? */
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 1d69b8014e0..4b17f8fe315 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -519,8 +519,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
519 pnotify = (struct file_notify_information *) 519 pnotify = (struct file_notify_information *)
520 ((char *)&pSMBr->hdr.Protocol + data_offset); 520 ((char *)&pSMBr->hdr.Protocol + data_offset);
521 cFYI(1, ("dnotify on %s Action: 0x%x", 521 cFYI(1, ("dnotify on %s Action: 0x%x",
522 pnotify->FileName, 522 pnotify->FileName, pnotify->Action));
523 pnotify->Action)); /* BB removeme BB */
524 /* cifs_dump_mem("Rcvd notify Data: ",buf, 523 /* cifs_dump_mem("Rcvd notify Data: ",buf,
525 sizeof(struct smb_hdr)+60); */ 524 sizeof(struct smb_hdr)+60); */
526 return true; 525 return true;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 00f4cff400b..8703d68f5b2 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -141,11 +141,11 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst)
141 int ret = 0; 141 int ret = 0;
142 142
143 /* calculate length by finding first slash or NULL */ 143 /* calculate length by finding first slash or NULL */
144 if (address_family == AF_INET) { 144 if (address_family == AF_INET)
145 ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL); 145 ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL);
146 } else if (address_family == AF_INET6) { 146 else if (address_family == AF_INET6)
147 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); 147 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
148 } 148
149 cFYI(DBG2, ("address conversion returned %d for %s", ret, cp)); 149 cFYI(DBG2, ("address conversion returned %d for %s", ret, cp));
150 if (ret > 0) 150 if (ret > 0)
151 ret = 1; 151 ret = 1;
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 7170a9b70f1..c377d8065d9 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -64,7 +64,7 @@ typedef struct _SECURITY_BUFFER {
64} __attribute__((packed)) SECURITY_BUFFER; 64} __attribute__((packed)) SECURITY_BUFFER;
65 65
66typedef struct _NEGOTIATE_MESSAGE { 66typedef struct _NEGOTIATE_MESSAGE {
67 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; 67 __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
68 __le32 MessageType; /* 1 */ 68 __le32 MessageType; /* 1 */
69 __le32 NegotiateFlags; 69 __le32 NegotiateFlags;
70 SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */ 70 SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */
@@ -74,7 +74,7 @@ typedef struct _NEGOTIATE_MESSAGE {
74} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE; 74} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
75 75
76typedef struct _CHALLENGE_MESSAGE { 76typedef struct _CHALLENGE_MESSAGE {
77 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; 77 __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
78 __le32 MessageType; /* 2 */ 78 __le32 MessageType; /* 2 */
79 SECURITY_BUFFER TargetName; 79 SECURITY_BUFFER TargetName;
80 __le32 NegotiateFlags; 80 __le32 NegotiateFlags;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 34ec32100c7..83f30695488 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -132,6 +132,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
132 __u32 attr; 132 __u32 attr;
133 __u64 allocation_size; 133 __u64 allocation_size;
134 __u64 end_of_file; 134 __u64 end_of_file;
135 umode_t default_mode;
135 136
136 /* save mtime and size */ 137 /* save mtime and size */
137 local_mtime = tmp_inode->i_mtime; 138 local_mtime = tmp_inode->i_mtime;
@@ -187,48 +188,54 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
187 if (atomic_read(&cifsInfo->inUse) == 0) { 188 if (atomic_read(&cifsInfo->inUse) == 0) {
188 tmp_inode->i_uid = cifs_sb->mnt_uid; 189 tmp_inode->i_uid = cifs_sb->mnt_uid;
189 tmp_inode->i_gid = cifs_sb->mnt_gid; 190 tmp_inode->i_gid = cifs_sb->mnt_gid;
190 /* set default mode. will override for dirs below */ 191 }
191 tmp_inode->i_mode = cifs_sb->mnt_file_mode; 192
192 } else { 193 if (attr & ATTR_DIRECTORY)
193 /* mask off the type bits since it gets set 194 default_mode = cifs_sb->mnt_dir_mode;
194 below and we do not want to get two type 195 else
195 bits set */ 196 default_mode = cifs_sb->mnt_file_mode;
197
198 /* set initial permissions */
199 if ((atomic_read(&cifsInfo->inUse) == 0) ||
200 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
201 tmp_inode->i_mode = default_mode;
202 else {
203 /* just reenable write bits if !ATTR_READONLY */
204 if ((tmp_inode->i_mode & S_IWUGO) == 0 &&
205 (attr & ATTR_READONLY) == 0)
206 tmp_inode->i_mode |= (S_IWUGO & default_mode);
207
196 tmp_inode->i_mode &= ~S_IFMT; 208 tmp_inode->i_mode &= ~S_IFMT;
197 } 209 }
198 210
199 if (attr & ATTR_DIRECTORY) { 211 /* clear write bits if ATTR_READONLY is set */
200 *pobject_type = DT_DIR; 212 if (attr & ATTR_READONLY)
201 /* override default perms since we do not lock dirs */ 213 tmp_inode->i_mode &= ~S_IWUGO;
202 if (atomic_read(&cifsInfo->inUse) == 0) 214
203 tmp_inode->i_mode = cifs_sb->mnt_dir_mode; 215 /* set inode type */
204 tmp_inode->i_mode |= S_IFDIR; 216 if ((attr & ATTR_SYSTEM) &&
205 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 217 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
206 (attr & ATTR_SYSTEM)) {
207 if (end_of_file == 0) { 218 if (end_of_file == 0) {
208 *pobject_type = DT_FIFO;
209 tmp_inode->i_mode |= S_IFIFO; 219 tmp_inode->i_mode |= S_IFIFO;
220 *pobject_type = DT_FIFO;
210 } else { 221 } else {
211 /* rather than get the type here, we mark the 222 /*
212 inode as needing revalidate and get the real type 223 * trying to get the type can be slow, so just call
213 (blk vs chr vs. symlink) later ie in lookup */ 224 * this a regular file for now, and mark for reval
214 *pobject_type = DT_REG; 225 */
215 tmp_inode->i_mode |= S_IFREG; 226 tmp_inode->i_mode |= S_IFREG;
227 *pobject_type = DT_REG;
216 cifsInfo->time = 0; 228 cifsInfo->time = 0;
217 } 229 }
218/* we no longer mark these because we could not follow them */
219/* } else if (attr & ATTR_REPARSE) {
220 *pobject_type = DT_LNK;
221 tmp_inode->i_mode |= S_IFLNK; */
222 } else { 230 } else {
223 *pobject_type = DT_REG; 231 if (attr & ATTR_DIRECTORY) {
224 tmp_inode->i_mode |= S_IFREG; 232 tmp_inode->i_mode |= S_IFDIR;
225 if (attr & ATTR_READONLY) 233 *pobject_type = DT_DIR;
226 tmp_inode->i_mode &= ~(S_IWUGO); 234 } else {
227 else if ((tmp_inode->i_mode & S_IWUGO) == 0) 235 tmp_inode->i_mode |= S_IFREG;
228 /* the ATTR_READONLY flag may have been changed on */ 236 *pobject_type = DT_REG;
229 /* server -- set any w bits allowed by mnt_file_mode */ 237 }
230 tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); 238 }
231 } /* could add code here - to validate if device or weird share type? */
232 239
233 /* can not fill in nlink here as in qpathinfo version and Unx search */ 240 /* can not fill in nlink here as in qpathinfo version and Unx search */
234 if (atomic_read(&cifsInfo->inUse) == 0) 241 if (atomic_read(&cifsInfo->inUse) == 0)
@@ -670,10 +677,11 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
670 (index_to_find < first_entry_in_buffer)) { 677 (index_to_find < first_entry_in_buffer)) {
671 /* close and restart search */ 678 /* close and restart search */
672 cFYI(1, ("search backing up - close and restart search")); 679 cFYI(1, ("search backing up - close and restart search"));
673 cifsFile->invalidHandle = true; 680 if (!cifsFile->srch_inf.endOfSearch &&
674 CIFSFindClose(xid, pTcon, cifsFile->netfid); 681 !cifsFile->invalidHandle) {
675 kfree(cifsFile->search_resume_name); 682 cifsFile->invalidHandle = true;
676 cifsFile->search_resume_name = NULL; 683 CIFSFindClose(xid, pTcon, cifsFile->netfid);
684 }
677 if (cifsFile->srch_inf.ntwrk_buf_start) { 685 if (cifsFile->srch_inf.ntwrk_buf_start) {
678 cFYI(1, ("freeing SMB ff cache buf on search rewind")); 686 cFYI(1, ("freeing SMB ff cache buf on search rewind"));
679 if (cifsFile->srch_inf.smallBuf) 687 if (cifsFile->srch_inf.smallBuf)
@@ -1040,9 +1048,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1040 } /* else { 1048 } /* else {
1041 cifsFile->invalidHandle = true; 1049 cifsFile->invalidHandle = true;
1042 CIFSFindClose(xid, pTcon, cifsFile->netfid); 1050 CIFSFindClose(xid, pTcon, cifsFile->netfid);
1043 } 1051 } */
1044 kfree(cifsFile->search_resume_name);
1045 cifsFile->search_resume_name = NULL; */
1046 1052
1047 rc = find_cifs_entry(xid, pTcon, file, 1053 rc = find_cifs_entry(xid, pTcon, file,
1048 &current_entry, &num_to_fill); 1054 &current_entry, &num_to_fill);
diff --git a/fs/dcache.c b/fs/dcache.c
index 3ee588d5f58..6068c25b393 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -17,6 +17,7 @@
17#include <linux/syscalls.h> 17#include <linux/syscalls.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/fdtable.h>
20#include <linux/fs.h> 21#include <linux/fs.h>
21#include <linux/fsnotify.h> 22#include <linux/fsnotify.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
@@ -106,9 +107,10 @@ static void dentry_lru_remove(struct dentry *dentry)
106/* 107/*
107 * Release the dentry's inode, using the filesystem 108 * Release the dentry's inode, using the filesystem
108 * d_iput() operation if defined. 109 * d_iput() operation if defined.
109 * Called with dcache_lock and per dentry lock held, drops both.
110 */ 110 */
111static void dentry_iput(struct dentry * dentry) 111static void dentry_iput(struct dentry * dentry)
112 __releases(dentry->d_lock)
113 __releases(dcache_lock)
112{ 114{
113 struct inode *inode = dentry->d_inode; 115 struct inode *inode = dentry->d_inode;
114 if (inode) { 116 if (inode) {
@@ -132,12 +134,13 @@ static void dentry_iput(struct dentry * dentry)
132 * d_kill - kill dentry and return parent 134 * d_kill - kill dentry and return parent
133 * @dentry: dentry to kill 135 * @dentry: dentry to kill
134 * 136 *
135 * Called with dcache_lock and d_lock, releases both. The dentry must 137 * The dentry must already be unhashed and removed from the LRU.
136 * already be unhashed and removed from the LRU.
137 * 138 *
138 * If this is the root of the dentry tree, return NULL. 139 * If this is the root of the dentry tree, return NULL.
139 */ 140 */
140static struct dentry *d_kill(struct dentry *dentry) 141static struct dentry *d_kill(struct dentry *dentry)
142 __releases(dentry->d_lock)
143 __releases(dcache_lock)
141{ 144{
142 struct dentry *parent; 145 struct dentry *parent;
143 146
@@ -383,11 +386,11 @@ restart:
383 * Try to prune ancestors as well. This is necessary to prevent 386 * Try to prune ancestors as well. This is necessary to prevent
384 * quadratic behavior of shrink_dcache_parent(), but is also expected 387 * quadratic behavior of shrink_dcache_parent(), but is also expected
385 * to be beneficial in reducing dentry cache fragmentation. 388 * to be beneficial in reducing dentry cache fragmentation.
386 *
387 * Called with dcache_lock, drops it and then regains.
388 * Called with dentry->d_lock held, drops it.
389 */ 389 */
390static void prune_one_dentry(struct dentry * dentry) 390static void prune_one_dentry(struct dentry * dentry)
391 __releases(dentry->d_lock)
392 __releases(dcache_lock)
393 __acquires(dcache_lock)
391{ 394{
392 __d_drop(dentry); 395 __d_drop(dentry);
393 dentry = d_kill(dentry); 396 dentry = d_kill(dentry);
@@ -1604,10 +1607,9 @@ static int d_isparent(struct dentry *p1, struct dentry *p2)
1604 * 1607 *
1605 * Note: If ever the locking in lock_rename() changes, then please 1608 * Note: If ever the locking in lock_rename() changes, then please
1606 * remember to update this too... 1609 * remember to update this too...
1607 *
1608 * On return, dcache_lock will have been unlocked.
1609 */ 1610 */
1610static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) 1611static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
1612 __releases(dcache_lock)
1611{ 1613{
1612 struct mutex *m1 = NULL, *m2 = NULL; 1614 struct mutex *m1 = NULL, *m2 = NULL;
1613 struct dentry *ret; 1615 struct dentry *ret;
@@ -1743,11 +1745,9 @@ out_nolock:
1743shouldnt_be_hashed: 1745shouldnt_be_hashed:
1744 spin_unlock(&dcache_lock); 1746 spin_unlock(&dcache_lock);
1745 BUG(); 1747 BUG();
1746 goto shouldnt_be_hashed;
1747} 1748}
1748 1749
1749static int prepend(char **buffer, int *buflen, const char *str, 1750static int prepend(char **buffer, int *buflen, const char *str, int namelen)
1750 int namelen)
1751{ 1751{
1752 *buflen -= namelen; 1752 *buflen -= namelen;
1753 if (*buflen < 0) 1753 if (*buflen < 0)
@@ -1757,8 +1757,13 @@ static int prepend(char **buffer, int *buflen, const char *str,
1757 return 0; 1757 return 0;
1758} 1758}
1759 1759
1760static int prepend_name(char **buffer, int *buflen, struct qstr *name)
1761{
1762 return prepend(buffer, buflen, name->name, name->len);
1763}
1764
1760/** 1765/**
1761 * d_path - return the path of a dentry 1766 * __d_path - return the path of a dentry
1762 * @path: the dentry/vfsmount to report 1767 * @path: the dentry/vfsmount to report
1763 * @root: root vfsmnt/dentry (may be modified by this function) 1768 * @root: root vfsmnt/dentry (may be modified by this function)
1764 * @buffer: buffer to return value in 1769 * @buffer: buffer to return value in
@@ -1779,9 +1784,10 @@ char *__d_path(const struct path *path, struct path *root,
1779{ 1784{
1780 struct dentry *dentry = path->dentry; 1785 struct dentry *dentry = path->dentry;
1781 struct vfsmount *vfsmnt = path->mnt; 1786 struct vfsmount *vfsmnt = path->mnt;
1782 char * end = buffer+buflen; 1787 char *end = buffer + buflen;
1783 char * retval; 1788 char *retval;
1784 1789
1790 spin_lock(&vfsmount_lock);
1785 prepend(&end, &buflen, "\0", 1); 1791 prepend(&end, &buflen, "\0", 1);
1786 if (!IS_ROOT(dentry) && d_unhashed(dentry) && 1792 if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
1787 (prepend(&end, &buflen, " (deleted)", 10) != 0)) 1793 (prepend(&end, &buflen, " (deleted)", 10) != 0))
@@ -1800,38 +1806,37 @@ char *__d_path(const struct path *path, struct path *root,
1800 break; 1806 break;
1801 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { 1807 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
1802 /* Global root? */ 1808 /* Global root? */
1803 spin_lock(&vfsmount_lock);
1804 if (vfsmnt->mnt_parent == vfsmnt) { 1809 if (vfsmnt->mnt_parent == vfsmnt) {
1805 spin_unlock(&vfsmount_lock);
1806 goto global_root; 1810 goto global_root;
1807 } 1811 }
1808 dentry = vfsmnt->mnt_mountpoint; 1812 dentry = vfsmnt->mnt_mountpoint;
1809 vfsmnt = vfsmnt->mnt_parent; 1813 vfsmnt = vfsmnt->mnt_parent;
1810 spin_unlock(&vfsmount_lock);
1811 continue; 1814 continue;
1812 } 1815 }
1813 parent = dentry->d_parent; 1816 parent = dentry->d_parent;
1814 prefetch(parent); 1817 prefetch(parent);
1815 if ((prepend(&end, &buflen, dentry->d_name.name, 1818 if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
1816 dentry->d_name.len) != 0) ||
1817 (prepend(&end, &buflen, "/", 1) != 0)) 1819 (prepend(&end, &buflen, "/", 1) != 0))
1818 goto Elong; 1820 goto Elong;
1819 retval = end; 1821 retval = end;
1820 dentry = parent; 1822 dentry = parent;
1821 } 1823 }
1822 1824
1825out:
1826 spin_unlock(&vfsmount_lock);
1823 return retval; 1827 return retval;
1824 1828
1825global_root: 1829global_root:
1826 retval += 1; /* hit the slash */ 1830 retval += 1; /* hit the slash */
1827 if (prepend(&retval, &buflen, dentry->d_name.name, 1831 if (prepend_name(&retval, &buflen, &dentry->d_name) != 0)
1828 dentry->d_name.len) != 0)
1829 goto Elong; 1832 goto Elong;
1830 root->mnt = vfsmnt; 1833 root->mnt = vfsmnt;
1831 root->dentry = dentry; 1834 root->dentry = dentry;
1832 return retval; 1835 goto out;
1836
1833Elong: 1837Elong:
1834 return ERR_PTR(-ENAMETOOLONG); 1838 retval = ERR_PTR(-ENAMETOOLONG);
1839 goto out;
1835} 1840}
1836 1841
1837/** 1842/**
@@ -1845,9 +1850,9 @@ Elong:
1845 * 1850 *
1846 * Returns the buffer or an error code if the path was too long. 1851 * Returns the buffer or an error code if the path was too long.
1847 * 1852 *
1848 * "buflen" should be positive. Caller holds the dcache_lock. 1853 * "buflen" should be positive.
1849 */ 1854 */
1850char *d_path(struct path *path, char *buf, int buflen) 1855char *d_path(const struct path *path, char *buf, int buflen)
1851{ 1856{
1852 char *res; 1857 char *res;
1853 struct path root; 1858 struct path root;
@@ -1915,16 +1920,11 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
1915 retval = end-1; 1920 retval = end-1;
1916 *retval = '/'; 1921 *retval = '/';
1917 1922
1918 for (;;) { 1923 while (!IS_ROOT(dentry)) {
1919 struct dentry *parent; 1924 struct dentry *parent = dentry->d_parent;
1920 if (IS_ROOT(dentry))
1921 break;
1922 1925
1923 parent = dentry->d_parent;
1924 prefetch(parent); 1926 prefetch(parent);
1925 1927 if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
1926 if ((prepend(&end, &buflen, dentry->d_name.name,
1927 dentry->d_name.len) != 0) ||
1928 (prepend(&end, &buflen, "/", 1) != 0)) 1928 (prepend(&end, &buflen, "/", 1) != 0))
1929 goto Elong; 1929 goto Elong;
1930 1930
@@ -1975,7 +1975,7 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
1975 error = -ENOENT; 1975 error = -ENOENT;
1976 /* Has the current directory has been unlinked? */ 1976 /* Has the current directory has been unlinked? */
1977 spin_lock(&dcache_lock); 1977 spin_lock(&dcache_lock);
1978 if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { 1978 if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
1979 unsigned long len; 1979 unsigned long len;
1980 struct path tmp = root; 1980 struct path tmp = root;
1981 char * cwd; 1981 char * cwd;
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index cd62d75b2cc..e2832bc7869 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -1906,9 +1906,9 @@ int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
1906 goto out; 1906 goto out;
1907 } 1907 }
1908 } 1908 }
1909 mutex_unlock(&key_tfm_list_mutex);
1910 (*tfm) = key_tfm->key_tfm; 1909 (*tfm) = key_tfm->key_tfm;
1911 (*tfm_mutex) = &key_tfm->key_tfm_mutex; 1910 (*tfm_mutex) = &key_tfm->key_tfm_mutex;
1912out: 1911out:
1912 mutex_unlock(&key_tfm_list_mutex);
1913 return rc; 1913 return rc;
1914} 1914}
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 951ee33a022..c15c25745e0 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -660,8 +660,6 @@ int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
660int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, 660int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
661 struct ecryptfs_auth_tok **auth_tok, 661 struct ecryptfs_auth_tok **auth_tok,
662 char *sig); 662 char *sig);
663int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start,
664 int num_zeros);
665int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, 663int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
666 loff_t offset, size_t size); 664 loff_t offset, size_t size);
667int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, 665int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index 6560da1a58c..09a4522f65e 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -243,7 +243,6 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
243 struct ecryptfs_daemon *daemon; 243 struct ecryptfs_daemon *daemon;
244 struct ecryptfs_msg_ctx *msg_ctx; 244 struct ecryptfs_msg_ctx *msg_ctx;
245 size_t packet_length_size; 245 size_t packet_length_size;
246 u32 counter_nbo;
247 char packet_length[3]; 246 char packet_length[3];
248 size_t i; 247 size_t i;
249 size_t total_length; 248 size_t total_length;
@@ -328,20 +327,18 @@ check_list:
328 "pending message\n", __func__, count, total_length); 327 "pending message\n", __func__, count, total_length);
329 goto out_unlock_msg_ctx; 328 goto out_unlock_msg_ctx;
330 } 329 }
331 i = 0; 330 rc = -EFAULT;
332 buf[i++] = msg_ctx->type; 331 if (put_user(msg_ctx->type, buf))
333 counter_nbo = cpu_to_be32(msg_ctx->counter); 332 goto out_unlock_msg_ctx;
334 memcpy(&buf[i], (char *)&counter_nbo, 4); 333 if (put_user(cpu_to_be32(msg_ctx->counter), (__be32 __user *)(buf + 1)))
335 i += 4; 334 goto out_unlock_msg_ctx;
335 i = 5;
336 if (msg_ctx->msg) { 336 if (msg_ctx->msg) {
337 memcpy(&buf[i], packet_length, packet_length_size); 337 if (copy_to_user(&buf[i], packet_length, packet_length_size))
338 goto out_unlock_msg_ctx;
338 i += packet_length_size; 339 i += packet_length_size;
339 rc = copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size); 340 if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
340 if (rc) {
341 printk(KERN_ERR "%s: copy_to_user returned error "
342 "[%d]\n", __func__, rc);
343 goto out_unlock_msg_ctx; 341 goto out_unlock_msg_ctx;
344 }
345 i += msg_ctx->msg_size; 342 i += msg_ctx->msg_size;
346 } 343 }
347 rc = i; 344 rc = i;
@@ -452,7 +449,8 @@ static ssize_t
452ecryptfs_miscdev_write(struct file *file, const char __user *buf, 449ecryptfs_miscdev_write(struct file *file, const char __user *buf,
453 size_t count, loff_t *ppos) 450 size_t count, loff_t *ppos)
454{ 451{
455 u32 counter_nbo, seq; 452 __be32 counter_nbo;
453 u32 seq;
456 size_t packet_size, packet_size_length, i; 454 size_t packet_size, packet_size_length, i;
457 ssize_t sz = 0; 455 ssize_t sz = 0;
458 char *data; 456 char *data;
@@ -485,7 +483,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
485 count); 483 count);
486 goto out_free; 484 goto out_free;
487 } 485 }
488 memcpy((char *)&counter_nbo, &data[i], 4); 486 memcpy(&counter_nbo, &data[i], 4);
489 seq = be32_to_cpu(counter_nbo); 487 seq = be32_to_cpu(counter_nbo);
490 i += 4; 488 i += 4;
491 rc = ecryptfs_parse_packet_length(&data[i], &packet_size, 489 rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
@@ -577,13 +575,11 @@ int ecryptfs_init_ecryptfs_miscdev(void)
577 int rc; 575 int rc;
578 576
579 atomic_set(&ecryptfs_num_miscdev_opens, 0); 577 atomic_set(&ecryptfs_num_miscdev_opens, 0);
580 mutex_lock(&ecryptfs_daemon_hash_mux);
581 rc = misc_register(&ecryptfs_miscdev); 578 rc = misc_register(&ecryptfs_miscdev);
582 if (rc) 579 if (rc)
583 printk(KERN_ERR "%s: Failed to register miscellaneous device " 580 printk(KERN_ERR "%s: Failed to register miscellaneous device "
584 "for communications with userspace daemons; rc = [%d]\n", 581 "for communications with userspace daemons; rc = [%d]\n",
585 __func__, rc); 582 __func__, rc);
586 mutex_unlock(&ecryptfs_daemon_hash_mux);
587 return rc; 583 return rc;
588} 584}
589 585
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index ebf55150be5..75c2ea9fee3 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -157,20 +157,6 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
157 ecryptfs_page_idx, rc); 157 ecryptfs_page_idx, rc);
158 goto out; 158 goto out;
159 } 159 }
160 if (start_offset_in_page) {
161 /* Read in the page from the lower
162 * into the eCryptfs inode page cache,
163 * decrypting */
164 rc = ecryptfs_decrypt_page(ecryptfs_page);
165 if (rc) {
166 printk(KERN_ERR "%s: Error decrypting "
167 "page; rc = [%d]\n",
168 __func__, rc);
169 ClearPageUptodate(ecryptfs_page);
170 page_cache_release(ecryptfs_page);
171 goto out;
172 }
173 }
174 ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); 160 ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
175 161
176 /* 162 /*
@@ -349,14 +335,6 @@ int ecryptfs_read(char *data, loff_t offset, size_t size,
349 ecryptfs_page_idx, rc); 335 ecryptfs_page_idx, rc);
350 goto out; 336 goto out;
351 } 337 }
352 rc = ecryptfs_decrypt_page(ecryptfs_page);
353 if (rc) {
354 printk(KERN_ERR "%s: Error decrypting "
355 "page; rc = [%d]\n", __func__, rc);
356 ClearPageUptodate(ecryptfs_page);
357 page_cache_release(ecryptfs_page);
358 goto out;
359 }
360 ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); 338 ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
361 memcpy((data + data_offset), 339 memcpy((data + data_offset),
362 ((char *)ecryptfs_page_virt + start_offset_in_page), 340 ((char *)ecryptfs_page_virt + start_offset_in_page),
diff --git a/fs/exec.c b/fs/exec.c
index 3c2ba7ce11d..da94a6f05df 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -26,7 +26,6 @@
26#include <linux/file.h> 26#include <linux/file.h>
27#include <linux/fdtable.h> 27#include <linux/fdtable.h>
28#include <linux/mman.h> 28#include <linux/mman.h>
29#include <linux/a.out.h>
30#include <linux/stat.h> 29#include <linux/stat.h>
31#include <linux/fcntl.h> 30#include <linux/fcntl.h>
32#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
@@ -61,6 +60,11 @@
61#include <linux/kmod.h> 60#include <linux/kmod.h>
62#endif 61#endif
63 62
63#ifdef __alpha__
64/* for /sbin/loader handling in search_binary_handler() */
65#include <linux/a.out.h>
66#endif
67
64int core_uses_pid; 68int core_uses_pid;
65char core_pattern[CORENAME_MAX_SIZE] = "core"; 69char core_pattern[CORENAME_MAX_SIZE] = "core";
66int suid_dumpable = 0; 70int suid_dumpable = 0;
@@ -860,6 +864,7 @@ static int de_thread(struct task_struct *tsk)
860 864
861no_thread_group: 865no_thread_group:
862 exit_itimers(sig); 866 exit_itimers(sig);
867 flush_itimer_signals();
863 if (leader) 868 if (leader)
864 release_task(leader); 869 release_task(leader);
865 870
@@ -1154,7 +1159,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1154{ 1159{
1155 int try,retval; 1160 int try,retval;
1156 struct linux_binfmt *fmt; 1161 struct linux_binfmt *fmt;
1157#if defined(__alpha__) && defined(CONFIG_ARCH_SUPPORTS_AOUT) 1162#ifdef __alpha__
1158 /* handle /sbin/loader.. */ 1163 /* handle /sbin/loader.. */
1159 { 1164 {
1160 struct exec * eh = (struct exec *) bprm->buf; 1165 struct exec * eh = (struct exec *) bprm->buf;
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 28cfd0b4052..77278e947e9 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -580,7 +580,8 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
580 } 580 }
581 581
582 blk = EXT3_SB(sb)->s_sbh->b_blocknr + 1 + EXT3_SB(sb)->s_gdb_count; 582 blk = EXT3_SB(sb)->s_sbh->b_blocknr + 1 + EXT3_SB(sb)->s_gdb_count;
583 data = (__le32 *)dind->b_data + EXT3_SB(sb)->s_gdb_count; 583 data = (__le32 *)dind->b_data + (EXT3_SB(sb)->s_gdb_count %
584 EXT3_ADDR_PER_BLOCK(sb));
584 end = (__le32 *)dind->b_data + EXT3_ADDR_PER_BLOCK(sb); 585 end = (__le32 *)dind->b_data + EXT3_ADDR_PER_BLOCK(sb);
585 586
586 /* Get each reserved primary GDT block and verify it holds backups */ 587 /* Get each reserved primary GDT block and verify it holds backups */
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index fe3119a71ad..2845425077e 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2875,8 +2875,10 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
2875 blk++; 2875 blk++;
2876 } 2876 }
2877out: 2877out:
2878 if (len == towrite) 2878 if (len == towrite) {
2879 mutex_unlock(&inode->i_mutex);
2879 return err; 2880 return err;
2881 }
2880 if (inode->i_size < off+len-towrite) { 2882 if (inode->i_size < off+len-towrite) {
2881 i_size_write(inode, off+len-towrite); 2883 i_size_write(inode, off+len-towrite);
2882 EXT3_I(inode)->i_disksize = inode->i_size; 2884 EXT3_I(inode)->i_disksize = inode->i_size;
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 30494c5da84..9cc80b9cc8d 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -43,6 +43,46 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
43 43
44} 44}
45 45
46static int ext4_block_in_group(struct super_block *sb, ext4_fsblk_t block,
47 ext4_group_t block_group)
48{
49 ext4_group_t actual_group;
50 ext4_get_group_no_and_offset(sb, block, &actual_group, 0);
51 if (actual_group == block_group)
52 return 1;
53 return 0;
54}
55
56static int ext4_group_used_meta_blocks(struct super_block *sb,
57 ext4_group_t block_group)
58{
59 ext4_fsblk_t tmp;
60 struct ext4_sb_info *sbi = EXT4_SB(sb);
61 /* block bitmap, inode bitmap, and inode table blocks */
62 int used_blocks = sbi->s_itb_per_group + 2;
63
64 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
65 struct ext4_group_desc *gdp;
66 struct buffer_head *bh;
67
68 gdp = ext4_get_group_desc(sb, block_group, &bh);
69 if (!ext4_block_in_group(sb, ext4_block_bitmap(sb, gdp),
70 block_group))
71 used_blocks--;
72
73 if (!ext4_block_in_group(sb, ext4_inode_bitmap(sb, gdp),
74 block_group))
75 used_blocks--;
76
77 tmp = ext4_inode_table(sb, gdp);
78 for (; tmp < ext4_inode_table(sb, gdp) +
79 sbi->s_itb_per_group; tmp++) {
80 if (!ext4_block_in_group(sb, tmp, block_group))
81 used_blocks -= 1;
82 }
83 }
84 return used_blocks;
85}
46/* Initializes an uninitialized block bitmap if given, and returns the 86/* Initializes an uninitialized block bitmap if given, and returns the
47 * number of blocks free in the group. */ 87 * number of blocks free in the group. */
48unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, 88unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
@@ -105,20 +145,34 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
105 free_blocks = group_blocks - bit_max; 145 free_blocks = group_blocks - bit_max;
106 146
107 if (bh) { 147 if (bh) {
108 ext4_fsblk_t start; 148 ext4_fsblk_t start, tmp;
149 int flex_bg = 0;
109 150
110 for (bit = 0; bit < bit_max; bit++) 151 for (bit = 0; bit < bit_max; bit++)
111 ext4_set_bit(bit, bh->b_data); 152 ext4_set_bit(bit, bh->b_data);
112 153
113 start = ext4_group_first_block_no(sb, block_group); 154 start = ext4_group_first_block_no(sb, block_group);
114 155
115 /* Set bits for block and inode bitmaps, and inode table */ 156 if (EXT4_HAS_INCOMPAT_FEATURE(sb,
116 ext4_set_bit(ext4_block_bitmap(sb, gdp) - start, bh->b_data); 157 EXT4_FEATURE_INCOMPAT_FLEX_BG))
117 ext4_set_bit(ext4_inode_bitmap(sb, gdp) - start, bh->b_data); 158 flex_bg = 1;
118 for (bit = (ext4_inode_table(sb, gdp) - start),
119 bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++)
120 ext4_set_bit(bit, bh->b_data);
121 159
160 /* Set bits for block and inode bitmaps, and inode table */
161 tmp = ext4_block_bitmap(sb, gdp);
162 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
163 ext4_set_bit(tmp - start, bh->b_data);
164
165 tmp = ext4_inode_bitmap(sb, gdp);
166 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
167 ext4_set_bit(tmp - start, bh->b_data);
168
169 tmp = ext4_inode_table(sb, gdp);
170 for (; tmp < ext4_inode_table(sb, gdp) +
171 sbi->s_itb_per_group; tmp++) {
172 if (!flex_bg ||
173 ext4_block_in_group(sb, tmp, block_group))
174 ext4_set_bit(tmp - start, bh->b_data);
175 }
122 /* 176 /*
123 * Also if the number of blocks within the group is 177 * Also if the number of blocks within the group is
124 * less than the blocksize * 8 ( which is the size 178 * less than the blocksize * 8 ( which is the size
@@ -126,8 +180,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
126 */ 180 */
127 mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data); 181 mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data);
128 } 182 }
129 183 return free_blocks - ext4_group_used_meta_blocks(sb, block_group);
130 return free_blocks - sbi->s_itb_per_group - 2;
131} 184}
132 185
133 186
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 873ad9b3418..c9900aade15 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2745,8 +2745,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2745 sbi = EXT4_SB(sb); 2745 sbi = EXT4_SB(sb);
2746 es = sbi->s_es; 2746 es = sbi->s_es;
2747 2747
2748 ext4_debug("using block group %lu(%d)\n", ac->ac_b_ex.fe_group,
2749 gdp->bg_free_blocks_count);
2750 2748
2751 err = -EIO; 2749 err = -EIO;
2752 bitmap_bh = read_block_bitmap(sb, ac->ac_b_ex.fe_group); 2750 bitmap_bh = read_block_bitmap(sb, ac->ac_b_ex.fe_group);
@@ -2762,6 +2760,9 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2762 if (!gdp) 2760 if (!gdp)
2763 goto out_err; 2761 goto out_err;
2764 2762
2763 ext4_debug("using block group %lu(%d)\n", ac->ac_b_ex.fe_group,
2764 gdp->bg_free_blocks_count);
2765
2765 err = ext4_journal_get_write_access(handle, gdp_bh); 2766 err = ext4_journal_get_write_access(handle, gdp_bh);
2766 if (err) 2767 if (err)
2767 goto out_err; 2768 goto out_err;
@@ -3094,8 +3095,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
3094static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac, 3095static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac,
3095 struct ext4_prealloc_space *pa) 3096 struct ext4_prealloc_space *pa)
3096{ 3097{
3097 unsigned len = ac->ac_o_ex.fe_len; 3098 unsigned int len = ac->ac_o_ex.fe_len;
3098
3099 ext4_get_group_no_and_offset(ac->ac_sb, pa->pa_pstart, 3099 ext4_get_group_no_and_offset(ac->ac_sb, pa->pa_pstart,
3100 &ac->ac_b_ex.fe_group, 3100 &ac->ac_b_ex.fe_group,
3101 &ac->ac_b_ex.fe_start); 3101 &ac->ac_b_ex.fe_start);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 9f086a6a472..9ff7b1c0423 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -563,7 +563,8 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
563 } 563 }
564 564
565 blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count; 565 blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count;
566 data = (__le32 *)dind->b_data + EXT4_SB(sb)->s_gdb_count; 566 data = (__le32 *)dind->b_data + (EXT4_SB(sb)->s_gdb_count %
567 EXT4_ADDR_PER_BLOCK(sb));
567 end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb); 568 end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb);
568 569
569 /* Get each reserved primary GDT block and verify it holds backups */ 570 /* Get each reserved primary GDT block and verify it holds backups */
@@ -854,7 +855,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
854 */ 855 */
855 856
856 /* Update group descriptor block for new group */ 857 /* Update group descriptor block for new group */
857 gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; 858 gdp = (struct ext4_group_desc *)((char *)primary->b_data +
859 gdb_off * EXT4_DESC_SIZE(sb));
858 860
859 ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ 861 ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
860 ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ 862 ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 09d9359c805..02bf2434397 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -671,6 +671,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
671 unsigned long def_mount_opts; 671 unsigned long def_mount_opts;
672 struct super_block *sb = vfs->mnt_sb; 672 struct super_block *sb = vfs->mnt_sb;
673 struct ext4_sb_info *sbi = EXT4_SB(sb); 673 struct ext4_sb_info *sbi = EXT4_SB(sb);
674 journal_t *journal = sbi->s_journal;
674 struct ext4_super_block *es = sbi->s_es; 675 struct ext4_super_block *es = sbi->s_es;
675 676
676 def_mount_opts = le32_to_cpu(es->s_default_mount_opts); 677 def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
@@ -729,8 +730,15 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
729 seq_printf(seq, ",commit=%u", 730 seq_printf(seq, ",commit=%u",
730 (unsigned) (sbi->s_commit_interval / HZ)); 731 (unsigned) (sbi->s_commit_interval / HZ));
731 } 732 }
732 if (test_opt(sb, BARRIER)) 733 /*
733 seq_puts(seq, ",barrier=1"); 734 * We're changing the default of barrier mount option, so
735 * let's always display its mount state so it's clear what its
736 * status is.
737 */
738 seq_puts(seq, ",barrier=");
739 seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0");
740 if (test_opt(sb, JOURNAL_ASYNC_COMMIT))
741 seq_puts(seq, ",journal_async_commit");
734 if (test_opt(sb, NOBH)) 742 if (test_opt(sb, NOBH))
735 seq_puts(seq, ",nobh"); 743 seq_puts(seq, ",nobh");
736 if (!test_opt(sb, EXTENTS)) 744 if (!test_opt(sb, EXTENTS))
@@ -1907,6 +1915,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1907 sbi->s_resgid = le16_to_cpu(es->s_def_resgid); 1915 sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
1908 1916
1909 set_opt(sbi->s_mount_opt, RESERVATION); 1917 set_opt(sbi->s_mount_opt, RESERVATION);
1918 set_opt(sbi->s_mount_opt, BARRIER);
1910 1919
1911 /* 1920 /*
1912 * turn on extents feature by default in ext4 filesystem 1921 * turn on extents feature by default in ext4 filesystem
@@ -2189,6 +2198,29 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
2189 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { 2198 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
2190 if (ext4_load_journal(sb, es, journal_devnum)) 2199 if (ext4_load_journal(sb, es, journal_devnum))
2191 goto failed_mount3; 2200 goto failed_mount3;
2201 if (!(sb->s_flags & MS_RDONLY) &&
2202 EXT4_SB(sb)->s_journal->j_failed_commit) {
2203 printk(KERN_CRIT "EXT4-fs error (device %s): "
2204 "ext4_fill_super: Journal transaction "
2205 "%u is corrupt\n", sb->s_id,
2206 EXT4_SB(sb)->s_journal->j_failed_commit);
2207 if (test_opt (sb, ERRORS_RO)) {
2208 printk (KERN_CRIT
2209 "Mounting filesystem read-only\n");
2210 sb->s_flags |= MS_RDONLY;
2211 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
2212 es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
2213 }
2214 if (test_opt(sb, ERRORS_PANIC)) {
2215 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
2216 es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
2217 ext4_commit_super(sb, es, 1);
2218 printk(KERN_CRIT
2219 "EXT4-fs (device %s): mount failed\n",
2220 sb->s_id);
2221 goto failed_mount4;
2222 }
2223 }
2192 } else if (journal_inum) { 2224 } else if (journal_inum) {
2193 if (ext4_create_journal(sb, es, journal_inum)) 2225 if (ext4_create_journal(sb, es, journal_inum))
2194 goto failed_mount3; 2226 goto failed_mount3;
@@ -3305,8 +3337,10 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
3305 blk++; 3337 blk++;
3306 } 3338 }
3307out: 3339out:
3308 if (len == towrite) 3340 if (len == towrite) {
3341 mutex_unlock(&inode->i_mutex);
3309 return err; 3342 return err;
3343 }
3310 if (inode->i_size < off+len-towrite) { 3344 if (inode->i_size < off+len-towrite) {
3311 i_size_write(inode, off+len-towrite); 3345 i_size_write(inode, off+len-towrite);
3312 EXT4_I(inode)->i_disksize = inode->i_size; 3346 EXT4_I(inode)->i_disksize = inode->i_size;
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 27cc1164ec3..771326b8047 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -257,26 +257,34 @@ int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
257} 257}
258EXPORT_SYMBOL_GPL(fat_getattr); 258EXPORT_SYMBOL_GPL(fat_getattr);
259 259
260static int fat_check_mode(const struct msdos_sb_info *sbi, struct inode *inode, 260static int fat_sanitize_mode(const struct msdos_sb_info *sbi,
261 mode_t mode) 261 struct inode *inode, umode_t *mode_ptr)
262{ 262{
263 mode_t mask, req = mode & ~S_IFMT; 263 mode_t mask, perm;
264 264
265 if (S_ISREG(mode)) 265 /*
266 * Note, the basic check is already done by a caller of
267 * (attr->ia_mode & ~MSDOS_VALID_MODE)
268 */
269
270 if (S_ISREG(inode->i_mode))
266 mask = sbi->options.fs_fmask; 271 mask = sbi->options.fs_fmask;
267 else 272 else
268 mask = sbi->options.fs_dmask; 273 mask = sbi->options.fs_dmask;
269 274
275 perm = *mode_ptr & ~(S_IFMT | mask);
276
270 /* 277 /*
271 * Of the r and x bits, all (subject to umask) must be present. Of the 278 * Of the r and x bits, all (subject to umask) must be present. Of the
272 * w bits, either all (subject to umask) or none must be present. 279 * w bits, either all (subject to umask) or none must be present.
273 */ 280 */
274 req &= ~mask; 281 if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO)))
275 if ((req & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO)))
276 return -EPERM; 282 return -EPERM;
277 if ((req & S_IWUGO) && ((req & S_IWUGO) != (S_IWUGO & ~mask))) 283 if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask)))
278 return -EPERM; 284 return -EPERM;
279 285
286 *mode_ptr &= S_IFMT | perm;
287
280 return 0; 288 return 0;
281} 289}
282 290
@@ -299,7 +307,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
299{ 307{
300 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); 308 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
301 struct inode *inode = dentry->d_inode; 309 struct inode *inode = dentry->d_inode;
302 int mask, error = 0; 310 int error = 0;
303 unsigned int ia_valid; 311 unsigned int ia_valid;
304 312
305 lock_kernel(); 313 lock_kernel();
@@ -332,12 +340,13 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
332 error = 0; 340 error = 0;
333 goto out; 341 goto out;
334 } 342 }
343
335 if (((attr->ia_valid & ATTR_UID) && 344 if (((attr->ia_valid & ATTR_UID) &&
336 (attr->ia_uid != sbi->options.fs_uid)) || 345 (attr->ia_uid != sbi->options.fs_uid)) ||
337 ((attr->ia_valid & ATTR_GID) && 346 ((attr->ia_valid & ATTR_GID) &&
338 (attr->ia_gid != sbi->options.fs_gid)) || 347 (attr->ia_gid != sbi->options.fs_gid)) ||
339 ((attr->ia_valid & ATTR_MODE) && 348 ((attr->ia_valid & ATTR_MODE) &&
340 fat_check_mode(sbi, inode, attr->ia_mode) < 0)) 349 (attr->ia_mode & ~MSDOS_VALID_MODE)))
341 error = -EPERM; 350 error = -EPERM;
342 351
343 if (error) { 352 if (error) {
@@ -346,15 +355,16 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
346 goto out; 355 goto out;
347 } 356 }
348 357
349 error = inode_setattr(inode, attr); 358 /*
350 if (error) 359 * We don't return -EPERM here. Yes, strange, but this is too
351 goto out; 360 * old behavior.
361 */
362 if (attr->ia_valid & ATTR_MODE) {
363 if (fat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0)
364 attr->ia_valid &= ~ATTR_MODE;
365 }
352 366
353 if (S_ISDIR(inode->i_mode)) 367 error = inode_setattr(inode, attr);
354 mask = sbi->options.fs_dmask;
355 else
356 mask = sbi->options.fs_fmask;
357 inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
358out: 368out:
359 unlock_kernel(); 369 unlock_kernel();
360 return error; 370 return error;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fb77e096213..3141690558c 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -488,7 +488,12 @@ static struct fuse_conn *new_conn(struct super_block *sb)
488 err = bdi_init(&fc->bdi); 488 err = bdi_init(&fc->bdi);
489 if (err) 489 if (err)
490 goto error_kfree; 490 goto error_kfree;
491 err = bdi_register_dev(&fc->bdi, fc->dev); 491 if (sb->s_bdev) {
492 err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk",
493 MAJOR(fc->dev), MINOR(fc->dev));
494 } else {
495 err = bdi_register_dev(&fc->bdi, fc->dev);
496 }
492 if (err) 497 if (err)
493 goto error_bdi_destroy; 498 goto error_bdi_destroy;
494 /* 499 /*
@@ -586,7 +591,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
586 fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); 591 fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages);
587 fc->minor = arg->minor; 592 fc->minor = arg->minor;
588 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; 593 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
589 fc->max_write = min_t(unsigned, 4096, fc->max_write); 594 fc->max_write = max_t(unsigned, 4096, fc->max_write);
590 fc->conn_init = 1; 595 fc->conn_init = 1;
591 } 596 }
592 fuse_put_request(fc, req); 597 fuse_put_request(fc, req);
@@ -662,7 +667,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
662 fc->flags = d.flags; 667 fc->flags = d.flags;
663 fc->user_id = d.user_id; 668 fc->user_id = d.user_id;
664 fc->group_id = d.group_id; 669 fc->group_id = d.group_id;
665 fc->max_read = min_t(unsigned, 4096, d.max_read); 670 fc->max_read = max_t(unsigned, 4096, d.max_read);
666 671
667 /* Used by get_root_inode() */ 672 /* Used by get_root_inode() */
668 sb->s_fs_info = fc; 673 sb->s_fs_info = fc;
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index c19184f2e70..bec76b1c2bb 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -246,15 +246,11 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block,
246 246
247} 247}
248 248
249static inline unsigned int zero_metapath_length(const struct metapath *mp, 249static inline unsigned int metapath_branch_start(const struct metapath *mp)
250 unsigned height)
251{ 250{
252 unsigned int i; 251 if (mp->mp_list[0] == 0)
253 for (i = 0; i < height - 1; i++) { 252 return 2;
254 if (mp->mp_list[i] != 0) 253 return 1;
255 return i;
256 }
257 return height;
258} 254}
259 255
260/** 256/**
@@ -436,7 +432,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
436 struct gfs2_sbd *sdp = GFS2_SB(inode); 432 struct gfs2_sbd *sdp = GFS2_SB(inode);
437 struct buffer_head *dibh = mp->mp_bh[0]; 433 struct buffer_head *dibh = mp->mp_bh[0];
438 u64 bn, dblock = 0; 434 u64 bn, dblock = 0;
439 unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0; 435 unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
440 unsigned dblks = 0; 436 unsigned dblks = 0;
441 unsigned ptrs_per_blk; 437 unsigned ptrs_per_blk;
442 const unsigned end_of_metadata = height - 1; 438 const unsigned end_of_metadata = height - 1;
@@ -471,9 +467,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
471 /* Building up tree height */ 467 /* Building up tree height */
472 state = ALLOC_GROW_HEIGHT; 468 state = ALLOC_GROW_HEIGHT;
473 iblks = height - ip->i_height; 469 iblks = height - ip->i_height;
474 zmpl = zero_metapath_length(mp, height); 470 branch_start = metapath_branch_start(mp);
475 iblks -= zmpl; 471 iblks += (height - branch_start);
476 iblks += height;
477 } 472 }
478 } 473 }
479 474
@@ -509,13 +504,13 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
509 sizeof(struct gfs2_meta_header)); 504 sizeof(struct gfs2_meta_header));
510 *ptr = zero_bn; 505 *ptr = zero_bn;
511 state = ALLOC_GROW_DEPTH; 506 state = ALLOC_GROW_DEPTH;
512 for(i = zmpl; i < height; i++) { 507 for(i = branch_start; i < height; i++) {
513 if (mp->mp_bh[i] == NULL) 508 if (mp->mp_bh[i] == NULL)
514 break; 509 break;
515 brelse(mp->mp_bh[i]); 510 brelse(mp->mp_bh[i]);
516 mp->mp_bh[i] = NULL; 511 mp->mp_bh[i] = NULL;
517 } 512 }
518 i = zmpl; 513 i = branch_start;
519 } 514 }
520 if (n == 0) 515 if (n == 0)
521 break; 516 break;
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index d31badadef8..07d84d16cda 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -249,7 +249,7 @@ static int inode_go_lock(struct gfs2_holder *gh)
249 struct gfs2_inode *ip = gl->gl_object; 249 struct gfs2_inode *ip = gl->gl_object;
250 int error = 0; 250 int error = 0;
251 251
252 if (!ip) 252 if (!ip || (gh->gh_flags & GL_SKIP))
253 return 0; 253 return 0;
254 254
255 if (test_bit(GIF_INVALID, &ip->i_flags)) { 255 if (test_bit(GIF_INVALID, &ip->i_flags)) {
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 9c2c0b90b22..eabe5eac41d 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -236,6 +236,7 @@ enum {
236 GIF_INVALID = 0, 236 GIF_INVALID = 0,
237 GIF_QD_LOCKED = 1, 237 GIF_QD_LOCKED = 1,
238 GIF_SW_PAGED = 3, 238 GIF_SW_PAGED = 3,
239 GIF_USER = 4, /* user inode, not metadata addr space */
239}; 240};
240 241
241struct gfs2_dinode_host { 242struct gfs2_dinode_host {
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 3a9ef526c30..09453d057e4 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -47,8 +47,7 @@ static int iget_test(struct inode *inode, void *opaque)
47 struct gfs2_inode *ip = GFS2_I(inode); 47 struct gfs2_inode *ip = GFS2_I(inode);
48 u64 *no_addr = opaque; 48 u64 *no_addr = opaque;
49 49
50 if (ip->i_no_addr == *no_addr && 50 if (ip->i_no_addr == *no_addr && test_bit(GIF_USER, &ip->i_flags))
51 inode->i_private != NULL)
52 return 1; 51 return 1;
53 52
54 return 0; 53 return 0;
@@ -61,6 +60,7 @@ static int iget_set(struct inode *inode, void *opaque)
61 60
62 inode->i_ino = (unsigned long)*no_addr; 61 inode->i_ino = (unsigned long)*no_addr;
63 ip->i_no_addr = *no_addr; 62 ip->i_no_addr = *no_addr;
63 set_bit(GIF_USER, &ip->i_flags);
64 return 0; 64 return 0;
65} 65}
66 66
@@ -86,7 +86,7 @@ static int iget_skip_test(struct inode *inode, void *opaque)
86 struct gfs2_inode *ip = GFS2_I(inode); 86 struct gfs2_inode *ip = GFS2_I(inode);
87 struct gfs2_skip_data *data = opaque; 87 struct gfs2_skip_data *data = opaque;
88 88
89 if (ip->i_no_addr == data->no_addr && inode->i_private != NULL){ 89 if (ip->i_no_addr == data->no_addr && test_bit(GIF_USER, &ip->i_flags)){
90 if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){ 90 if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){
91 data->skipped = 1; 91 data->skipped = 1;
92 return 0; 92 return 0;
@@ -105,6 +105,7 @@ static int iget_skip_set(struct inode *inode, void *opaque)
105 return 1; 105 return 1;
106 inode->i_ino = (unsigned long)(data->no_addr); 106 inode->i_ino = (unsigned long)(data->no_addr);
107 ip->i_no_addr = data->no_addr; 107 ip->i_no_addr = data->no_addr;
108 set_bit(GIF_USER, &ip->i_flags);
108 return 0; 109 return 0;
109} 110}
110 111
@@ -166,7 +167,7 @@ void gfs2_set_iop(struct inode *inode)
166 * Returns: A VFS inode, or an error 167 * Returns: A VFS inode, or an error
167 */ 168 */
168 169
169struct inode *gfs2_inode_lookup(struct super_block *sb, 170struct inode *gfs2_inode_lookup(struct super_block *sb,
170 unsigned int type, 171 unsigned int type,
171 u64 no_addr, 172 u64 no_addr,
172 u64 no_formal_ino, int skip_freeing) 173 u64 no_formal_ino, int skip_freeing)
@@ -187,7 +188,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
187 188
188 if (inode->i_state & I_NEW) { 189 if (inode->i_state & I_NEW) {
189 struct gfs2_sbd *sdp = GFS2_SB(inode); 190 struct gfs2_sbd *sdp = GFS2_SB(inode);
190 inode->i_private = ip;
191 ip->i_no_formal_ino = no_formal_ino; 191 ip->i_no_formal_ino = no_formal_ino;
192 192
193 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); 193 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 85aea27b4a8..78d75f892f8 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
@@ -69,13 +69,15 @@ static const struct address_space_operations aspace_aops = {
69struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp) 69struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp)
70{ 70{
71 struct inode *aspace; 71 struct inode *aspace;
72 struct gfs2_inode *ip;
72 73
73 aspace = new_inode(sdp->sd_vfs); 74 aspace = new_inode(sdp->sd_vfs);
74 if (aspace) { 75 if (aspace) {
75 mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS); 76 mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS);
76 aspace->i_mapping->a_ops = &aspace_aops; 77 aspace->i_mapping->a_ops = &aspace_aops;
77 aspace->i_size = ~0ULL; 78 aspace->i_size = ~0ULL;
78 aspace->i_private = NULL; 79 ip = GFS2_I(aspace);
80 clear_bit(GIF_USER, &ip->i_flags);
79 insert_inode_hash(aspace); 81 insert_inode_hash(aspace);
80 } 82 }
81 return aspace; 83 return aspace;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index ef9c6c4f80f..b2028c82e8d 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -142,8 +142,8 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
142 if (!table[0]) 142 if (!table[0])
143 table = sdp->sd_vfs->s_id; 143 table = sdp->sd_vfs->s_id;
144 144
145 snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto); 145 strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN);
146 snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table); 146 strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN);
147 147
148 table = sdp->sd_table_name; 148 table = sdp->sd_table_name;
149 while ((table = strchr(table, '/'))) 149 while ((table = strchr(table, '/')))
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 2278c68b7e3..0b7cc920eb8 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
@@ -52,7 +52,7 @@ static int gfs2_write_inode(struct inode *inode, int sync)
52 struct gfs2_inode *ip = GFS2_I(inode); 52 struct gfs2_inode *ip = GFS2_I(inode);
53 53
54 /* Check this is a "normal" inode */ 54 /* Check this is a "normal" inode */
55 if (inode->i_private) { 55 if (test_bit(GIF_USER, &ip->i_flags)) {
56 if (current->flags & PF_MEMALLOC) 56 if (current->flags & PF_MEMALLOC)
57 return 0; 57 return 0;
58 if (sync) 58 if (sync)
@@ -297,8 +297,9 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
297 */ 297 */
298static void gfs2_drop_inode(struct inode *inode) 298static void gfs2_drop_inode(struct inode *inode)
299{ 299{
300 if (inode->i_private && inode->i_nlink) { 300 struct gfs2_inode *ip = GFS2_I(inode);
301 struct gfs2_inode *ip = GFS2_I(inode); 301
302 if (test_bit(GIF_USER, &ip->i_flags) && inode->i_nlink) {
302 struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl; 303 struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
303 if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags)) 304 if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags))
304 clear_nlink(inode); 305 clear_nlink(inode);
@@ -314,12 +315,13 @@ static void gfs2_drop_inode(struct inode *inode)
314 315
315static void gfs2_clear_inode(struct inode *inode) 316static void gfs2_clear_inode(struct inode *inode)
316{ 317{
318 struct gfs2_inode *ip = GFS2_I(inode);
319
317 /* This tells us its a "real" inode and not one which only 320 /* This tells us its a "real" inode and not one which only
318 * serves to contain an address space (see rgrp.c, meta_io.c) 321 * serves to contain an address space (see rgrp.c, meta_io.c)
319 * which therefore doesn't have its own glocks. 322 * which therefore doesn't have its own glocks.
320 */ 323 */
321 if (inode->i_private) { 324 if (test_bit(GIF_USER, &ip->i_flags)) {
322 struct gfs2_inode *ip = GFS2_I(inode);
323 ip->i_gl->gl_object = NULL; 325 ip->i_gl->gl_object = NULL;
324 gfs2_glock_schedule_for_reclaim(ip->i_gl); 326 gfs2_glock_schedule_for_reclaim(ip->i_gl);
325 gfs2_glock_put(ip->i_gl); 327 gfs2_glock_put(ip->i_gl);
@@ -419,7 +421,7 @@ static void gfs2_delete_inode(struct inode *inode)
419 struct gfs2_holder gh; 421 struct gfs2_holder gh;
420 int error; 422 int error;
421 423
422 if (!inode->i_private) 424 if (!test_bit(GIF_USER, &ip->i_flags))
423 goto out; 425 goto out;
424 426
425 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 427 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 7e8f0b1d6c6..3401628d742 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -195,7 +195,7 @@ ulong_aligned:
195 depending on architecture. I've experimented with several ways 195 depending on architecture. I've experimented with several ways
196 of writing this section such as using an else before the goto 196 of writing this section such as using an else before the goto
197 but this one seems to be the fastest. */ 197 but this one seems to be the fastest. */
198 while ((unsigned char *)plong < end - 1) { 198 while ((unsigned char *)plong < end - sizeof(unsigned long)) {
199 prefetch(plong + 1); 199 prefetch(plong + 1);
200 if (((*plong) & LBITMASK) != lskipval) 200 if (((*plong) & LBITMASK) != lskipval)
201 break; 201 break;
@@ -1495,7 +1495,7 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
1495 1495
1496 al->al_alloced += *n; 1496 al->al_alloced += *n;
1497 1497
1498 gfs2_statfs_change(sdp, 0, -*n, 0); 1498 gfs2_statfs_change(sdp, 0, -(s64)*n, 0);
1499 gfs2_quota_change(ip, *n, ip->i_inode.i_uid, ip->i_inode.i_gid); 1499 gfs2_quota_change(ip, *n, ip->i_inode.i_uid, ip->i_inode.i_gid);
1500 1500
1501 spin_lock(&sdp->sd_rindex_spin); 1501 spin_lock(&sdp->sd_rindex_spin);
diff --git a/fs/hppfs/Makefile b/fs/hppfs/Makefile
index 8a1f5034436..3a982bd975d 100644
--- a/fs/hppfs/Makefile
+++ b/fs/hppfs/Makefile
@@ -3,7 +3,4 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6hppfs-objs := hppfs.o 6obj-$(CONFIG_HPPFS) += hppfs.o
7
8obj-y =
9obj-$(CONFIG_HPPFS) += $(hppfs-objs)
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 4d99685fdce..a2ed72f7cee 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -168,6 +168,7 @@ static int journal_submit_commit_record(journal_t *journal,
168 spin_unlock(&journal->j_state_lock); 168 spin_unlock(&journal->j_state_lock);
169 169
170 /* And try again, without the barrier */ 170 /* And try again, without the barrier */
171 lock_buffer(bh);
171 set_buffer_uptodate(bh); 172 set_buffer_uptodate(bh);
172 set_buffer_dirty(bh); 173 set_buffer_dirty(bh);
173 ret = submit_bh(WRITE, bh); 174 ret = submit_bh(WRITE, bh);
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index 5d0405a9e7c..058f50f65b7 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -344,6 +344,7 @@ static int calc_chksums(journal_t *journal, struct buffer_head *bh,
344 *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data, 344 *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data,
345 obh->b_size); 345 obh->b_size);
346 } 346 }
347 put_bh(obh);
347 } 348 }
348 return 0; 349 return 0;
349} 350}
@@ -610,9 +611,8 @@ static int do_one_pass(journal_t *journal,
610 chksum_err = chksum_seen = 0; 611 chksum_err = chksum_seen = 0;
611 612
612 if (info->end_transaction) { 613 if (info->end_transaction) {
613 printk(KERN_ERR "JBD: Transaction %u " 614 journal->j_failed_commit =
614 "found to be corrupt.\n", 615 info->end_transaction;
615 next_commit_ID - 1);
616 brelse(bh); 616 brelse(bh);
617 break; 617 break;
618 } 618 }
@@ -643,10 +643,8 @@ static int do_one_pass(journal_t *journal,
643 643
644 if (!JBD2_HAS_INCOMPAT_FEATURE(journal, 644 if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
645 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){ 645 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){
646 printk(KERN_ERR 646 journal->j_failed_commit =
647 "JBD: Transaction %u " 647 next_commit_ID;
648 "found to be corrupt.\n",
649 next_commit_ID);
650 brelse(bh); 648 brelse(bh);
651 break; 649 break;
652 } 650 }
diff --git a/fs/libfs.c b/fs/libfs.c
index b004dfadd89..baeb71ee1cd 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -512,6 +512,20 @@ void simple_release_fs(struct vfsmount **mount, int *count)
512 mntput(mnt); 512 mntput(mnt);
513} 513}
514 514
515/**
516 * simple_read_from_buffer - copy data from the buffer to user space
517 * @to: the user space buffer to read to
518 * @count: the maximum number of bytes to read
519 * @ppos: the current position in the buffer
520 * @from: the buffer to read from
521 * @available: the size of the buffer
522 *
523 * The simple_read_from_buffer() function reads up to @count bytes from the
524 * buffer @from at offset @ppos into the user space address starting at @to.
525 *
526 * On success, the number of bytes read is returned and the offset @ppos is
527 * advanced by this number, or negative value is returned on error.
528 **/
515ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos, 529ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
516 const void *from, size_t available) 530 const void *from, size_t available)
517{ 531{
@@ -528,6 +542,37 @@ ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
528 return count; 542 return count;
529} 543}
530 544
545/**
546 * memory_read_from_buffer - copy data from the buffer
547 * @to: the kernel space buffer to read to
548 * @count: the maximum number of bytes to read
549 * @ppos: the current position in the buffer
550 * @from: the buffer to read from
551 * @available: the size of the buffer
552 *
553 * The memory_read_from_buffer() function reads up to @count bytes from the
554 * buffer @from at offset @ppos into the kernel space address starting at @to.
555 *
556 * On success, the number of bytes read is returned and the offset @ppos is
557 * advanced by this number, or negative value is returned on error.
558 **/
559ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
560 const void *from, size_t available)
561{
562 loff_t pos = *ppos;
563
564 if (pos < 0)
565 return -EINVAL;
566 if (pos >= available)
567 return 0;
568 if (count > available - pos)
569 count = available - pos;
570 memcpy(to, from + pos, count);
571 *ppos = pos + count;
572
573 return count;
574}
575
531/* 576/*
532 * Transaction based IO. 577 * Transaction based IO.
533 * The file expects a single write which triggers the transaction, and then 578 * The file expects a single write which triggers the transaction, and then
@@ -800,6 +845,7 @@ EXPORT_SYMBOL(simple_statfs);
800EXPORT_SYMBOL(simple_sync_file); 845EXPORT_SYMBOL(simple_sync_file);
801EXPORT_SYMBOL(simple_unlink); 846EXPORT_SYMBOL(simple_unlink);
802EXPORT_SYMBOL(simple_read_from_buffer); 847EXPORT_SYMBOL(simple_read_from_buffer);
848EXPORT_SYMBOL(memory_read_from_buffer);
803EXPORT_SYMBOL(simple_transaction_get); 849EXPORT_SYMBOL(simple_transaction_get);
804EXPORT_SYMBOL(simple_transaction_read); 850EXPORT_SYMBOL(simple_transaction_read);
805EXPORT_SYMBOL(simple_transaction_release); 851EXPORT_SYMBOL(simple_transaction_release);
diff --git a/fs/locks.c b/fs/locks.c
index 11dbf08651b..dce8c747371 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -561,9 +561,6 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
561 /* insert into file's list */ 561 /* insert into file's list */
562 fl->fl_next = *pos; 562 fl->fl_next = *pos;
563 *pos = fl; 563 *pos = fl;
564
565 if (fl->fl_ops && fl->fl_ops->fl_insert)
566 fl->fl_ops->fl_insert(fl);
567} 564}
568 565
569/* 566/*
@@ -586,9 +583,6 @@ static void locks_delete_lock(struct file_lock **thisfl_p)
586 fl->fl_fasync = NULL; 583 fl->fl_fasync = NULL;
587 } 584 }
588 585
589 if (fl->fl_ops && fl->fl_ops->fl_remove)
590 fl->fl_ops->fl_remove(fl);
591
592 if (fl->fl_nspid) { 586 if (fl->fl_nspid) {
593 put_pid(fl->fl_nspid); 587 put_pid(fl->fl_nspid);
594 fl->fl_nspid = NULL; 588 fl->fl_nspid = NULL;
diff --git a/fs/namei.c b/fs/namei.c
index c7e43536c49..01e67dddcc3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -581,15 +581,13 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd
581 int result; 581 int result;
582 582
583 /* make sure the stuff we saved doesn't go away */ 583 /* make sure the stuff we saved doesn't go away */
584 dget(save.dentry); 584 path_get(&save);
585 mntget(save.mnt);
586 585
587 result = __link_path_walk(name, nd); 586 result = __link_path_walk(name, nd);
588 if (result == -ESTALE) { 587 if (result == -ESTALE) {
589 /* nd->path had been dropped */ 588 /* nd->path had been dropped */
590 nd->path = save; 589 nd->path = save;
591 dget(nd->path.dentry); 590 path_get(&nd->path);
592 mntget(nd->path.mnt);
593 nd->flags |= LOOKUP_REVAL; 591 nd->flags |= LOOKUP_REVAL;
594 result = __link_path_walk(name, nd); 592 result = __link_path_walk(name, nd);
595 } 593 }
@@ -1216,8 +1214,9 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1216 nd->flags = flags; 1214 nd->flags = flags;
1217 nd->depth = 0; 1215 nd->depth = 0;
1218 1216
1219 nd->path.mnt = mntget(mnt); 1217 nd->path.dentry = dentry;
1220 nd->path.dentry = dget(dentry); 1218 nd->path.mnt = mnt;
1219 path_get(&nd->path);
1221 1220
1222 retval = path_walk(name, nd); 1221 retval = path_walk(name, nd);
1223 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && 1222 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
@@ -2857,16 +2856,17 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
2857{ 2856{
2858 struct nameidata nd; 2857 struct nameidata nd;
2859 void *cookie; 2858 void *cookie;
2859 int res;
2860 2860
2861 nd.depth = 0; 2861 nd.depth = 0;
2862 cookie = dentry->d_inode->i_op->follow_link(dentry, &nd); 2862 cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
2863 if (!IS_ERR(cookie)) { 2863 if (IS_ERR(cookie))
2864 int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); 2864 return PTR_ERR(cookie);
2865 if (dentry->d_inode->i_op->put_link) 2865
2866 dentry->d_inode->i_op->put_link(dentry, &nd, cookie); 2866 res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
2867 cookie = ERR_PTR(res); 2867 if (dentry->d_inode->i_op->put_link)
2868 } 2868 dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
2869 return PTR_ERR(cookie); 2869 return res;
2870} 2870}
2871 2871
2872int vfs_follow_link(struct nameidata *nd, const char *link) 2872int vfs_follow_link(struct nameidata *nd, const char *link)
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 49c7cd0502c..779d2eb649c 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -130,10 +130,11 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
130 struct mnt_fhstatus *res) 130 struct mnt_fhstatus *res)
131{ 131{
132 struct nfs_fh *fh = res->fh; 132 struct nfs_fh *fh = res->fh;
133 unsigned size;
133 134
134 if ((res->status = ntohl(*p++)) == 0) { 135 if ((res->status = ntohl(*p++)) == 0) {
135 int size = ntohl(*p++); 136 size = ntohl(*p++);
136 if (size <= NFS3_FHSIZE) { 137 if (size <= NFS3_FHSIZE && size != 0) {
137 fh->size = size; 138 fh->size = size;
138 memcpy(fh->data, p, size); 139 memcpy(fh->data, p, size);
139 } else 140 } else
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2a4a024a4e7..614efeed543 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1216,8 +1216,6 @@ static int nfs_validate_mount_data(void *options,
1216{ 1216{
1217 struct nfs_mount_data *data = (struct nfs_mount_data *)options; 1217 struct nfs_mount_data *data = (struct nfs_mount_data *)options;
1218 1218
1219 memset(args, 0, sizeof(*args));
1220
1221 if (data == NULL) 1219 if (data == NULL)
1222 goto out_no_data; 1220 goto out_no_data;
1223 1221
@@ -1251,13 +1249,13 @@ static int nfs_validate_mount_data(void *options,
1251 case 5: 1249 case 5:
1252 memset(data->context, 0, sizeof(data->context)); 1250 memset(data->context, 0, sizeof(data->context));
1253 case 6: 1251 case 6:
1254 if (data->flags & NFS_MOUNT_VER3) 1252 if (data->flags & NFS_MOUNT_VER3) {
1253 if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
1254 goto out_invalid_fh;
1255 mntfh->size = data->root.size; 1255 mntfh->size = data->root.size;
1256 else 1256 } else
1257 mntfh->size = NFS2_FHSIZE; 1257 mntfh->size = NFS2_FHSIZE;
1258 1258
1259 if (mntfh->size > sizeof(mntfh->data))
1260 goto out_invalid_fh;
1261 1259
1262 memcpy(mntfh->data, data->root.data, mntfh->size); 1260 memcpy(mntfh->data, data->root.data, mntfh->size);
1263 if (mntfh->size < sizeof(mntfh->data)) 1261 if (mntfh->size < sizeof(mntfh->data))
@@ -1585,24 +1583,29 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1585{ 1583{
1586 struct nfs_server *server = NULL; 1584 struct nfs_server *server = NULL;
1587 struct super_block *s; 1585 struct super_block *s;
1588 struct nfs_fh mntfh; 1586 struct nfs_parsed_mount_data *data;
1589 struct nfs_parsed_mount_data data; 1587 struct nfs_fh *mntfh;
1590 struct dentry *mntroot; 1588 struct dentry *mntroot;
1591 int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 1589 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1592 struct nfs_sb_mountdata sb_mntdata = { 1590 struct nfs_sb_mountdata sb_mntdata = {
1593 .mntflags = flags, 1591 .mntflags = flags,
1594 }; 1592 };
1595 int error; 1593 int error = -ENOMEM;
1594
1595 data = kzalloc(sizeof(*data), GFP_KERNEL);
1596 mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
1597 if (data == NULL || mntfh == NULL)
1598 goto out_free_fh;
1596 1599
1597 security_init_mnt_opts(&data.lsm_opts); 1600 security_init_mnt_opts(&data->lsm_opts);
1598 1601
1599 /* Validate the mount data */ 1602 /* Validate the mount data */
1600 error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); 1603 error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
1601 if (error < 0) 1604 if (error < 0)
1602 goto out; 1605 goto out;
1603 1606
1604 /* Get a volume representation */ 1607 /* Get a volume representation */
1605 server = nfs_create_server(&data, &mntfh); 1608 server = nfs_create_server(data, mntfh);
1606 if (IS_ERR(server)) { 1609 if (IS_ERR(server)) {
1607 error = PTR_ERR(server); 1610 error = PTR_ERR(server);
1608 goto out; 1611 goto out;
@@ -1630,16 +1633,16 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1630 1633
1631 if (!s->s_root) { 1634 if (!s->s_root) {
1632 /* initial superblock/root creation */ 1635 /* initial superblock/root creation */
1633 nfs_fill_super(s, &data); 1636 nfs_fill_super(s, data);
1634 } 1637 }
1635 1638
1636 mntroot = nfs_get_root(s, &mntfh); 1639 mntroot = nfs_get_root(s, mntfh);
1637 if (IS_ERR(mntroot)) { 1640 if (IS_ERR(mntroot)) {
1638 error = PTR_ERR(mntroot); 1641 error = PTR_ERR(mntroot);
1639 goto error_splat_super; 1642 goto error_splat_super;
1640 } 1643 }
1641 1644
1642 error = security_sb_set_mnt_opts(s, &data.lsm_opts); 1645 error = security_sb_set_mnt_opts(s, &data->lsm_opts);
1643 if (error) 1646 if (error)
1644 goto error_splat_root; 1647 goto error_splat_root;
1645 1648
@@ -1649,9 +1652,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1649 error = 0; 1652 error = 0;
1650 1653
1651out: 1654out:
1652 kfree(data.nfs_server.hostname); 1655 kfree(data->nfs_server.hostname);
1653 kfree(data.mount_server.hostname); 1656 kfree(data->mount_server.hostname);
1654 security_free_mnt_opts(&data.lsm_opts); 1657 security_free_mnt_opts(&data->lsm_opts);
1658out_free_fh:
1659 kfree(mntfh);
1660 kfree(data);
1655 return error; 1661 return error;
1656 1662
1657out_err_nosb: 1663out_err_nosb:
@@ -1800,8 +1806,6 @@ static int nfs4_validate_mount_data(void *options,
1800 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; 1806 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
1801 char *c; 1807 char *c;
1802 1808
1803 memset(args, 0, sizeof(*args));
1804
1805 if (data == NULL) 1809 if (data == NULL)
1806 goto out_no_data; 1810 goto out_no_data;
1807 1811
@@ -1959,26 +1963,31 @@ out_no_client_address:
1959static int nfs4_get_sb(struct file_system_type *fs_type, 1963static int nfs4_get_sb(struct file_system_type *fs_type,
1960 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 1964 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1961{ 1965{
1962 struct nfs_parsed_mount_data data; 1966 struct nfs_parsed_mount_data *data;
1963 struct super_block *s; 1967 struct super_block *s;
1964 struct nfs_server *server; 1968 struct nfs_server *server;
1965 struct nfs_fh mntfh; 1969 struct nfs_fh *mntfh;
1966 struct dentry *mntroot; 1970 struct dentry *mntroot;
1967 int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 1971 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1968 struct nfs_sb_mountdata sb_mntdata = { 1972 struct nfs_sb_mountdata sb_mntdata = {
1969 .mntflags = flags, 1973 .mntflags = flags,
1970 }; 1974 };
1971 int error; 1975 int error = -ENOMEM;
1972 1976
1973 security_init_mnt_opts(&data.lsm_opts); 1977 data = kzalloc(sizeof(*data), GFP_KERNEL);
1978 mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
1979 if (data == NULL || mntfh == NULL)
1980 goto out_free_fh;
1981
1982 security_init_mnt_opts(&data->lsm_opts);
1974 1983
1975 /* Validate the mount data */ 1984 /* Validate the mount data */
1976 error = nfs4_validate_mount_data(raw_data, &data, dev_name); 1985 error = nfs4_validate_mount_data(raw_data, data, dev_name);
1977 if (error < 0) 1986 if (error < 0)
1978 goto out; 1987 goto out;
1979 1988
1980 /* Get a volume representation */ 1989 /* Get a volume representation */
1981 server = nfs4_create_server(&data, &mntfh); 1990 server = nfs4_create_server(data, mntfh);
1982 if (IS_ERR(server)) { 1991 if (IS_ERR(server)) {
1983 error = PTR_ERR(server); 1992 error = PTR_ERR(server);
1984 goto out; 1993 goto out;
@@ -2009,13 +2018,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
2009 nfs4_fill_super(s); 2018 nfs4_fill_super(s);
2010 } 2019 }
2011 2020
2012 mntroot = nfs4_get_root(s, &mntfh); 2021 mntroot = nfs4_get_root(s, mntfh);
2013 if (IS_ERR(mntroot)) { 2022 if (IS_ERR(mntroot)) {
2014 error = PTR_ERR(mntroot); 2023 error = PTR_ERR(mntroot);
2015 goto error_splat_super; 2024 goto error_splat_super;
2016 } 2025 }
2017 2026
2018 error = security_sb_set_mnt_opts(s, &data.lsm_opts); 2027 error = security_sb_set_mnt_opts(s, &data->lsm_opts);
2019 if (error) 2028 if (error)
2020 goto error_splat_root; 2029 goto error_splat_root;
2021 2030
@@ -2025,10 +2034,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
2025 error = 0; 2034 error = 0;
2026 2035
2027out: 2036out:
2028 kfree(data.client_address); 2037 kfree(data->client_address);
2029 kfree(data.nfs_server.export_path); 2038 kfree(data->nfs_server.export_path);
2030 kfree(data.nfs_server.hostname); 2039 kfree(data->nfs_server.hostname);
2031 security_free_mnt_opts(&data.lsm_opts); 2040 security_free_mnt_opts(&data->lsm_opts);
2041out_free_fh:
2042 kfree(mntfh);
2043 kfree(data);
2032 return error; 2044 return error;
2033 2045
2034out_free: 2046out_free:
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 6d8ace3e325..f333848fd3b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -739,12 +739,13 @@ int nfs_updatepage(struct file *file, struct page *page,
739 } 739 }
740 740
741 status = nfs_writepage_setup(ctx, page, offset, count); 741 status = nfs_writepage_setup(ctx, page, offset, count);
742 __set_page_dirty_nobuffers(page); 742 if (status < 0)
743 nfs_set_pageerror(page);
744 else
745 __set_page_dirty_nobuffers(page);
743 746
744 dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", 747 dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
745 status, (long long)i_size_read(inode)); 748 status, (long long)i_size_read(inode));
746 if (status < 0)
747 nfs_set_pageerror(page);
748 return status; 749 return status;
749} 750}
750 751
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 0b3ffa9840c..4d4760e687c 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -419,9 +419,9 @@ static int do_probe_callback(void *data)
419out_release_client: 419out_release_client:
420 rpc_shutdown_client(client); 420 rpc_shutdown_client(client);
421out_err: 421out_err:
422 put_nfs4_client(clp);
423 dprintk("NFSD: warning: no callback path to client %.*s\n", 422 dprintk("NFSD: warning: no callback path to client %.*s\n",
424 (int)clp->cl_name.len, clp->cl_name.data); 423 (int)clp->cl_name.len, clp->cl_name.data);
424 put_nfs4_client(clp);
425 return status; 425 return status;
426} 426}
427 427
diff --git a/fs/ntfs/upcase.c b/fs/ntfs/upcase.c
index 9101807dc81..e2f72ca9803 100644
--- a/fs/ntfs/upcase.c
+++ b/fs/ntfs/upcase.c
@@ -77,11 +77,10 @@ ntfschar *generate_default_upcase(void)
77 uc[i] = cpu_to_le16(i); 77 uc[i] = cpu_to_le16(i);
78 for (r = 0; uc_run_table[r][0]; r++) 78 for (r = 0; uc_run_table[r][0]; r++)
79 for (i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++) 79 for (i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++)
80 uc[i] = cpu_to_le16(le16_to_cpu(uc[i]) + 80 le16_add_cpu(&uc[i], uc_run_table[r][2]);
81 uc_run_table[r][2]);
82 for (r = 0; uc_dup_table[r][0]; r++) 81 for (r = 0; uc_dup_table[r][0]; r++)
83 for (i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2) 82 for (i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2)
84 uc[i + 1] = cpu_to_le16(le16_to_cpu(uc[i + 1]) - 1); 83 le16_add_cpu(&uc[i + 1], -1);
85 for (r = 0; uc_word_table[r][0]; r++) 84 for (r = 0; uc_word_table[r][0]; r++)
86 uc[uc_word_table[r][0]] = cpu_to_le16(uc_word_table[r][1]); 85 uc[uc_word_table[r][0]] = cpu_to_le16(uc_word_table[r][1]);
87 return uc; 86 return uc;
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 41f84c92094..10bfb466e06 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -2788,7 +2788,7 @@ static int ocfs2_merge_rec_right(struct inode *inode,
2788 BUG_ON(index >= le16_to_cpu(el->l_next_free_rec)); 2788 BUG_ON(index >= le16_to_cpu(el->l_next_free_rec));
2789 left_rec = &el->l_recs[index]; 2789 left_rec = &el->l_recs[index];
2790 2790
2791 if (index == le16_to_cpu(el->l_next_free_rec - 1) && 2791 if (index == le16_to_cpu(el->l_next_free_rec) - 1 &&
2792 le16_to_cpu(el->l_next_free_rec) == le16_to_cpu(el->l_count)) { 2792 le16_to_cpu(el->l_next_free_rec) == le16_to_cpu(el->l_count)) {
2793 /* we meet with a cross extent block merge. */ 2793 /* we meet with a cross extent block merge. */
2794 ret = ocfs2_get_right_path(inode, left_path, &right_path); 2794 ret = ocfs2_get_right_path(inode, left_path, &right_path);
@@ -2802,7 +2802,7 @@ static int ocfs2_merge_rec_right(struct inode *inode,
2802 BUG_ON(next_free <= 0); 2802 BUG_ON(next_free <= 0);
2803 right_rec = &right_el->l_recs[0]; 2803 right_rec = &right_el->l_recs[0];
2804 if (ocfs2_is_empty_extent(right_rec)) { 2804 if (ocfs2_is_empty_extent(right_rec)) {
2805 BUG_ON(le16_to_cpu(next_free) <= 1); 2805 BUG_ON(next_free <= 1);
2806 right_rec = &right_el->l_recs[1]; 2806 right_rec = &right_el->l_recs[1];
2807 } 2807 }
2808 2808
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index cf9401e8cd0..cfdb08b484e 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -21,7 +21,6 @@
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/sysctl.h>
25#include <linux/configfs.h> 24#include <linux/configfs.h>
26 25
27#include "tcp.h" 26#include "tcp.h"
@@ -36,65 +35,6 @@
36 * cluster references throughout where nodes are looked up */ 35 * cluster references throughout where nodes are looked up */
37struct o2nm_cluster *o2nm_single_cluster = NULL; 36struct o2nm_cluster *o2nm_single_cluster = NULL;
38 37
39#define OCFS2_MAX_HB_CTL_PATH 256
40static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl";
41
42static ctl_table ocfs2_nm_table[] = {
43 {
44 .ctl_name = 1,
45 .procname = "hb_ctl_path",
46 .data = ocfs2_hb_ctl_path,
47 .maxlen = OCFS2_MAX_HB_CTL_PATH,
48 .mode = 0644,
49 .proc_handler = &proc_dostring,
50 .strategy = &sysctl_string,
51 },
52 { .ctl_name = 0 }
53};
54
55static ctl_table ocfs2_mod_table[] = {
56 {
57 .ctl_name = FS_OCFS2_NM,
58 .procname = "nm",
59 .data = NULL,
60 .maxlen = 0,
61 .mode = 0555,
62 .child = ocfs2_nm_table
63 },
64 { .ctl_name = 0}
65};
66
67static ctl_table ocfs2_kern_table[] = {
68 {
69 .ctl_name = FS_OCFS2,
70 .procname = "ocfs2",
71 .data = NULL,
72 .maxlen = 0,
73 .mode = 0555,
74 .child = ocfs2_mod_table
75 },
76 { .ctl_name = 0}
77};
78
79static ctl_table ocfs2_root_table[] = {
80 {
81 .ctl_name = CTL_FS,
82 .procname = "fs",
83 .data = NULL,
84 .maxlen = 0,
85 .mode = 0555,
86 .child = ocfs2_kern_table
87 },
88 { .ctl_name = 0 }
89};
90
91static struct ctl_table_header *ocfs2_table_header = NULL;
92
93const char *o2nm_get_hb_ctl_path(void)
94{
95 return ocfs2_hb_ctl_path;
96}
97EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path);
98 38
99struct o2nm_node *o2nm_get_node_by_num(u8 node_num) 39struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
100{ 40{
@@ -941,9 +881,6 @@ void o2nm_undepend_this_node(void)
941 881
942static void __exit exit_o2nm(void) 882static void __exit exit_o2nm(void)
943{ 883{
944 if (ocfs2_table_header)
945 unregister_sysctl_table(ocfs2_table_header);
946
947 /* XXX sync with hb callbacks and shut down hb? */ 884 /* XXX sync with hb callbacks and shut down hb? */
948 o2net_unregister_hb_callbacks(); 885 o2net_unregister_hb_callbacks();
949 configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); 886 configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
@@ -964,16 +901,9 @@ static int __init init_o2nm(void)
964 if (ret) 901 if (ret)
965 goto out; 902 goto out;
966 903
967 ocfs2_table_header = register_sysctl_table(ocfs2_root_table);
968 if (!ocfs2_table_header) {
969 printk(KERN_ERR "nodemanager: unable to register sysctl\n");
970 ret = -ENOMEM; /* or something. */
971 goto out_o2net;
972 }
973
974 ret = o2net_register_hb_callbacks(); 904 ret = o2net_register_hb_callbacks();
975 if (ret) 905 if (ret)
976 goto out_sysctl; 906 goto out_o2net;
977 907
978 config_group_init(&o2nm_cluster_group.cs_subsys.su_group); 908 config_group_init(&o2nm_cluster_group.cs_subsys.su_group);
979 mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); 909 mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex);
@@ -990,8 +920,6 @@ static int __init init_o2nm(void)
990 configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); 920 configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
991out_callbacks: 921out_callbacks:
992 o2net_unregister_hb_callbacks(); 922 o2net_unregister_hb_callbacks();
993out_sysctl:
994 unregister_sysctl_table(ocfs2_table_header);
995out_o2net: 923out_o2net:
996 o2net_exit(); 924 o2net_exit();
997out: 925out:
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h
index 7c860361b8d..c992ea0da4a 100644
--- a/fs/ocfs2/cluster/nodemanager.h
+++ b/fs/ocfs2/cluster/nodemanager.h
@@ -33,10 +33,6 @@
33#include <linux/configfs.h> 33#include <linux/configfs.h>
34#include <linux/rbtree.h> 34#include <linux/rbtree.h>
35 35
36#define FS_OCFS2_NM 1
37
38const char *o2nm_get_hb_ctl_path(void);
39
40struct o2nm_node { 36struct o2nm_node {
41 spinlock_t nd_lock; 37 spinlock_t nd_lock;
42 struct config_item nd_item; 38 struct config_item nd_item;
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 1e44ad14881..a27d61581bd 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -142,53 +142,43 @@ static void o2net_idle_timer(unsigned long data);
142static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); 142static void o2net_sc_postpone_idle(struct o2net_sock_container *sc);
143static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc); 143static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc);
144 144
145static void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
146 u32 msgkey, struct task_struct *task, u8 node)
147{
148#ifdef CONFIG_DEBUG_FS 145#ifdef CONFIG_DEBUG_FS
146void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
147 u32 msgkey, struct task_struct *task, u8 node)
148{
149 INIT_LIST_HEAD(&nst->st_net_debug_item); 149 INIT_LIST_HEAD(&nst->st_net_debug_item);
150 nst->st_task = task; 150 nst->st_task = task;
151 nst->st_msg_type = msgtype; 151 nst->st_msg_type = msgtype;
152 nst->st_msg_key = msgkey; 152 nst->st_msg_key = msgkey;
153 nst->st_node = node; 153 nst->st_node = node;
154#endif
155} 154}
156 155
157static void o2net_set_nst_sock_time(struct o2net_send_tracking *nst) 156void o2net_set_nst_sock_time(struct o2net_send_tracking *nst)
158{ 157{
159#ifdef CONFIG_DEBUG_FS
160 do_gettimeofday(&nst->st_sock_time); 158 do_gettimeofday(&nst->st_sock_time);
161#endif
162} 159}
163 160
164static void o2net_set_nst_send_time(struct o2net_send_tracking *nst) 161void o2net_set_nst_send_time(struct o2net_send_tracking *nst)
165{ 162{
166#ifdef CONFIG_DEBUG_FS
167 do_gettimeofday(&nst->st_send_time); 163 do_gettimeofday(&nst->st_send_time);
168#endif
169} 164}
170 165
171static void o2net_set_nst_status_time(struct o2net_send_tracking *nst) 166void o2net_set_nst_status_time(struct o2net_send_tracking *nst)
172{ 167{
173#ifdef CONFIG_DEBUG_FS
174 do_gettimeofday(&nst->st_status_time); 168 do_gettimeofday(&nst->st_status_time);
175#endif
176} 169}
177 170
178static void o2net_set_nst_sock_container(struct o2net_send_tracking *nst, 171void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
179 struct o2net_sock_container *sc) 172 struct o2net_sock_container *sc)
180{ 173{
181#ifdef CONFIG_DEBUG_FS
182 nst->st_sc = sc; 174 nst->st_sc = sc;
183#endif
184} 175}
185 176
186static void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, u32 msg_id) 177void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, u32 msg_id)
187{ 178{
188#ifdef CONFIG_DEBUG_FS
189 nst->st_id = msg_id; 179 nst->st_id = msg_id;
190#endif
191} 180}
181#endif /* CONFIG_DEBUG_FS */
192 182
193static inline int o2net_reconnect_delay(void) 183static inline int o2net_reconnect_delay(void)
194{ 184{
diff --git a/fs/ocfs2/cluster/tcp.h b/fs/ocfs2/cluster/tcp.h
index a705d5d1903..fd6179eb26d 100644
--- a/fs/ocfs2/cluster/tcp.h
+++ b/fs/ocfs2/cluster/tcp.h
@@ -128,23 +128,23 @@ void o2net_debug_del_nst(struct o2net_send_tracking *nst);
128void o2net_debug_add_sc(struct o2net_sock_container *sc); 128void o2net_debug_add_sc(struct o2net_sock_container *sc);
129void o2net_debug_del_sc(struct o2net_sock_container *sc); 129void o2net_debug_del_sc(struct o2net_sock_container *sc);
130#else 130#else
131static int o2net_debugfs_init(void) 131static inline int o2net_debugfs_init(void)
132{ 132{
133 return 0; 133 return 0;
134} 134}
135static void o2net_debugfs_exit(void) 135static inline void o2net_debugfs_exit(void)
136{ 136{
137} 137}
138static void o2net_debug_add_nst(struct o2net_send_tracking *nst) 138static inline void o2net_debug_add_nst(struct o2net_send_tracking *nst)
139{ 139{
140} 140}
141static void o2net_debug_del_nst(struct o2net_send_tracking *nst) 141static inline void o2net_debug_del_nst(struct o2net_send_tracking *nst)
142{ 142{
143} 143}
144static void o2net_debug_add_sc(struct o2net_sock_container *sc) 144static inline void o2net_debug_add_sc(struct o2net_sock_container *sc)
145{ 145{
146} 146}
147static void o2net_debug_del_sc(struct o2net_sock_container *sc) 147static inline void o2net_debug_del_sc(struct o2net_sock_container *sc)
148{ 148{
149} 149}
150#endif /* CONFIG_DEBUG_FS */ 150#endif /* CONFIG_DEBUG_FS */
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h
index 8d58cfe410b..18307ff81b7 100644
--- a/fs/ocfs2/cluster/tcp_internal.h
+++ b/fs/ocfs2/cluster/tcp_internal.h
@@ -224,10 +224,42 @@ struct o2net_send_tracking {
224 struct timeval st_send_time; 224 struct timeval st_send_time;
225 struct timeval st_status_time; 225 struct timeval st_status_time;
226}; 226};
227
228void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
229 u32 msgkey, struct task_struct *task, u8 node);
230void o2net_set_nst_sock_time(struct o2net_send_tracking *nst);
231void o2net_set_nst_send_time(struct o2net_send_tracking *nst);
232void o2net_set_nst_status_time(struct o2net_send_tracking *nst);
233void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
234 struct o2net_sock_container *sc);
235void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, u32 msg_id);
236
227#else 237#else
228struct o2net_send_tracking { 238struct o2net_send_tracking {
229 u32 dummy; 239 u32 dummy;
230}; 240};
241
242static inline void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
243 u32 msgkey, struct task_struct *task, u8 node)
244{
245}
246static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst)
247{
248}
249static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst)
250{
251}
252static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst)
253{
254}
255static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
256 struct o2net_sock_container *sc)
257{
258}
259static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst,
260 u32 msg_id)
261{
262}
231#endif /* CONFIG_DEBUG_FS */ 263#endif /* CONFIG_DEBUG_FS */
232 264
233#endif /* O2CLUSTER_TCP_INTERNAL_H */ 265#endif /* O2CLUSTER_TCP_INTERNAL_H */
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index d34a62a3a62..8c686d22f9c 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -60,25 +60,25 @@ void dlm_destroy_debugfs_root(void);
60 60
61#else 61#else
62 62
63static int dlm_debug_init(struct dlm_ctxt *dlm) 63static inline int dlm_debug_init(struct dlm_ctxt *dlm)
64{ 64{
65 return 0; 65 return 0;
66} 66}
67static void dlm_debug_shutdown(struct dlm_ctxt *dlm) 67static inline void dlm_debug_shutdown(struct dlm_ctxt *dlm)
68{ 68{
69} 69}
70static int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm) 70static inline int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
71{ 71{
72 return 0; 72 return 0;
73} 73}
74static void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm) 74static inline void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
75{ 75{
76} 76}
77static int dlm_create_debugfs_root(void) 77static inline int dlm_create_debugfs_root(void)
78{ 78{
79 return 0; 79 return 0;
80} 80}
81static void dlm_destroy_debugfs_root(void) 81static inline void dlm_destroy_debugfs_root(void)
82{ 82{
83} 83}
84 84
diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c
index bbd1667aa7d..fcd120f1493 100644
--- a/fs/ocfs2/stack_o2cb.c
+++ b/fs/ocfs2/stack_o2cb.c
@@ -317,8 +317,7 @@ out:
317 return rc; 317 return rc;
318} 318}
319 319
320static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn, 320static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn)
321 int hangup_pending)
322{ 321{
323 struct dlm_ctxt *dlm = conn->cc_lockspace; 322 struct dlm_ctxt *dlm = conn->cc_lockspace;
324 struct o2dlm_private *priv = conn->cc_private; 323 struct o2dlm_private *priv = conn->cc_private;
@@ -333,43 +332,6 @@ static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn,
333 return 0; 332 return 0;
334} 333}
335 334
336static void o2hb_stop(const char *group)
337{
338 int ret;
339 char *argv[5], *envp[3];
340
341 argv[0] = (char *)o2nm_get_hb_ctl_path();
342 argv[1] = "-K";
343 argv[2] = "-u";
344 argv[3] = (char *)group;
345 argv[4] = NULL;
346
347 mlog(0, "Run: %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
348
349 /* minimal command environment taken from cpu_run_sbin_hotplug */
350 envp[0] = "HOME=/";
351 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
352 envp[2] = NULL;
353
354 ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
355 if (ret < 0)
356 mlog_errno(ret);
357}
358
359/*
360 * Hangup is a hack for tools compatibility. Older ocfs2-tools software
361 * expects the filesystem to call "ocfs2_hb_ctl" during unmount. This
362 * happens regardless of whether the DLM got started, so we can't do it
363 * in ocfs2_cluster_disconnect(). We bring the o2hb_stop() function into
364 * the glue and provide a "hangup" API for super.c to call.
365 *
366 * Other stacks will eventually provide a NULL ->hangup() pointer.
367 */
368static void o2cb_cluster_hangup(const char *group, int grouplen)
369{
370 o2hb_stop(group);
371}
372
373static int o2cb_cluster_this_node(unsigned int *node) 335static int o2cb_cluster_this_node(unsigned int *node)
374{ 336{
375 int node_num; 337 int node_num;
@@ -388,7 +350,6 @@ static int o2cb_cluster_this_node(unsigned int *node)
388static struct ocfs2_stack_operations o2cb_stack_ops = { 350static struct ocfs2_stack_operations o2cb_stack_ops = {
389 .connect = o2cb_cluster_connect, 351 .connect = o2cb_cluster_connect,
390 .disconnect = o2cb_cluster_disconnect, 352 .disconnect = o2cb_cluster_disconnect,
391 .hangup = o2cb_cluster_hangup,
392 .this_node = o2cb_cluster_this_node, 353 .this_node = o2cb_cluster_this_node,
393 .dlm_lock = o2cb_dlm_lock, 354 .dlm_lock = o2cb_dlm_lock,
394 .dlm_unlock = o2cb_dlm_unlock, 355 .dlm_unlock = o2cb_dlm_unlock,
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c
index b503772cd0e..c021280dd46 100644
--- a/fs/ocfs2/stack_user.c
+++ b/fs/ocfs2/stack_user.c
@@ -61,7 +61,7 @@
61 * negotiated by the client. The client negotiates based on the maximum 61 * negotiated by the client. The client negotiates based on the maximum
62 * version advertised in /sys/fs/ocfs2/max_locking_protocol. The major 62 * version advertised in /sys/fs/ocfs2/max_locking_protocol. The major
63 * number from the "SETV" message must match 63 * number from the "SETV" message must match
64 * user_stack.sp_proto->lp_max_version.pv_major, and the minor number 64 * ocfs2_user_plugin.sp_proto->lp_max_version.pv_major, and the minor number
65 * must be less than or equal to ...->lp_max_version.pv_minor. 65 * must be less than or equal to ...->lp_max_version.pv_minor.
66 * 66 *
67 * Once this information has been set, mounts will be allowed. From this 67 * Once this information has been set, mounts will be allowed. From this
@@ -153,7 +153,7 @@ union ocfs2_control_message {
153 struct ocfs2_control_message_down u_down; 153 struct ocfs2_control_message_down u_down;
154}; 154};
155 155
156static struct ocfs2_stack_plugin user_stack; 156static struct ocfs2_stack_plugin ocfs2_user_plugin;
157 157
158static atomic_t ocfs2_control_opened; 158static atomic_t ocfs2_control_opened;
159static int ocfs2_control_this_node = -1; 159static int ocfs2_control_this_node = -1;
@@ -399,7 +399,7 @@ static int ocfs2_control_do_setversion_msg(struct file *file,
399 char *ptr = NULL; 399 char *ptr = NULL;
400 struct ocfs2_control_private *p = file->private_data; 400 struct ocfs2_control_private *p = file->private_data;
401 struct ocfs2_protocol_version *max = 401 struct ocfs2_protocol_version *max =
402 &user_stack.sp_proto->lp_max_version; 402 &ocfs2_user_plugin.sp_proto->lp_max_version;
403 403
404 if (ocfs2_control_get_handshake_state(file) != 404 if (ocfs2_control_get_handshake_state(file) !=
405 OCFS2_CONTROL_HANDSHAKE_PROTOCOL) 405 OCFS2_CONTROL_HANDSHAKE_PROTOCOL)
@@ -680,7 +680,7 @@ static void fsdlm_lock_ast_wrapper(void *astarg)
680 struct dlm_lksb *lksb = fsdlm_astarg_to_lksb(astarg); 680 struct dlm_lksb *lksb = fsdlm_astarg_to_lksb(astarg);
681 int status = lksb->sb_status; 681 int status = lksb->sb_status;
682 682
683 BUG_ON(user_stack.sp_proto == NULL); 683 BUG_ON(ocfs2_user_plugin.sp_proto == NULL);
684 684
685 /* 685 /*
686 * For now we're punting on the issue of other non-standard errors 686 * For now we're punting on the issue of other non-standard errors
@@ -693,16 +693,16 @@ static void fsdlm_lock_ast_wrapper(void *astarg)
693 */ 693 */
694 694
695 if (status == -DLM_EUNLOCK || status == -DLM_ECANCEL) 695 if (status == -DLM_EUNLOCK || status == -DLM_ECANCEL)
696 user_stack.sp_proto->lp_unlock_ast(astarg, 0); 696 ocfs2_user_plugin.sp_proto->lp_unlock_ast(astarg, 0);
697 else 697 else
698 user_stack.sp_proto->lp_lock_ast(astarg); 698 ocfs2_user_plugin.sp_proto->lp_lock_ast(astarg);
699} 699}
700 700
701static void fsdlm_blocking_ast_wrapper(void *astarg, int level) 701static void fsdlm_blocking_ast_wrapper(void *astarg, int level)
702{ 702{
703 BUG_ON(user_stack.sp_proto == NULL); 703 BUG_ON(ocfs2_user_plugin.sp_proto == NULL);
704 704
705 user_stack.sp_proto->lp_blocking_ast(astarg, level); 705 ocfs2_user_plugin.sp_proto->lp_blocking_ast(astarg, level);
706} 706}
707 707
708static int user_dlm_lock(struct ocfs2_cluster_connection *conn, 708static int user_dlm_lock(struct ocfs2_cluster_connection *conn,
@@ -816,8 +816,7 @@ out:
816 return rc; 816 return rc;
817} 817}
818 818
819static int user_cluster_disconnect(struct ocfs2_cluster_connection *conn, 819static int user_cluster_disconnect(struct ocfs2_cluster_connection *conn)
820 int hangup_pending)
821{ 820{
822 dlm_release_lockspace(conn->cc_lockspace, 2); 821 dlm_release_lockspace(conn->cc_lockspace, 2);
823 conn->cc_lockspace = NULL; 822 conn->cc_lockspace = NULL;
@@ -838,7 +837,7 @@ static int user_cluster_this_node(unsigned int *this_node)
838 return 0; 837 return 0;
839} 838}
840 839
841static struct ocfs2_stack_operations user_stack_ops = { 840static struct ocfs2_stack_operations ocfs2_user_plugin_ops = {
842 .connect = user_cluster_connect, 841 .connect = user_cluster_connect,
843 .disconnect = user_cluster_disconnect, 842 .disconnect = user_cluster_disconnect,
844 .this_node = user_cluster_this_node, 843 .this_node = user_cluster_this_node,
@@ -849,20 +848,20 @@ static struct ocfs2_stack_operations user_stack_ops = {
849 .dump_lksb = user_dlm_dump_lksb, 848 .dump_lksb = user_dlm_dump_lksb,
850}; 849};
851 850
852static struct ocfs2_stack_plugin user_stack = { 851static struct ocfs2_stack_plugin ocfs2_user_plugin = {
853 .sp_name = "user", 852 .sp_name = "user",
854 .sp_ops = &user_stack_ops, 853 .sp_ops = &ocfs2_user_plugin_ops,
855 .sp_owner = THIS_MODULE, 854 .sp_owner = THIS_MODULE,
856}; 855};
857 856
858 857
859static int __init user_stack_init(void) 858static int __init ocfs2_user_plugin_init(void)
860{ 859{
861 int rc; 860 int rc;
862 861
863 rc = ocfs2_control_init(); 862 rc = ocfs2_control_init();
864 if (!rc) { 863 if (!rc) {
865 rc = ocfs2_stack_glue_register(&user_stack); 864 rc = ocfs2_stack_glue_register(&ocfs2_user_plugin);
866 if (rc) 865 if (rc)
867 ocfs2_control_exit(); 866 ocfs2_control_exit();
868 } 867 }
@@ -870,14 +869,14 @@ static int __init user_stack_init(void)
870 return rc; 869 return rc;
871} 870}
872 871
873static void __exit user_stack_exit(void) 872static void __exit ocfs2_user_plugin_exit(void)
874{ 873{
875 ocfs2_stack_glue_unregister(&user_stack); 874 ocfs2_stack_glue_unregister(&ocfs2_user_plugin);
876 ocfs2_control_exit(); 875 ocfs2_control_exit();
877} 876}
878 877
879MODULE_AUTHOR("Oracle"); 878MODULE_AUTHOR("Oracle");
880MODULE_DESCRIPTION("ocfs2 driver for userspace cluster stacks"); 879MODULE_DESCRIPTION("ocfs2 driver for userspace cluster stacks");
881MODULE_LICENSE("GPL"); 880MODULE_LICENSE("GPL");
882module_init(user_stack_init); 881module_init(ocfs2_user_plugin_init);
883module_exit(user_stack_exit); 882module_exit(ocfs2_user_plugin_exit);
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
index 119f60cea9c..10e149ae5e3 100644
--- a/fs/ocfs2/stackglue.c
+++ b/fs/ocfs2/stackglue.c
@@ -26,6 +26,7 @@
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/kobject.h> 27#include <linux/kobject.h>
28#include <linux/sysfs.h> 28#include <linux/sysfs.h>
29#include <linux/sysctl.h>
29 30
30#include "ocfs2_fs.h" 31#include "ocfs2_fs.h"
31 32
@@ -33,11 +34,13 @@
33 34
34#define OCFS2_STACK_PLUGIN_O2CB "o2cb" 35#define OCFS2_STACK_PLUGIN_O2CB "o2cb"
35#define OCFS2_STACK_PLUGIN_USER "user" 36#define OCFS2_STACK_PLUGIN_USER "user"
37#define OCFS2_MAX_HB_CTL_PATH 256
36 38
37static struct ocfs2_locking_protocol *lproto; 39static struct ocfs2_locking_protocol *lproto;
38static DEFINE_SPINLOCK(ocfs2_stack_lock); 40static DEFINE_SPINLOCK(ocfs2_stack_lock);
39static LIST_HEAD(ocfs2_stack_list); 41static LIST_HEAD(ocfs2_stack_list);
40static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1]; 42static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1];
43static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl";
41 44
42/* 45/*
43 * The stack currently in use. If not null, active_stack->sp_count > 0, 46 * The stack currently in use. If not null, active_stack->sp_count > 0,
@@ -349,7 +352,7 @@ int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
349 352
350 BUG_ON(conn == NULL); 353 BUG_ON(conn == NULL);
351 354
352 ret = active_stack->sp_ops->disconnect(conn, hangup_pending); 355 ret = active_stack->sp_ops->disconnect(conn);
353 356
354 /* XXX Should we free it anyway? */ 357 /* XXX Should we free it anyway? */
355 if (!ret) { 358 if (!ret) {
@@ -362,13 +365,48 @@ int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
362} 365}
363EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect); 366EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect);
364 367
368/*
369 * Leave the group for this filesystem. This is executed by a userspace
370 * program (stored in ocfs2_hb_ctl_path).
371 */
372static void ocfs2_leave_group(const char *group)
373{
374 int ret;
375 char *argv[5], *envp[3];
376
377 argv[0] = ocfs2_hb_ctl_path;
378 argv[1] = "-K";
379 argv[2] = "-u";
380 argv[3] = (char *)group;
381 argv[4] = NULL;
382
383 /* minimal command environment taken from cpu_run_sbin_hotplug */
384 envp[0] = "HOME=/";
385 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
386 envp[2] = NULL;
387
388 ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
389 if (ret < 0) {
390 printk(KERN_ERR
391 "ocfs2: Error %d running user helper "
392 "\"%s %s %s %s\"\n",
393 ret, argv[0], argv[1], argv[2], argv[3]);
394 }
395}
396
397/*
398 * Hangup is a required post-umount. ocfs2-tools software expects the
399 * filesystem to call "ocfs2_hb_ctl" during unmount. This happens
400 * regardless of whether the DLM got started, so we can't do it
401 * in ocfs2_cluster_disconnect(). The ocfs2_leave_group() function does
402 * the actual work.
403 */
365void ocfs2_cluster_hangup(const char *group, int grouplen) 404void ocfs2_cluster_hangup(const char *group, int grouplen)
366{ 405{
367 BUG_ON(group == NULL); 406 BUG_ON(group == NULL);
368 BUG_ON(group[grouplen] != '\0'); 407 BUG_ON(group[grouplen] != '\0');
369 408
370 if (active_stack->sp_ops->hangup) 409 ocfs2_leave_group(group);
371 active_stack->sp_ops->hangup(group, grouplen);
372 410
373 /* cluster_disconnect() was called with hangup_pending==1 */ 411 /* cluster_disconnect() was called with hangup_pending==1 */
374 ocfs2_stack_driver_put(); 412 ocfs2_stack_driver_put();
@@ -548,10 +586,83 @@ error:
548 return ret; 586 return ret;
549} 587}
550 588
589/*
590 * Sysctl bits
591 *
592 * The sysctl lives at /proc/sys/fs/ocfs2/nm/hb_ctl_path. The 'nm' doesn't
593 * make as much sense in a multiple cluster stack world, but it's safer
594 * and easier to preserve the name.
595 */
596
597#define FS_OCFS2_NM 1
598
599static ctl_table ocfs2_nm_table[] = {
600 {
601 .ctl_name = 1,
602 .procname = "hb_ctl_path",
603 .data = ocfs2_hb_ctl_path,
604 .maxlen = OCFS2_MAX_HB_CTL_PATH,
605 .mode = 0644,
606 .proc_handler = &proc_dostring,
607 .strategy = &sysctl_string,
608 },
609 { .ctl_name = 0 }
610};
611
612static ctl_table ocfs2_mod_table[] = {
613 {
614 .ctl_name = FS_OCFS2_NM,
615 .procname = "nm",
616 .data = NULL,
617 .maxlen = 0,
618 .mode = 0555,
619 .child = ocfs2_nm_table
620 },
621 { .ctl_name = 0}
622};
623
624static ctl_table ocfs2_kern_table[] = {
625 {
626 .ctl_name = FS_OCFS2,
627 .procname = "ocfs2",
628 .data = NULL,
629 .maxlen = 0,
630 .mode = 0555,
631 .child = ocfs2_mod_table
632 },
633 { .ctl_name = 0}
634};
635
636static ctl_table ocfs2_root_table[] = {
637 {
638 .ctl_name = CTL_FS,
639 .procname = "fs",
640 .data = NULL,
641 .maxlen = 0,
642 .mode = 0555,
643 .child = ocfs2_kern_table
644 },
645 { .ctl_name = 0 }
646};
647
648static struct ctl_table_header *ocfs2_table_header = NULL;
649
650
651/*
652 * Initialization
653 */
654
551static int __init ocfs2_stack_glue_init(void) 655static int __init ocfs2_stack_glue_init(void)
552{ 656{
553 strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB); 657 strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
554 658
659 ocfs2_table_header = register_sysctl_table(ocfs2_root_table);
660 if (!ocfs2_table_header) {
661 printk(KERN_ERR
662 "ocfs2 stack glue: unable to register sysctl\n");
663 return -ENOMEM; /* or something. */
664 }
665
555 return ocfs2_sysfs_init(); 666 return ocfs2_sysfs_init();
556} 667}
557 668
@@ -559,6 +670,8 @@ static void __exit ocfs2_stack_glue_exit(void)
559{ 670{
560 lproto = NULL; 671 lproto = NULL;
561 ocfs2_sysfs_exit(); 672 ocfs2_sysfs_exit();
673 if (ocfs2_table_header)
674 unregister_sysctl_table(ocfs2_table_header);
562} 675}
563 676
564MODULE_AUTHOR("Oracle"); 677MODULE_AUTHOR("Oracle");
diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h
index 005e4f170e0..db56281dd1b 100644
--- a/fs/ocfs2/stackglue.h
+++ b/fs/ocfs2/stackglue.h
@@ -134,22 +134,10 @@ struct ocfs2_stack_operations {
134 * be freed. Thus, a stack must not return from ->disconnect() 134 * be freed. Thus, a stack must not return from ->disconnect()
135 * until it will no longer reference the conn pointer. 135 * until it will no longer reference the conn pointer.
136 * 136 *
137 * If hangup_pending is zero, ocfs2_cluster_disconnect() will also 137 * Once this call returns, the stack glue will be dropping this
138 * be dropping the reference on the module. 138 * connection's reference on the module.
139 */ 139 */
140 int (*disconnect)(struct ocfs2_cluster_connection *conn, 140 int (*disconnect)(struct ocfs2_cluster_connection *conn);
141 int hangup_pending);
142
143 /*
144 * ocfs2_cluster_hangup() exists for compatibility with older
145 * ocfs2 tools. Only the classic stack really needs it. As such
146 * ->hangup() is not required of all stacks. See the comment by
147 * ocfs2_cluster_hangup() for more details.
148 *
149 * Note that ocfs2_cluster_hangup() can only be called if
150 * hangup_pending was passed to ocfs2_cluster_disconnect().
151 */
152 void (*hangup)(const char *group, int grouplen);
153 141
154 /* 142 /*
155 * ->this_node() returns the cluster's unique identifier for the 143 * ->this_node() returns the cluster's unique identifier for the
@@ -258,4 +246,5 @@ void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto)
258/* Used by stack plugins */ 246/* Used by stack plugins */
259int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin); 247int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin);
260void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin); 248void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin);
249
261#endif /* STACKGLUE_H */ 250#endif /* STACKGLUE_H */
diff --git a/fs/open.c b/fs/open.c
index a1450086e92..a99ad09c319 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -16,6 +16,7 @@
16#include <linux/namei.h> 16#include <linux/namei.h>
17#include <linux/backing-dev.h> 17#include <linux/backing-dev.h>
18#include <linux/capability.h> 18#include <linux/capability.h>
19#include <linux/securebits.h>
19#include <linux/security.h> 20#include <linux/security.h>
20#include <linux/mount.h> 21#include <linux/mount.h>
21#include <linux/vfs.h> 22#include <linux/vfs.h>
@@ -425,7 +426,7 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
425{ 426{
426 struct nameidata nd; 427 struct nameidata nd;
427 int old_fsuid, old_fsgid; 428 int old_fsuid, old_fsgid;
428 kernel_cap_t old_cap; 429 kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */
429 int res; 430 int res;
430 431
431 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 432 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
@@ -433,23 +434,27 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
433 434
434 old_fsuid = current->fsuid; 435 old_fsuid = current->fsuid;
435 old_fsgid = current->fsgid; 436 old_fsgid = current->fsgid;
436 old_cap = current->cap_effective;
437 437
438 current->fsuid = current->uid; 438 current->fsuid = current->uid;
439 current->fsgid = current->gid; 439 current->fsgid = current->gid;
440 440
441 /* 441 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
442 * Clear the capabilities if we switch to a non-root user 442 /*
443 * 443 * Clear the capabilities if we switch to a non-root user
444 * FIXME: There is a race here against sys_capset. The 444 */
445 * capabilities can change yet we will restore the old 445#ifndef CONFIG_SECURITY_FILE_CAPABILITIES
446 * value below. We should hold task_capabilities_lock, 446 /*
447 * but we cannot because user_path_walk can sleep. 447 * FIXME: There is a race here against sys_capset. The
448 */ 448 * capabilities can change yet we will restore the old
449 if (current->uid) 449 * value below. We should hold task_capabilities_lock,
450 cap_clear(current->cap_effective); 450 * but we cannot because user_path_walk can sleep.
451 else 451 */
452 current->cap_effective = current->cap_permitted; 452#endif /* ndef CONFIG_SECURITY_FILE_CAPABILITIES */
453 if (current->uid)
454 old_cap = cap_set_effective(__cap_empty_set);
455 else
456 old_cap = cap_set_effective(current->cap_permitted);
457 }
453 458
454 res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); 459 res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
455 if (res) 460 if (res)
@@ -478,7 +483,9 @@ out_path_release:
478out: 483out:
479 current->fsuid = old_fsuid; 484 current->fsuid = old_fsuid;
480 current->fsgid = old_fsgid; 485 current->fsgid = old_fsgid;
481 current->cap_effective = old_cap; 486
487 if (!issecure(SECURE_NO_SETUID_FIXUP))
488 cap_set_effective(old_cap);
482 489
483 return res; 490 return res;
484} 491}
diff --git a/fs/pipe.c b/fs/pipe.c
index ec228bc9f88..700f4e0d957 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1003,8 +1003,7 @@ struct file *create_write_pipe(void)
1003void free_write_pipe(struct file *f) 1003void free_write_pipe(struct file *f)
1004{ 1004{
1005 free_pipe_info(f->f_dentry->d_inode); 1005 free_pipe_info(f->f_dentry->d_inode);
1006 dput(f->f_path.dentry); 1006 path_put(&f->f_path);
1007 mntput(f->f_path.mnt);
1008 put_filp(f); 1007 put_filp(f);
1009} 1008}
1010 1009
@@ -1015,8 +1014,8 @@ struct file *create_read_pipe(struct file *wrf)
1015 return ERR_PTR(-ENFILE); 1014 return ERR_PTR(-ENFILE);
1016 1015
1017 /* Grab pipe from the writer */ 1016 /* Grab pipe from the writer */
1018 f->f_path.mnt = mntget(wrf->f_path.mnt); 1017 f->f_path = wrf->f_path;
1019 f->f_path.dentry = dget(wrf->f_path.dentry); 1018 path_get(&wrf->f_path);
1020 f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; 1019 f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping;
1021 1020
1022 f->f_pos = 0; 1021 f->f_pos = 0;
@@ -1068,8 +1067,7 @@ int do_pipe(int *fd)
1068 err_fdr: 1067 err_fdr:
1069 put_unused_fd(fdr); 1068 put_unused_fd(fdr);
1070 err_read_pipe: 1069 err_read_pipe:
1071 dput(fr->f_dentry); 1070 path_put(&fr->f_path);
1072 mntput(fr->f_vfsmnt);
1073 put_filp(fr); 1071 put_filp(fr);
1074 err_write_pipe: 1072 err_write_pipe:
1075 free_write_pipe(fw); 1073 free_write_pipe(fw);
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 9e3b8c33c24..797d775e035 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -288,7 +288,7 @@ static void render_cap_t(struct seq_file *m, const char *header,
288 seq_printf(m, "%s", header); 288 seq_printf(m, "%s", header);
289 CAP_FOR_EACH_U32(__capi) { 289 CAP_FOR_EACH_U32(__capi) {
290 seq_printf(m, "%08x", 290 seq_printf(m, "%08x",
291 a->cap[(_LINUX_CAPABILITY_U32S-1) - __capi]); 291 a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
292 } 292 }
293 seq_printf(m, "\n"); 293 seq_printf(m, "\n");
294} 294}
diff --git a/fs/proc/base.c b/fs/proc/base.c
index c447e0743a3..3b455371e7f 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -127,6 +127,25 @@ struct pid_entry {
127 NULL, &proc_single_file_operations, \ 127 NULL, &proc_single_file_operations, \
128 { .proc_show = &proc_##OTYPE } ) 128 { .proc_show = &proc_##OTYPE } )
129 129
130/*
131 * Count the number of hardlinks for the pid_entry table, excluding the .
132 * and .. links.
133 */
134static unsigned int pid_entry_count_dirs(const struct pid_entry *entries,
135 unsigned int n)
136{
137 unsigned int i;
138 unsigned int count;
139
140 count = 0;
141 for (i = 0; i < n; ++i) {
142 if (S_ISDIR(entries[i].mode))
143 ++count;
144 }
145
146 return count;
147}
148
130int maps_protect; 149int maps_protect;
131EXPORT_SYMBOL(maps_protect); 150EXPORT_SYMBOL(maps_protect);
132 151
@@ -2585,10 +2604,9 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
2585 inode->i_op = &proc_tgid_base_inode_operations; 2604 inode->i_op = &proc_tgid_base_inode_operations;
2586 inode->i_fop = &proc_tgid_base_operations; 2605 inode->i_fop = &proc_tgid_base_operations;
2587 inode->i_flags|=S_IMMUTABLE; 2606 inode->i_flags|=S_IMMUTABLE;
2588 inode->i_nlink = 5; 2607
2589#ifdef CONFIG_SECURITY 2608 inode->i_nlink = 2 + pid_entry_count_dirs(tgid_base_stuff,
2590 inode->i_nlink += 1; 2609 ARRAY_SIZE(tgid_base_stuff));
2591#endif
2592 2610
2593 dentry->d_op = &pid_dentry_operations; 2611 dentry->d_op = &pid_dentry_operations;
2594 2612
@@ -2816,10 +2834,9 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
2816 inode->i_op = &proc_tid_base_inode_operations; 2834 inode->i_op = &proc_tid_base_inode_operations;
2817 inode->i_fop = &proc_tid_base_operations; 2835 inode->i_fop = &proc_tid_base_operations;
2818 inode->i_flags|=S_IMMUTABLE; 2836 inode->i_flags|=S_IMMUTABLE;
2819 inode->i_nlink = 4; 2837
2820#ifdef CONFIG_SECURITY 2838 inode->i_nlink = 2 + pid_entry_count_dirs(tid_base_stuff,
2821 inode->i_nlink += 1; 2839 ARRAY_SIZE(tid_base_stuff));
2822#endif
2823 2840
2824 dentry->d_op = &pid_dentry_operations; 2841 dentry->d_op = &pid_dentry_operations;
2825 2842
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 6f4e8dc97da..b08d1001791 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -425,7 +425,8 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
425 } 425 }
426 } 426 }
427 unlock_new_inode(inode); 427 unlock_new_inode(inode);
428 } 428 } else
429 module_put(de->owner);
429 return inode; 430 return inode;
430 431
431out_ino: 432out_ino:
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 74a323d2b85..c652d469dc0 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -123,6 +123,11 @@ static int uptime_read_proc(char *page, char **start, off_t off,
123 return proc_calc_metrics(page, start, off, count, eof, len); 123 return proc_calc_metrics(page, start, off, count, eof, len);
124} 124}
125 125
126int __attribute__((weak)) arch_report_meminfo(char *page)
127{
128 return 0;
129}
130
126static int meminfo_read_proc(char *page, char **start, off_t off, 131static int meminfo_read_proc(char *page, char **start, off_t off,
127 int count, int *eof, void *data) 132 int count, int *eof, void *data)
128{ 133{
@@ -139,7 +144,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
139#define K(x) ((x) << (PAGE_SHIFT - 10)) 144#define K(x) ((x) << (PAGE_SHIFT - 10))
140 si_meminfo(&i); 145 si_meminfo(&i);
141 si_swapinfo(&i); 146 si_swapinfo(&i);
142 committed = atomic_read(&vm_committed_space); 147 committed = atomic_long_read(&vm_committed_space);
143 allowed = ((totalram_pages - hugetlb_total_pages()) 148 allowed = ((totalram_pages - hugetlb_total_pages())
144 * sysctl_overcommit_ratio / 100) + total_swap_pages; 149 * sysctl_overcommit_ratio / 100) + total_swap_pages;
145 150
@@ -221,6 +226,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
221 226
222 len += hugetlb_report_meminfo(page + len); 227 len += hugetlb_report_meminfo(page + len);
223 228
229 len += arch_report_meminfo(page + len);
230
224 return proc_calc_metrics(page, start, off, count, eof, len); 231 return proc_calc_metrics(page, start, off, count, eof, len);
225#undef K 232#undef K
226} 233}
@@ -472,6 +479,13 @@ static const struct file_operations proc_vmalloc_operations = {
472}; 479};
473#endif 480#endif
474 481
482#ifndef arch_irq_stat_cpu
483#define arch_irq_stat_cpu(cpu) 0
484#endif
485#ifndef arch_irq_stat
486#define arch_irq_stat() 0
487#endif
488
475static int show_stat(struct seq_file *p, void *v) 489static int show_stat(struct seq_file *p, void *v)
476{ 490{
477 int i; 491 int i;
@@ -509,7 +523,9 @@ static int show_stat(struct seq_file *p, void *v)
509 sum += temp; 523 sum += temp;
510 per_irq_sum[j] += temp; 524 per_irq_sum[j] += temp;
511 } 525 }
526 sum += arch_irq_stat_cpu(i);
512 } 527 }
528 sum += arch_irq_stat();
513 529
514 seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", 530 seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
515 (unsigned long long)cputime64_to_clock_t(user), 531 (unsigned long long)cputime64_to_clock_t(user),
@@ -716,7 +732,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
716 pfn = src / KPMSIZE; 732 pfn = src / KPMSIZE;
717 count = min_t(size_t, count, (max_pfn * KPMSIZE) - src); 733 count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
718 if (src & KPMMASK || count & KPMMASK) 734 if (src & KPMMASK || count & KPMMASK)
719 return -EIO; 735 return -EINVAL;
720 736
721 while (count > 0) { 737 while (count > 0) {
722 ppage = NULL; 738 ppage = NULL;
@@ -726,7 +742,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
726 if (!ppage) 742 if (!ppage)
727 pcount = 0; 743 pcount = 0;
728 else 744 else
729 pcount = atomic_read(&ppage->_count); 745 pcount = page_mapcount(ppage);
730 746
731 if (put_user(pcount, out++)) { 747 if (put_user(pcount, out++)) {
732 ret = -EFAULT; 748 ret = -EFAULT;
@@ -782,7 +798,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
782 pfn = src / KPMSIZE; 798 pfn = src / KPMSIZE;
783 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); 799 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
784 if (src & KPMMASK || count & KPMMASK) 800 if (src & KPMMASK || count & KPMMASK)
785 return -EIO; 801 return -EINVAL;
786 802
787 while (count > 0) { 803 while (count > 0) {
788 ppage = NULL; 804 ppage = NULL;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 88717c0f941..c492449f3b4 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -315,9 +315,9 @@ struct mem_size_stats {
315}; 315};
316 316
317static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 317static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
318 void *private) 318 struct mm_walk *walk)
319{ 319{
320 struct mem_size_stats *mss = private; 320 struct mem_size_stats *mss = walk->private;
321 struct vm_area_struct *vma = mss->vma; 321 struct vm_area_struct *vma = mss->vma;
322 pte_t *pte, ptent; 322 pte_t *pte, ptent;
323 spinlock_t *ptl; 323 spinlock_t *ptl;
@@ -365,19 +365,21 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
365 return 0; 365 return 0;
366} 366}
367 367
368static struct mm_walk smaps_walk = { .pmd_entry = smaps_pte_range };
369
370static int show_smap(struct seq_file *m, void *v) 368static int show_smap(struct seq_file *m, void *v)
371{ 369{
372 struct vm_area_struct *vma = v; 370 struct vm_area_struct *vma = v;
373 struct mem_size_stats mss; 371 struct mem_size_stats mss;
374 int ret; 372 int ret;
373 struct mm_walk smaps_walk = {
374 .pmd_entry = smaps_pte_range,
375 .mm = vma->vm_mm,
376 .private = &mss,
377 };
375 378
376 memset(&mss, 0, sizeof mss); 379 memset(&mss, 0, sizeof mss);
377 mss.vma = vma; 380 mss.vma = vma;
378 if (vma->vm_mm && !is_vm_hugetlb_page(vma)) 381 if (vma->vm_mm && !is_vm_hugetlb_page(vma))
379 walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end, 382 walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
380 &smaps_walk, &mss);
381 383
382 ret = show_map(m, v); 384 ret = show_map(m, v);
383 if (ret) 385 if (ret)
@@ -426,9 +428,9 @@ const struct file_operations proc_smaps_operations = {
426}; 428};
427 429
428static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, 430static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
429 unsigned long end, void *private) 431 unsigned long end, struct mm_walk *walk)
430{ 432{
431 struct vm_area_struct *vma = private; 433 struct vm_area_struct *vma = walk->private;
432 pte_t *pte, ptent; 434 pte_t *pte, ptent;
433 spinlock_t *ptl; 435 spinlock_t *ptl;
434 struct page *page; 436 struct page *page;
@@ -452,8 +454,6 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
452 return 0; 454 return 0;
453} 455}
454 456
455static struct mm_walk clear_refs_walk = { .pmd_entry = clear_refs_pte_range };
456
457static ssize_t clear_refs_write(struct file *file, const char __user *buf, 457static ssize_t clear_refs_write(struct file *file, const char __user *buf,
458 size_t count, loff_t *ppos) 458 size_t count, loff_t *ppos)
459{ 459{
@@ -476,11 +476,17 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
476 return -ESRCH; 476 return -ESRCH;
477 mm = get_task_mm(task); 477 mm = get_task_mm(task);
478 if (mm) { 478 if (mm) {
479 struct mm_walk clear_refs_walk = {
480 .pmd_entry = clear_refs_pte_range,
481 .mm = mm,
482 };
479 down_read(&mm->mmap_sem); 483 down_read(&mm->mmap_sem);
480 for (vma = mm->mmap; vma; vma = vma->vm_next) 484 for (vma = mm->mmap; vma; vma = vma->vm_next) {
485 clear_refs_walk.private = vma;
481 if (!is_vm_hugetlb_page(vma)) 486 if (!is_vm_hugetlb_page(vma))
482 walk_page_range(mm, vma->vm_start, vma->vm_end, 487 walk_page_range(vma->vm_start, vma->vm_end,
483 &clear_refs_walk, vma); 488 &clear_refs_walk);
489 }
484 flush_tlb_mm(mm); 490 flush_tlb_mm(mm);
485 up_read(&mm->mmap_sem); 491 up_read(&mm->mmap_sem);
486 mmput(mm); 492 mmput(mm);
@@ -496,7 +502,7 @@ const struct file_operations proc_clear_refs_operations = {
496}; 502};
497 503
498struct pagemapread { 504struct pagemapread {
499 char __user *out, *end; 505 u64 __user *out, *end;
500}; 506};
501 507
502#define PM_ENTRY_BYTES sizeof(u64) 508#define PM_ENTRY_BYTES sizeof(u64)
@@ -519,28 +525,18 @@ struct pagemapread {
519static int add_to_pagemap(unsigned long addr, u64 pfn, 525static int add_to_pagemap(unsigned long addr, u64 pfn,
520 struct pagemapread *pm) 526 struct pagemapread *pm)
521{ 527{
522 /*
523 * Make sure there's room in the buffer for an
524 * entire entry. Otherwise, only copy part of
525 * the pfn.
526 */
527 if (pm->out + PM_ENTRY_BYTES >= pm->end) {
528 if (copy_to_user(pm->out, &pfn, pm->end - pm->out))
529 return -EFAULT;
530 pm->out = pm->end;
531 return PM_END_OF_BUFFER;
532 }
533
534 if (put_user(pfn, pm->out)) 528 if (put_user(pfn, pm->out))
535 return -EFAULT; 529 return -EFAULT;
536 pm->out += PM_ENTRY_BYTES; 530 pm->out++;
531 if (pm->out >= pm->end)
532 return PM_END_OF_BUFFER;
537 return 0; 533 return 0;
538} 534}
539 535
540static int pagemap_pte_hole(unsigned long start, unsigned long end, 536static int pagemap_pte_hole(unsigned long start, unsigned long end,
541 void *private) 537 struct mm_walk *walk)
542{ 538{
543 struct pagemapread *pm = private; 539 struct pagemapread *pm = walk->private;
544 unsigned long addr; 540 unsigned long addr;
545 int err = 0; 541 int err = 0;
546 for (addr = start; addr < end; addr += PAGE_SIZE) { 542 for (addr = start; addr < end; addr += PAGE_SIZE) {
@@ -557,24 +553,45 @@ static u64 swap_pte_to_pagemap_entry(pte_t pte)
557 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); 553 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
558} 554}
559 555
556static unsigned long pte_to_pagemap_entry(pte_t pte)
557{
558 unsigned long pme = 0;
559 if (is_swap_pte(pte))
560 pme = PM_PFRAME(swap_pte_to_pagemap_entry(pte))
561 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP;
562 else if (pte_present(pte))
563 pme = PM_PFRAME(pte_pfn(pte))
564 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
565 return pme;
566}
567
560static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 568static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
561 void *private) 569 struct mm_walk *walk)
562{ 570{
563 struct pagemapread *pm = private; 571 struct vm_area_struct *vma;
572 struct pagemapread *pm = walk->private;
564 pte_t *pte; 573 pte_t *pte;
565 int err = 0; 574 int err = 0;
566 575
576 /* find the first VMA at or above 'addr' */
577 vma = find_vma(walk->mm, addr);
567 for (; addr != end; addr += PAGE_SIZE) { 578 for (; addr != end; addr += PAGE_SIZE) {
568 u64 pfn = PM_NOT_PRESENT; 579 u64 pfn = PM_NOT_PRESENT;
569 pte = pte_offset_map(pmd, addr); 580
570 if (is_swap_pte(*pte)) 581 /* check to see if we've left 'vma' behind
571 pfn = PM_PFRAME(swap_pte_to_pagemap_entry(*pte)) 582 * and need a new, higher one */
572 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; 583 if (vma && (addr >= vma->vm_end))
573 else if (pte_present(*pte)) 584 vma = find_vma(walk->mm, addr);
574 pfn = PM_PFRAME(pte_pfn(*pte)) 585
575 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; 586 /* check that 'vma' actually covers this address,
576 /* unmap so we're not in atomic when we copy to userspace */ 587 * and that it isn't a huge page vma */
577 pte_unmap(pte); 588 if (vma && (vma->vm_start <= addr) &&
589 !is_vm_hugetlb_page(vma)) {
590 pte = pte_offset_map(pmd, addr);
591 pfn = pte_to_pagemap_entry(*pte);
592 /* unmap before userspace copy */
593 pte_unmap(pte);
594 }
578 err = add_to_pagemap(addr, pfn, pm); 595 err = add_to_pagemap(addr, pfn, pm);
579 if (err) 596 if (err)
580 return err; 597 return err;
@@ -585,11 +602,6 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
585 return err; 602 return err;
586} 603}
587 604
588static struct mm_walk pagemap_walk = {
589 .pmd_entry = pagemap_pte_range,
590 .pte_hole = pagemap_pte_hole
591};
592
593/* 605/*
594 * /proc/pid/pagemap - an array mapping virtual pages to pfns 606 * /proc/pid/pagemap - an array mapping virtual pages to pfns
595 * 607 *
@@ -624,6 +636,11 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
624 struct pagemapread pm; 636 struct pagemapread pm;
625 int pagecount; 637 int pagecount;
626 int ret = -ESRCH; 638 int ret = -ESRCH;
639 struct mm_walk pagemap_walk;
640 unsigned long src;
641 unsigned long svpfn;
642 unsigned long start_vaddr;
643 unsigned long end_vaddr;
627 644
628 if (!task) 645 if (!task)
629 goto out; 646 goto out;
@@ -634,7 +651,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
634 651
635 ret = -EINVAL; 652 ret = -EINVAL;
636 /* file position must be aligned */ 653 /* file position must be aligned */
637 if (*ppos % PM_ENTRY_BYTES) 654 if ((*ppos % PM_ENTRY_BYTES) || (count % PM_ENTRY_BYTES))
638 goto out_task; 655 goto out_task;
639 656
640 ret = 0; 657 ret = 0;
@@ -642,11 +659,15 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
642 if (!mm) 659 if (!mm)
643 goto out_task; 660 goto out_task;
644 661
645 ret = -ENOMEM; 662
646 uaddr = (unsigned long)buf & PAGE_MASK; 663 uaddr = (unsigned long)buf & PAGE_MASK;
647 uend = (unsigned long)(buf + count); 664 uend = (unsigned long)(buf + count);
648 pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE; 665 pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE;
649 pages = kmalloc(pagecount * sizeof(struct page *), GFP_KERNEL); 666 ret = 0;
667 if (pagecount == 0)
668 goto out_mm;
669 pages = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
670 ret = -ENOMEM;
650 if (!pages) 671 if (!pages)
651 goto out_mm; 672 goto out_mm;
652 673
@@ -664,36 +685,36 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
664 goto out_pages; 685 goto out_pages;
665 } 686 }
666 687
667 pm.out = buf; 688 pm.out = (u64 *)buf;
668 pm.end = buf + count; 689 pm.end = (u64 *)(buf + count);
669 690
670 if (!ptrace_may_attach(task)) { 691 pagemap_walk.pmd_entry = pagemap_pte_range;
671 ret = -EIO; 692 pagemap_walk.pte_hole = pagemap_pte_hole;
672 } else { 693 pagemap_walk.mm = mm;
673 unsigned long src = *ppos; 694 pagemap_walk.private = &pm;
674 unsigned long svpfn = src / PM_ENTRY_BYTES; 695
675 unsigned long start_vaddr = svpfn << PAGE_SHIFT; 696 src = *ppos;
676 unsigned long end_vaddr = TASK_SIZE_OF(task); 697 svpfn = src / PM_ENTRY_BYTES;
677 698 start_vaddr = svpfn << PAGE_SHIFT;
678 /* watch out for wraparound */ 699 end_vaddr = TASK_SIZE_OF(task);
679 if (svpfn > TASK_SIZE_OF(task) >> PAGE_SHIFT) 700
680 start_vaddr = end_vaddr; 701 /* watch out for wraparound */
681 702 if (svpfn > TASK_SIZE_OF(task) >> PAGE_SHIFT)
682 /* 703 start_vaddr = end_vaddr;
683 * The odds are that this will stop walking way 704
684 * before end_vaddr, because the length of the 705 /*
685 * user buffer is tracked in "pm", and the walk 706 * The odds are that this will stop walking way
686 * will stop when we hit the end of the buffer. 707 * before end_vaddr, because the length of the
687 */ 708 * user buffer is tracked in "pm", and the walk
688 ret = walk_page_range(mm, start_vaddr, end_vaddr, 709 * will stop when we hit the end of the buffer.
689 &pagemap_walk, &pm); 710 */
690 if (ret == PM_END_OF_BUFFER) 711 ret = walk_page_range(start_vaddr, end_vaddr, &pagemap_walk);
691 ret = 0; 712 if (ret == PM_END_OF_BUFFER)
692 /* don't need mmap_sem for these, but this looks cleaner */ 713 ret = 0;
693 *ppos += pm.out - buf; 714 /* don't need mmap_sem for these, but this looks cleaner */
694 if (!ret) 715 *ppos += (char *)pm.out - buf;
695 ret = pm.out - buf; 716 if (!ret)
696 } 717 ret = (char *)pm.out - buf;
697 718
698out_pages: 719out_pages:
699 for (; pagecount; pagecount--) { 720 for (; pagecount; pagecount--) {
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index ed424d708e6..1d40f2bd197 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2165,8 +2165,10 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
2165 blk++; 2165 blk++;
2166 } 2166 }
2167out: 2167out:
2168 if (len == towrite) 2168 if (len == towrite) {
2169 mutex_unlock(&inode->i_mutex);
2169 return err; 2170 return err;
2171 }
2170 if (inode->i_size < off + len - towrite) 2172 if (inode->i_size < off + len - towrite)
2171 i_size_write(inode, off + len - towrite); 2173 i_size_write(inode, off + len - towrite);
2172 inode->i_version++; 2174 inode->i_version++;
diff --git a/fs/select.c b/fs/select.c
index 8dda969614a..da0e88201c3 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -249,7 +249,6 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
249 retval++; 249 retval++;
250 } 250 }
251 } 251 }
252 cond_resched();
253 } 252 }
254 if (res_in) 253 if (res_in)
255 *rinp = res_in; 254 *rinp = res_in;
@@ -257,6 +256,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
257 *routp = res_out; 256 *routp = res_out;
258 if (res_ex) 257 if (res_ex)
259 *rexp = res_ex; 258 *rexp = res_ex;
259 cond_resched();
260 } 260 }
261 wait = NULL; 261 wait = NULL;
262 if (retval || !*timeout || signal_pending(current)) 262 if (retval || !*timeout || signal_pending(current))
diff --git a/fs/splice.c b/fs/splice.c
index 78150038b58..aa5f6f60b30 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -58,8 +58,8 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
58 */ 58 */
59 wait_on_page_writeback(page); 59 wait_on_page_writeback(page);
60 60
61 if (PagePrivate(page)) 61 if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL))
62 try_to_release_page(page, GFP_KERNEL); 62 goto out_unlock;
63 63
64 /* 64 /*
65 * If we succeeded in removing the mapping, set LRU flag 65 * If we succeeded in removing the mapping, set LRU flag
@@ -75,6 +75,7 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
75 * Raced with truncate or failed to remove page from current 75 * Raced with truncate or failed to remove page from current
76 * address space, unlock and return failure. 76 * address space, unlock and return failure.
77 */ 77 */
78out_unlock:
78 unlock_page(page); 79 unlock_page(page);
79 return 1; 80 return 1;
80} 81}
@@ -983,7 +984,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
983 984
984 while (len) { 985 while (len) {
985 size_t read_len; 986 size_t read_len;
986 loff_t pos = sd->pos; 987 loff_t pos = sd->pos, prev_pos = pos;
987 988
988 ret = do_splice_to(in, &pos, pipe, len, flags); 989 ret = do_splice_to(in, &pos, pipe, len, flags);
989 if (unlikely(ret <= 0)) 990 if (unlikely(ret <= 0))
@@ -998,15 +999,19 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
998 * could get stuck data in the internal pipe: 999 * could get stuck data in the internal pipe:
999 */ 1000 */
1000 ret = actor(pipe, sd); 1001 ret = actor(pipe, sd);
1001 if (unlikely(ret <= 0)) 1002 if (unlikely(ret <= 0)) {
1003 sd->pos = prev_pos;
1002 goto out_release; 1004 goto out_release;
1005 }
1003 1006
1004 bytes += ret; 1007 bytes += ret;
1005 len -= ret; 1008 len -= ret;
1006 sd->pos = pos; 1009 sd->pos = pos;
1007 1010
1008 if (ret < read_len) 1011 if (ret < read_len) {
1012 sd->pos = prev_pos + ret;
1009 goto out_release; 1013 goto out_release;
1014 }
1010 } 1015 }
1011 1016
1012done: 1017done:
@@ -1072,7 +1077,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1072 1077
1073 ret = splice_direct_to_actor(in, &sd, direct_splice_actor); 1078 ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
1074 if (ret > 0) 1079 if (ret > 0)
1075 *ppos += ret; 1080 *ppos = sd.pos;
1076 1081
1077 return ret; 1082 return ret;
1078} 1083}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index a1c3a1fab7f..8c0e4b92574 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -419,12 +419,8 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
419 */ 419 */
420int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 420int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
421{ 421{
422 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) { 422 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
423 printk(KERN_WARNING "sysfs: duplicate filename '%s' "
424 "can not be created\n", sd->s_name);
425 WARN_ON(1);
426 return -EEXIST; 423 return -EEXIST;
427 }
428 424
429 sd->s_parent = sysfs_get(acxt->parent_sd); 425 sd->s_parent = sysfs_get(acxt->parent_sd);
430 426
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 7a5f69be6ac..44cc702f96c 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -682,38 +682,26 @@ static int udf_vrs(struct super_block *sb, int silent)
682/* 682/*
683 * Check whether there is an anchor block in the given block 683 * Check whether there is an anchor block in the given block
684 */ 684 */
685static int udf_check_anchor_block(struct super_block *sb, sector_t block, 685static int udf_check_anchor_block(struct super_block *sb, sector_t block)
686 bool varconv)
687{ 686{
688 struct buffer_head *bh = NULL; 687 struct buffer_head *bh;
689 tag *t;
690 uint16_t ident; 688 uint16_t ident;
691 uint32_t location;
692 689
693 if (varconv) { 690 if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
694 if (udf_fixed_to_variable(block) >= 691 udf_fixed_to_variable(block) >=
695 sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) 692 sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
696 return 0; 693 return 0;
697 bh = sb_bread(sb, udf_fixed_to_variable(block));
698 }
699 else
700 bh = sb_bread(sb, block);
701 694
695 bh = udf_read_tagged(sb, block, block, &ident);
702 if (!bh) 696 if (!bh)
703 return 0; 697 return 0;
704
705 t = (tag *)bh->b_data;
706 ident = le16_to_cpu(t->tagIdent);
707 location = le32_to_cpu(t->tagLocation);
708 brelse(bh); 698 brelse(bh);
709 if (ident != TAG_IDENT_AVDP) 699
710 return 0; 700 return ident == TAG_IDENT_AVDP;
711 return location == block;
712} 701}
713 702
714/* Search for an anchor volume descriptor pointer */ 703/* Search for an anchor volume descriptor pointer */
715static sector_t udf_scan_anchors(struct super_block *sb, bool varconv, 704static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock)
716 sector_t lastblock)
717{ 705{
718 sector_t last[6]; 706 sector_t last[6];
719 int i; 707 int i;
@@ -739,7 +727,7 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
739 sb->s_blocksize_bits) 727 sb->s_blocksize_bits)
740 continue; 728 continue;
741 729
742 if (udf_check_anchor_block(sb, last[i], varconv)) { 730 if (udf_check_anchor_block(sb, last[i])) {
743 sbi->s_anchor[0] = last[i]; 731 sbi->s_anchor[0] = last[i];
744 sbi->s_anchor[1] = last[i] - 256; 732 sbi->s_anchor[1] = last[i] - 256;
745 return last[i]; 733 return last[i];
@@ -748,17 +736,17 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
748 if (last[i] < 256) 736 if (last[i] < 256)
749 continue; 737 continue;
750 738
751 if (udf_check_anchor_block(sb, last[i] - 256, varconv)) { 739 if (udf_check_anchor_block(sb, last[i] - 256)) {
752 sbi->s_anchor[1] = last[i] - 256; 740 sbi->s_anchor[1] = last[i] - 256;
753 return last[i]; 741 return last[i];
754 } 742 }
755 } 743 }
756 744
757 if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) { 745 if (udf_check_anchor_block(sb, sbi->s_session + 256)) {
758 sbi->s_anchor[0] = sbi->s_session + 256; 746 sbi->s_anchor[0] = sbi->s_session + 256;
759 return last[0]; 747 return last[0];
760 } 748 }
761 if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) { 749 if (udf_check_anchor_block(sb, sbi->s_session + 512)) {
762 sbi->s_anchor[0] = sbi->s_session + 512; 750 sbi->s_anchor[0] = sbi->s_session + 512;
763 return last[0]; 751 return last[0];
764 } 752 }
@@ -780,23 +768,24 @@ static void udf_find_anchor(struct super_block *sb)
780 int i; 768 int i;
781 struct udf_sb_info *sbi = UDF_SB(sb); 769 struct udf_sb_info *sbi = UDF_SB(sb);
782 770
783 lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block); 771 lastblock = udf_scan_anchors(sb, sbi->s_last_block);
784 if (lastblock) 772 if (lastblock)
785 goto check_anchor; 773 goto check_anchor;
786 774
787 /* No anchor found? Try VARCONV conversion of block numbers */ 775 /* No anchor found? Try VARCONV conversion of block numbers */
776 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
788 /* Firstly, we try to not convert number of the last block */ 777 /* Firstly, we try to not convert number of the last block */
789 lastblock = udf_scan_anchors(sb, 1, 778 lastblock = udf_scan_anchors(sb,
790 udf_variable_to_fixed(sbi->s_last_block)); 779 udf_variable_to_fixed(sbi->s_last_block));
791 if (lastblock) { 780 if (lastblock)
792 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
793 goto check_anchor; 781 goto check_anchor;
794 }
795 782
796 /* Secondly, we try with converted number of the last block */ 783 /* Secondly, we try with converted number of the last block */
797 lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block); 784 lastblock = udf_scan_anchors(sb, sbi->s_last_block);
798 if (lastblock) 785 if (!lastblock) {
799 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); 786 /* VARCONV didn't help. Clear it. */
787 UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
788 }
800 789
801check_anchor: 790check_anchor:
802 /* 791 /*
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 8fa9c2d7091..8ec865de5f1 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -16,7 +16,7 @@
16#define UDF_PREALLOCATE 16#define UDF_PREALLOCATE
17#define UDF_DEFAULT_PREALLOC_BLOCKS 8 17#define UDF_DEFAULT_PREALLOC_BLOCKS 8
18 18
19#define UDFFS_DEBUG 19#undef UDFFS_DEBUG
20 20
21#ifdef UDFFS_DEBUG 21#ifdef UDFFS_DEBUG
22#define udf_debug(f, a...) \ 22#define udf_debug(f, a...) \
diff --git a/fs/utimes.c b/fs/utimes.c
index af059d5cb48..b6b664e7145 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -40,14 +40,9 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)
40 40
41#endif 41#endif
42 42
43static bool nsec_special(long nsec)
44{
45 return nsec == UTIME_OMIT || nsec == UTIME_NOW;
46}
47
48static bool nsec_valid(long nsec) 43static bool nsec_valid(long nsec)
49{ 44{
50 if (nsec_special(nsec)) 45 if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
51 return true; 46 return true;
52 47
53 return nsec >= 0 && nsec <= 999999999; 48 return nsec >= 0 && nsec <= 999999999;
@@ -102,7 +97,11 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
102 if (error) 97 if (error)
103 goto dput_and_out; 98 goto dput_and_out;
104 99
105 /* Don't worry, the checks are done in inode_change_ok() */ 100 if (times && times[0].tv_nsec == UTIME_NOW &&
101 times[1].tv_nsec == UTIME_NOW)
102 times = NULL;
103
104 /* In most cases, the checks are done in inode_change_ok() */
106 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; 105 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
107 if (times) { 106 if (times) {
108 error = -EPERM; 107 error = -EPERM;
@@ -124,28 +123,34 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
124 newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; 123 newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
125 newattrs.ia_valid |= ATTR_MTIME_SET; 124 newattrs.ia_valid |= ATTR_MTIME_SET;
126 } 125 }
127 }
128 126
129 /* 127 /*
130 * If times is NULL or both times are either UTIME_OMIT or 128 * For the UTIME_OMIT/UTIME_NOW and UTIME_NOW/UTIME_OMIT
131 * UTIME_NOW, then need to check permissions, because 129 * cases, we need to make an extra check that is not done by
132 * inode_change_ok() won't do it. 130 * inode_change_ok().
133 */ 131 */
134 if (!times || (nsec_special(times[0].tv_nsec) && 132 if (((times[0].tv_nsec == UTIME_NOW &&
135 nsec_special(times[1].tv_nsec))) { 133 times[1].tv_nsec == UTIME_OMIT)
134 ||
135 (times[0].tv_nsec == UTIME_OMIT &&
136 times[1].tv_nsec == UTIME_NOW))
137 && !is_owner_or_cap(inode))
138 goto mnt_drop_write_and_out;
139 } else {
140
141 /*
142 * If times is NULL (or both times are UTIME_NOW),
143 * then we need to check permissions, because
144 * inode_change_ok() won't do it.
145 */
136 error = -EACCES; 146 error = -EACCES;
137 if (IS_IMMUTABLE(inode)) 147 if (IS_IMMUTABLE(inode))
138 goto mnt_drop_write_and_out; 148 goto mnt_drop_write_and_out;
139 149
140 if (!is_owner_or_cap(inode)) { 150 if (!is_owner_or_cap(inode)) {
141 if (f) { 151 error = permission(inode, MAY_WRITE, NULL);
142 if (!(f->f_mode & FMODE_WRITE)) 152 if (error)
143 goto mnt_drop_write_and_out; 153 goto mnt_drop_write_and_out;
144 } else {
145 error = vfs_permission(&nd, MAY_WRITE);
146 if (error)
147 goto mnt_drop_write_and_out;
148 }
149 } 154 }
150 } 155 }
151 mutex_lock(&inode->i_mutex); 156 mutex_lock(&inode->i_mutex);
@@ -169,14 +174,6 @@ asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __
169 if (utimes) { 174 if (utimes) {
170 if (copy_from_user(&tstimes, utimes, sizeof(tstimes))) 175 if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
171 return -EFAULT; 176 return -EFAULT;
172 if ((tstimes[0].tv_nsec == UTIME_OMIT ||
173 tstimes[0].tv_nsec == UTIME_NOW) &&
174 tstimes[0].tv_sec != 0)
175 return -EINVAL;
176 if ((tstimes[1].tv_nsec == UTIME_OMIT ||
177 tstimes[1].tv_nsec == UTIME_NOW) &&
178 tstimes[1].tv_sec != 0)
179 return -EINVAL;
180 177
181 /* Nothing to do, we must not even check the path. */ 178 /* Nothing to do, we must not even check the path. */
182 if (tstimes[0].tv_nsec == UTIME_OMIT && 179 if (tstimes[0].tv_nsec == UTIME_OMIT &&
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 5105015a75a..98e0e86093b 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -387,6 +387,8 @@ _xfs_buf_lookup_pages(
387 if (unlikely(page == NULL)) { 387 if (unlikely(page == NULL)) {
388 if (flags & XBF_READ_AHEAD) { 388 if (flags & XBF_READ_AHEAD) {
389 bp->b_page_count = i; 389 bp->b_page_count = i;
390 for (i = 0; i < bp->b_page_count; i++)
391 unlock_page(bp->b_pages[i]);
390 return -ENOMEM; 392 return -ENOMEM;
391 } 393 }
392 394
@@ -416,17 +418,24 @@ _xfs_buf_lookup_pages(
416 ASSERT(!PagePrivate(page)); 418 ASSERT(!PagePrivate(page));
417 if (!PageUptodate(page)) { 419 if (!PageUptodate(page)) {
418 page_count--; 420 page_count--;
419 if (blocksize < PAGE_CACHE_SIZE && !PagePrivate(page)) { 421 if (blocksize >= PAGE_CACHE_SIZE) {
422 if (flags & XBF_READ)
423 bp->b_flags |= _XBF_PAGE_LOCKED;
424 } else if (!PagePrivate(page)) {
420 if (test_page_region(page, offset, nbytes)) 425 if (test_page_region(page, offset, nbytes))
421 page_count++; 426 page_count++;
422 } 427 }
423 } 428 }
424 429
425 unlock_page(page);
426 bp->b_pages[i] = page; 430 bp->b_pages[i] = page;
427 offset = 0; 431 offset = 0;
428 } 432 }
429 433
434 if (!(bp->b_flags & _XBF_PAGE_LOCKED)) {
435 for (i = 0; i < bp->b_page_count; i++)
436 unlock_page(bp->b_pages[i]);
437 }
438
430 if (page_count == bp->b_page_count) 439 if (page_count == bp->b_page_count)
431 bp->b_flags |= XBF_DONE; 440 bp->b_flags |= XBF_DONE;
432 441
@@ -746,6 +755,7 @@ xfs_buf_associate_memory(
746 bp->b_count_desired = len; 755 bp->b_count_desired = len;
747 bp->b_buffer_length = buflen; 756 bp->b_buffer_length = buflen;
748 bp->b_flags |= XBF_MAPPED; 757 bp->b_flags |= XBF_MAPPED;
758 bp->b_flags &= ~_XBF_PAGE_LOCKED;
749 759
750 return 0; 760 return 0;
751} 761}
@@ -1093,8 +1103,10 @@ _xfs_buf_ioend(
1093 xfs_buf_t *bp, 1103 xfs_buf_t *bp,
1094 int schedule) 1104 int schedule)
1095{ 1105{
1096 if (atomic_dec_and_test(&bp->b_io_remaining) == 1) 1106 if (atomic_dec_and_test(&bp->b_io_remaining) == 1) {
1107 bp->b_flags &= ~_XBF_PAGE_LOCKED;
1097 xfs_buf_ioend(bp, schedule); 1108 xfs_buf_ioend(bp, schedule);
1109 }
1098} 1110}
1099 1111
1100STATIC void 1112STATIC void
@@ -1125,6 +1137,9 @@ xfs_buf_bio_end_io(
1125 1137
1126 if (--bvec >= bio->bi_io_vec) 1138 if (--bvec >= bio->bi_io_vec)
1127 prefetchw(&bvec->bv_page->flags); 1139 prefetchw(&bvec->bv_page->flags);
1140
1141 if (bp->b_flags & _XBF_PAGE_LOCKED)
1142 unlock_page(page);
1128 } while (bvec >= bio->bi_io_vec); 1143 } while (bvec >= bio->bi_io_vec);
1129 1144
1130 _xfs_buf_ioend(bp, 1); 1145 _xfs_buf_ioend(bp, 1);
@@ -1163,7 +1178,8 @@ _xfs_buf_ioapply(
1163 * filesystem block size is not smaller than the page size. 1178 * filesystem block size is not smaller than the page size.
1164 */ 1179 */
1165 if ((bp->b_buffer_length < PAGE_CACHE_SIZE) && 1180 if ((bp->b_buffer_length < PAGE_CACHE_SIZE) &&
1166 (bp->b_flags & XBF_READ) && 1181 ((bp->b_flags & (XBF_READ|_XBF_PAGE_LOCKED)) ==
1182 (XBF_READ|_XBF_PAGE_LOCKED)) &&
1167 (blocksize >= PAGE_CACHE_SIZE)) { 1183 (blocksize >= PAGE_CACHE_SIZE)) {
1168 bio = bio_alloc(GFP_NOIO, 1); 1184 bio = bio_alloc(GFP_NOIO, 1);
1169 1185
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 841d7883528..f948ec7ba9a 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -66,6 +66,25 @@ typedef enum {
66 _XBF_PAGES = (1 << 18), /* backed by refcounted pages */ 66 _XBF_PAGES = (1 << 18), /* backed by refcounted pages */
67 _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */ 67 _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */
68 _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */ 68 _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */
69
70 /*
71 * Special flag for supporting metadata blocks smaller than a FSB.
72 *
73 * In this case we can have multiple xfs_buf_t on a single page and
74 * need to lock out concurrent xfs_buf_t readers as they only
75 * serialise access to the buffer.
76 *
77 * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation
78 * between reads of the page. Hence we can have one thread read the
79 * page and modify it, but then race with another thread that thinks
80 * the page is not up-to-date and hence reads it again.
81 *
82 * The result is that the first modifcation to the page is lost.
83 * This sort of AGF/AGI reading race can happen when unlinking inodes
84 * that require truncation and results in the AGI unlinked list
85 * modifications being lost.
86 */
87 _XBF_PAGE_LOCKED = (1 << 22),
69} xfs_buf_flags_t; 88} xfs_buf_flags_t;
70 89
71typedef enum { 90typedef enum {
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 65e78c13d4a..5f60363b934 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -184,19 +184,24 @@ xfs_file_release(
184 return -xfs_release(XFS_I(inode)); 184 return -xfs_release(XFS_I(inode));
185} 185}
186 186
187/*
188 * We ignore the datasync flag here because a datasync is effectively
189 * identical to an fsync. That is, datasync implies that we need to write
190 * only the metadata needed to be able to access the data that is written
191 * if we crash after the call completes. Hence if we are writing beyond
192 * EOF we have to log the inode size change as well, which makes it a
193 * full fsync. If we don't write beyond EOF, the inode core will be
194 * clean in memory and so we don't need to log the inode, just like
195 * fsync.
196 */
187STATIC int 197STATIC int
188xfs_file_fsync( 198xfs_file_fsync(
189 struct file *filp, 199 struct file *filp,
190 struct dentry *dentry, 200 struct dentry *dentry,
191 int datasync) 201 int datasync)
192{ 202{
193 int flags = FSYNC_WAIT;
194
195 if (datasync)
196 flags |= FSYNC_DATA;
197 xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED); 203 xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED);
198 return -xfs_fsync(XFS_I(dentry->d_inode), flags, 204 return -xfs_fsync(XFS_I(dentry->d_inode));
199 (xfs_off_t)0, (xfs_off_t)-1);
200} 205}
201 206
202/* 207/*
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 9d73cb5c0fc..25eb2a9e8d9 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -230,14 +230,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
230#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ 230#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
231 231
232/* 232/*
233 * Flags to vop_fsync/reclaim.
234 */
235#define FSYNC_NOWAIT 0 /* asynchronous flush */
236#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */
237#define FSYNC_INVAL 0x2 /* flush and invalidate cached data */
238#define FSYNC_DATA 0x4 /* synchronous fsync of data only */
239
240/*
241 * Tracking vnode activity. 233 * Tracking vnode activity.
242 */ 234 */
243#if defined(XFS_INODE_TRACE) 235#if defined(XFS_INODE_TRACE)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index cf0bb9c1d62..e569bf5d6cf 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2974,6 +2974,7 @@ xfs_iflush_cluster(
2974 xfs_mount_t *mp = ip->i_mount; 2974 xfs_mount_t *mp = ip->i_mount;
2975 xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino); 2975 xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino);
2976 unsigned long first_index, mask; 2976 unsigned long first_index, mask;
2977 unsigned long inodes_per_cluster;
2977 int ilist_size; 2978 int ilist_size;
2978 xfs_inode_t **ilist; 2979 xfs_inode_t **ilist;
2979 xfs_inode_t *iq; 2980 xfs_inode_t *iq;
@@ -2985,8 +2986,9 @@ xfs_iflush_cluster(
2985 ASSERT(pag->pagi_inodeok); 2986 ASSERT(pag->pagi_inodeok);
2986 ASSERT(pag->pag_ici_init); 2987 ASSERT(pag->pag_ici_init);
2987 2988
2988 ilist_size = XFS_INODE_CLUSTER_SIZE(mp) * sizeof(xfs_inode_t *); 2989 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog;
2989 ilist = kmem_alloc(ilist_size, KM_MAYFAIL); 2990 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
2991 ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS);
2990 if (!ilist) 2992 if (!ilist)
2991 return 0; 2993 return 0;
2992 2994
@@ -2995,8 +2997,7 @@ xfs_iflush_cluster(
2995 read_lock(&pag->pag_ici_lock); 2997 read_lock(&pag->pag_ici_lock);
2996 /* really need a gang lookup range call here */ 2998 /* really need a gang lookup range call here */
2997 nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist, 2999 nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist,
2998 first_index, 3000 first_index, inodes_per_cluster);
2999 XFS_INODE_CLUSTER_SIZE(mp));
3000 if (nr_found == 0) 3001 if (nr_found == 0)
3001 goto out_free; 3002 goto out_free;
3002 3003
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 70702a60b4b..e475e3717eb 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -856,18 +856,14 @@ xfs_readlink(
856/* 856/*
857 * xfs_fsync 857 * xfs_fsync
858 * 858 *
859 * This is called to sync the inode and its data out to disk. 859 * This is called to sync the inode and its data out to disk. We need to hold
860 * We need to hold the I/O lock while flushing the data, and 860 * the I/O lock while flushing the data, and the inode lock while flushing the
861 * the inode lock while flushing the inode. The inode lock CANNOT 861 * inode. The inode lock CANNOT be held while flushing the data, so acquire
862 * be held while flushing the data, so acquire after we're done 862 * after we're done with that.
863 * with that.
864 */ 863 */
865int 864int
866xfs_fsync( 865xfs_fsync(
867 xfs_inode_t *ip, 866 xfs_inode_t *ip)
868 int flag,
869 xfs_off_t start,
870 xfs_off_t stop)
871{ 867{
872 xfs_trans_t *tp; 868 xfs_trans_t *tp;
873 int error; 869 int error;
@@ -875,103 +871,79 @@ xfs_fsync(
875 871
876 xfs_itrace_entry(ip); 872 xfs_itrace_entry(ip);
877 873
878 ASSERT(start >= 0 && stop >= -1);
879
880 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 874 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
881 return XFS_ERROR(EIO); 875 return XFS_ERROR(EIO);
882 876
883 if (flag & FSYNC_DATA) 877 /* capture size updates in I/O completion before writing the inode. */
884 filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping); 878 error = filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping);
879 if (error)
880 return XFS_ERROR(error);
885 881
886 /* 882 /*
887 * We always need to make sure that the required inode state 883 * We always need to make sure that the required inode state is safe on
888 * is safe on disk. The vnode might be clean but because 884 * disk. The vnode might be clean but we still might need to force the
889 * of committed transactions that haven't hit the disk yet. 885 * log because of committed transactions that haven't hit the disk yet.
890 * Likewise, there could be unflushed non-transactional 886 * Likewise, there could be unflushed non-transactional changes to the
891 * changes to the inode core that have to go to disk. 887 * inode core that have to go to disk and this requires us to issue
888 * a synchronous transaction to capture these changes correctly.
892 * 889 *
893 * The following code depends on one assumption: that 890 * This code relies on the assumption that if the update_* fields
894 * any transaction that changes an inode logs the core 891 * of the inode are clear and the inode is unpinned then it is clean
895 * because it has to change some field in the inode core 892 * and no action is required.
896 * (typically nextents or nblocks). That assumption
897 * implies that any transactions against an inode will
898 * catch any non-transactional updates. If inode-altering
899 * transactions exist that violate this assumption, the
900 * code breaks. Right now, it figures that if the involved
901 * update_* field is clear and the inode is unpinned, the
902 * inode is clean. Either it's been flushed or it's been
903 * committed and the commit has hit the disk unpinning the inode.
904 * (Note that xfs_inode_item_format() called at commit clears
905 * the update_* fields.)
906 */ 893 */
907 xfs_ilock(ip, XFS_ILOCK_SHARED); 894 xfs_ilock(ip, XFS_ILOCK_SHARED);
908 895
909 /* If we are flushing data then we care about update_size 896 if (!(ip->i_update_size || ip->i_update_core)) {
910 * being set, otherwise we care about update_core
911 */
912 if ((flag & FSYNC_DATA) ?
913 (ip->i_update_size == 0) :
914 (ip->i_update_core == 0)) {
915 /* 897 /*
916 * Timestamps/size haven't changed since last inode 898 * Timestamps/size haven't changed since last inode flush or
917 * flush or inode transaction commit. That means 899 * inode transaction commit. That means either nothing got
918 * either nothing got written or a transaction 900 * written or a transaction committed which caught the updates.
919 * committed which caught the updates. If the 901 * If the latter happened and the transaction hasn't hit the
920 * latter happened and the transaction hasn't 902 * disk yet, the inode will be still be pinned. If it is,
921 * hit the disk yet, the inode will be still 903 * force the log.
922 * be pinned. If it is, force the log.
923 */ 904 */
924 905
925 xfs_iunlock(ip, XFS_ILOCK_SHARED); 906 xfs_iunlock(ip, XFS_ILOCK_SHARED);
926 907
927 if (xfs_ipincount(ip)) { 908 if (xfs_ipincount(ip)) {
928 _xfs_log_force(ip->i_mount, (xfs_lsn_t)0, 909 error = _xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
929 XFS_LOG_FORCE | 910 XFS_LOG_FORCE | XFS_LOG_SYNC,
930 ((flag & FSYNC_WAIT)
931 ? XFS_LOG_SYNC : 0),
932 &log_flushed); 911 &log_flushed);
933 } else { 912 } else {
934 /* 913 /*
935 * If the inode is not pinned and nothing 914 * If the inode is not pinned and nothing has changed
936 * has changed we don't need to flush the 915 * we don't need to flush the cache.
937 * cache.
938 */ 916 */
939 changed = 0; 917 changed = 0;
940 } 918 }
941 error = 0;
942 } else { 919 } else {
943 /* 920 /*
944 * Kick off a transaction to log the inode 921 * Kick off a transaction to log the inode core to get the
945 * core to get the updates. Make it 922 * updates. The sync transaction will also force the log.
946 * sync if FSYNC_WAIT is passed in (which
947 * is done by everybody but specfs). The
948 * sync transaction will also force the log.
949 */ 923 */
950 xfs_iunlock(ip, XFS_ILOCK_SHARED); 924 xfs_iunlock(ip, XFS_ILOCK_SHARED);
951 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS); 925 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
952 if ((error = xfs_trans_reserve(tp, 0, 926 error = xfs_trans_reserve(tp, 0,
953 XFS_FSYNC_TS_LOG_RES(ip->i_mount), 927 XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
954 0, 0, 0))) { 928 if (error) {
955 xfs_trans_cancel(tp, 0); 929 xfs_trans_cancel(tp, 0);
956 return error; 930 return error;
957 } 931 }
958 xfs_ilock(ip, XFS_ILOCK_EXCL); 932 xfs_ilock(ip, XFS_ILOCK_EXCL);
959 933
960 /* 934 /*
961 * Note - it's possible that we might have pushed 935 * Note - it's possible that we might have pushed ourselves out
962 * ourselves out of the way during trans_reserve 936 * of the way during trans_reserve which would flush the inode.
963 * which would flush the inode. But there's no 937 * But there's no guarantee that the inode buffer has actually
964 * guarantee that the inode buffer has actually 938 * gone out yet (it's delwri). Plus the buffer could be pinned
965 * gone out yet (it's delwri). Plus the buffer 939 * anyway if it's part of an inode in another recent
966 * could be pinned anyway if it's part of an 940 * transaction. So we play it safe and fire off the
967 * inode in another recent transaction. So we 941 * transaction anyway.
968 * play it safe and fire off the transaction anyway.
969 */ 942 */
970 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 943 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
971 xfs_trans_ihold(tp, ip); 944 xfs_trans_ihold(tp, ip);
972 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 945 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
973 if (flag & FSYNC_WAIT) 946 xfs_trans_set_sync(tp);
974 xfs_trans_set_sync(tp);
975 error = _xfs_trans_commit(tp, 0, &log_flushed); 947 error = _xfs_trans_commit(tp, 0, &log_flushed);
976 948
977 xfs_iunlock(ip, XFS_ILOCK_EXCL); 949 xfs_iunlock(ip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 8abe8f186e2..57335ba4ce5 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -18,8 +18,7 @@ int xfs_open(struct xfs_inode *ip);
18int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, 18int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags,
19 struct cred *credp); 19 struct cred *credp);
20int xfs_readlink(struct xfs_inode *ip, char *link); 20int xfs_readlink(struct xfs_inode *ip, char *link);
21int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start, 21int xfs_fsync(struct xfs_inode *ip);
22 xfs_off_t stop);
23int xfs_release(struct xfs_inode *ip); 22int xfs_release(struct xfs_inode *ip);
24int xfs_inactive(struct xfs_inode *ip); 23int xfs_inactive(struct xfs_inode *ip);
25int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, 24int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,