diff options
Diffstat (limited to 'fs')
171 files changed, 3090 insertions, 1838 deletions
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index bed48fa96521..3128aa948a4e 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/file.h> | 29 | #include <linux/file.h> |
30 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/inet.h> | 32 | #include <linux/inet.h> |
34 | #include <linux/pagemap.h> | 33 | #include <linux/pagemap.h> |
35 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index ddffd8aa902d..775e26e82cbc 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
31 | #include <linux/stat.h> | 31 | #include <linux/stat.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
35 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
36 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 3129688143ea..1dd86ee90bc5 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/file.h> | 29 | #include <linux/file.h> |
30 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
34 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
35 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index c7b677253843..6e7678e4852f 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/file.h> | 30 | #include <linux/file.h> |
31 | #include <linux/stat.h> | 31 | #include <linux/stat.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
35 | #include <linux/list.h> | 34 | #include <linux/list.h> |
36 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index b01b0a457932..7624821729a0 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
31 | #include <linux/stat.h> | 31 | #include <linux/stat.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
35 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
36 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 0ec42f665457..8eb9263a67b9 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/file.h> | 31 | #include <linux/file.h> |
32 | #include <linux/stat.h> | 32 | #include <linux/stat.h> |
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/inet.h> | 34 | #include <linux/inet.h> |
36 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
37 | #include <linux/seq_file.h> | 36 | #include <linux/seq_file.h> |
diff --git a/fs/Kconfig b/fs/Kconfig index 8ea7b04c661f..4622dabb2253 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -314,7 +314,7 @@ config REISERFS_CHECK | |||
314 | 314 | ||
315 | config REISERFS_PROC_INFO | 315 | config REISERFS_PROC_INFO |
316 | bool "Stats in /proc/fs/reiserfs" | 316 | bool "Stats in /proc/fs/reiserfs" |
317 | depends on REISERFS_FS | 317 | depends on REISERFS_FS && PROC_FS |
318 | help | 318 | help |
319 | Create under /proc/fs/reiserfs a hierarchy of files, displaying | 319 | Create under /proc/fs/reiserfs a hierarchy of files, displaying |
320 | various ReiserFS statistics and internal data at the expense of | 320 | various ReiserFS statistics and internal data at the expense of |
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/time.h> | 9 | #include <linux/time.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
14 | #include <linux/fsnotify.h> | 13 | #include <linux/fsnotify.h> |
15 | #include <linux/fcntl.h> | 14 | #include <linux/fcntl.h> |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 26063dc84a2a..5769a2f9ad60 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/parser.h> | 19 | #include <linux/parser.h> |
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/magic.h> | 21 | #include <linux/magic.h> |
23 | #include "autofs_i.h" | 22 | #include "autofs_i.h" |
24 | #include <linux/module.h> | 23 | #include <linux/module.h> |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index d0e9b3a3905d..15170f4e13a7 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/stat.h> | 17 | #include <linux/stat.h> |
18 | #include <linux/param.h> | 18 | #include <linux/param.h> |
19 | #include <linux/time.h> | 19 | #include <linux/time.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include "autofs_i.h" | 20 | #include "autofs_i.h" |
22 | 21 | ||
23 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); | 22 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index efeab2fab40b..329ee473eede 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/stat.h> | 13 | #include <linux/stat.h> |
14 | #include <linux/time.h> | 14 | #include <linux/time.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/namei.h> | 15 | #include <linux/namei.h> |
17 | #include <linux/poll.h> | 16 | #include <linux/poll.h> |
18 | 17 | ||
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 9cc4f0a8aaae..fa8ea33ab0be 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/highuid.h> | 32 | #include <linux/highuid.h> |
33 | #include <linux/smp.h> | 33 | #include <linux/smp.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/compiler.h> | 34 | #include <linux/compiler.h> |
36 | #include <linux/highmem.h> | 35 | #include <linux/highmem.h> |
37 | #include <linux/pagemap.h> | 36 | #include <linux/pagemap.h> |
@@ -39,6 +38,7 @@ | |||
39 | #include <linux/syscalls.h> | 38 | #include <linux/syscalls.h> |
40 | #include <linux/random.h> | 39 | #include <linux/random.h> |
41 | #include <linux/elf.h> | 40 | #include <linux/elf.h> |
41 | #include <linux/utsname.h> | ||
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | #include <asm/param.h> | 43 | #include <asm/param.h> |
44 | #include <asm/page.h> | 44 | #include <asm/page.h> |
@@ -871,6 +871,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
871 | elf_prot, elf_flags); | 871 | elf_prot, elf_flags); |
872 | if (BAD_ADDR(error)) { | 872 | if (BAD_ADDR(error)) { |
873 | send_sig(SIGKILL, current, 0); | 873 | send_sig(SIGKILL, current, 0); |
874 | retval = IS_ERR((void *)error) ? | ||
875 | PTR_ERR((void*)error) : -EINVAL; | ||
874 | goto out_free_dentry; | 876 | goto out_free_dentry; |
875 | } | 877 | } |
876 | 878 | ||
@@ -900,6 +902,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
900 | TASK_SIZE - elf_ppnt->p_memsz < k) { | 902 | TASK_SIZE - elf_ppnt->p_memsz < k) { |
901 | /* set_brk can never work. Avoid overflows. */ | 903 | /* set_brk can never work. Avoid overflows. */ |
902 | send_sig(SIGKILL, current, 0); | 904 | send_sig(SIGKILL, current, 0); |
905 | retval = -EINVAL; | ||
903 | goto out_free_dentry; | 906 | goto out_free_dentry; |
904 | } | 907 | } |
905 | 908 | ||
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index f3ddca4a387b..9d62fbad3d4b 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/personality.h> | 30 | #include <linux/personality.h> |
31 | #include <linux/ptrace.h> | 31 | #include <linux/ptrace.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/elf.h> | 33 | #include <linux/elf.h> |
35 | #include <linux/elf-fdpic.h> | 34 | #include <linux/elf-fdpic.h> |
36 | #include <linux/elfcore.h> | 35 | #include <linux/elfcore.h> |
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c index 1f2d1ad63319..576dd7de2278 100644 --- a/fs/binfmt_em86.c +++ b/fs/binfmt_em86.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/stat.h> | 13 | #include <linux/stat.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/binfmts.h> | 15 | #include <linux/binfmts.h> |
17 | #include <linux/elf.h> | 16 | #include <linux/elf.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index e6f57990b121..18657f001b43 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -727,8 +727,8 @@ static const struct super_operations s_ops = { | |||
727 | static int bm_fill_super(struct super_block * sb, void * data, int silent) | 727 | static int bm_fill_super(struct super_block * sb, void * data, int silent) |
728 | { | 728 | { |
729 | static struct tree_descr bm_files[] = { | 729 | static struct tree_descr bm_files[] = { |
730 | [1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, | 730 | [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, |
731 | [2] = {"register", &bm_register_operations, S_IWUSR}, | 731 | [3] = {"register", &bm_register_operations, S_IWUSR}, |
732 | /* last one */ {""} | 732 | /* last one */ {""} |
733 | }; | 733 | }; |
734 | int err = simple_fill_super(sb, 0x42494e4d, bm_files); | 734 | int err = simple_fill_super(sb, 0x42494e4d, bm_files); |
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c index 1edbcca25a73..304c88544d89 100644 --- a/fs/binfmt_script.c +++ b/fs/binfmt_script.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/binfmts.h> | 12 | #include <linux/binfmts.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/file.h> | 14 | #include <linux/file.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/err.h> | 15 | #include <linux/err.h> |
17 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
18 | 17 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index f02b7bdd9864..742899240872 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/mount.h> | 22 | #include <linux/mount.h> |
23 | #include <linux/uio.h> | 23 | #include <linux/uio.h> |
24 | #include <linux/namei.h> | 24 | #include <linux/namei.h> |
25 | #include <linux/log2.h> | ||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | #include "internal.h" | 27 | #include "internal.h" |
27 | 28 | ||
@@ -67,7 +68,7 @@ static void kill_bdev(struct block_device *bdev) | |||
67 | int set_blocksize(struct block_device *bdev, int size) | 68 | int set_blocksize(struct block_device *bdev, int size) |
68 | { | 69 | { |
69 | /* Size must be a power of two, and between 512 and PAGE_SIZE */ | 70 | /* Size must be a power of two, and between 512 and PAGE_SIZE */ |
70 | if (size > PAGE_SIZE || size < 512 || (size & (size-1))) | 71 | if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size)) |
71 | return -EINVAL; | 72 | return -EINVAL; |
72 | 73 | ||
73 | /* Size cannot be smaller than the size supported by the device */ | 74 | /* Size cannot be smaller than the size supported by the device */ |
diff --git a/fs/buffer.c b/fs/buffer.c index 7db24b9e5449..eb820b82a636 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/percpu.h> | 25 | #include <linux/percpu.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include <linux/capability.h> | 27 | #include <linux/capability.h> |
29 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
30 | #include <linux/file.h> | 29 | #include <linux/file.h> |
@@ -1727,6 +1726,7 @@ recover: | |||
1727 | } while ((bh = bh->b_this_page) != head); | 1726 | } while ((bh = bh->b_this_page) != head); |
1728 | SetPageError(page); | 1727 | SetPageError(page); |
1729 | BUG_ON(PageWriteback(page)); | 1728 | BUG_ON(PageWriteback(page)); |
1729 | mapping_set_error(page->mapping, err); | ||
1730 | set_page_writeback(page); | 1730 | set_page_writeback(page); |
1731 | do { | 1731 | do { |
1732 | struct buffer_head *next = bh->b_this_page; | 1732 | struct buffer_head *next = bh->b_this_page; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b570530f97bf..94d5b49049df 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/fcntl.h> | 27 | #include <linux/fcntl.h> |
28 | #include <linux/pagemap.h> | 28 | #include <linux/pagemap.h> |
29 | #include <linux/pagevec.h> | 29 | #include <linux/pagevec.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/writeback.h> | 30 | #include <linux/writeback.h> |
32 | #include <linux/task_io_accounting_ops.h> | 31 | #include <linux/task_io_accounting_ops.h> |
33 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b5364f90d551..c08bda9fcac6 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/pagemap.h> | 24 | #include <linux/pagemap.h> |
25 | #include <linux/stat.h> | 25 | #include <linux/stat.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include "cifspdu.h" | 26 | #include "cifspdu.h" |
28 | #include "cifsglob.h" | 27 | #include "cifsglob.h" |
29 | #include "cifsproto.h" | 28 | #include "cifsproto.h" |
diff --git a/fs/compat.c b/fs/compat.c index 72e5e6923828..9cf75df9b2bb 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * published by the Free Software Foundation. | 15 | * published by the Free Software Foundation. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/kernel.h> | ||
18 | #include <linux/linkage.h> | 19 | #include <linux/linkage.h> |
19 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
20 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
@@ -24,10 +25,8 @@ | |||
24 | #include <linux/namei.h> | 25 | #include <linux/namei.h> |
25 | #include <linux/file.h> | 26 | #include <linux/file.h> |
26 | #include <linux/vfs.h> | 27 | #include <linux/vfs.h> |
27 | #include <linux/ioctl32.h> | ||
28 | #include <linux/ioctl.h> | 28 | #include <linux/ioctl.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/sockios.h> /* for SIOCDEVPRIVATE */ | ||
31 | #include <linux/smb.h> | 30 | #include <linux/smb.h> |
32 | #include <linux/smb_mount.h> | 31 | #include <linux/smb_mount.h> |
33 | #include <linux/ncp_mount.h> | 32 | #include <linux/ncp_mount.h> |
@@ -45,13 +44,12 @@ | |||
45 | #include <linux/personality.h> | 44 | #include <linux/personality.h> |
46 | #include <linux/rwsem.h> | 45 | #include <linux/rwsem.h> |
47 | #include <linux/tsacct_kern.h> | 46 | #include <linux/tsacct_kern.h> |
47 | #include <linux/security.h> | ||
48 | #include <linux/highmem.h> | 48 | #include <linux/highmem.h> |
49 | #include <linux/poll.h> | 49 | #include <linux/poll.h> |
50 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
51 | #include <linux/eventpoll.h> | 51 | #include <linux/eventpoll.h> |
52 | 52 | ||
53 | #include <net/sock.h> /* siocdevprivate_ioctl */ | ||
54 | |||
55 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
56 | #include <asm/mmu_context.h> | 54 | #include <asm/mmu_context.h> |
57 | #include <asm/ioctls.h> | 55 | #include <asm/ioctls.h> |
@@ -79,30 +77,57 @@ int compat_printk(const char *fmt, ...) | |||
79 | */ | 77 | */ |
80 | asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t) | 78 | asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t) |
81 | { | 79 | { |
82 | struct timeval tv[2]; | 80 | struct timespec tv[2]; |
83 | 81 | ||
84 | if (t) { | 82 | if (t) { |
85 | if (get_user(tv[0].tv_sec, &t->actime) || | 83 | if (get_user(tv[0].tv_sec, &t->actime) || |
86 | get_user(tv[1].tv_sec, &t->modtime)) | 84 | get_user(tv[1].tv_sec, &t->modtime)) |
87 | return -EFAULT; | 85 | return -EFAULT; |
88 | tv[0].tv_usec = 0; | 86 | tv[0].tv_nsec = 0; |
89 | tv[1].tv_usec = 0; | 87 | tv[1].tv_nsec = 0; |
88 | } | ||
89 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0); | ||
90 | } | ||
91 | |||
92 | asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, struct compat_timespec __user *t, int flags) | ||
93 | { | ||
94 | struct timespec tv[2]; | ||
95 | |||
96 | if (t) { | ||
97 | if (get_compat_timespec(&tv[0], &t[0]) || | ||
98 | get_compat_timespec(&tv[1], &t[1])) | ||
99 | return -EFAULT; | ||
100 | |||
101 | if ((tv[0].tv_nsec == UTIME_OMIT || tv[0].tv_nsec == UTIME_NOW) | ||
102 | && tv[0].tv_sec != 0) | ||
103 | return -EINVAL; | ||
104 | if ((tv[1].tv_nsec == UTIME_OMIT || tv[1].tv_nsec == UTIME_NOW) | ||
105 | && tv[1].tv_sec != 0) | ||
106 | return -EINVAL; | ||
107 | |||
108 | if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) | ||
109 | return 0; | ||
90 | } | 110 | } |
91 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL); | 111 | return do_utimes(dfd, filename, t ? tv : NULL, flags); |
92 | } | 112 | } |
93 | 113 | ||
94 | asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t) | 114 | asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t) |
95 | { | 115 | { |
96 | struct timeval tv[2]; | 116 | struct timespec tv[2]; |
97 | 117 | ||
98 | if (t) { | 118 | if (t) { |
99 | if (get_user(tv[0].tv_sec, &t[0].tv_sec) || | 119 | if (get_user(tv[0].tv_sec, &t[0].tv_sec) || |
100 | get_user(tv[0].tv_usec, &t[0].tv_usec) || | 120 | get_user(tv[0].tv_nsec, &t[0].tv_usec) || |
101 | get_user(tv[1].tv_sec, &t[1].tv_sec) || | 121 | get_user(tv[1].tv_sec, &t[1].tv_sec) || |
102 | get_user(tv[1].tv_usec, &t[1].tv_usec)) | 122 | get_user(tv[1].tv_nsec, &t[1].tv_usec)) |
103 | return -EFAULT; | 123 | return -EFAULT; |
124 | if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 || | ||
125 | tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0) | ||
126 | return -EINVAL; | ||
127 | tv[0].tv_nsec *= 1000; | ||
128 | tv[1].tv_nsec *= 1000; | ||
104 | } | 129 | } |
105 | return do_utimes(dfd, filename, t ? tv : NULL); | 130 | return do_utimes(dfd, filename, t ? tv : NULL, 0); |
106 | } | 131 | } |
107 | 132 | ||
108 | asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t) | 133 | asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t) |
@@ -312,163 +337,6 @@ out: | |||
312 | return error; | 337 | return error; |
313 | } | 338 | } |
314 | 339 | ||
315 | /* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64, MIPS */ | ||
316 | |||
317 | #define IOCTL_HASHSIZE 256 | ||
318 | static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; | ||
319 | |||
320 | static inline unsigned long ioctl32_hash(unsigned long cmd) | ||
321 | { | ||
322 | return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; | ||
323 | } | ||
324 | |||
325 | static void ioctl32_insert_translation(struct ioctl_trans *trans) | ||
326 | { | ||
327 | unsigned long hash; | ||
328 | struct ioctl_trans *t; | ||
329 | |||
330 | hash = ioctl32_hash (trans->cmd); | ||
331 | if (!ioctl32_hash_table[hash]) | ||
332 | ioctl32_hash_table[hash] = trans; | ||
333 | else { | ||
334 | t = ioctl32_hash_table[hash]; | ||
335 | while (t->next) | ||
336 | t = t->next; | ||
337 | trans->next = NULL; | ||
338 | t->next = trans; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | static int __init init_sys32_ioctl(void) | ||
343 | { | ||
344 | int i; | ||
345 | |||
346 | for (i = 0; i < ioctl_table_size; i++) { | ||
347 | if (ioctl_start[i].next != 0) { | ||
348 | printk("ioctl translation %d bad\n",i); | ||
349 | return -1; | ||
350 | } | ||
351 | |||
352 | ioctl32_insert_translation(&ioctl_start[i]); | ||
353 | } | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | __initcall(init_sys32_ioctl); | ||
358 | |||
359 | static void compat_ioctl_error(struct file *filp, unsigned int fd, | ||
360 | unsigned int cmd, unsigned long arg) | ||
361 | { | ||
362 | char buf[10]; | ||
363 | char *fn = "?"; | ||
364 | char *path; | ||
365 | |||
366 | /* find the name of the device. */ | ||
367 | path = (char *)__get_free_page(GFP_KERNEL); | ||
368 | if (path) { | ||
369 | fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE); | ||
370 | if (IS_ERR(fn)) | ||
371 | fn = "?"; | ||
372 | } | ||
373 | |||
374 | sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK); | ||
375 | if (!isprint(buf[1])) | ||
376 | sprintf(buf, "%02x", buf[1]); | ||
377 | compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) " | ||
378 | "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n", | ||
379 | current->comm, current->pid, | ||
380 | (int)fd, (unsigned int)cmd, buf, | ||
381 | (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK, | ||
382 | (unsigned int)arg, fn); | ||
383 | |||
384 | if (path) | ||
385 | free_page((unsigned long)path); | ||
386 | } | ||
387 | |||
388 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | ||
389 | unsigned long arg) | ||
390 | { | ||
391 | struct file *filp; | ||
392 | int error = -EBADF; | ||
393 | struct ioctl_trans *t; | ||
394 | int fput_needed; | ||
395 | |||
396 | filp = fget_light(fd, &fput_needed); | ||
397 | if (!filp) | ||
398 | goto out; | ||
399 | |||
400 | /* RED-PEN how should LSM module know it's handling 32bit? */ | ||
401 | error = security_file_ioctl(filp, cmd, arg); | ||
402 | if (error) | ||
403 | goto out_fput; | ||
404 | |||
405 | /* | ||
406 | * To allow the compat_ioctl handlers to be self contained | ||
407 | * we need to check the common ioctls here first. | ||
408 | * Just handle them with the standard handlers below. | ||
409 | */ | ||
410 | switch (cmd) { | ||
411 | case FIOCLEX: | ||
412 | case FIONCLEX: | ||
413 | case FIONBIO: | ||
414 | case FIOASYNC: | ||
415 | case FIOQSIZE: | ||
416 | break; | ||
417 | |||
418 | case FIBMAP: | ||
419 | case FIGETBSZ: | ||
420 | case FIONREAD: | ||
421 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | ||
422 | break; | ||
423 | /*FALL THROUGH*/ | ||
424 | |||
425 | default: | ||
426 | if (filp->f_op && filp->f_op->compat_ioctl) { | ||
427 | error = filp->f_op->compat_ioctl(filp, cmd, arg); | ||
428 | if (error != -ENOIOCTLCMD) | ||
429 | goto out_fput; | ||
430 | } | ||
431 | |||
432 | if (!filp->f_op || | ||
433 | (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl)) | ||
434 | goto do_ioctl; | ||
435 | break; | ||
436 | } | ||
437 | |||
438 | for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) { | ||
439 | if (t->cmd == cmd) | ||
440 | goto found_handler; | ||
441 | } | ||
442 | |||
443 | if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) && | ||
444 | cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { | ||
445 | error = siocdevprivate_ioctl(fd, cmd, arg); | ||
446 | } else { | ||
447 | static int count; | ||
448 | |||
449 | if (++count <= 50) | ||
450 | compat_ioctl_error(filp, fd, cmd, arg); | ||
451 | error = -EINVAL; | ||
452 | } | ||
453 | |||
454 | goto out_fput; | ||
455 | |||
456 | found_handler: | ||
457 | if (t->handler) { | ||
458 | lock_kernel(); | ||
459 | error = t->handler(fd, cmd, arg, filp); | ||
460 | unlock_kernel(); | ||
461 | goto out_fput; | ||
462 | } | ||
463 | |||
464 | do_ioctl: | ||
465 | error = vfs_ioctl(filp, fd, cmd, arg); | ||
466 | out_fput: | ||
467 | fput_light(filp, fput_needed); | ||
468 | out: | ||
469 | return error; | ||
470 | } | ||
471 | |||
472 | static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) | 340 | static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) |
473 | { | 341 | { |
474 | if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || | 342 | if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || |
@@ -902,8 +770,6 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | |||
902 | } | 770 | } |
903 | 771 | ||
904 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) | 772 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) |
905 | #define COMPAT_ROUND_UP(x) (((x)+sizeof(compat_long_t)-1) & \ | ||
906 | ~(sizeof(compat_long_t)-1)) | ||
907 | 773 | ||
908 | struct compat_old_linux_dirent { | 774 | struct compat_old_linux_dirent { |
909 | compat_ulong_t d_ino; | 775 | compat_ulong_t d_ino; |
@@ -991,7 +857,7 @@ static int compat_filldir(void *__buf, const char *name, int namlen, | |||
991 | struct compat_linux_dirent __user * dirent; | 857 | struct compat_linux_dirent __user * dirent; |
992 | struct compat_getdents_callback *buf = __buf; | 858 | struct compat_getdents_callback *buf = __buf; |
993 | compat_ulong_t d_ino; | 859 | compat_ulong_t d_ino; |
994 | int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); | 860 | int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(compat_long_t)); |
995 | 861 | ||
996 | buf->error = -EINVAL; /* only used if we fail.. */ | 862 | buf->error = -EINVAL; /* only used if we fail.. */ |
997 | if (reclen > buf->count) | 863 | if (reclen > buf->count) |
@@ -1066,7 +932,6 @@ out: | |||
1066 | } | 932 | } |
1067 | 933 | ||
1068 | #ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64 | 934 | #ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64 |
1069 | #define COMPAT_ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) | ||
1070 | 935 | ||
1071 | struct compat_getdents_callback64 { | 936 | struct compat_getdents_callback64 { |
1072 | struct linux_dirent64 __user *current_dir; | 937 | struct linux_dirent64 __user *current_dir; |
@@ -1081,7 +946,7 @@ static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t | |||
1081 | struct linux_dirent64 __user *dirent; | 946 | struct linux_dirent64 __user *dirent; |
1082 | struct compat_getdents_callback64 *buf = __buf; | 947 | struct compat_getdents_callback64 *buf = __buf; |
1083 | int jj = NAME_OFFSET(dirent); | 948 | int jj = NAME_OFFSET(dirent); |
1084 | int reclen = COMPAT_ROUND_UP64(jj + namlen + 1); | 949 | int reclen = ALIGN(jj + namlen + 1, sizeof(u64)); |
1085 | u64 off; | 950 | u64 off; |
1086 | 951 | ||
1087 | buf->error = -EINVAL; /* only used if we fail.. */ | 952 | buf->error = -EINVAL; /* only used if we fail.. */ |
@@ -1594,8 +1459,6 @@ out_ret: | |||
1594 | 1459 | ||
1595 | #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) | 1460 | #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) |
1596 | 1461 | ||
1597 | #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) | ||
1598 | |||
1599 | /* | 1462 | /* |
1600 | * Ooo, nasty. We need here to frob 32-bit unsigned longs to | 1463 | * Ooo, nasty. We need here to frob 32-bit unsigned longs to |
1601 | * 64-bit unsigned longs. | 1464 | * 64-bit unsigned longs. |
@@ -1604,7 +1467,7 @@ static | |||
1604 | int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | 1467 | int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, |
1605 | unsigned long *fdset) | 1468 | unsigned long *fdset) |
1606 | { | 1469 | { |
1607 | nr = ROUND_UP(nr, __COMPAT_NFDBITS); | 1470 | nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); |
1608 | if (ufdset) { | 1471 | if (ufdset) { |
1609 | unsigned long odd; | 1472 | unsigned long odd; |
1610 | 1473 | ||
@@ -1638,7 +1501,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1638 | unsigned long *fdset) | 1501 | unsigned long *fdset) |
1639 | { | 1502 | { |
1640 | unsigned long odd; | 1503 | unsigned long odd; |
1641 | nr = ROUND_UP(nr, __COMPAT_NFDBITS); | 1504 | nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); |
1642 | 1505 | ||
1643 | if (!ufdset) | 1506 | if (!ufdset) |
1644 | return 0; | 1507 | return 0; |
@@ -1760,7 +1623,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, | |||
1760 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) | 1623 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) |
1761 | timeout = -1; /* infinite */ | 1624 | timeout = -1; /* infinite */ |
1762 | else { | 1625 | else { |
1763 | timeout = ROUND_UP(tv.tv_usec, 1000000/HZ); | 1626 | timeout = DIV_ROUND_UP(tv.tv_usec, 1000000/HZ); |
1764 | timeout += tv.tv_sec * HZ; | 1627 | timeout += tv.tv_sec * HZ; |
1765 | } | 1628 | } |
1766 | } | 1629 | } |
@@ -1828,7 +1691,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, | |||
1828 | do { | 1691 | do { |
1829 | if (tsp) { | 1692 | if (tsp) { |
1830 | if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) { | 1693 | if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) { |
1831 | timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ); | 1694 | timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ); |
1832 | timeout += ts.tv_sec * (unsigned long)HZ; | 1695 | timeout += ts.tv_sec * (unsigned long)HZ; |
1833 | ts.tv_sec = 0; | 1696 | ts.tv_sec = 0; |
1834 | ts.tv_nsec = 0; | 1697 | ts.tv_nsec = 0; |
@@ -1924,7 +1787,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | |||
1924 | /* We assume that ts.tv_sec is always lower than | 1787 | /* We assume that ts.tv_sec is always lower than |
1925 | the number of seconds that can be expressed in | 1788 | the number of seconds that can be expressed in |
1926 | an s64. Otherwise the compiler bitches at us */ | 1789 | an s64. Otherwise the compiler bitches at us */ |
1927 | timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ); | 1790 | timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ); |
1928 | timeout += ts.tv_sec * HZ; | 1791 | timeout += ts.tv_sec * HZ; |
1929 | } | 1792 | } |
1930 | 1793 | ||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 464c04a9541d..d92bc3eb7afc 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/ioctl.h> | 20 | #include <linux/ioctl.h> |
22 | #include <linux/if.h> | 21 | #include <linux/if.h> |
23 | #include <linux/if_bridge.h> | 22 | #include <linux/if_bridge.h> |
@@ -58,7 +57,6 @@ | |||
58 | #include <linux/serial.h> | 57 | #include <linux/serial.h> |
59 | #include <linux/if_tun.h> | 58 | #include <linux/if_tun.h> |
60 | #include <linux/ctype.h> | 59 | #include <linux/ctype.h> |
61 | #include <linux/ioctl32.h> | ||
62 | #include <linux/syscalls.h> | 60 | #include <linux/syscalls.h> |
63 | #include <linux/i2c.h> | 61 | #include <linux/i2c.h> |
64 | #include <linux/i2c-dev.h> | 62 | #include <linux/i2c-dev.h> |
@@ -66,7 +64,6 @@ | |||
66 | #include <linux/atalk.h> | 64 | #include <linux/atalk.h> |
67 | #include <linux/blktrace_api.h> | 65 | #include <linux/blktrace_api.h> |
68 | 66 | ||
69 | #include <net/sock.h> /* siocdevprivate_ioctl */ | ||
70 | #include <net/bluetooth/bluetooth.h> | 67 | #include <net/bluetooth/bluetooth.h> |
71 | #include <net/bluetooth/hci.h> | 68 | #include <net/bluetooth/hci.h> |
72 | #include <net/bluetooth/rfcomm.h> | 69 | #include <net/bluetooth/rfcomm.h> |
@@ -475,7 +472,7 @@ static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
475 | }; | 472 | }; |
476 | } | 473 | } |
477 | 474 | ||
478 | int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | 475 | static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) |
479 | { | 476 | { |
480 | struct ifreq __user *u_ifreq64; | 477 | struct ifreq __user *u_ifreq64; |
481 | struct ifreq32 __user *u_ifreq32 = compat_ptr(arg); | 478 | struct ifreq32 __user *u_ifreq32 = compat_ptr(arg); |
@@ -687,8 +684,10 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
687 | if (!err) { | 684 | if (!err) { |
688 | err = copy_to_user (ugeo, &geo, 4); | 685 | err = copy_to_user (ugeo, &geo, 4); |
689 | err |= __put_user (geo.start, &ugeo->start); | 686 | err |= __put_user (geo.start, &ugeo->start); |
687 | if (err) | ||
688 | err = -EFAULT; | ||
690 | } | 689 | } |
691 | return err ? -EFAULT : 0; | 690 | return err; |
692 | } | 691 | } |
693 | 692 | ||
694 | static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 693 | static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) |
@@ -2385,6 +2384,16 @@ lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
2385 | return sys_ioctl(fd, cmd, (unsigned long)tn); | 2384 | return sys_ioctl(fd, cmd, (unsigned long)tn); |
2386 | } | 2385 | } |
2387 | 2386 | ||
2387 | |||
2388 | typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int, | ||
2389 | unsigned long, struct file *); | ||
2390 | |||
2391 | struct ioctl_trans { | ||
2392 | unsigned long cmd; | ||
2393 | ioctl_trans_handler_t handler; | ||
2394 | struct ioctl_trans *next; | ||
2395 | }; | ||
2396 | |||
2388 | #define HANDLE_IOCTL(cmd,handler) \ | 2397 | #define HANDLE_IOCTL(cmd,handler) \ |
2389 | { (cmd), (ioctl_trans_handler_t)(handler) }, | 2398 | { (cmd), (ioctl_trans_handler_t)(handler) }, |
2390 | 2399 | ||
@@ -2405,8 +2414,835 @@ lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
2405 | Most other reasons are not valid. */ | 2414 | Most other reasons are not valid. */ |
2406 | #define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd) | 2415 | #define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd) |
2407 | 2416 | ||
2408 | struct ioctl_trans ioctl_start[] = { | 2417 | static struct ioctl_trans ioctl_start[] = { |
2409 | #include <linux/compat_ioctl.h> | 2418 | /* compatible ioctls first */ |
2419 | COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */ | ||
2420 | COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */ | ||
2421 | |||
2422 | /* Big T */ | ||
2423 | COMPATIBLE_IOCTL(TCGETA) | ||
2424 | COMPATIBLE_IOCTL(TCSETA) | ||
2425 | COMPATIBLE_IOCTL(TCSETAW) | ||
2426 | COMPATIBLE_IOCTL(TCSETAF) | ||
2427 | COMPATIBLE_IOCTL(TCSBRK) | ||
2428 | ULONG_IOCTL(TCSBRKP) | ||
2429 | COMPATIBLE_IOCTL(TCXONC) | ||
2430 | COMPATIBLE_IOCTL(TCFLSH) | ||
2431 | COMPATIBLE_IOCTL(TCGETS) | ||
2432 | COMPATIBLE_IOCTL(TCSETS) | ||
2433 | COMPATIBLE_IOCTL(TCSETSW) | ||
2434 | COMPATIBLE_IOCTL(TCSETSF) | ||
2435 | COMPATIBLE_IOCTL(TIOCLINUX) | ||
2436 | COMPATIBLE_IOCTL(TIOCSBRK) | ||
2437 | COMPATIBLE_IOCTL(TIOCCBRK) | ||
2438 | ULONG_IOCTL(TIOCMIWAIT) | ||
2439 | COMPATIBLE_IOCTL(TIOCGICOUNT) | ||
2440 | /* Little t */ | ||
2441 | COMPATIBLE_IOCTL(TIOCGETD) | ||
2442 | COMPATIBLE_IOCTL(TIOCSETD) | ||
2443 | COMPATIBLE_IOCTL(TIOCEXCL) | ||
2444 | COMPATIBLE_IOCTL(TIOCNXCL) | ||
2445 | COMPATIBLE_IOCTL(TIOCCONS) | ||
2446 | COMPATIBLE_IOCTL(TIOCGSOFTCAR) | ||
2447 | COMPATIBLE_IOCTL(TIOCSSOFTCAR) | ||
2448 | COMPATIBLE_IOCTL(TIOCSWINSZ) | ||
2449 | COMPATIBLE_IOCTL(TIOCGWINSZ) | ||
2450 | COMPATIBLE_IOCTL(TIOCMGET) | ||
2451 | COMPATIBLE_IOCTL(TIOCMBIC) | ||
2452 | COMPATIBLE_IOCTL(TIOCMBIS) | ||
2453 | COMPATIBLE_IOCTL(TIOCMSET) | ||
2454 | COMPATIBLE_IOCTL(TIOCPKT) | ||
2455 | COMPATIBLE_IOCTL(TIOCNOTTY) | ||
2456 | COMPATIBLE_IOCTL(TIOCSTI) | ||
2457 | COMPATIBLE_IOCTL(TIOCOUTQ) | ||
2458 | COMPATIBLE_IOCTL(TIOCSPGRP) | ||
2459 | COMPATIBLE_IOCTL(TIOCGPGRP) | ||
2460 | ULONG_IOCTL(TIOCSCTTY) | ||
2461 | COMPATIBLE_IOCTL(TIOCGPTN) | ||
2462 | COMPATIBLE_IOCTL(TIOCSPTLCK) | ||
2463 | COMPATIBLE_IOCTL(TIOCSERGETLSR) | ||
2464 | /* Little f */ | ||
2465 | COMPATIBLE_IOCTL(FIOCLEX) | ||
2466 | COMPATIBLE_IOCTL(FIONCLEX) | ||
2467 | COMPATIBLE_IOCTL(FIOASYNC) | ||
2468 | COMPATIBLE_IOCTL(FIONBIO) | ||
2469 | COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */ | ||
2470 | /* 0x00 */ | ||
2471 | COMPATIBLE_IOCTL(FIBMAP) | ||
2472 | COMPATIBLE_IOCTL(FIGETBSZ) | ||
2473 | /* 0x03 -- HD/IDE ioctl's used by hdparm and friends. | ||
2474 | * Some need translations, these do not. | ||
2475 | */ | ||
2476 | COMPATIBLE_IOCTL(HDIO_GET_IDENTITY) | ||
2477 | COMPATIBLE_IOCTL(HDIO_DRIVE_TASK) | ||
2478 | COMPATIBLE_IOCTL(HDIO_DRIVE_CMD) | ||
2479 | ULONG_IOCTL(HDIO_SET_MULTCOUNT) | ||
2480 | ULONG_IOCTL(HDIO_SET_UNMASKINTR) | ||
2481 | ULONG_IOCTL(HDIO_SET_KEEPSETTINGS) | ||
2482 | ULONG_IOCTL(HDIO_SET_32BIT) | ||
2483 | ULONG_IOCTL(HDIO_SET_NOWERR) | ||
2484 | ULONG_IOCTL(HDIO_SET_DMA) | ||
2485 | ULONG_IOCTL(HDIO_SET_PIO_MODE) | ||
2486 | ULONG_IOCTL(HDIO_SET_NICE) | ||
2487 | ULONG_IOCTL(HDIO_SET_WCACHE) | ||
2488 | ULONG_IOCTL(HDIO_SET_ACOUSTIC) | ||
2489 | ULONG_IOCTL(HDIO_SET_BUSSTATE) | ||
2490 | ULONG_IOCTL(HDIO_SET_ADDRESS) | ||
2491 | COMPATIBLE_IOCTL(HDIO_SCAN_HWIF) | ||
2492 | /* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */ | ||
2493 | COMPATIBLE_IOCTL(0x330) | ||
2494 | /* 0x02 -- Floppy ioctls */ | ||
2495 | COMPATIBLE_IOCTL(FDMSGON) | ||
2496 | COMPATIBLE_IOCTL(FDMSGOFF) | ||
2497 | COMPATIBLE_IOCTL(FDSETEMSGTRESH) | ||
2498 | COMPATIBLE_IOCTL(FDFLUSH) | ||
2499 | COMPATIBLE_IOCTL(FDWERRORCLR) | ||
2500 | COMPATIBLE_IOCTL(FDSETMAXERRS) | ||
2501 | COMPATIBLE_IOCTL(FDGETMAXERRS) | ||
2502 | COMPATIBLE_IOCTL(FDGETDRVTYP) | ||
2503 | COMPATIBLE_IOCTL(FDEJECT) | ||
2504 | COMPATIBLE_IOCTL(FDCLRPRM) | ||
2505 | COMPATIBLE_IOCTL(FDFMTBEG) | ||
2506 | COMPATIBLE_IOCTL(FDFMTEND) | ||
2507 | COMPATIBLE_IOCTL(FDRESET) | ||
2508 | COMPATIBLE_IOCTL(FDTWADDLE) | ||
2509 | COMPATIBLE_IOCTL(FDFMTTRK) | ||
2510 | COMPATIBLE_IOCTL(FDRAWCMD) | ||
2511 | /* 0x12 */ | ||
2512 | #ifdef CONFIG_BLOCK | ||
2513 | COMPATIBLE_IOCTL(BLKRASET) | ||
2514 | COMPATIBLE_IOCTL(BLKROSET) | ||
2515 | COMPATIBLE_IOCTL(BLKROGET) | ||
2516 | COMPATIBLE_IOCTL(BLKRRPART) | ||
2517 | COMPATIBLE_IOCTL(BLKFLSBUF) | ||
2518 | COMPATIBLE_IOCTL(BLKSECTSET) | ||
2519 | COMPATIBLE_IOCTL(BLKSSZGET) | ||
2520 | COMPATIBLE_IOCTL(BLKTRACESTART) | ||
2521 | COMPATIBLE_IOCTL(BLKTRACESTOP) | ||
2522 | COMPATIBLE_IOCTL(BLKTRACESETUP) | ||
2523 | COMPATIBLE_IOCTL(BLKTRACETEARDOWN) | ||
2524 | ULONG_IOCTL(BLKRASET) | ||
2525 | ULONG_IOCTL(BLKFRASET) | ||
2526 | #endif | ||
2527 | /* RAID */ | ||
2528 | COMPATIBLE_IOCTL(RAID_VERSION) | ||
2529 | COMPATIBLE_IOCTL(GET_ARRAY_INFO) | ||
2530 | COMPATIBLE_IOCTL(GET_DISK_INFO) | ||
2531 | COMPATIBLE_IOCTL(PRINT_RAID_DEBUG) | ||
2532 | COMPATIBLE_IOCTL(RAID_AUTORUN) | ||
2533 | COMPATIBLE_IOCTL(CLEAR_ARRAY) | ||
2534 | COMPATIBLE_IOCTL(ADD_NEW_DISK) | ||
2535 | ULONG_IOCTL(HOT_REMOVE_DISK) | ||
2536 | COMPATIBLE_IOCTL(SET_ARRAY_INFO) | ||
2537 | COMPATIBLE_IOCTL(SET_DISK_INFO) | ||
2538 | COMPATIBLE_IOCTL(WRITE_RAID_INFO) | ||
2539 | COMPATIBLE_IOCTL(UNPROTECT_ARRAY) | ||
2540 | COMPATIBLE_IOCTL(PROTECT_ARRAY) | ||
2541 | ULONG_IOCTL(HOT_ADD_DISK) | ||
2542 | ULONG_IOCTL(SET_DISK_FAULTY) | ||
2543 | COMPATIBLE_IOCTL(RUN_ARRAY) | ||
2544 | COMPATIBLE_IOCTL(STOP_ARRAY) | ||
2545 | COMPATIBLE_IOCTL(STOP_ARRAY_RO) | ||
2546 | COMPATIBLE_IOCTL(RESTART_ARRAY_RW) | ||
2547 | COMPATIBLE_IOCTL(GET_BITMAP_FILE) | ||
2548 | ULONG_IOCTL(SET_BITMAP_FILE) | ||
2549 | /* DM */ | ||
2550 | COMPATIBLE_IOCTL(DM_VERSION_32) | ||
2551 | COMPATIBLE_IOCTL(DM_REMOVE_ALL_32) | ||
2552 | COMPATIBLE_IOCTL(DM_LIST_DEVICES_32) | ||
2553 | COMPATIBLE_IOCTL(DM_DEV_CREATE_32) | ||
2554 | COMPATIBLE_IOCTL(DM_DEV_REMOVE_32) | ||
2555 | COMPATIBLE_IOCTL(DM_DEV_RENAME_32) | ||
2556 | COMPATIBLE_IOCTL(DM_DEV_SUSPEND_32) | ||
2557 | COMPATIBLE_IOCTL(DM_DEV_STATUS_32) | ||
2558 | COMPATIBLE_IOCTL(DM_DEV_WAIT_32) | ||
2559 | COMPATIBLE_IOCTL(DM_TABLE_LOAD_32) | ||
2560 | COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32) | ||
2561 | COMPATIBLE_IOCTL(DM_TABLE_DEPS_32) | ||
2562 | COMPATIBLE_IOCTL(DM_TABLE_STATUS_32) | ||
2563 | COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32) | ||
2564 | COMPATIBLE_IOCTL(DM_TARGET_MSG_32) | ||
2565 | COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY_32) | ||
2566 | COMPATIBLE_IOCTL(DM_VERSION) | ||
2567 | COMPATIBLE_IOCTL(DM_REMOVE_ALL) | ||
2568 | COMPATIBLE_IOCTL(DM_LIST_DEVICES) | ||
2569 | COMPATIBLE_IOCTL(DM_DEV_CREATE) | ||
2570 | COMPATIBLE_IOCTL(DM_DEV_REMOVE) | ||
2571 | COMPATIBLE_IOCTL(DM_DEV_RENAME) | ||
2572 | COMPATIBLE_IOCTL(DM_DEV_SUSPEND) | ||
2573 | COMPATIBLE_IOCTL(DM_DEV_STATUS) | ||
2574 | COMPATIBLE_IOCTL(DM_DEV_WAIT) | ||
2575 | COMPATIBLE_IOCTL(DM_TABLE_LOAD) | ||
2576 | COMPATIBLE_IOCTL(DM_TABLE_CLEAR) | ||
2577 | COMPATIBLE_IOCTL(DM_TABLE_DEPS) | ||
2578 | COMPATIBLE_IOCTL(DM_TABLE_STATUS) | ||
2579 | COMPATIBLE_IOCTL(DM_LIST_VERSIONS) | ||
2580 | COMPATIBLE_IOCTL(DM_TARGET_MSG) | ||
2581 | COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY) | ||
2582 | /* Big K */ | ||
2583 | COMPATIBLE_IOCTL(PIO_FONT) | ||
2584 | COMPATIBLE_IOCTL(GIO_FONT) | ||
2585 | ULONG_IOCTL(KDSIGACCEPT) | ||
2586 | COMPATIBLE_IOCTL(KDGETKEYCODE) | ||
2587 | COMPATIBLE_IOCTL(KDSETKEYCODE) | ||
2588 | ULONG_IOCTL(KIOCSOUND) | ||
2589 | ULONG_IOCTL(KDMKTONE) | ||
2590 | COMPATIBLE_IOCTL(KDGKBTYPE) | ||
2591 | ULONG_IOCTL(KDSETMODE) | ||
2592 | COMPATIBLE_IOCTL(KDGETMODE) | ||
2593 | ULONG_IOCTL(KDSKBMODE) | ||
2594 | COMPATIBLE_IOCTL(KDGKBMODE) | ||
2595 | ULONG_IOCTL(KDSKBMETA) | ||
2596 | COMPATIBLE_IOCTL(KDGKBMETA) | ||
2597 | COMPATIBLE_IOCTL(KDGKBENT) | ||
2598 | COMPATIBLE_IOCTL(KDSKBENT) | ||
2599 | COMPATIBLE_IOCTL(KDGKBSENT) | ||
2600 | COMPATIBLE_IOCTL(KDSKBSENT) | ||
2601 | COMPATIBLE_IOCTL(KDGKBDIACR) | ||
2602 | COMPATIBLE_IOCTL(KDSKBDIACR) | ||
2603 | COMPATIBLE_IOCTL(KDKBDREP) | ||
2604 | COMPATIBLE_IOCTL(KDGKBLED) | ||
2605 | ULONG_IOCTL(KDSKBLED) | ||
2606 | COMPATIBLE_IOCTL(KDGETLED) | ||
2607 | ULONG_IOCTL(KDSETLED) | ||
2608 | COMPATIBLE_IOCTL(GIO_SCRNMAP) | ||
2609 | COMPATIBLE_IOCTL(PIO_SCRNMAP) | ||
2610 | COMPATIBLE_IOCTL(GIO_UNISCRNMAP) | ||
2611 | COMPATIBLE_IOCTL(PIO_UNISCRNMAP) | ||
2612 | COMPATIBLE_IOCTL(PIO_FONTRESET) | ||
2613 | COMPATIBLE_IOCTL(PIO_UNIMAPCLR) | ||
2614 | /* Big S */ | ||
2615 | COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) | ||
2616 | COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK) | ||
2617 | COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK) | ||
2618 | COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY) | ||
2619 | COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER) | ||
2620 | COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND) | ||
2621 | COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST) | ||
2622 | COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) | ||
2623 | /* Big T */ | ||
2624 | COMPATIBLE_IOCTL(TUNSETNOCSUM) | ||
2625 | COMPATIBLE_IOCTL(TUNSETDEBUG) | ||
2626 | COMPATIBLE_IOCTL(TUNSETPERSIST) | ||
2627 | COMPATIBLE_IOCTL(TUNSETOWNER) | ||
2628 | /* Big V */ | ||
2629 | COMPATIBLE_IOCTL(VT_SETMODE) | ||
2630 | COMPATIBLE_IOCTL(VT_GETMODE) | ||
2631 | COMPATIBLE_IOCTL(VT_GETSTATE) | ||
2632 | COMPATIBLE_IOCTL(VT_OPENQRY) | ||
2633 | ULONG_IOCTL(VT_ACTIVATE) | ||
2634 | ULONG_IOCTL(VT_WAITACTIVE) | ||
2635 | ULONG_IOCTL(VT_RELDISP) | ||
2636 | ULONG_IOCTL(VT_DISALLOCATE) | ||
2637 | COMPATIBLE_IOCTL(VT_RESIZE) | ||
2638 | COMPATIBLE_IOCTL(VT_RESIZEX) | ||
2639 | COMPATIBLE_IOCTL(VT_LOCKSWITCH) | ||
2640 | COMPATIBLE_IOCTL(VT_UNLOCKSWITCH) | ||
2641 | COMPATIBLE_IOCTL(VT_GETHIFONTMASK) | ||
2642 | /* Little p (/dev/rtc, /dev/envctrl, etc.) */ | ||
2643 | COMPATIBLE_IOCTL(RTC_AIE_ON) | ||
2644 | COMPATIBLE_IOCTL(RTC_AIE_OFF) | ||
2645 | COMPATIBLE_IOCTL(RTC_UIE_ON) | ||
2646 | COMPATIBLE_IOCTL(RTC_UIE_OFF) | ||
2647 | COMPATIBLE_IOCTL(RTC_PIE_ON) | ||
2648 | COMPATIBLE_IOCTL(RTC_PIE_OFF) | ||
2649 | COMPATIBLE_IOCTL(RTC_WIE_ON) | ||
2650 | COMPATIBLE_IOCTL(RTC_WIE_OFF) | ||
2651 | COMPATIBLE_IOCTL(RTC_ALM_SET) | ||
2652 | COMPATIBLE_IOCTL(RTC_ALM_READ) | ||
2653 | COMPATIBLE_IOCTL(RTC_RD_TIME) | ||
2654 | COMPATIBLE_IOCTL(RTC_SET_TIME) | ||
2655 | COMPATIBLE_IOCTL(RTC_WKALM_SET) | ||
2656 | COMPATIBLE_IOCTL(RTC_WKALM_RD) | ||
2657 | /* | ||
2658 | * These two are only for the sbus rtc driver, but | ||
2659 | * hwclock tries them on every rtc device first when | ||
2660 | * running on sparc. On other architectures the entries | ||
2661 | * are useless but harmless. | ||
2662 | */ | ||
2663 | COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ | ||
2664 | COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ | ||
2665 | /* Little m */ | ||
2666 | COMPATIBLE_IOCTL(MTIOCTOP) | ||
2667 | /* Socket level stuff */ | ||
2668 | COMPATIBLE_IOCTL(FIOQSIZE) | ||
2669 | COMPATIBLE_IOCTL(FIOSETOWN) | ||
2670 | COMPATIBLE_IOCTL(SIOCSPGRP) | ||
2671 | COMPATIBLE_IOCTL(FIOGETOWN) | ||
2672 | COMPATIBLE_IOCTL(SIOCGPGRP) | ||
2673 | COMPATIBLE_IOCTL(SIOCATMARK) | ||
2674 | COMPATIBLE_IOCTL(SIOCSIFLINK) | ||
2675 | COMPATIBLE_IOCTL(SIOCSIFENCAP) | ||
2676 | COMPATIBLE_IOCTL(SIOCGIFENCAP) | ||
2677 | COMPATIBLE_IOCTL(SIOCSIFNAME) | ||
2678 | COMPATIBLE_IOCTL(SIOCSARP) | ||
2679 | COMPATIBLE_IOCTL(SIOCGARP) | ||
2680 | COMPATIBLE_IOCTL(SIOCDARP) | ||
2681 | COMPATIBLE_IOCTL(SIOCSRARP) | ||
2682 | COMPATIBLE_IOCTL(SIOCGRARP) | ||
2683 | COMPATIBLE_IOCTL(SIOCDRARP) | ||
2684 | COMPATIBLE_IOCTL(SIOCADDDLCI) | ||
2685 | COMPATIBLE_IOCTL(SIOCDELDLCI) | ||
2686 | COMPATIBLE_IOCTL(SIOCGMIIPHY) | ||
2687 | COMPATIBLE_IOCTL(SIOCGMIIREG) | ||
2688 | COMPATIBLE_IOCTL(SIOCSMIIREG) | ||
2689 | COMPATIBLE_IOCTL(SIOCGIFVLAN) | ||
2690 | COMPATIBLE_IOCTL(SIOCSIFVLAN) | ||
2691 | COMPATIBLE_IOCTL(SIOCBRADDBR) | ||
2692 | COMPATIBLE_IOCTL(SIOCBRDELBR) | ||
2693 | /* SG stuff */ | ||
2694 | COMPATIBLE_IOCTL(SG_SET_TIMEOUT) | ||
2695 | COMPATIBLE_IOCTL(SG_GET_TIMEOUT) | ||
2696 | COMPATIBLE_IOCTL(SG_EMULATED_HOST) | ||
2697 | ULONG_IOCTL(SG_SET_TRANSFORM) | ||
2698 | COMPATIBLE_IOCTL(SG_GET_TRANSFORM) | ||
2699 | COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) | ||
2700 | COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) | ||
2701 | COMPATIBLE_IOCTL(SG_GET_SCSI_ID) | ||
2702 | COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA) | ||
2703 | COMPATIBLE_IOCTL(SG_GET_LOW_DMA) | ||
2704 | COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID) | ||
2705 | COMPATIBLE_IOCTL(SG_GET_PACK_ID) | ||
2706 | COMPATIBLE_IOCTL(SG_GET_NUM_WAITING) | ||
2707 | COMPATIBLE_IOCTL(SG_SET_DEBUG) | ||
2708 | COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE) | ||
2709 | COMPATIBLE_IOCTL(SG_GET_COMMAND_Q) | ||
2710 | COMPATIBLE_IOCTL(SG_SET_COMMAND_Q) | ||
2711 | COMPATIBLE_IOCTL(SG_GET_VERSION_NUM) | ||
2712 | COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN) | ||
2713 | COMPATIBLE_IOCTL(SG_SCSI_RESET) | ||
2714 | COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE) | ||
2715 | COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN) | ||
2716 | COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN) | ||
2717 | /* PPP stuff */ | ||
2718 | COMPATIBLE_IOCTL(PPPIOCGFLAGS) | ||
2719 | COMPATIBLE_IOCTL(PPPIOCSFLAGS) | ||
2720 | COMPATIBLE_IOCTL(PPPIOCGASYNCMAP) | ||
2721 | COMPATIBLE_IOCTL(PPPIOCSASYNCMAP) | ||
2722 | COMPATIBLE_IOCTL(PPPIOCGUNIT) | ||
2723 | COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP) | ||
2724 | COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP) | ||
2725 | COMPATIBLE_IOCTL(PPPIOCGMRU) | ||
2726 | COMPATIBLE_IOCTL(PPPIOCSMRU) | ||
2727 | COMPATIBLE_IOCTL(PPPIOCSMAXCID) | ||
2728 | COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP) | ||
2729 | COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP) | ||
2730 | COMPATIBLE_IOCTL(PPPIOCXFERUNIT) | ||
2731 | /* PPPIOCSCOMPRESS is translated */ | ||
2732 | COMPATIBLE_IOCTL(PPPIOCGNPMODE) | ||
2733 | COMPATIBLE_IOCTL(PPPIOCSNPMODE) | ||
2734 | COMPATIBLE_IOCTL(PPPIOCGDEBUG) | ||
2735 | COMPATIBLE_IOCTL(PPPIOCSDEBUG) | ||
2736 | /* PPPIOCSPASS is translated */ | ||
2737 | /* PPPIOCSACTIVE is translated */ | ||
2738 | /* PPPIOCGIDLE is translated */ | ||
2739 | COMPATIBLE_IOCTL(PPPIOCNEWUNIT) | ||
2740 | COMPATIBLE_IOCTL(PPPIOCATTACH) | ||
2741 | COMPATIBLE_IOCTL(PPPIOCDETACH) | ||
2742 | COMPATIBLE_IOCTL(PPPIOCSMRRU) | ||
2743 | COMPATIBLE_IOCTL(PPPIOCCONNECT) | ||
2744 | COMPATIBLE_IOCTL(PPPIOCDISCONN) | ||
2745 | COMPATIBLE_IOCTL(PPPIOCATTCHAN) | ||
2746 | COMPATIBLE_IOCTL(PPPIOCGCHAN) | ||
2747 | /* PPPOX */ | ||
2748 | COMPATIBLE_IOCTL(PPPOEIOCSFWD) | ||
2749 | COMPATIBLE_IOCTL(PPPOEIOCDFWD) | ||
2750 | /* LP */ | ||
2751 | COMPATIBLE_IOCTL(LPGETSTATUS) | ||
2752 | /* ppdev */ | ||
2753 | COMPATIBLE_IOCTL(PPSETMODE) | ||
2754 | COMPATIBLE_IOCTL(PPRSTATUS) | ||
2755 | COMPATIBLE_IOCTL(PPRCONTROL) | ||
2756 | COMPATIBLE_IOCTL(PPWCONTROL) | ||
2757 | COMPATIBLE_IOCTL(PPFCONTROL) | ||
2758 | COMPATIBLE_IOCTL(PPRDATA) | ||
2759 | COMPATIBLE_IOCTL(PPWDATA) | ||
2760 | COMPATIBLE_IOCTL(PPCLAIM) | ||
2761 | COMPATIBLE_IOCTL(PPRELEASE) | ||
2762 | COMPATIBLE_IOCTL(PPYIELD) | ||
2763 | COMPATIBLE_IOCTL(PPEXCL) | ||
2764 | COMPATIBLE_IOCTL(PPDATADIR) | ||
2765 | COMPATIBLE_IOCTL(PPNEGOT) | ||
2766 | COMPATIBLE_IOCTL(PPWCTLONIRQ) | ||
2767 | COMPATIBLE_IOCTL(PPCLRIRQ) | ||
2768 | COMPATIBLE_IOCTL(PPSETPHASE) | ||
2769 | COMPATIBLE_IOCTL(PPGETMODES) | ||
2770 | COMPATIBLE_IOCTL(PPGETMODE) | ||
2771 | COMPATIBLE_IOCTL(PPGETPHASE) | ||
2772 | COMPATIBLE_IOCTL(PPGETFLAGS) | ||
2773 | COMPATIBLE_IOCTL(PPSETFLAGS) | ||
2774 | /* CDROM stuff */ | ||
2775 | COMPATIBLE_IOCTL(CDROMPAUSE) | ||
2776 | COMPATIBLE_IOCTL(CDROMRESUME) | ||
2777 | COMPATIBLE_IOCTL(CDROMPLAYMSF) | ||
2778 | COMPATIBLE_IOCTL(CDROMPLAYTRKIND) | ||
2779 | COMPATIBLE_IOCTL(CDROMREADTOCHDR) | ||
2780 | COMPATIBLE_IOCTL(CDROMREADTOCENTRY) | ||
2781 | COMPATIBLE_IOCTL(CDROMSTOP) | ||
2782 | COMPATIBLE_IOCTL(CDROMSTART) | ||
2783 | COMPATIBLE_IOCTL(CDROMEJECT) | ||
2784 | COMPATIBLE_IOCTL(CDROMVOLCTRL) | ||
2785 | COMPATIBLE_IOCTL(CDROMSUBCHNL) | ||
2786 | ULONG_IOCTL(CDROMEJECT_SW) | ||
2787 | COMPATIBLE_IOCTL(CDROMMULTISESSION) | ||
2788 | COMPATIBLE_IOCTL(CDROM_GET_MCN) | ||
2789 | COMPATIBLE_IOCTL(CDROMRESET) | ||
2790 | COMPATIBLE_IOCTL(CDROMVOLREAD) | ||
2791 | COMPATIBLE_IOCTL(CDROMSEEK) | ||
2792 | COMPATIBLE_IOCTL(CDROMPLAYBLK) | ||
2793 | COMPATIBLE_IOCTL(CDROMCLOSETRAY) | ||
2794 | ULONG_IOCTL(CDROM_SET_OPTIONS) | ||
2795 | ULONG_IOCTL(CDROM_CLEAR_OPTIONS) | ||
2796 | ULONG_IOCTL(CDROM_SELECT_SPEED) | ||
2797 | ULONG_IOCTL(CDROM_SELECT_DISC) | ||
2798 | ULONG_IOCTL(CDROM_MEDIA_CHANGED) | ||
2799 | ULONG_IOCTL(CDROM_DRIVE_STATUS) | ||
2800 | COMPATIBLE_IOCTL(CDROM_DISC_STATUS) | ||
2801 | COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS) | ||
2802 | ULONG_IOCTL(CDROM_LOCKDOOR) | ||
2803 | ULONG_IOCTL(CDROM_DEBUG) | ||
2804 | COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY) | ||
2805 | /* Ignore cdrom.h about these next 5 ioctls, they absolutely do | ||
2806 | * not take a struct cdrom_read, instead they take a struct cdrom_msf | ||
2807 | * which is compatible. | ||
2808 | */ | ||
2809 | COMPATIBLE_IOCTL(CDROMREADMODE2) | ||
2810 | COMPATIBLE_IOCTL(CDROMREADMODE1) | ||
2811 | COMPATIBLE_IOCTL(CDROMREADRAW) | ||
2812 | COMPATIBLE_IOCTL(CDROMREADCOOKED) | ||
2813 | COMPATIBLE_IOCTL(CDROMREADALL) | ||
2814 | /* DVD ioctls */ | ||
2815 | COMPATIBLE_IOCTL(DVD_READ_STRUCT) | ||
2816 | COMPATIBLE_IOCTL(DVD_WRITE_STRUCT) | ||
2817 | COMPATIBLE_IOCTL(DVD_AUTH) | ||
2818 | /* pktcdvd */ | ||
2819 | COMPATIBLE_IOCTL(PACKET_CTRL_CMD) | ||
2820 | /* Big A */ | ||
2821 | /* sparc only */ | ||
2822 | /* Big Q for sound/OSS */ | ||
2823 | COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET) | ||
2824 | COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC) | ||
2825 | COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO) | ||
2826 | COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE) | ||
2827 | COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT) | ||
2828 | COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT) | ||
2829 | COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE) | ||
2830 | COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR) | ||
2831 | COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI) | ||
2832 | COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES) | ||
2833 | COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS) | ||
2834 | COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS) | ||
2835 | COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO) | ||
2836 | COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD) | ||
2837 | COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL) | ||
2838 | COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE) | ||
2839 | COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC) | ||
2840 | COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND) | ||
2841 | COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME) | ||
2842 | COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID) | ||
2843 | COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL) | ||
2844 | COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE) | ||
2845 | /* Big T for sound/OSS */ | ||
2846 | COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE) | ||
2847 | COMPATIBLE_IOCTL(SNDCTL_TMR_START) | ||
2848 | COMPATIBLE_IOCTL(SNDCTL_TMR_STOP) | ||
2849 | COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE) | ||
2850 | COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO) | ||
2851 | COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE) | ||
2852 | COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME) | ||
2853 | COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT) | ||
2854 | /* Little m for sound/OSS */ | ||
2855 | COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME) | ||
2856 | COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE) | ||
2857 | COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD) | ||
2858 | /* Big P for sound/OSS */ | ||
2859 | COMPATIBLE_IOCTL(SNDCTL_DSP_RESET) | ||
2860 | COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC) | ||
2861 | COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED) | ||
2862 | COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO) | ||
2863 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE) | ||
2864 | COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS) | ||
2865 | COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER) | ||
2866 | COMPATIBLE_IOCTL(SNDCTL_DSP_POST) | ||
2867 | COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE) | ||
2868 | COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT) | ||
2869 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS) | ||
2870 | COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT) | ||
2871 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE) | ||
2872 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE) | ||
2873 | COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK) | ||
2874 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS) | ||
2875 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER) | ||
2876 | COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER) | ||
2877 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR) | ||
2878 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR) | ||
2879 | /* SNDCTL_DSP_MAPINBUF, XXX needs translation */ | ||
2880 | /* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */ | ||
2881 | COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO) | ||
2882 | COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX) | ||
2883 | COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY) | ||
2884 | COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE) | ||
2885 | COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE) | ||
2886 | COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS) | ||
2887 | COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS) | ||
2888 | COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER) | ||
2889 | /* Big C for sound/OSS */ | ||
2890 | COMPATIBLE_IOCTL(SNDCTL_COPR_RESET) | ||
2891 | COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD) | ||
2892 | COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA) | ||
2893 | COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE) | ||
2894 | COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA) | ||
2895 | COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE) | ||
2896 | COMPATIBLE_IOCTL(SNDCTL_COPR_RUN) | ||
2897 | COMPATIBLE_IOCTL(SNDCTL_COPR_HALT) | ||
2898 | COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG) | ||
2899 | COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG) | ||
2900 | /* Big M for sound/OSS */ | ||
2901 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME) | ||
2902 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS) | ||
2903 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE) | ||
2904 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH) | ||
2905 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM) | ||
2906 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER) | ||
2907 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE) | ||
2908 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC) | ||
2909 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD) | ||
2910 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX) | ||
2911 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM) | ||
2912 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV) | ||
2913 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN) | ||
2914 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN) | ||
2915 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1) | ||
2916 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2) | ||
2917 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3) | ||
2918 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1)) | ||
2919 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2)) | ||
2920 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3)) | ||
2921 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN)) | ||
2922 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT)) | ||
2923 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO)) | ||
2924 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO)) | ||
2925 | COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR)) | ||
2926 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE) | ||
2927 | /* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */ | ||
2928 | /* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */ | ||
2929 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC) | ||
2930 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK) | ||
2931 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK) | ||
2932 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS) | ||
2933 | COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS) | ||
2934 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME) | ||
2935 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS) | ||
2936 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE) | ||
2937 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH) | ||
2938 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM) | ||
2939 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER) | ||
2940 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE) | ||
2941 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC) | ||
2942 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD) | ||
2943 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX) | ||
2944 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM) | ||
2945 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV) | ||
2946 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN) | ||
2947 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN) | ||
2948 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1) | ||
2949 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2) | ||
2950 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3) | ||
2951 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1)) | ||
2952 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2)) | ||
2953 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3)) | ||
2954 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN)) | ||
2955 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT)) | ||
2956 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO)) | ||
2957 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO)) | ||
2958 | COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR)) | ||
2959 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE) | ||
2960 | /* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */ | ||
2961 | /* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */ | ||
2962 | COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC) | ||
2963 | COMPATIBLE_IOCTL(SOUND_MIXER_INFO) | ||
2964 | COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO) | ||
2965 | COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS) | ||
2966 | COMPATIBLE_IOCTL(SOUND_MIXER_AGC) | ||
2967 | COMPATIBLE_IOCTL(SOUND_MIXER_3DSE) | ||
2968 | COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1) | ||
2969 | COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2) | ||
2970 | COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3) | ||
2971 | COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4) | ||
2972 | COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5) | ||
2973 | COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) | ||
2974 | COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) | ||
2975 | COMPATIBLE_IOCTL(OSS_GETVERSION) | ||
2976 | /* AUTOFS */ | ||
2977 | ULONG_IOCTL(AUTOFS_IOC_READY) | ||
2978 | ULONG_IOCTL(AUTOFS_IOC_FAIL) | ||
2979 | COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) | ||
2980 | COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) | ||
2981 | COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) | ||
2982 | COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) | ||
2983 | COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER) | ||
2984 | COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST) | ||
2985 | COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST) | ||
2986 | COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT) | ||
2987 | /* Raw devices */ | ||
2988 | COMPATIBLE_IOCTL(RAW_SETBIND) | ||
2989 | COMPATIBLE_IOCTL(RAW_GETBIND) | ||
2990 | /* SMB ioctls which do not need any translations */ | ||
2991 | COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) | ||
2992 | /* Little a */ | ||
2993 | COMPATIBLE_IOCTL(ATMSIGD_CTRL) | ||
2994 | COMPATIBLE_IOCTL(ATMARPD_CTRL) | ||
2995 | COMPATIBLE_IOCTL(ATMLEC_CTRL) | ||
2996 | COMPATIBLE_IOCTL(ATMLEC_MCAST) | ||
2997 | COMPATIBLE_IOCTL(ATMLEC_DATA) | ||
2998 | COMPATIBLE_IOCTL(ATM_SETSC) | ||
2999 | COMPATIBLE_IOCTL(SIOCSIFATMTCP) | ||
3000 | COMPATIBLE_IOCTL(SIOCMKCLIP) | ||
3001 | COMPATIBLE_IOCTL(ATMARP_MKIP) | ||
3002 | COMPATIBLE_IOCTL(ATMARP_SETENTRY) | ||
3003 | COMPATIBLE_IOCTL(ATMARP_ENCAP) | ||
3004 | COMPATIBLE_IOCTL(ATMTCP_CREATE) | ||
3005 | COMPATIBLE_IOCTL(ATMTCP_REMOVE) | ||
3006 | COMPATIBLE_IOCTL(ATMMPC_CTRL) | ||
3007 | COMPATIBLE_IOCTL(ATMMPC_DATA) | ||
3008 | /* Watchdog */ | ||
3009 | COMPATIBLE_IOCTL(WDIOC_GETSUPPORT) | ||
3010 | COMPATIBLE_IOCTL(WDIOC_GETSTATUS) | ||
3011 | COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS) | ||
3012 | COMPATIBLE_IOCTL(WDIOC_GETTEMP) | ||
3013 | COMPATIBLE_IOCTL(WDIOC_SETOPTIONS) | ||
3014 | COMPATIBLE_IOCTL(WDIOC_KEEPALIVE) | ||
3015 | COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT) | ||
3016 | COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT) | ||
3017 | /* Big R */ | ||
3018 | COMPATIBLE_IOCTL(RNDGETENTCNT) | ||
3019 | COMPATIBLE_IOCTL(RNDADDTOENTCNT) | ||
3020 | COMPATIBLE_IOCTL(RNDGETPOOL) | ||
3021 | COMPATIBLE_IOCTL(RNDADDENTROPY) | ||
3022 | COMPATIBLE_IOCTL(RNDZAPENTCNT) | ||
3023 | COMPATIBLE_IOCTL(RNDCLEARPOOL) | ||
3024 | /* Bluetooth */ | ||
3025 | COMPATIBLE_IOCTL(HCIDEVUP) | ||
3026 | COMPATIBLE_IOCTL(HCIDEVDOWN) | ||
3027 | COMPATIBLE_IOCTL(HCIDEVRESET) | ||
3028 | COMPATIBLE_IOCTL(HCIDEVRESTAT) | ||
3029 | COMPATIBLE_IOCTL(HCIGETDEVLIST) | ||
3030 | COMPATIBLE_IOCTL(HCIGETDEVINFO) | ||
3031 | COMPATIBLE_IOCTL(HCIGETCONNLIST) | ||
3032 | COMPATIBLE_IOCTL(HCIGETCONNINFO) | ||
3033 | COMPATIBLE_IOCTL(HCISETRAW) | ||
3034 | COMPATIBLE_IOCTL(HCISETSCAN) | ||
3035 | COMPATIBLE_IOCTL(HCISETAUTH) | ||
3036 | COMPATIBLE_IOCTL(HCISETENCRYPT) | ||
3037 | COMPATIBLE_IOCTL(HCISETPTYPE) | ||
3038 | COMPATIBLE_IOCTL(HCISETLINKPOL) | ||
3039 | COMPATIBLE_IOCTL(HCISETLINKMODE) | ||
3040 | COMPATIBLE_IOCTL(HCISETACLMTU) | ||
3041 | COMPATIBLE_IOCTL(HCISETSCOMTU) | ||
3042 | COMPATIBLE_IOCTL(HCIINQUIRY) | ||
3043 | COMPATIBLE_IOCTL(HCIUARTSETPROTO) | ||
3044 | COMPATIBLE_IOCTL(HCIUARTGETPROTO) | ||
3045 | COMPATIBLE_IOCTL(RFCOMMCREATEDEV) | ||
3046 | COMPATIBLE_IOCTL(RFCOMMRELEASEDEV) | ||
3047 | COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) | ||
3048 | COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) | ||
3049 | COMPATIBLE_IOCTL(RFCOMMSTEALDLC) | ||
3050 | COMPATIBLE_IOCTL(BNEPCONNADD) | ||
3051 | COMPATIBLE_IOCTL(BNEPCONNDEL) | ||
3052 | COMPATIBLE_IOCTL(BNEPGETCONNLIST) | ||
3053 | COMPATIBLE_IOCTL(BNEPGETCONNINFO) | ||
3054 | COMPATIBLE_IOCTL(CMTPCONNADD) | ||
3055 | COMPATIBLE_IOCTL(CMTPCONNDEL) | ||
3056 | COMPATIBLE_IOCTL(CMTPGETCONNLIST) | ||
3057 | COMPATIBLE_IOCTL(CMTPGETCONNINFO) | ||
3058 | COMPATIBLE_IOCTL(HIDPCONNADD) | ||
3059 | COMPATIBLE_IOCTL(HIDPCONNDEL) | ||
3060 | COMPATIBLE_IOCTL(HIDPGETCONNLIST) | ||
3061 | COMPATIBLE_IOCTL(HIDPGETCONNINFO) | ||
3062 | /* CAPI */ | ||
3063 | COMPATIBLE_IOCTL(CAPI_REGISTER) | ||
3064 | COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER) | ||
3065 | COMPATIBLE_IOCTL(CAPI_GET_VERSION) | ||
3066 | COMPATIBLE_IOCTL(CAPI_GET_SERIAL) | ||
3067 | COMPATIBLE_IOCTL(CAPI_GET_PROFILE) | ||
3068 | COMPATIBLE_IOCTL(CAPI_MANUFACTURER_CMD) | ||
3069 | COMPATIBLE_IOCTL(CAPI_GET_ERRCODE) | ||
3070 | COMPATIBLE_IOCTL(CAPI_INSTALLED) | ||
3071 | COMPATIBLE_IOCTL(CAPI_GET_FLAGS) | ||
3072 | COMPATIBLE_IOCTL(CAPI_SET_FLAGS) | ||
3073 | COMPATIBLE_IOCTL(CAPI_CLR_FLAGS) | ||
3074 | COMPATIBLE_IOCTL(CAPI_NCCI_OPENCOUNT) | ||
3075 | COMPATIBLE_IOCTL(CAPI_NCCI_GETUNIT) | ||
3076 | /* Siemens Gigaset */ | ||
3077 | COMPATIBLE_IOCTL(GIGASET_REDIR) | ||
3078 | COMPATIBLE_IOCTL(GIGASET_CONFIG) | ||
3079 | COMPATIBLE_IOCTL(GIGASET_BRKCHARS) | ||
3080 | COMPATIBLE_IOCTL(GIGASET_VERSION) | ||
3081 | /* Misc. */ | ||
3082 | COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */ | ||
3083 | COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */ | ||
3084 | COMPATIBLE_IOCTL(PCIIOC_CONTROLLER) | ||
3085 | COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) | ||
3086 | COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) | ||
3087 | COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) | ||
3088 | /* USB */ | ||
3089 | COMPATIBLE_IOCTL(USBDEVFS_RESETEP) | ||
3090 | COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE) | ||
3091 | COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION) | ||
3092 | COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER) | ||
3093 | COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB) | ||
3094 | COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE) | ||
3095 | COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE) | ||
3096 | COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO) | ||
3097 | COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO) | ||
3098 | COMPATIBLE_IOCTL(USBDEVFS_RESET) | ||
3099 | COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32) | ||
3100 | COMPATIBLE_IOCTL(USBDEVFS_REAPURB32) | ||
3101 | COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) | ||
3102 | COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) | ||
3103 | /* MTD */ | ||
3104 | COMPATIBLE_IOCTL(MEMGETINFO) | ||
3105 | COMPATIBLE_IOCTL(MEMERASE) | ||
3106 | COMPATIBLE_IOCTL(MEMLOCK) | ||
3107 | COMPATIBLE_IOCTL(MEMUNLOCK) | ||
3108 | COMPATIBLE_IOCTL(MEMGETREGIONCOUNT) | ||
3109 | COMPATIBLE_IOCTL(MEMGETREGIONINFO) | ||
3110 | COMPATIBLE_IOCTL(MEMGETBADBLOCK) | ||
3111 | COMPATIBLE_IOCTL(MEMSETBADBLOCK) | ||
3112 | /* NBD */ | ||
3113 | ULONG_IOCTL(NBD_SET_SOCK) | ||
3114 | ULONG_IOCTL(NBD_SET_BLKSIZE) | ||
3115 | ULONG_IOCTL(NBD_SET_SIZE) | ||
3116 | COMPATIBLE_IOCTL(NBD_DO_IT) | ||
3117 | COMPATIBLE_IOCTL(NBD_CLEAR_SOCK) | ||
3118 | COMPATIBLE_IOCTL(NBD_CLEAR_QUE) | ||
3119 | COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) | ||
3120 | ULONG_IOCTL(NBD_SET_SIZE_BLOCKS) | ||
3121 | COMPATIBLE_IOCTL(NBD_DISCONNECT) | ||
3122 | /* i2c */ | ||
3123 | COMPATIBLE_IOCTL(I2C_SLAVE) | ||
3124 | COMPATIBLE_IOCTL(I2C_SLAVE_FORCE) | ||
3125 | COMPATIBLE_IOCTL(I2C_TENBIT) | ||
3126 | COMPATIBLE_IOCTL(I2C_PEC) | ||
3127 | COMPATIBLE_IOCTL(I2C_RETRIES) | ||
3128 | COMPATIBLE_IOCTL(I2C_TIMEOUT) | ||
3129 | /* wireless */ | ||
3130 | COMPATIBLE_IOCTL(SIOCSIWCOMMIT) | ||
3131 | COMPATIBLE_IOCTL(SIOCGIWNAME) | ||
3132 | COMPATIBLE_IOCTL(SIOCSIWNWID) | ||
3133 | COMPATIBLE_IOCTL(SIOCGIWNWID) | ||
3134 | COMPATIBLE_IOCTL(SIOCSIWFREQ) | ||
3135 | COMPATIBLE_IOCTL(SIOCGIWFREQ) | ||
3136 | COMPATIBLE_IOCTL(SIOCSIWMODE) | ||
3137 | COMPATIBLE_IOCTL(SIOCGIWMODE) | ||
3138 | COMPATIBLE_IOCTL(SIOCSIWSENS) | ||
3139 | COMPATIBLE_IOCTL(SIOCGIWSENS) | ||
3140 | COMPATIBLE_IOCTL(SIOCSIWRANGE) | ||
3141 | COMPATIBLE_IOCTL(SIOCSIWPRIV) | ||
3142 | COMPATIBLE_IOCTL(SIOCGIWPRIV) | ||
3143 | COMPATIBLE_IOCTL(SIOCSIWSTATS) | ||
3144 | COMPATIBLE_IOCTL(SIOCGIWSTATS) | ||
3145 | COMPATIBLE_IOCTL(SIOCSIWAP) | ||
3146 | COMPATIBLE_IOCTL(SIOCGIWAP) | ||
3147 | COMPATIBLE_IOCTL(SIOCSIWSCAN) | ||
3148 | COMPATIBLE_IOCTL(SIOCSIWRATE) | ||
3149 | COMPATIBLE_IOCTL(SIOCGIWRATE) | ||
3150 | COMPATIBLE_IOCTL(SIOCSIWRTS) | ||
3151 | COMPATIBLE_IOCTL(SIOCGIWRTS) | ||
3152 | COMPATIBLE_IOCTL(SIOCSIWFRAG) | ||
3153 | COMPATIBLE_IOCTL(SIOCGIWFRAG) | ||
3154 | COMPATIBLE_IOCTL(SIOCSIWTXPOW) | ||
3155 | COMPATIBLE_IOCTL(SIOCGIWTXPOW) | ||
3156 | COMPATIBLE_IOCTL(SIOCSIWRETRY) | ||
3157 | COMPATIBLE_IOCTL(SIOCGIWRETRY) | ||
3158 | COMPATIBLE_IOCTL(SIOCSIWPOWER) | ||
3159 | COMPATIBLE_IOCTL(SIOCGIWPOWER) | ||
3160 | /* hiddev */ | ||
3161 | COMPATIBLE_IOCTL(HIDIOCGVERSION) | ||
3162 | COMPATIBLE_IOCTL(HIDIOCAPPLICATION) | ||
3163 | COMPATIBLE_IOCTL(HIDIOCGDEVINFO) | ||
3164 | COMPATIBLE_IOCTL(HIDIOCGSTRING) | ||
3165 | COMPATIBLE_IOCTL(HIDIOCINITREPORT) | ||
3166 | COMPATIBLE_IOCTL(HIDIOCGREPORT) | ||
3167 | COMPATIBLE_IOCTL(HIDIOCSREPORT) | ||
3168 | COMPATIBLE_IOCTL(HIDIOCGREPORTINFO) | ||
3169 | COMPATIBLE_IOCTL(HIDIOCGFIELDINFO) | ||
3170 | COMPATIBLE_IOCTL(HIDIOCGUSAGE) | ||
3171 | COMPATIBLE_IOCTL(HIDIOCSUSAGE) | ||
3172 | COMPATIBLE_IOCTL(HIDIOCGUCODE) | ||
3173 | COMPATIBLE_IOCTL(HIDIOCGFLAG) | ||
3174 | COMPATIBLE_IOCTL(HIDIOCSFLAG) | ||
3175 | COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX) | ||
3176 | COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO) | ||
3177 | /* dvb */ | ||
3178 | COMPATIBLE_IOCTL(AUDIO_STOP) | ||
3179 | COMPATIBLE_IOCTL(AUDIO_PLAY) | ||
3180 | COMPATIBLE_IOCTL(AUDIO_PAUSE) | ||
3181 | COMPATIBLE_IOCTL(AUDIO_CONTINUE) | ||
3182 | COMPATIBLE_IOCTL(AUDIO_SELECT_SOURCE) | ||
3183 | COMPATIBLE_IOCTL(AUDIO_SET_MUTE) | ||
3184 | COMPATIBLE_IOCTL(AUDIO_SET_AV_SYNC) | ||
3185 | COMPATIBLE_IOCTL(AUDIO_SET_BYPASS_MODE) | ||
3186 | COMPATIBLE_IOCTL(AUDIO_CHANNEL_SELECT) | ||
3187 | COMPATIBLE_IOCTL(AUDIO_GET_STATUS) | ||
3188 | COMPATIBLE_IOCTL(AUDIO_GET_CAPABILITIES) | ||
3189 | COMPATIBLE_IOCTL(AUDIO_CLEAR_BUFFER) | ||
3190 | COMPATIBLE_IOCTL(AUDIO_SET_ID) | ||
3191 | COMPATIBLE_IOCTL(AUDIO_SET_MIXER) | ||
3192 | COMPATIBLE_IOCTL(AUDIO_SET_STREAMTYPE) | ||
3193 | COMPATIBLE_IOCTL(AUDIO_SET_EXT_ID) | ||
3194 | COMPATIBLE_IOCTL(AUDIO_SET_ATTRIBUTES) | ||
3195 | COMPATIBLE_IOCTL(AUDIO_SET_KARAOKE) | ||
3196 | COMPATIBLE_IOCTL(DMX_START) | ||
3197 | COMPATIBLE_IOCTL(DMX_STOP) | ||
3198 | COMPATIBLE_IOCTL(DMX_SET_FILTER) | ||
3199 | COMPATIBLE_IOCTL(DMX_SET_PES_FILTER) | ||
3200 | COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE) | ||
3201 | COMPATIBLE_IOCTL(DMX_GET_PES_PIDS) | ||
3202 | COMPATIBLE_IOCTL(DMX_GET_CAPS) | ||
3203 | COMPATIBLE_IOCTL(DMX_SET_SOURCE) | ||
3204 | COMPATIBLE_IOCTL(DMX_GET_STC) | ||
3205 | COMPATIBLE_IOCTL(FE_GET_INFO) | ||
3206 | COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD) | ||
3207 | COMPATIBLE_IOCTL(FE_DISEQC_SEND_MASTER_CMD) | ||
3208 | COMPATIBLE_IOCTL(FE_DISEQC_RECV_SLAVE_REPLY) | ||
3209 | COMPATIBLE_IOCTL(FE_DISEQC_SEND_BURST) | ||
3210 | COMPATIBLE_IOCTL(FE_SET_TONE) | ||
3211 | COMPATIBLE_IOCTL(FE_SET_VOLTAGE) | ||
3212 | COMPATIBLE_IOCTL(FE_ENABLE_HIGH_LNB_VOLTAGE) | ||
3213 | COMPATIBLE_IOCTL(FE_READ_STATUS) | ||
3214 | COMPATIBLE_IOCTL(FE_READ_BER) | ||
3215 | COMPATIBLE_IOCTL(FE_READ_SIGNAL_STRENGTH) | ||
3216 | COMPATIBLE_IOCTL(FE_READ_SNR) | ||
3217 | COMPATIBLE_IOCTL(FE_READ_UNCORRECTED_BLOCKS) | ||
3218 | COMPATIBLE_IOCTL(FE_SET_FRONTEND) | ||
3219 | COMPATIBLE_IOCTL(FE_GET_FRONTEND) | ||
3220 | COMPATIBLE_IOCTL(FE_GET_EVENT) | ||
3221 | COMPATIBLE_IOCTL(FE_DISHNETWORK_SEND_LEGACY_CMD) | ||
3222 | COMPATIBLE_IOCTL(VIDEO_STOP) | ||
3223 | COMPATIBLE_IOCTL(VIDEO_PLAY) | ||
3224 | COMPATIBLE_IOCTL(VIDEO_FREEZE) | ||
3225 | COMPATIBLE_IOCTL(VIDEO_CONTINUE) | ||
3226 | COMPATIBLE_IOCTL(VIDEO_SELECT_SOURCE) | ||
3227 | COMPATIBLE_IOCTL(VIDEO_SET_BLANK) | ||
3228 | COMPATIBLE_IOCTL(VIDEO_GET_STATUS) | ||
3229 | COMPATIBLE_IOCTL(VIDEO_SET_DISPLAY_FORMAT) | ||
3230 | COMPATIBLE_IOCTL(VIDEO_FAST_FORWARD) | ||
3231 | COMPATIBLE_IOCTL(VIDEO_SLOWMOTION) | ||
3232 | COMPATIBLE_IOCTL(VIDEO_GET_CAPABILITIES) | ||
3233 | COMPATIBLE_IOCTL(VIDEO_CLEAR_BUFFER) | ||
3234 | COMPATIBLE_IOCTL(VIDEO_SET_ID) | ||
3235 | COMPATIBLE_IOCTL(VIDEO_SET_STREAMTYPE) | ||
3236 | COMPATIBLE_IOCTL(VIDEO_SET_FORMAT) | ||
3237 | COMPATIBLE_IOCTL(VIDEO_SET_SYSTEM) | ||
3238 | COMPATIBLE_IOCTL(VIDEO_SET_HIGHLIGHT) | ||
3239 | COMPATIBLE_IOCTL(VIDEO_SET_SPU) | ||
3240 | COMPATIBLE_IOCTL(VIDEO_GET_NAVI) | ||
3241 | COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES) | ||
3242 | COMPATIBLE_IOCTL(VIDEO_GET_SIZE) | ||
3243 | COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE) | ||
3244 | |||
3245 | /* now things that need handlers */ | ||
2410 | HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) | 3246 | HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) |
2411 | HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) | 3247 | HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) |
2412 | #ifdef CONFIG_NET | 3248 | #ifdef CONFIG_NET |
@@ -2638,4 +3474,156 @@ IGNORE_IOCTL(VFAT_IOCTL_READDIR_BOTH32) | |||
2638 | IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32) | 3474 | IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32) |
2639 | }; | 3475 | }; |
2640 | 3476 | ||
2641 | int ioctl_table_size = ARRAY_SIZE(ioctl_start); | 3477 | #define IOCTL_HASHSIZE 256 |
3478 | static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; | ||
3479 | |||
3480 | static inline unsigned long ioctl32_hash(unsigned long cmd) | ||
3481 | { | ||
3482 | return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; | ||
3483 | } | ||
3484 | |||
3485 | static void compat_ioctl_error(struct file *filp, unsigned int fd, | ||
3486 | unsigned int cmd, unsigned long arg) | ||
3487 | { | ||
3488 | char buf[10]; | ||
3489 | char *fn = "?"; | ||
3490 | char *path; | ||
3491 | |||
3492 | /* find the name of the device. */ | ||
3493 | path = (char *)__get_free_page(GFP_KERNEL); | ||
3494 | if (path) { | ||
3495 | fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE); | ||
3496 | if (IS_ERR(fn)) | ||
3497 | fn = "?"; | ||
3498 | } | ||
3499 | |||
3500 | sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK); | ||
3501 | if (!isprint(buf[1])) | ||
3502 | sprintf(buf, "%02x", buf[1]); | ||
3503 | compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) " | ||
3504 | "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n", | ||
3505 | current->comm, current->pid, | ||
3506 | (int)fd, (unsigned int)cmd, buf, | ||
3507 | (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK, | ||
3508 | (unsigned int)arg, fn); | ||
3509 | |||
3510 | if (path) | ||
3511 | free_page((unsigned long)path); | ||
3512 | } | ||
3513 | |||
3514 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | ||
3515 | unsigned long arg) | ||
3516 | { | ||
3517 | struct file *filp; | ||
3518 | int error = -EBADF; | ||
3519 | struct ioctl_trans *t; | ||
3520 | int fput_needed; | ||
3521 | |||
3522 | filp = fget_light(fd, &fput_needed); | ||
3523 | if (!filp) | ||
3524 | goto out; | ||
3525 | |||
3526 | /* RED-PEN how should LSM module know it's handling 32bit? */ | ||
3527 | error = security_file_ioctl(filp, cmd, arg); | ||
3528 | if (error) | ||
3529 | goto out_fput; | ||
3530 | |||
3531 | /* | ||
3532 | * To allow the compat_ioctl handlers to be self contained | ||
3533 | * we need to check the common ioctls here first. | ||
3534 | * Just handle them with the standard handlers below. | ||
3535 | */ | ||
3536 | switch (cmd) { | ||
3537 | case FIOCLEX: | ||
3538 | case FIONCLEX: | ||
3539 | case FIONBIO: | ||
3540 | case FIOASYNC: | ||
3541 | case FIOQSIZE: | ||
3542 | break; | ||
3543 | |||
3544 | case FIBMAP: | ||
3545 | case FIGETBSZ: | ||
3546 | case FIONREAD: | ||
3547 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | ||
3548 | break; | ||
3549 | /*FALL THROUGH*/ | ||
3550 | |||
3551 | default: | ||
3552 | if (filp->f_op && filp->f_op->compat_ioctl) { | ||
3553 | error = filp->f_op->compat_ioctl(filp, cmd, arg); | ||
3554 | if (error != -ENOIOCTLCMD) | ||
3555 | goto out_fput; | ||
3556 | } | ||
3557 | |||
3558 | if (!filp->f_op || | ||
3559 | (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl)) | ||
3560 | goto do_ioctl; | ||
3561 | break; | ||
3562 | } | ||
3563 | |||
3564 | for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) { | ||
3565 | if (t->cmd == cmd) | ||
3566 | goto found_handler; | ||
3567 | } | ||
3568 | |||
3569 | if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) && | ||
3570 | cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { | ||
3571 | error = siocdevprivate_ioctl(fd, cmd, arg); | ||
3572 | } else { | ||
3573 | static int count; | ||
3574 | |||
3575 | if (++count <= 50) | ||
3576 | compat_ioctl_error(filp, fd, cmd, arg); | ||
3577 | error = -EINVAL; | ||
3578 | } | ||
3579 | |||
3580 | goto out_fput; | ||
3581 | |||
3582 | found_handler: | ||
3583 | if (t->handler) { | ||
3584 | lock_kernel(); | ||
3585 | error = t->handler(fd, cmd, arg, filp); | ||
3586 | unlock_kernel(); | ||
3587 | goto out_fput; | ||
3588 | } | ||
3589 | |||
3590 | do_ioctl: | ||
3591 | error = vfs_ioctl(filp, fd, cmd, arg); | ||
3592 | out_fput: | ||
3593 | fput_light(filp, fput_needed); | ||
3594 | out: | ||
3595 | return error; | ||
3596 | } | ||
3597 | |||
3598 | static void ioctl32_insert_translation(struct ioctl_trans *trans) | ||
3599 | { | ||
3600 | unsigned long hash; | ||
3601 | struct ioctl_trans *t; | ||
3602 | |||
3603 | hash = ioctl32_hash (trans->cmd); | ||
3604 | if (!ioctl32_hash_table[hash]) | ||
3605 | ioctl32_hash_table[hash] = trans; | ||
3606 | else { | ||
3607 | t = ioctl32_hash_table[hash]; | ||
3608 | while (t->next) | ||
3609 | t = t->next; | ||
3610 | trans->next = NULL; | ||
3611 | t->next = trans; | ||
3612 | } | ||
3613 | } | ||
3614 | |||
3615 | static int __init init_sys32_ioctl(void) | ||
3616 | { | ||
3617 | int i; | ||
3618 | |||
3619 | for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) { | ||
3620 | if (ioctl_start[i].next != 0) { | ||
3621 | printk("ioctl translation %d bad\n",i); | ||
3622 | return -1; | ||
3623 | } | ||
3624 | |||
3625 | ioctl32_insert_translation(&ioctl_start[i]); | ||
3626 | } | ||
3627 | return 0; | ||
3628 | } | ||
3629 | __initcall(init_sys32_ioctl); | ||
diff --git a/fs/dcache.c b/fs/dcache.c index d1bf5d8aeb5a..0e73aa0a0e8b 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/fsnotify.h> | 21 | #include <linux/fsnotify.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/hash.h> | 24 | #include <linux/hash.h> |
26 | #include <linux/cache.h> | 25 | #include <linux/cache.h> |
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -121,6 +120,28 @@ static void dentry_iput(struct dentry * dentry) | |||
121 | } | 120 | } |
122 | } | 121 | } |
123 | 122 | ||
123 | /** | ||
124 | * d_kill - kill dentry and return parent | ||
125 | * @dentry: dentry to kill | ||
126 | * | ||
127 | * Called with dcache_lock and d_lock, releases both. The dentry must | ||
128 | * already be unhashed and removed from the LRU. | ||
129 | * | ||
130 | * If this is the root of the dentry tree, return NULL. | ||
131 | */ | ||
132 | static struct dentry *d_kill(struct dentry *dentry) | ||
133 | { | ||
134 | struct dentry *parent; | ||
135 | |||
136 | list_del(&dentry->d_u.d_child); | ||
137 | dentry_stat.nr_dentry--; /* For d_free, below */ | ||
138 | /*drops the locks, at that point nobody can reach this dentry */ | ||
139 | dentry_iput(dentry); | ||
140 | parent = dentry->d_parent; | ||
141 | d_free(dentry); | ||
142 | return dentry == parent ? NULL : parent; | ||
143 | } | ||
144 | |||
124 | /* | 145 | /* |
125 | * This is dput | 146 | * This is dput |
126 | * | 147 | * |
@@ -189,28 +210,17 @@ repeat: | |||
189 | 210 | ||
190 | unhash_it: | 211 | unhash_it: |
191 | __d_drop(dentry); | 212 | __d_drop(dentry); |
192 | 213 | kill_it: | |
193 | kill_it: { | 214 | /* If dentry was on d_lru list |
194 | struct dentry *parent; | 215 | * delete it from there |
195 | 216 | */ | |
196 | /* If dentry was on d_lru list | 217 | if (!list_empty(&dentry->d_lru)) { |
197 | * delete it from there | 218 | list_del(&dentry->d_lru); |
198 | */ | 219 | dentry_stat.nr_unused--; |
199 | if (!list_empty(&dentry->d_lru)) { | ||
200 | list_del(&dentry->d_lru); | ||
201 | dentry_stat.nr_unused--; | ||
202 | } | ||
203 | list_del(&dentry->d_u.d_child); | ||
204 | dentry_stat.nr_dentry--; /* For d_free, below */ | ||
205 | /*drops the locks, at that point nobody can reach this dentry */ | ||
206 | dentry_iput(dentry); | ||
207 | parent = dentry->d_parent; | ||
208 | d_free(dentry); | ||
209 | if (dentry == parent) | ||
210 | return; | ||
211 | dentry = parent; | ||
212 | goto repeat; | ||
213 | } | 220 | } |
221 | dentry = d_kill(dentry); | ||
222 | if (dentry) | ||
223 | goto repeat; | ||
214 | } | 224 | } |
215 | 225 | ||
216 | /** | 226 | /** |
@@ -371,22 +381,40 @@ restart: | |||
371 | * Throw away a dentry - free the inode, dput the parent. This requires that | 381 | * Throw away a dentry - free the inode, dput the parent. This requires that |
372 | * the LRU list has already been removed. | 382 | * the LRU list has already been removed. |
373 | * | 383 | * |
384 | * If prune_parents is true, try to prune ancestors as well. | ||
385 | * | ||
374 | * Called with dcache_lock, drops it and then regains. | 386 | * Called with dcache_lock, drops it and then regains. |
375 | * Called with dentry->d_lock held, drops it. | 387 | * Called with dentry->d_lock held, drops it. |
376 | */ | 388 | */ |
377 | static void prune_one_dentry(struct dentry * dentry) | 389 | static void prune_one_dentry(struct dentry * dentry, int prune_parents) |
378 | { | 390 | { |
379 | struct dentry * parent; | ||
380 | |||
381 | __d_drop(dentry); | 391 | __d_drop(dentry); |
382 | list_del(&dentry->d_u.d_child); | 392 | dentry = d_kill(dentry); |
383 | dentry_stat.nr_dentry--; /* For d_free, below */ | 393 | if (!prune_parents) { |
384 | dentry_iput(dentry); | 394 | dput(dentry); |
385 | parent = dentry->d_parent; | 395 | spin_lock(&dcache_lock); |
386 | d_free(dentry); | 396 | return; |
387 | if (parent != dentry) | 397 | } |
388 | dput(parent); | 398 | |
399 | /* | ||
400 | * Prune ancestors. Locking is simpler than in dput(), | ||
401 | * because dcache_lock needs to be taken anyway. | ||
402 | */ | ||
389 | spin_lock(&dcache_lock); | 403 | spin_lock(&dcache_lock); |
404 | while (dentry) { | ||
405 | if (!atomic_dec_and_lock(&dentry->d_count, &dentry->d_lock)) | ||
406 | return; | ||
407 | |||
408 | if (dentry->d_op && dentry->d_op->d_delete) | ||
409 | dentry->d_op->d_delete(dentry); | ||
410 | if (!list_empty(&dentry->d_lru)) { | ||
411 | list_del(&dentry->d_lru); | ||
412 | dentry_stat.nr_unused--; | ||
413 | } | ||
414 | __d_drop(dentry); | ||
415 | dentry = d_kill(dentry); | ||
416 | spin_lock(&dcache_lock); | ||
417 | } | ||
390 | } | 418 | } |
391 | 419 | ||
392 | /** | 420 | /** |
@@ -394,6 +422,7 @@ static void prune_one_dentry(struct dentry * dentry) | |||
394 | * @count: number of entries to try and free | 422 | * @count: number of entries to try and free |
395 | * @sb: if given, ignore dentries for other superblocks | 423 | * @sb: if given, ignore dentries for other superblocks |
396 | * which are being unmounted. | 424 | * which are being unmounted. |
425 | * @prune_parents: if true, try to prune ancestors as well in one go | ||
397 | * | 426 | * |
398 | * Shrink the dcache. This is done when we need | 427 | * Shrink the dcache. This is done when we need |
399 | * more memory, or simply when we need to unmount | 428 | * more memory, or simply when we need to unmount |
@@ -404,7 +433,7 @@ static void prune_one_dentry(struct dentry * dentry) | |||
404 | * all the dentries are in use. | 433 | * all the dentries are in use. |
405 | */ | 434 | */ |
406 | 435 | ||
407 | static void prune_dcache(int count, struct super_block *sb) | 436 | static void prune_dcache(int count, struct super_block *sb, int prune_parents) |
408 | { | 437 | { |
409 | spin_lock(&dcache_lock); | 438 | spin_lock(&dcache_lock); |
410 | for (; count ; count--) { | 439 | for (; count ; count--) { |
@@ -464,7 +493,7 @@ static void prune_dcache(int count, struct super_block *sb) | |||
464 | * without taking the s_umount lock (I already hold it). | 493 | * without taking the s_umount lock (I already hold it). |
465 | */ | 494 | */ |
466 | if (sb && dentry->d_sb == sb) { | 495 | if (sb && dentry->d_sb == sb) { |
467 | prune_one_dentry(dentry); | 496 | prune_one_dentry(dentry, prune_parents); |
468 | continue; | 497 | continue; |
469 | } | 498 | } |
470 | /* | 499 | /* |
@@ -479,7 +508,7 @@ static void prune_dcache(int count, struct super_block *sb) | |||
479 | s_umount = &dentry->d_sb->s_umount; | 508 | s_umount = &dentry->d_sb->s_umount; |
480 | if (down_read_trylock(s_umount)) { | 509 | if (down_read_trylock(s_umount)) { |
481 | if (dentry->d_sb->s_root != NULL) { | 510 | if (dentry->d_sb->s_root != NULL) { |
482 | prune_one_dentry(dentry); | 511 | prune_one_dentry(dentry, prune_parents); |
483 | up_read(s_umount); | 512 | up_read(s_umount); |
484 | continue; | 513 | continue; |
485 | } | 514 | } |
@@ -550,7 +579,7 @@ repeat: | |||
550 | spin_unlock(&dentry->d_lock); | 579 | spin_unlock(&dentry->d_lock); |
551 | continue; | 580 | continue; |
552 | } | 581 | } |
553 | prune_one_dentry(dentry); | 582 | prune_one_dentry(dentry, 1); |
554 | cond_resched_lock(&dcache_lock); | 583 | cond_resched_lock(&dcache_lock); |
555 | goto repeat; | 584 | goto repeat; |
556 | } | 585 | } |
@@ -829,7 +858,7 @@ void shrink_dcache_parent(struct dentry * parent) | |||
829 | int found; | 858 | int found; |
830 | 859 | ||
831 | while ((found = select_parent(parent)) != 0) | 860 | while ((found = select_parent(parent)) != 0) |
832 | prune_dcache(found, parent->d_sb); | 861 | prune_dcache(found, parent->d_sb, 1); |
833 | } | 862 | } |
834 | 863 | ||
835 | /* | 864 | /* |
@@ -849,7 +878,7 @@ static int shrink_dcache_memory(int nr, gfp_t gfp_mask) | |||
849 | if (nr) { | 878 | if (nr) { |
850 | if (!(gfp_mask & __GFP_FS)) | 879 | if (!(gfp_mask & __GFP_FS)) |
851 | return -1; | 880 | return -1; |
852 | prune_dcache(nr, NULL); | 881 | prune_dcache(nr, NULL, 1); |
853 | } | 882 | } |
854 | return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; | 883 | return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; |
855 | } | 884 | } |
@@ -1823,6 +1852,16 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | |||
1823 | struct vfsmount *rootmnt; | 1852 | struct vfsmount *rootmnt; |
1824 | struct dentry *root; | 1853 | struct dentry *root; |
1825 | 1854 | ||
1855 | /* | ||
1856 | * We have various synthetic filesystems that never get mounted. On | ||
1857 | * these filesystems dentries are never used for lookup purposes, and | ||
1858 | * thus don't need to be hashed. They also don't need a name until a | ||
1859 | * user wants to identify the object in /proc/pid/fd/. The little hack | ||
1860 | * below allows us to generate a name for these objects on demand: | ||
1861 | */ | ||
1862 | if (dentry->d_op && dentry->d_op->d_dname) | ||
1863 | return dentry->d_op->d_dname(dentry, buf, buflen); | ||
1864 | |||
1826 | read_lock(¤t->fs->lock); | 1865 | read_lock(¤t->fs->lock); |
1827 | rootmnt = mntget(current->fs->rootmnt); | 1866 | rootmnt = mntget(current->fs->rootmnt); |
1828 | root = dget(current->fs->root); | 1867 | root = dget(current->fs->root); |
@@ -1836,6 +1875,27 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | |||
1836 | } | 1875 | } |
1837 | 1876 | ||
1838 | /* | 1877 | /* |
1878 | * Helper function for dentry_operations.d_dname() members | ||
1879 | */ | ||
1880 | char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, | ||
1881 | const char *fmt, ...) | ||
1882 | { | ||
1883 | va_list args; | ||
1884 | char temp[64]; | ||
1885 | int sz; | ||
1886 | |||
1887 | va_start(args, fmt); | ||
1888 | sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1; | ||
1889 | va_end(args); | ||
1890 | |||
1891 | if (sz > sizeof(temp) || sz > buflen) | ||
1892 | return ERR_PTR(-ENAMETOOLONG); | ||
1893 | |||
1894 | buffer += buflen - sz; | ||
1895 | return memcpy(buffer, temp, sz); | ||
1896 | } | ||
1897 | |||
1898 | /* | ||
1839 | * NOTE! The user-level library version returns a | 1899 | * NOTE! The user-level library version returns a |
1840 | * character pointer. The kernel system call just | 1900 | * character pointer. The kernel system call just |
1841 | * returns the length of the buffer filled (which | 1901 | * returns the length of the buffer filled (which |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 643e57b622bd..06ef9a255c76 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/tty.h> | 19 | #include <linux/tty.h> |
20 | #include <linux/devpts_fs.h> | 20 | #include <linux/devpts_fs.h> |
21 | #include <linux/parser.h> | 21 | #include <linux/parser.h> |
22 | #include <linux/fsnotify.h> | ||
22 | 23 | ||
23 | #define DEVPTS_SUPER_MAGIC 0x1cd1 | 24 | #define DEVPTS_SUPER_MAGIC 0x1cd1 |
24 | 25 | ||
@@ -178,8 +179,10 @@ int devpts_pty_new(struct tty_struct *tty) | |||
178 | inode->i_private = tty; | 179 | inode->i_private = tty; |
179 | 180 | ||
180 | dentry = get_node(number); | 181 | dentry = get_node(number); |
181 | if (!IS_ERR(dentry) && !dentry->d_inode) | 182 | if (!IS_ERR(dentry) && !dentry->d_inode) { |
182 | d_instantiate(dentry, inode); | 183 | d_instantiate(dentry, inode); |
184 | fsnotify_create(devpts_root->d_inode, dentry); | ||
185 | } | ||
183 | 186 | ||
184 | mutex_unlock(&devpts_root->d_inode->i_mutex); | 187 | mutex_unlock(&devpts_root->d_inode->i_mutex); |
185 | 188 | ||
diff --git a/fs/dquot.c b/fs/dquot.c index 0a5febc159f2..3a995841de90 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -69,7 +69,6 @@ | |||
69 | #include <linux/file.h> | 69 | #include <linux/file.h> |
70 | #include <linux/slab.h> | 70 | #include <linux/slab.h> |
71 | #include <linux/sysctl.h> | 71 | #include <linux/sysctl.h> |
72 | #include <linux/smp_lock.h> | ||
73 | #include <linux/init.h> | 72 | #include <linux/init.h> |
74 | #include <linux/module.h> | 73 | #include <linux/module.h> |
75 | #include <linux/proc_fs.h> | 74 | #include <linux/proc_fs.h> |
@@ -475,7 +474,7 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
475 | spin_lock(&dq_list_lock); | 474 | spin_lock(&dq_list_lock); |
476 | dirty = &dqopt->info[cnt].dqi_dirty_list; | 475 | dirty = &dqopt->info[cnt].dqi_dirty_list; |
477 | while (!list_empty(dirty)) { | 476 | while (!list_empty(dirty)) { |
478 | dquot = list_entry(dirty->next, struct dquot, dq_dirty); | 477 | dquot = list_first_entry(dirty, struct dquot, dq_dirty); |
479 | /* Dirty and inactive can be only bad dquot... */ | 478 | /* Dirty and inactive can be only bad dquot... */ |
480 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { | 479 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { |
481 | clear_dquot_dirty(dquot); | 480 | clear_dquot_dirty(dquot); |
@@ -721,7 +720,8 @@ static inline int dqput_blocks(struct dquot *dquot) | |||
721 | 720 | ||
722 | /* Remove references to dquots from inode - add dquot to list for freeing if needed */ | 721 | /* Remove references to dquots from inode - add dquot to list for freeing if needed */ |
723 | /* We can't race with anybody because we hold dqptr_sem for writing... */ | 722 | /* We can't race with anybody because we hold dqptr_sem for writing... */ |
724 | int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head) | 723 | static int remove_inode_dquot_ref(struct inode *inode, int type, |
724 | struct list_head *tofree_head) | ||
725 | { | 725 | { |
726 | struct dquot *dquot = inode->i_dquot[type]; | 726 | struct dquot *dquot = inode->i_dquot[type]; |
727 | 727 | ||
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 7a7d25d541e7..9881b5c5de59 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/security.h> | 30 | #include <linux/security.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/compat.h> | 31 | #include <linux/compat.h> |
33 | #include <linux/fs_stack.h> | 32 | #include <linux/fs_stack.h> |
34 | #include "ecryptfs_kernel.h" | 33 | #include "ecryptfs_kernel.h" |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 3ae644e7e860..b5c7ca584939 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/poll.h> | 24 | #include <linux/poll.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/string.h> | 25 | #include <linux/string.h> |
27 | #include <linux/list.h> | 26 | #include <linux/list.h> |
28 | #include <linux/hash.h> | 27 | #include <linux/hash.h> |
@@ -185,7 +184,7 @@ struct eppoll_entry { | |||
185 | 184 | ||
186 | /* | 185 | /* |
187 | * Each file descriptor added to the eventpoll interface will | 186 | * Each file descriptor added to the eventpoll interface will |
188 | * have an entry of this type linked to the hash. | 187 | * have an entry of this type linked to the "rbr" RB tree. |
189 | */ | 188 | */ |
190 | struct epitem { | 189 | struct epitem { |
191 | /* RB-Tree node used to link this structure to the eventpoll rb-tree */ | 190 | /* RB-Tree node used to link this structure to the eventpoll rb-tree */ |
@@ -217,15 +216,6 @@ struct epitem { | |||
217 | 216 | ||
218 | /* List header used to link this item to the "struct file" items list */ | 217 | /* List header used to link this item to the "struct file" items list */ |
219 | struct list_head fllink; | 218 | struct list_head fllink; |
220 | |||
221 | /* List header used to link the item to the transfer list */ | ||
222 | struct list_head txlink; | ||
223 | |||
224 | /* | ||
225 | * This is used during the collection/transfer of events to userspace | ||
226 | * to pin items empty events set. | ||
227 | */ | ||
228 | unsigned int revents; | ||
229 | }; | 219 | }; |
230 | 220 | ||
231 | /* Wrapper struct used by poll queueing */ | 221 | /* Wrapper struct used by poll queueing */ |
@@ -258,11 +248,8 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi); | |||
258 | static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key); | 248 | static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key); |
259 | static int ep_eventpoll_close(struct inode *inode, struct file *file); | 249 | static int ep_eventpoll_close(struct inode *inode, struct file *file); |
260 | static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait); | 250 | static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait); |
261 | static int ep_collect_ready_items(struct eventpoll *ep, | ||
262 | struct list_head *txlist, int maxevents); | ||
263 | static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, | 251 | static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, |
264 | struct epoll_event __user *events); | 252 | struct epoll_event __user *events, int maxevents); |
265 | static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist); | ||
266 | static int ep_events_transfer(struct eventpoll *ep, | 253 | static int ep_events_transfer(struct eventpoll *ep, |
267 | struct epoll_event __user *events, | 254 | struct epoll_event __user *events, |
268 | int maxevents); | 255 | int maxevents); |
@@ -355,17 +342,6 @@ static inline int ep_rb_linked(struct rb_node *n) | |||
355 | return rb_parent(n) != n; | 342 | return rb_parent(n) != n; |
356 | } | 343 | } |
357 | 344 | ||
358 | /* | ||
359 | * Remove the item from the list and perform its initialization. | ||
360 | * This is useful for us because we can test if the item is linked | ||
361 | * using "ep_is_linked(p)". | ||
362 | */ | ||
363 | static inline void ep_list_del(struct list_head *p) | ||
364 | { | ||
365 | list_del(p); | ||
366 | INIT_LIST_HEAD(p); | ||
367 | } | ||
368 | |||
369 | /* Tells us if the item is currently linked */ | 345 | /* Tells us if the item is currently linked */ |
370 | static inline int ep_is_linked(struct list_head *p) | 346 | static inline int ep_is_linked(struct list_head *p) |
371 | { | 347 | { |
@@ -385,7 +361,7 @@ static inline struct epitem * ep_item_from_epqueue(poll_table *p) | |||
385 | } | 361 | } |
386 | 362 | ||
387 | /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ | 363 | /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ |
388 | static inline int ep_op_hash_event(int op) | 364 | static inline int ep_op_has_event(int op) |
389 | { | 365 | { |
390 | return op != EPOLL_CTL_DEL; | 366 | return op != EPOLL_CTL_DEL; |
391 | } | 367 | } |
@@ -477,10 +453,10 @@ void eventpoll_release_file(struct file *file) | |||
477 | mutex_lock(&epmutex); | 453 | mutex_lock(&epmutex); |
478 | 454 | ||
479 | while (!list_empty(lsthead)) { | 455 | while (!list_empty(lsthead)) { |
480 | epi = list_entry(lsthead->next, struct epitem, fllink); | 456 | epi = list_first_entry(lsthead, struct epitem, fllink); |
481 | 457 | ||
482 | ep = epi->ep; | 458 | ep = epi->ep; |
483 | ep_list_del(&epi->fllink); | 459 | list_del_init(&epi->fllink); |
484 | down_write(&ep->sem); | 460 | down_write(&ep->sem); |
485 | ep_remove(ep, epi); | 461 | ep_remove(ep, epi); |
486 | up_write(&ep->sem); | 462 | up_write(&ep->sem); |
@@ -557,7 +533,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) | |||
557 | current, epfd, op, fd, event)); | 533 | current, epfd, op, fd, event)); |
558 | 534 | ||
559 | error = -EFAULT; | 535 | error = -EFAULT; |
560 | if (ep_op_hash_event(op) && | 536 | if (ep_op_has_event(op) && |
561 | copy_from_user(&epds, event, sizeof(struct epoll_event))) | 537 | copy_from_user(&epds, event, sizeof(struct epoll_event))) |
562 | goto eexit_1; | 538 | goto eexit_1; |
563 | 539 | ||
@@ -594,7 +570,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) | |||
594 | 570 | ||
595 | down_write(&ep->sem); | 571 | down_write(&ep->sem); |
596 | 572 | ||
597 | /* Try to lookup the file inside our hash table */ | 573 | /* Try to lookup the file inside our RB tree */ |
598 | epi = ep_find(ep, tfile, fd); | 574 | epi = ep_find(ep, tfile, fd); |
599 | 575 | ||
600 | error = -EINVAL; | 576 | error = -EINVAL; |
@@ -876,7 +852,7 @@ static void ep_free(struct eventpoll *ep) | |||
876 | } | 852 | } |
877 | 853 | ||
878 | /* | 854 | /* |
879 | * Walks through the whole hash by freeing each "struct epitem". At this | 855 | * Walks through the whole tree by freeing each "struct epitem". At this |
880 | * point we are sure no poll callbacks will be lingering around, and also by | 856 | * point we are sure no poll callbacks will be lingering around, and also by |
881 | * write-holding "sem" we can be sure that no file cleanup code will hit | 857 | * write-holding "sem" we can be sure that no file cleanup code will hit |
882 | * us during this operation. So we can avoid the lock on "ep->lock". | 858 | * us during this operation. So we can avoid the lock on "ep->lock". |
@@ -891,7 +867,7 @@ static void ep_free(struct eventpoll *ep) | |||
891 | 867 | ||
892 | 868 | ||
893 | /* | 869 | /* |
894 | * Search the file inside the eventpoll hash. It add usage count to | 870 | * Search the file inside the eventpoll tree. It add usage count to |
895 | * the returned item, so the caller must call ep_release_epitem() | 871 | * the returned item, so the caller must call ep_release_epitem() |
896 | * after finished using the "struct epitem". | 872 | * after finished using the "struct epitem". |
897 | */ | 873 | */ |
@@ -1011,7 +987,6 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
1011 | ep_rb_initnode(&epi->rbn); | 987 | ep_rb_initnode(&epi->rbn); |
1012 | INIT_LIST_HEAD(&epi->rdllink); | 988 | INIT_LIST_HEAD(&epi->rdllink); |
1013 | INIT_LIST_HEAD(&epi->fllink); | 989 | INIT_LIST_HEAD(&epi->fllink); |
1014 | INIT_LIST_HEAD(&epi->txlink); | ||
1015 | INIT_LIST_HEAD(&epi->pwqlist); | 990 | INIT_LIST_HEAD(&epi->pwqlist); |
1016 | epi->ep = ep; | 991 | epi->ep = ep; |
1017 | ep_set_ffd(&epi->ffd, tfile, fd); | 992 | ep_set_ffd(&epi->ffd, tfile, fd); |
@@ -1080,7 +1055,7 @@ eexit_2: | |||
1080 | */ | 1055 | */ |
1081 | write_lock_irqsave(&ep->lock, flags); | 1056 | write_lock_irqsave(&ep->lock, flags); |
1082 | if (ep_is_linked(&epi->rdllink)) | 1057 | if (ep_is_linked(&epi->rdllink)) |
1083 | ep_list_del(&epi->rdllink); | 1058 | list_del_init(&epi->rdllink); |
1084 | write_unlock_irqrestore(&ep->lock, flags); | 1059 | write_unlock_irqrestore(&ep->lock, flags); |
1085 | 1060 | ||
1086 | kmem_cache_free(epi_cache, epi); | 1061 | kmem_cache_free(epi_cache, epi); |
@@ -1119,7 +1094,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even | |||
1119 | epi->event.data = event->data; | 1094 | epi->event.data = event->data; |
1120 | 1095 | ||
1121 | /* | 1096 | /* |
1122 | * If the item is not linked to the hash it means that it's on its | 1097 | * If the item is not linked to the RB tree it means that it's on its |
1123 | * way toward the removal. Do nothing in this case. | 1098 | * way toward the removal. Do nothing in this case. |
1124 | */ | 1099 | */ |
1125 | if (ep_rb_linked(&epi->rbn)) { | 1100 | if (ep_rb_linked(&epi->rbn)) { |
@@ -1168,9 +1143,9 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi) | |||
1168 | 1143 | ||
1169 | if (nwait) { | 1144 | if (nwait) { |
1170 | while (!list_empty(lsthead)) { | 1145 | while (!list_empty(lsthead)) { |
1171 | pwq = list_entry(lsthead->next, struct eppoll_entry, llink); | 1146 | pwq = list_first_entry(lsthead, struct eppoll_entry, llink); |
1172 | 1147 | ||
1173 | ep_list_del(&pwq->llink); | 1148 | list_del_init(&pwq->llink); |
1174 | remove_wait_queue(pwq->whead, &pwq->wait); | 1149 | remove_wait_queue(pwq->whead, &pwq->wait); |
1175 | kmem_cache_free(pwq_cache, pwq); | 1150 | kmem_cache_free(pwq_cache, pwq); |
1176 | } | 1151 | } |
@@ -1213,7 +1188,7 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi) | |||
1213 | * we want to remove it from this list to avoid stale events. | 1188 | * we want to remove it from this list to avoid stale events. |
1214 | */ | 1189 | */ |
1215 | if (ep_is_linked(&epi->rdllink)) | 1190 | if (ep_is_linked(&epi->rdllink)) |
1216 | ep_list_del(&epi->rdllink); | 1191 | list_del_init(&epi->rdllink); |
1217 | 1192 | ||
1218 | error = 0; | 1193 | error = 0; |
1219 | eexit_1: | 1194 | eexit_1: |
@@ -1226,7 +1201,7 @@ eexit_1: | |||
1226 | 1201 | ||
1227 | 1202 | ||
1228 | /* | 1203 | /* |
1229 | * Removes a "struct epitem" from the eventpoll hash and deallocates | 1204 | * Removes a "struct epitem" from the eventpoll RB tree and deallocates |
1230 | * all the associated resources. | 1205 | * all the associated resources. |
1231 | */ | 1206 | */ |
1232 | static int ep_remove(struct eventpoll *ep, struct epitem *epi) | 1207 | static int ep_remove(struct eventpoll *ep, struct epitem *epi) |
@@ -1248,13 +1223,13 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) | |||
1248 | /* Remove the current item from the list of epoll hooks */ | 1223 | /* Remove the current item from the list of epoll hooks */ |
1249 | spin_lock(&file->f_ep_lock); | 1224 | spin_lock(&file->f_ep_lock); |
1250 | if (ep_is_linked(&epi->fllink)) | 1225 | if (ep_is_linked(&epi->fllink)) |
1251 | ep_list_del(&epi->fllink); | 1226 | list_del_init(&epi->fllink); |
1252 | spin_unlock(&file->f_ep_lock); | 1227 | spin_unlock(&file->f_ep_lock); |
1253 | 1228 | ||
1254 | /* We need to acquire the write IRQ lock before calling ep_unlink() */ | 1229 | /* We need to acquire the write IRQ lock before calling ep_unlink() */ |
1255 | write_lock_irqsave(&ep->lock, flags); | 1230 | write_lock_irqsave(&ep->lock, flags); |
1256 | 1231 | ||
1257 | /* Really unlink the item from the hash */ | 1232 | /* Really unlink the item from the RB tree */ |
1258 | error = ep_unlink(ep, epi); | 1233 | error = ep_unlink(ep, epi); |
1259 | 1234 | ||
1260 | write_unlock_irqrestore(&ep->lock, flags); | 1235 | write_unlock_irqrestore(&ep->lock, flags); |
@@ -1362,71 +1337,30 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait) | |||
1362 | 1337 | ||
1363 | 1338 | ||
1364 | /* | 1339 | /* |
1365 | * Since we have to release the lock during the __copy_to_user() operation and | ||
1366 | * during the f_op->poll() call, we try to collect the maximum number of items | ||
1367 | * by reducing the irqlock/irqunlock switching rate. | ||
1368 | */ | ||
1369 | static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist, int maxevents) | ||
1370 | { | ||
1371 | int nepi; | ||
1372 | unsigned long flags; | ||
1373 | struct list_head *lsthead = &ep->rdllist, *lnk; | ||
1374 | struct epitem *epi; | ||
1375 | |||
1376 | write_lock_irqsave(&ep->lock, flags); | ||
1377 | |||
1378 | for (nepi = 0, lnk = lsthead->next; lnk != lsthead && nepi < maxevents;) { | ||
1379 | epi = list_entry(lnk, struct epitem, rdllink); | ||
1380 | |||
1381 | lnk = lnk->next; | ||
1382 | |||
1383 | /* If this file is already in the ready list we exit soon */ | ||
1384 | if (!ep_is_linked(&epi->txlink)) { | ||
1385 | /* | ||
1386 | * This is initialized in this way so that the default | ||
1387 | * behaviour of the reinjecting code will be to push back | ||
1388 | * the item inside the ready list. | ||
1389 | */ | ||
1390 | epi->revents = epi->event.events; | ||
1391 | |||
1392 | /* Link the ready item into the transfer list */ | ||
1393 | list_add(&epi->txlink, txlist); | ||
1394 | nepi++; | ||
1395 | |||
1396 | /* | ||
1397 | * Unlink the item from the ready list. | ||
1398 | */ | ||
1399 | ep_list_del(&epi->rdllink); | ||
1400 | } | ||
1401 | } | ||
1402 | |||
1403 | write_unlock_irqrestore(&ep->lock, flags); | ||
1404 | |||
1405 | return nepi; | ||
1406 | } | ||
1407 | |||
1408 | |||
1409 | /* | ||
1410 | * This function is called without holding the "ep->lock" since the call to | 1340 | * This function is called without holding the "ep->lock" since the call to |
1411 | * __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ | 1341 | * __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ |
1412 | * because of the way poll() is traditionally implemented in Linux. | 1342 | * because of the way poll() is traditionally implemented in Linux. |
1413 | */ | 1343 | */ |
1414 | static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, | 1344 | static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, |
1415 | struct epoll_event __user *events) | 1345 | struct epoll_event __user *events, int maxevents) |
1416 | { | 1346 | { |
1417 | int eventcnt = 0; | 1347 | int eventcnt, error = -EFAULT, pwake = 0; |
1418 | unsigned int revents; | 1348 | unsigned int revents; |
1419 | struct list_head *lnk; | 1349 | unsigned long flags; |
1420 | struct epitem *epi; | 1350 | struct epitem *epi; |
1351 | struct list_head injlist; | ||
1352 | |||
1353 | INIT_LIST_HEAD(&injlist); | ||
1421 | 1354 | ||
1422 | /* | 1355 | /* |
1423 | * We can loop without lock because this is a task private list. | 1356 | * We can loop without lock because this is a task private list. |
1424 | * The test done during the collection loop will guarantee us that | 1357 | * We just splice'd out the ep->rdllist in ep_collect_ready_items(). |
1425 | * another task will not try to collect this file. Also, items | 1358 | * Items cannot vanish during the loop because we are holding "sem" in |
1426 | * cannot vanish during the loop because we are holding "sem". | 1359 | * read. |
1427 | */ | 1360 | */ |
1428 | list_for_each(lnk, txlist) { | 1361 | for (eventcnt = 0; !list_empty(txlist) && eventcnt < maxevents;) { |
1429 | epi = list_entry(lnk, struct epitem, txlink); | 1362 | epi = list_first_entry(txlist, struct epitem, rdllink); |
1363 | prefetch(epi->rdllink.next); | ||
1430 | 1364 | ||
1431 | /* | 1365 | /* |
1432 | * Get the ready file event set. We can safely use the file | 1366 | * Get the ready file event set. We can safely use the file |
@@ -1434,64 +1368,65 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, | |||
1434 | * guarantee that both the file and the item will not vanish. | 1368 | * guarantee that both the file and the item will not vanish. |
1435 | */ | 1369 | */ |
1436 | revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL); | 1370 | revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL); |
1371 | revents &= epi->event.events; | ||
1437 | 1372 | ||
1438 | /* | 1373 | /* |
1439 | * Set the return event set for the current file descriptor. | 1374 | * Is the event mask intersect the caller-requested one, |
1440 | * Note that only the task task was successfully able to link | 1375 | * deliver the event to userspace. Again, we are holding |
1441 | * the item to its "txlist" will write this field. | 1376 | * "sem" in read, so no operations coming from userspace |
1377 | * can change the item. | ||
1442 | */ | 1378 | */ |
1443 | epi->revents = revents & epi->event.events; | 1379 | if (revents) { |
1444 | 1380 | if (__put_user(revents, | |
1445 | if (epi->revents) { | ||
1446 | if (__put_user(epi->revents, | ||
1447 | &events[eventcnt].events) || | 1381 | &events[eventcnt].events) || |
1448 | __put_user(epi->event.data, | 1382 | __put_user(epi->event.data, |
1449 | &events[eventcnt].data)) | 1383 | &events[eventcnt].data)) |
1450 | return -EFAULT; | 1384 | goto errxit; |
1451 | if (epi->event.events & EPOLLONESHOT) | 1385 | if (epi->event.events & EPOLLONESHOT) |
1452 | epi->event.events &= EP_PRIVATE_BITS; | 1386 | epi->event.events &= EP_PRIVATE_BITS; |
1453 | eventcnt++; | 1387 | eventcnt++; |
1454 | } | 1388 | } |
1455 | } | ||
1456 | return eventcnt; | ||
1457 | } | ||
1458 | |||
1459 | |||
1460 | /* | ||
1461 | * Walk through the transfer list we collected with ep_collect_ready_items() | ||
1462 | * and, if 1) the item is still "alive" 2) its event set is not empty 3) it's | ||
1463 | * not already linked, links it to the ready list. Same as above, we are holding | ||
1464 | * "sem" so items cannot vanish underneath our nose. | ||
1465 | */ | ||
1466 | static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist) | ||
1467 | { | ||
1468 | int ricnt = 0, pwake = 0; | ||
1469 | unsigned long flags; | ||
1470 | struct epitem *epi; | ||
1471 | |||
1472 | write_lock_irqsave(&ep->lock, flags); | ||
1473 | |||
1474 | while (!list_empty(txlist)) { | ||
1475 | epi = list_entry(txlist->next, struct epitem, txlink); | ||
1476 | |||
1477 | /* Unlink the current item from the transfer list */ | ||
1478 | ep_list_del(&epi->txlink); | ||
1479 | 1389 | ||
1480 | /* | 1390 | /* |
1481 | * If the item is no more linked to the interest set, we don't | 1391 | * This is tricky. We are holding the "sem" in read, and this |
1482 | * have to push it inside the ready list because the following | 1392 | * means that the operations that can change the "linked" status |
1483 | * ep_release_epitem() is going to drop it. Also, if the current | 1393 | * of the epoll item (epi->rbn and epi->rdllink), cannot touch |
1484 | * item is set to have an Edge Triggered behaviour, we don't have | 1394 | * them. Also, since we are "linked" from a epi->rdllink POV |
1485 | * to push it back either. | 1395 | * (the item is linked to our transmission list we just |
1396 | * spliced), the ep_poll_callback() cannot touch us either, | ||
1397 | * because of the check present in there. Another parallel | ||
1398 | * epoll_wait() will not get the same result set, since we | ||
1399 | * spliced the ready list before. Note that list_del() still | ||
1400 | * shows the item as linked to the test in ep_poll_callback(). | ||
1486 | */ | 1401 | */ |
1487 | if (ep_rb_linked(&epi->rbn) && !(epi->event.events & EPOLLET) && | 1402 | list_del(&epi->rdllink); |
1488 | (epi->revents & epi->event.events) && !ep_is_linked(&epi->rdllink)) { | 1403 | if (!(epi->event.events & EPOLLET) && |
1489 | list_add_tail(&epi->rdllink, &ep->rdllist); | 1404 | (revents & epi->event.events)) |
1490 | ricnt++; | 1405 | list_add_tail(&epi->rdllink, &injlist); |
1406 | else { | ||
1407 | /* | ||
1408 | * Be sure the item is totally detached before re-init | ||
1409 | * the list_head. After INIT_LIST_HEAD() is committed, | ||
1410 | * the ep_poll_callback() can requeue the item again, | ||
1411 | * but we don't care since we are already past it. | ||
1412 | */ | ||
1413 | smp_mb(); | ||
1414 | INIT_LIST_HEAD(&epi->rdllink); | ||
1491 | } | 1415 | } |
1492 | } | 1416 | } |
1417 | error = 0; | ||
1493 | 1418 | ||
1494 | if (ricnt) { | 1419 | errxit: |
1420 | |||
1421 | /* | ||
1422 | * If the re-injection list or the txlist are not empty, re-splice | ||
1423 | * them to the ready list and do proper wakeups. | ||
1424 | */ | ||
1425 | if (!list_empty(&injlist) || !list_empty(txlist)) { | ||
1426 | write_lock_irqsave(&ep->lock, flags); | ||
1427 | |||
1428 | list_splice(txlist, &ep->rdllist); | ||
1429 | list_splice(&injlist, &ep->rdllist); | ||
1495 | /* | 1430 | /* |
1496 | * Wake up ( if active ) both the eventpoll wait list and the ->poll() | 1431 | * Wake up ( if active ) both the eventpoll wait list and the ->poll() |
1497 | * wait list. | 1432 | * wait list. |
@@ -1501,13 +1436,15 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist) | |||
1501 | TASK_INTERRUPTIBLE); | 1436 | TASK_INTERRUPTIBLE); |
1502 | if (waitqueue_active(&ep->poll_wait)) | 1437 | if (waitqueue_active(&ep->poll_wait)) |
1503 | pwake++; | 1438 | pwake++; |
1504 | } | ||
1505 | 1439 | ||
1506 | write_unlock_irqrestore(&ep->lock, flags); | 1440 | write_unlock_irqrestore(&ep->lock, flags); |
1441 | } | ||
1507 | 1442 | ||
1508 | /* We have to call this outside the lock */ | 1443 | /* We have to call this outside the lock */ |
1509 | if (pwake) | 1444 | if (pwake) |
1510 | ep_poll_safewake(&psw, &ep->poll_wait); | 1445 | ep_poll_safewake(&psw, &ep->poll_wait); |
1446 | |||
1447 | return eventcnt == 0 ? error: eventcnt; | ||
1511 | } | 1448 | } |
1512 | 1449 | ||
1513 | 1450 | ||
@@ -1517,7 +1454,8 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist) | |||
1517 | static int ep_events_transfer(struct eventpoll *ep, | 1454 | static int ep_events_transfer(struct eventpoll *ep, |
1518 | struct epoll_event __user *events, int maxevents) | 1455 | struct epoll_event __user *events, int maxevents) |
1519 | { | 1456 | { |
1520 | int eventcnt = 0; | 1457 | int eventcnt; |
1458 | unsigned long flags; | ||
1521 | struct list_head txlist; | 1459 | struct list_head txlist; |
1522 | 1460 | ||
1523 | INIT_LIST_HEAD(&txlist); | 1461 | INIT_LIST_HEAD(&txlist); |
@@ -1528,14 +1466,17 @@ static int ep_events_transfer(struct eventpoll *ep, | |||
1528 | */ | 1466 | */ |
1529 | down_read(&ep->sem); | 1467 | down_read(&ep->sem); |
1530 | 1468 | ||
1531 | /* Collect/extract ready items */ | 1469 | /* |
1532 | if (ep_collect_ready_items(ep, &txlist, maxevents) > 0) { | 1470 | * Steal the ready list, and re-init the original one to the |
1533 | /* Build result set in userspace */ | 1471 | * empty list. |
1534 | eventcnt = ep_send_events(ep, &txlist, events); | 1472 | */ |
1473 | write_lock_irqsave(&ep->lock, flags); | ||
1474 | list_splice(&ep->rdllist, &txlist); | ||
1475 | INIT_LIST_HEAD(&ep->rdllist); | ||
1476 | write_unlock_irqrestore(&ep->lock, flags); | ||
1535 | 1477 | ||
1536 | /* Reinject ready items into the ready list */ | 1478 | /* Build result set in userspace */ |
1537 | ep_reinject_items(ep, &txlist); | 1479 | eventcnt = ep_send_events(ep, &txlist, events, maxevents); |
1538 | } | ||
1539 | 1480 | ||
1540 | up_read(&ep->sem); | 1481 | up_read(&ep->sem); |
1541 | 1482 | ||
@@ -1612,14 +1553,12 @@ retry: | |||
1612 | return res; | 1553 | return res; |
1613 | } | 1554 | } |
1614 | 1555 | ||
1615 | |||
1616 | static int eventpollfs_delete_dentry(struct dentry *dentry) | 1556 | static int eventpollfs_delete_dentry(struct dentry *dentry) |
1617 | { | 1557 | { |
1618 | 1558 | ||
1619 | return 1; | 1559 | return 1; |
1620 | } | 1560 | } |
1621 | 1561 | ||
1622 | |||
1623 | static struct inode *ep_eventpoll_inode(void) | 1562 | static struct inode *ep_eventpoll_inode(void) |
1624 | { | 1563 | { |
1625 | int error = -ENOMEM; | 1564 | int error = -ENOMEM; |
@@ -1647,7 +1586,6 @@ eexit_1: | |||
1647 | return ERR_PTR(error); | 1586 | return ERR_PTR(error); |
1648 | } | 1587 | } |
1649 | 1588 | ||
1650 | |||
1651 | static int | 1589 | static int |
1652 | eventpollfs_get_sb(struct file_system_type *fs_type, int flags, | 1590 | eventpollfs_get_sb(struct file_system_type *fs_type, int flags, |
1653 | const char *dev_name, void *data, struct vfsmount *mnt) | 1591 | const char *dev_name, void *data, struct vfsmount *mnt) |
@@ -100,6 +100,7 @@ int unregister_binfmt(struct linux_binfmt * fmt) | |||
100 | while (*tmp) { | 100 | while (*tmp) { |
101 | if (fmt == *tmp) { | 101 | if (fmt == *tmp) { |
102 | *tmp = fmt->next; | 102 | *tmp = fmt->next; |
103 | fmt->next = NULL; | ||
103 | write_unlock(&binfmt_lock); | 104 | write_unlock(&binfmt_lock); |
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |
@@ -982,33 +983,51 @@ void compute_creds(struct linux_binprm *bprm) | |||
982 | task_unlock(current); | 983 | task_unlock(current); |
983 | security_bprm_post_apply_creds(bprm); | 984 | security_bprm_post_apply_creds(bprm); |
984 | } | 985 | } |
985 | |||
986 | EXPORT_SYMBOL(compute_creds); | 986 | EXPORT_SYMBOL(compute_creds); |
987 | 987 | ||
988 | /* | ||
989 | * Arguments are '\0' separated strings found at the location bprm->p | ||
990 | * points to; chop off the first by relocating brpm->p to right after | ||
991 | * the first '\0' encountered. | ||
992 | */ | ||
988 | void remove_arg_zero(struct linux_binprm *bprm) | 993 | void remove_arg_zero(struct linux_binprm *bprm) |
989 | { | 994 | { |
990 | if (bprm->argc) { | 995 | if (bprm->argc) { |
991 | unsigned long offset; | 996 | char ch; |
992 | char * kaddr; | ||
993 | struct page *page; | ||
994 | 997 | ||
995 | offset = bprm->p % PAGE_SIZE; | 998 | do { |
996 | goto inside; | 999 | unsigned long offset; |
1000 | unsigned long index; | ||
1001 | char *kaddr; | ||
1002 | struct page *page; | ||
997 | 1003 | ||
998 | while (bprm->p++, *(kaddr+offset++)) { | 1004 | offset = bprm->p & ~PAGE_MASK; |
999 | if (offset != PAGE_SIZE) | 1005 | index = bprm->p >> PAGE_SHIFT; |
1000 | continue; | 1006 | |
1001 | offset = 0; | 1007 | page = bprm->page[index]; |
1002 | kunmap_atomic(kaddr, KM_USER0); | ||
1003 | inside: | ||
1004 | page = bprm->page[bprm->p/PAGE_SIZE]; | ||
1005 | kaddr = kmap_atomic(page, KM_USER0); | 1008 | kaddr = kmap_atomic(page, KM_USER0); |
1006 | } | 1009 | |
1007 | kunmap_atomic(kaddr, KM_USER0); | 1010 | /* run through page until we reach end or find NUL */ |
1011 | do { | ||
1012 | ch = *(kaddr + offset); | ||
1013 | |||
1014 | /* discard that character... */ | ||
1015 | bprm->p++; | ||
1016 | offset++; | ||
1017 | } while (offset < PAGE_SIZE && ch != '\0'); | ||
1018 | |||
1019 | kunmap_atomic(kaddr, KM_USER0); | ||
1020 | |||
1021 | /* free the old page */ | ||
1022 | if (offset == PAGE_SIZE) { | ||
1023 | __free_page(page); | ||
1024 | bprm->page[index] = NULL; | ||
1025 | } | ||
1026 | } while (ch != '\0'); | ||
1027 | |||
1008 | bprm->argc--; | 1028 | bprm->argc--; |
1009 | } | 1029 | } |
1010 | } | 1030 | } |
1011 | |||
1012 | EXPORT_SYMBOL(remove_arg_zero); | 1031 | EXPORT_SYMBOL(remove_arg_zero); |
1013 | 1032 | ||
1014 | /* | 1033 | /* |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 93e77c3d2490..e98f6cd7200c 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -2,7 +2,6 @@ | |||
2 | #include <linux/fs.h> | 2 | #include <linux/fs.h> |
3 | #include <linux/file.h> | 3 | #include <linux/file.h> |
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/smp_lock.h> | ||
6 | #include <linux/namei.h> | 5 | #include <linux/namei.h> |
7 | 6 | ||
8 | struct export_operations export_op_default; | 7 | struct export_operations export_op_default; |
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 1d1e7e30d70e..2bf49d7ef841 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include "ext2.h" | 24 | #include "ext2.h" |
25 | #include <linux/pagemap.h> | 25 | #include <linux/pagemap.h> |
26 | #include <linux/smp_lock.h> | ||
27 | 26 | ||
28 | typedef struct ext2_dir_entry_2 ext2_dirent; | 27 | typedef struct ext2_dir_entry_2 ext2_dirent; |
29 | 28 | ||
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index e2a0ea50af1d..9fd0ec5ba0d0 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -133,6 +133,7 @@ extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); | |||
133 | extern void ext2_truncate (struct inode *); | 133 | extern void ext2_truncate (struct inode *); |
134 | extern int ext2_setattr (struct dentry *, struct iattr *); | 134 | extern int ext2_setattr (struct dentry *, struct iattr *); |
135 | extern void ext2_set_inode_flags(struct inode *inode); | 135 | extern void ext2_set_inode_flags(struct inode *inode); |
136 | extern void ext2_get_inode_flags(struct ext2_inode_info *); | ||
136 | 137 | ||
137 | /* ioctl.c */ | 138 | /* ioctl.c */ |
138 | extern int ext2_ioctl (struct inode *, struct file *, unsigned int, | 139 | extern int ext2_ioctl (struct inode *, struct file *, unsigned int, |
diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c index 7806b9e8155b..fc66c93fcb5c 100644 --- a/fs/ext2/fsync.c +++ b/fs/ext2/fsync.c | |||
@@ -23,7 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "ext2.h" | 25 | #include "ext2.h" |
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/buffer_head.h> /* for sync_mapping_buffers() */ | 26 | #include <linux/buffer_head.h> /* for sync_mapping_buffers() */ |
28 | 27 | ||
29 | 28 | ||
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index dd4e14c221e0..0079b2cd5314 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -1055,6 +1055,25 @@ void ext2_set_inode_flags(struct inode *inode) | |||
1055 | inode->i_flags |= S_DIRSYNC; | 1055 | inode->i_flags |= S_DIRSYNC; |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */ | ||
1059 | void ext2_get_inode_flags(struct ext2_inode_info *ei) | ||
1060 | { | ||
1061 | unsigned int flags = ei->vfs_inode.i_flags; | ||
1062 | |||
1063 | ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL| | ||
1064 | EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL); | ||
1065 | if (flags & S_SYNC) | ||
1066 | ei->i_flags |= EXT2_SYNC_FL; | ||
1067 | if (flags & S_APPEND) | ||
1068 | ei->i_flags |= EXT2_APPEND_FL; | ||
1069 | if (flags & S_IMMUTABLE) | ||
1070 | ei->i_flags |= EXT2_IMMUTABLE_FL; | ||
1071 | if (flags & S_NOATIME) | ||
1072 | ei->i_flags |= EXT2_NOATIME_FL; | ||
1073 | if (flags & S_DIRSYNC) | ||
1074 | ei->i_flags |= EXT2_DIRSYNC_FL; | ||
1075 | } | ||
1076 | |||
1058 | void ext2_read_inode (struct inode * inode) | 1077 | void ext2_read_inode (struct inode * inode) |
1059 | { | 1078 | { |
1060 | struct ext2_inode_info *ei = EXT2_I(inode); | 1079 | struct ext2_inode_info *ei = EXT2_I(inode); |
@@ -1079,9 +1098,9 @@ void ext2_read_inode (struct inode * inode) | |||
1079 | } | 1098 | } |
1080 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); | 1099 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
1081 | inode->i_size = le32_to_cpu(raw_inode->i_size); | 1100 | inode->i_size = le32_to_cpu(raw_inode->i_size); |
1082 | inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); | 1101 | inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); |
1083 | inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime); | 1102 | inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime); |
1084 | inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime); | 1103 | inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime); |
1085 | inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0; | 1104 | inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0; |
1086 | ei->i_dtime = le32_to_cpu(raw_inode->i_dtime); | 1105 | ei->i_dtime = le32_to_cpu(raw_inode->i_dtime); |
1087 | /* We now have enough fields to check if the inode was active or not. | 1106 | /* We now have enough fields to check if the inode was active or not. |
@@ -1188,6 +1207,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync) | |||
1188 | if (ei->i_state & EXT2_STATE_NEW) | 1207 | if (ei->i_state & EXT2_STATE_NEW) |
1189 | memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size); | 1208 | memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size); |
1190 | 1209 | ||
1210 | ext2_get_inode_flags(ei); | ||
1191 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); | 1211 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
1192 | if (!(test_opt(sb, NO_UID32))) { | 1212 | if (!(test_opt(sb, NO_UID32))) { |
1193 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid)); | 1213 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid)); |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 4b099d310712..e85c48218239 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -27,6 +27,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
27 | 27 | ||
28 | switch (cmd) { | 28 | switch (cmd) { |
29 | case EXT2_IOC_GETFLAGS: | 29 | case EXT2_IOC_GETFLAGS: |
30 | ext2_get_inode_flags(ei); | ||
30 | flags = ei->i_flags & EXT2_FL_USER_VISIBLE; | 31 | flags = ei->i_flags & EXT2_FL_USER_VISIBLE; |
31 | return put_user(flags, (int __user *) arg); | 32 | return put_user(flags, (int __user *) arg); |
32 | case EXT2_IOC_SETFLAGS: { | 33 | case EXT2_IOC_SETFLAGS: { |
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index a26612798471..eaa23d2d5213 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/smp_lock.h> | ||
10 | #include <linux/ext2_fs.h> | 9 | #include <linux/ext2_fs.h> |
11 | #include <linux/security.h> | 10 | #include <linux/security.h> |
12 | #include "xattr.h" | 11 | #include "xattr.h" |
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index f28a6a499c96..83ee149f353d 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/ext2_fs.h> | 12 | #include <linux/ext2_fs.h> |
14 | #include "xattr.h" | 13 | #include "xattr.h" |
15 | 14 | ||
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 665adee99b31..852869840f24 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/jbd.h> | 25 | #include <linux/jbd.h> |
26 | #include <linux/ext3_fs.h> | 26 | #include <linux/ext3_fs.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <linux/rbtree.h> | 29 | #include <linux/rbtree.h> |
31 | 30 | ||
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index a5b150f7e8a2..e1bb03171986 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/ext3_jbd.h> | 28 | #include <linux/ext3_jbd.h> |
29 | #include <linux/jbd.h> | 29 | #include <linux/jbd.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/highuid.h> | 30 | #include <linux/highuid.h> |
32 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
33 | #include <linux/quotaops.h> | 32 | #include <linux/quotaops.h> |
@@ -2581,6 +2580,25 @@ void ext3_set_inode_flags(struct inode *inode) | |||
2581 | inode->i_flags |= S_DIRSYNC; | 2580 | inode->i_flags |= S_DIRSYNC; |
2582 | } | 2581 | } |
2583 | 2582 | ||
2583 | /* Propagate flags from i_flags to EXT3_I(inode)->i_flags */ | ||
2584 | void ext3_get_inode_flags(struct ext3_inode_info *ei) | ||
2585 | { | ||
2586 | unsigned int flags = ei->vfs_inode.i_flags; | ||
2587 | |||
2588 | ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL| | ||
2589 | EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL); | ||
2590 | if (flags & S_SYNC) | ||
2591 | ei->i_flags |= EXT3_SYNC_FL; | ||
2592 | if (flags & S_APPEND) | ||
2593 | ei->i_flags |= EXT3_APPEND_FL; | ||
2594 | if (flags & S_IMMUTABLE) | ||
2595 | ei->i_flags |= EXT3_IMMUTABLE_FL; | ||
2596 | if (flags & S_NOATIME) | ||
2597 | ei->i_flags |= EXT3_NOATIME_FL; | ||
2598 | if (flags & S_DIRSYNC) | ||
2599 | ei->i_flags |= EXT3_DIRSYNC_FL; | ||
2600 | } | ||
2601 | |||
2584 | void ext3_read_inode(struct inode * inode) | 2602 | void ext3_read_inode(struct inode * inode) |
2585 | { | 2603 | { |
2586 | struct ext3_iloc iloc; | 2604 | struct ext3_iloc iloc; |
@@ -2608,9 +2626,9 @@ void ext3_read_inode(struct inode * inode) | |||
2608 | } | 2626 | } |
2609 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); | 2627 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
2610 | inode->i_size = le32_to_cpu(raw_inode->i_size); | 2628 | inode->i_size = le32_to_cpu(raw_inode->i_size); |
2611 | inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); | 2629 | inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); |
2612 | inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime); | 2630 | inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime); |
2613 | inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime); | 2631 | inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime); |
2614 | inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; | 2632 | inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; |
2615 | 2633 | ||
2616 | ei->i_state = 0; | 2634 | ei->i_state = 0; |
@@ -2736,6 +2754,7 @@ static int ext3_do_update_inode(handle_t *handle, | |||
2736 | if (ei->i_state & EXT3_STATE_NEW) | 2754 | if (ei->i_state & EXT3_STATE_NEW) |
2737 | memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size); | 2755 | memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size); |
2738 | 2756 | ||
2757 | ext3_get_inode_flags(ei); | ||
2739 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); | 2758 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
2740 | if(!(test_opt(inode->i_sb, NO_UID32))) { | 2759 | if(!(test_opt(inode->i_sb, NO_UID32))) { |
2741 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); | 2760 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); |
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 9b8090d94e6c..965006dba6be 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -28,6 +28,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
28 | 28 | ||
29 | switch (cmd) { | 29 | switch (cmd) { |
30 | case EXT3_IOC_GETFLAGS: | 30 | case EXT3_IOC_GETFLAGS: |
31 | ext3_get_inode_flags(ei); | ||
31 | flags = ei->i_flags & EXT3_FL_USER_VISIBLE; | 32 | flags = ei->i_flags & EXT3_FL_USER_VISIBLE; |
32 | return put_user(flags, (int __user *) arg); | 33 | return put_user(flags, (int __user *) arg); |
33 | case EXT3_IOC_SETFLAGS: { | 34 | case EXT3_IOC_SETFLAGS: { |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 49159f13cc1f..9bb046df827a 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/quotaops.h> | 36 | #include <linux/quotaops.h> |
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/bio.h> | 38 | #include <linux/bio.h> |
39 | #include <linux/smp_lock.h> | ||
40 | 39 | ||
41 | #include "namei.h" | 40 | #include "namei.h" |
42 | #include "xattr.h" | 41 | #include "xattr.h" |
@@ -969,6 +968,7 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, | |||
969 | (block<<EXT3_BLOCK_SIZE_BITS(sb)) | 968 | (block<<EXT3_BLOCK_SIZE_BITS(sb)) |
970 | +((char *)de - bh->b_data))) { | 969 | +((char *)de - bh->b_data))) { |
971 | brelse (bh); | 970 | brelse (bh); |
971 | *err = ERR_BAD_DX_DIR; | ||
972 | goto errout; | 972 | goto errout; |
973 | } | 973 | } |
974 | *res_dir = de; | 974 | *res_dir = de; |
@@ -1134,9 +1134,9 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, | |||
1134 | char *data1 = (*bh)->b_data, *data2; | 1134 | char *data1 = (*bh)->b_data, *data2; |
1135 | unsigned split; | 1135 | unsigned split; |
1136 | struct ext3_dir_entry_2 *de = NULL, *de2; | 1136 | struct ext3_dir_entry_2 *de = NULL, *de2; |
1137 | int err; | 1137 | int err = 0; |
1138 | 1138 | ||
1139 | bh2 = ext3_append (handle, dir, &newblock, error); | 1139 | bh2 = ext3_append (handle, dir, &newblock, &err); |
1140 | if (!(bh2)) { | 1140 | if (!(bh2)) { |
1141 | brelse(*bh); | 1141 | brelse(*bh); |
1142 | *bh = NULL; | 1142 | *bh = NULL; |
@@ -1145,14 +1145,9 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, | |||
1145 | 1145 | ||
1146 | BUFFER_TRACE(*bh, "get_write_access"); | 1146 | BUFFER_TRACE(*bh, "get_write_access"); |
1147 | err = ext3_journal_get_write_access(handle, *bh); | 1147 | err = ext3_journal_get_write_access(handle, *bh); |
1148 | if (err) { | 1148 | if (err) |
1149 | journal_error: | 1149 | goto journal_error; |
1150 | brelse(*bh); | 1150 | |
1151 | brelse(bh2); | ||
1152 | *bh = NULL; | ||
1153 | ext3_std_error(dir->i_sb, err); | ||
1154 | goto errout; | ||
1155 | } | ||
1156 | BUFFER_TRACE(frame->bh, "get_write_access"); | 1151 | BUFFER_TRACE(frame->bh, "get_write_access"); |
1157 | err = ext3_journal_get_write_access(handle, frame->bh); | 1152 | err = ext3_journal_get_write_access(handle, frame->bh); |
1158 | if (err) | 1153 | if (err) |
@@ -1195,8 +1190,16 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, | |||
1195 | goto journal_error; | 1190 | goto journal_error; |
1196 | brelse (bh2); | 1191 | brelse (bh2); |
1197 | dxtrace(dx_show_index ("frame", frame->entries)); | 1192 | dxtrace(dx_show_index ("frame", frame->entries)); |
1198 | errout: | ||
1199 | return de; | 1193 | return de; |
1194 | |||
1195 | journal_error: | ||
1196 | brelse(*bh); | ||
1197 | brelse(bh2); | ||
1198 | *bh = NULL; | ||
1199 | ext3_std_error(dir->i_sb, err); | ||
1200 | errout: | ||
1201 | *error = err; | ||
1202 | return NULL; | ||
1200 | } | 1203 | } |
1201 | #endif | 1204 | #endif |
1202 | 1205 | ||
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index ecf89904c113..2c97e09c6c6b 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #define EXT3FS_DEBUG | 12 | #define EXT3FS_DEBUG |
13 | 13 | ||
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/ext3_jbd.h> | 14 | #include <linux/ext3_jbd.h> |
16 | 15 | ||
17 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c index b9c40c15647b..821efaf2b94e 100644 --- a/fs/ext3/xattr_security.c +++ b/fs/ext3/xattr_security.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/smp_lock.h> | ||
10 | #include <linux/ext3_jbd.h> | 9 | #include <linux/ext3_jbd.h> |
11 | #include <linux/ext3_fs.h> | 10 | #include <linux/ext3_fs.h> |
12 | #include <linux/security.h> | 11 | #include <linux/security.h> |
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c index 86d91f1186dc..0327497a55ce 100644 --- a/fs/ext3/xattr_trusted.c +++ b/fs/ext3/xattr_trusted.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/ext3_jbd.h> | 12 | #include <linux/ext3_jbd.h> |
14 | #include <linux/ext3_fs.h> | 13 | #include <linux/ext3_fs.h> |
15 | #include "xattr.h" | 14 | #include "xattr.h" |
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c index a85a0a17c4fd..1abd8f92c440 100644 --- a/fs/ext3/xattr_user.c +++ b/fs/ext3/xattr_user.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/ext3_jbd.h> | 11 | #include <linux/ext3_jbd.h> |
13 | #include <linux/ext3_fs.h> | 12 | #include <linux/ext3_fs.h> |
14 | #include "xattr.h" | 13 | #include "xattr.h" |
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index da80368b66f0..e8ad06e28318 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/jbd2.h> | 25 | #include <linux/jbd2.h> |
26 | #include <linux/ext4_fs.h> | 26 | #include <linux/ext4_fs.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <linux/rbtree.h> | 29 | #include <linux/rbtree.h> |
31 | 30 | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7916b50f9a13..a0f0c04e79b2 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/time.h> | 34 | #include <linux/time.h> |
35 | #include <linux/ext4_jbd2.h> | 35 | #include <linux/ext4_jbd2.h> |
36 | #include <linux/jbd.h> | 36 | #include <linux/jbd.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/highuid.h> | 37 | #include <linux/highuid.h> |
39 | #include <linux/pagemap.h> | 38 | #include <linux/pagemap.h> |
40 | #include <linux/quotaops.h> | 39 | #include <linux/quotaops.h> |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 810b6d6474bf..b34182b6ee4d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/ext4_jbd2.h> | 28 | #include <linux/ext4_jbd2.h> |
29 | #include <linux/jbd2.h> | 29 | #include <linux/jbd2.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/highuid.h> | 30 | #include <linux/highuid.h> |
32 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
33 | #include <linux/quotaops.h> | 32 | #include <linux/quotaops.h> |
@@ -2611,9 +2610,9 @@ void ext4_read_inode(struct inode * inode) | |||
2611 | } | 2610 | } |
2612 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); | 2611 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
2613 | inode->i_size = le32_to_cpu(raw_inode->i_size); | 2612 | inode->i_size = le32_to_cpu(raw_inode->i_size); |
2614 | inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); | 2613 | inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); |
2615 | inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime); | 2614 | inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime); |
2616 | inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime); | 2615 | inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime); |
2617 | inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; | 2616 | inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; |
2618 | 2617 | ||
2619 | ei->i_state = 0; | 2618 | ei->i_state = 0; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index e7e1d79a7d75..4ec57be5baf5 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/quotaops.h> | 36 | #include <linux/quotaops.h> |
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/bio.h> | 38 | #include <linux/bio.h> |
39 | #include <linux/smp_lock.h> | ||
40 | 39 | ||
41 | #include "namei.h" | 40 | #include "namei.h" |
42 | #include "xattr.h" | 41 | #include "xattr.h" |
@@ -967,6 +966,7 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, | |||
967 | (block<<EXT4_BLOCK_SIZE_BITS(sb)) | 966 | (block<<EXT4_BLOCK_SIZE_BITS(sb)) |
968 | +((char *)de - bh->b_data))) { | 967 | +((char *)de - bh->b_data))) { |
969 | brelse (bh); | 968 | brelse (bh); |
969 | *err = ERR_BAD_DX_DIR; | ||
970 | goto errout; | 970 | goto errout; |
971 | } | 971 | } |
972 | *res_dir = de; | 972 | *res_dir = de; |
@@ -1132,9 +1132,9 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, | |||
1132 | char *data1 = (*bh)->b_data, *data2; | 1132 | char *data1 = (*bh)->b_data, *data2; |
1133 | unsigned split; | 1133 | unsigned split; |
1134 | struct ext4_dir_entry_2 *de = NULL, *de2; | 1134 | struct ext4_dir_entry_2 *de = NULL, *de2; |
1135 | int err; | 1135 | int err = 0; |
1136 | 1136 | ||
1137 | bh2 = ext4_append (handle, dir, &newblock, error); | 1137 | bh2 = ext4_append (handle, dir, &newblock, &err); |
1138 | if (!(bh2)) { | 1138 | if (!(bh2)) { |
1139 | brelse(*bh); | 1139 | brelse(*bh); |
1140 | *bh = NULL; | 1140 | *bh = NULL; |
@@ -1143,14 +1143,9 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, | |||
1143 | 1143 | ||
1144 | BUFFER_TRACE(*bh, "get_write_access"); | 1144 | BUFFER_TRACE(*bh, "get_write_access"); |
1145 | err = ext4_journal_get_write_access(handle, *bh); | 1145 | err = ext4_journal_get_write_access(handle, *bh); |
1146 | if (err) { | 1146 | if (err) |
1147 | journal_error: | 1147 | goto journal_error; |
1148 | brelse(*bh); | 1148 | |
1149 | brelse(bh2); | ||
1150 | *bh = NULL; | ||
1151 | ext4_std_error(dir->i_sb, err); | ||
1152 | goto errout; | ||
1153 | } | ||
1154 | BUFFER_TRACE(frame->bh, "get_write_access"); | 1149 | BUFFER_TRACE(frame->bh, "get_write_access"); |
1155 | err = ext4_journal_get_write_access(handle, frame->bh); | 1150 | err = ext4_journal_get_write_access(handle, frame->bh); |
1156 | if (err) | 1151 | if (err) |
@@ -1193,8 +1188,16 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, | |||
1193 | goto journal_error; | 1188 | goto journal_error; |
1194 | brelse (bh2); | 1189 | brelse (bh2); |
1195 | dxtrace(dx_show_index ("frame", frame->entries)); | 1190 | dxtrace(dx_show_index ("frame", frame->entries)); |
1196 | errout: | ||
1197 | return de; | 1191 | return de; |
1192 | |||
1193 | journal_error: | ||
1194 | brelse(*bh); | ||
1195 | brelse(bh2); | ||
1196 | *bh = NULL; | ||
1197 | ext4_std_error(dir->i_sb, err); | ||
1198 | errout: | ||
1199 | *error = err; | ||
1200 | return NULL; | ||
1198 | } | 1201 | } |
1199 | #endif | 1202 | #endif |
1200 | 1203 | ||
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index ea99f6c97f56..aa11d7dbe970 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #define EXT4FS_DEBUG | 12 | #define EXT4FS_DEBUG |
13 | 13 | ||
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/ext4_jbd2.h> | 14 | #include <linux/ext4_jbd2.h> |
16 | 15 | ||
17 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index b6a6861951f9..f17eaf2321b9 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/smp_lock.h> | ||
10 | #include <linux/ext4_jbd2.h> | 9 | #include <linux/ext4_jbd2.h> |
11 | #include <linux/ext4_fs.h> | 10 | #include <linux/ext4_fs.h> |
12 | #include <linux/security.h> | 11 | #include <linux/security.h> |
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index b76f2dbc82da..e0f05acdafec 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/ext4_jbd2.h> | 12 | #include <linux/ext4_jbd2.h> |
14 | #include <linux/ext4_fs.h> | 13 | #include <linux/ext4_fs.h> |
15 | #include "xattr.h" | 14 | #include "xattr.h" |
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index c53cded0761a..7ed3d8ebf096 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/ext4_jbd2.h> | 11 | #include <linux/ext4_jbd2.h> |
13 | #include <linux/ext4_fs.h> | 12 | #include <linux/ext4_fs.h> |
14 | #include "xattr.h" | 13 | #include "xattr.h" |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index c16af246d245..ccf161dffb63 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -422,7 +422,7 @@ EODir: | |||
422 | EXPORT_SYMBOL_GPL(fat_search_long); | 422 | EXPORT_SYMBOL_GPL(fat_search_long); |
423 | 423 | ||
424 | struct fat_ioctl_filldir_callback { | 424 | struct fat_ioctl_filldir_callback { |
425 | struct dirent __user *dirent; | 425 | void __user *dirent; |
426 | int result; | 426 | int result; |
427 | /* for dir ioctl */ | 427 | /* for dir ioctl */ |
428 | const char *longname; | 428 | const char *longname; |
@@ -647,62 +647,85 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
647 | return __fat_readdir(inode, filp, dirent, filldir, 0, 0); | 647 | return __fat_readdir(inode, filp, dirent, filldir, 0, 0); |
648 | } | 648 | } |
649 | 649 | ||
650 | static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, | 650 | #define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \ |
651 | loff_t offset, u64 ino, unsigned int d_type) | 651 | static int func(void *__buf, const char *name, int name_len, \ |
652 | loff_t offset, u64 ino, unsigned int d_type) \ | ||
653 | { \ | ||
654 | struct fat_ioctl_filldir_callback *buf = __buf; \ | ||
655 | struct dirent_type __user *d1 = buf->dirent; \ | ||
656 | struct dirent_type __user *d2 = d1 + 1; \ | ||
657 | \ | ||
658 | if (buf->result) \ | ||
659 | return -EINVAL; \ | ||
660 | buf->result++; \ | ||
661 | \ | ||
662 | if (name != NULL) { \ | ||
663 | /* dirent has only short name */ \ | ||
664 | if (name_len >= sizeof(d1->d_name)) \ | ||
665 | name_len = sizeof(d1->d_name) - 1; \ | ||
666 | \ | ||
667 | if (put_user(0, d2->d_name) || \ | ||
668 | put_user(0, &d2->d_reclen) || \ | ||
669 | copy_to_user(d1->d_name, name, name_len) || \ | ||
670 | put_user(0, d1->d_name + name_len) || \ | ||
671 | put_user(name_len, &d1->d_reclen)) \ | ||
672 | goto efault; \ | ||
673 | } else { \ | ||
674 | /* dirent has short and long name */ \ | ||
675 | const char *longname = buf->longname; \ | ||
676 | int long_len = buf->long_len; \ | ||
677 | const char *shortname = buf->shortname; \ | ||
678 | int short_len = buf->short_len; \ | ||
679 | \ | ||
680 | if (long_len >= sizeof(d1->d_name)) \ | ||
681 | long_len = sizeof(d1->d_name) - 1; \ | ||
682 | if (short_len >= sizeof(d1->d_name)) \ | ||
683 | short_len = sizeof(d1->d_name) - 1; \ | ||
684 | \ | ||
685 | if (copy_to_user(d2->d_name, longname, long_len) || \ | ||
686 | put_user(0, d2->d_name + long_len) || \ | ||
687 | put_user(long_len, &d2->d_reclen) || \ | ||
688 | put_user(ino, &d2->d_ino) || \ | ||
689 | put_user(offset, &d2->d_off) || \ | ||
690 | copy_to_user(d1->d_name, shortname, short_len) || \ | ||
691 | put_user(0, d1->d_name + short_len) || \ | ||
692 | put_user(short_len, &d1->d_reclen)) \ | ||
693 | goto efault; \ | ||
694 | } \ | ||
695 | return 0; \ | ||
696 | efault: \ | ||
697 | buf->result = -EFAULT; \ | ||
698 | return -EFAULT; \ | ||
699 | } | ||
700 | |||
701 | FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, dirent) | ||
702 | |||
703 | static int fat_ioctl_readdir(struct inode *inode, struct file *filp, | ||
704 | void __user *dirent, filldir_t filldir, | ||
705 | int short_only, int both) | ||
652 | { | 706 | { |
653 | struct fat_ioctl_filldir_callback *buf = __buf; | 707 | struct fat_ioctl_filldir_callback buf; |
654 | struct dirent __user *d1 = buf->dirent; | 708 | int ret; |
655 | struct dirent __user *d2 = d1 + 1; | 709 | |
656 | 710 | buf.dirent = dirent; | |
657 | if (buf->result) | 711 | buf.result = 0; |
658 | return -EINVAL; | 712 | mutex_lock(&inode->i_mutex); |
659 | buf->result++; | 713 | ret = -ENOENT; |
660 | 714 | if (!IS_DEADDIR(inode)) { | |
661 | if (name != NULL) { | 715 | ret = __fat_readdir(inode, filp, &buf, filldir, |
662 | /* dirent has only short name */ | 716 | short_only, both); |
663 | if (name_len >= sizeof(d1->d_name)) | ||
664 | name_len = sizeof(d1->d_name) - 1; | ||
665 | |||
666 | if (put_user(0, d2->d_name) || | ||
667 | put_user(0, &d2->d_reclen) || | ||
668 | copy_to_user(d1->d_name, name, name_len) || | ||
669 | put_user(0, d1->d_name + name_len) || | ||
670 | put_user(name_len, &d1->d_reclen)) | ||
671 | goto efault; | ||
672 | } else { | ||
673 | /* dirent has short and long name */ | ||
674 | const char *longname = buf->longname; | ||
675 | int long_len = buf->long_len; | ||
676 | const char *shortname = buf->shortname; | ||
677 | int short_len = buf->short_len; | ||
678 | |||
679 | if (long_len >= sizeof(d1->d_name)) | ||
680 | long_len = sizeof(d1->d_name) - 1; | ||
681 | if (short_len >= sizeof(d1->d_name)) | ||
682 | short_len = sizeof(d1->d_name) - 1; | ||
683 | |||
684 | if (copy_to_user(d2->d_name, longname, long_len) || | ||
685 | put_user(0, d2->d_name + long_len) || | ||
686 | put_user(long_len, &d2->d_reclen) || | ||
687 | put_user(ino, &d2->d_ino) || | ||
688 | put_user(offset, &d2->d_off) || | ||
689 | copy_to_user(d1->d_name, shortname, short_len) || | ||
690 | put_user(0, d1->d_name + short_len) || | ||
691 | put_user(short_len, &d1->d_reclen)) | ||
692 | goto efault; | ||
693 | } | 717 | } |
694 | return 0; | 718 | mutex_unlock(&inode->i_mutex); |
695 | efault: | 719 | if (ret >= 0) |
696 | buf->result = -EFAULT; | 720 | ret = buf.result; |
697 | return -EFAULT; | 721 | return ret; |
698 | } | 722 | } |
699 | 723 | ||
700 | static int fat_dir_ioctl(struct inode * inode, struct file * filp, | 724 | static int fat_dir_ioctl(struct inode *inode, struct file *filp, |
701 | unsigned int cmd, unsigned long arg) | 725 | unsigned int cmd, unsigned long arg) |
702 | { | 726 | { |
703 | struct fat_ioctl_filldir_callback buf; | 727 | struct dirent __user *d1 = (struct dirent __user *)arg; |
704 | struct dirent __user *d1; | 728 | int short_only, both; |
705 | int ret, short_only, both; | ||
706 | 729 | ||
707 | switch (cmd) { | 730 | switch (cmd) { |
708 | case VFAT_IOCTL_READDIR_SHORT: | 731 | case VFAT_IOCTL_READDIR_SHORT: |
@@ -717,7 +740,6 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, | |||
717 | return fat_generic_ioctl(inode, filp, cmd, arg); | 740 | return fat_generic_ioctl(inode, filp, cmd, arg); |
718 | } | 741 | } |
719 | 742 | ||
720 | d1 = (struct dirent __user *)arg; | ||
721 | if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2]))) | 743 | if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2]))) |
722 | return -EFAULT; | 744 | return -EFAULT; |
723 | /* | 745 | /* |
@@ -728,69 +750,48 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, | |||
728 | if (put_user(0, &d1->d_reclen)) | 750 | if (put_user(0, &d1->d_reclen)) |
729 | return -EFAULT; | 751 | return -EFAULT; |
730 | 752 | ||
731 | buf.dirent = d1; | 753 | return fat_ioctl_readdir(inode, filp, d1, fat_ioctl_filldir, |
732 | buf.result = 0; | 754 | short_only, both); |
733 | mutex_lock(&inode->i_mutex); | ||
734 | ret = -ENOENT; | ||
735 | if (!IS_DEADDIR(inode)) { | ||
736 | ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir, | ||
737 | short_only, both); | ||
738 | } | ||
739 | mutex_unlock(&inode->i_mutex); | ||
740 | if (ret >= 0) | ||
741 | ret = buf.result; | ||
742 | return ret; | ||
743 | } | 755 | } |
744 | 756 | ||
745 | #ifdef CONFIG_COMPAT | 757 | #ifdef CONFIG_COMPAT |
746 | #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) | 758 | #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) |
747 | #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) | 759 | #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) |
748 | 760 | ||
749 | static long fat_compat_put_dirent32(struct dirent *d, | 761 | FAT_IOCTL_FILLDIR_FUNC(fat_compat_ioctl_filldir, compat_dirent) |
750 | struct compat_dirent __user *d32) | ||
751 | { | ||
752 | if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) | ||
753 | return -EFAULT; | ||
754 | |||
755 | __put_user(d->d_ino, &d32->d_ino); | ||
756 | __put_user(d->d_off, &d32->d_off); | ||
757 | __put_user(d->d_reclen, &d32->d_reclen); | ||
758 | if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) | ||
759 | return -EFAULT; | ||
760 | 762 | ||
761 | return 0; | 763 | static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd, |
762 | } | ||
763 | |||
764 | static long fat_compat_dir_ioctl(struct file *file, unsigned cmd, | ||
765 | unsigned long arg) | 764 | unsigned long arg) |
766 | { | 765 | { |
767 | struct compat_dirent __user *p = compat_ptr(arg); | 766 | struct inode *inode = filp->f_path.dentry->d_inode; |
768 | int ret; | 767 | struct compat_dirent __user *d1 = compat_ptr(arg); |
769 | mm_segment_t oldfs = get_fs(); | 768 | int short_only, both; |
770 | struct dirent d[2]; | ||
771 | 769 | ||
772 | switch (cmd) { | 770 | switch (cmd) { |
773 | case VFAT_IOCTL_READDIR_BOTH32: | ||
774 | cmd = VFAT_IOCTL_READDIR_BOTH; | ||
775 | break; | ||
776 | case VFAT_IOCTL_READDIR_SHORT32: | 771 | case VFAT_IOCTL_READDIR_SHORT32: |
777 | cmd = VFAT_IOCTL_READDIR_SHORT; | 772 | short_only = 1; |
773 | both = 0; | ||
774 | break; | ||
775 | case VFAT_IOCTL_READDIR_BOTH32: | ||
776 | short_only = 0; | ||
777 | both = 1; | ||
778 | break; | 778 | break; |
779 | default: | 779 | default: |
780 | return -ENOIOCTLCMD; | 780 | return -ENOIOCTLCMD; |
781 | } | 781 | } |
782 | 782 | ||
783 | set_fs(KERNEL_DS); | 783 | if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2]))) |
784 | lock_kernel(); | 784 | return -EFAULT; |
785 | ret = fat_dir_ioctl(file->f_path.dentry->d_inode, file, | 785 | /* |
786 | cmd, (unsigned long) &d); | 786 | * Yes, we don't need this put_user() absolutely. However old |
787 | unlock_kernel(); | 787 | * code didn't return the right value. So, app use this value, |
788 | set_fs(oldfs); | 788 | * in order to check whether it is EOF. |
789 | if (ret >= 0) { | 789 | */ |
790 | ret |= fat_compat_put_dirent32(&d[0], p); | 790 | if (put_user(0, &d1->d_reclen)) |
791 | ret |= fat_compat_put_dirent32(&d[1], p + 1); | 791 | return -EFAULT; |
792 | } | 792 | |
793 | return ret; | 793 | return fat_ioctl_readdir(inode, filp, d1, fat_compat_ioctl_filldir, |
794 | short_only, both); | ||
794 | } | 795 | } |
795 | #endif /* CONFIG_COMPAT */ | 796 | #endif /* CONFIG_COMPAT */ |
796 | 797 | ||
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 65cb54bde481..2c55e8dce793 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/parser.h> | 25 | #include <linux/parser.h> |
26 | #include <linux/uio.h> | 26 | #include <linux/uio.h> |
27 | #include <linux/writeback.h> | 27 | #include <linux/writeback.h> |
28 | #include <linux/log2.h> | ||
28 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
29 | 30 | ||
30 | #ifndef CONFIG_FAT_DEFAULT_IOCHARSET | 31 | #ifndef CONFIG_FAT_DEFAULT_IOCHARSET |
@@ -824,6 +825,8 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
824 | } | 825 | } |
825 | if (opts->name_check != 'n') | 826 | if (opts->name_check != 'n') |
826 | seq_printf(m, ",check=%c", opts->name_check); | 827 | seq_printf(m, ",check=%c", opts->name_check); |
828 | if (opts->usefree) | ||
829 | seq_puts(m, ",usefree"); | ||
827 | if (opts->quiet) | 830 | if (opts->quiet) |
828 | seq_puts(m, ",quiet"); | 831 | seq_puts(m, ",quiet"); |
829 | if (opts->showexec) | 832 | if (opts->showexec) |
@@ -849,7 +852,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
849 | 852 | ||
850 | enum { | 853 | enum { |
851 | Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid, | 854 | Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid, |
852 | Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase, | 855 | Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_usefree, Opt_nocase, |
853 | Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable, | 856 | Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable, |
854 | Opt_dots, Opt_nodots, | 857 | Opt_dots, Opt_nodots, |
855 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, | 858 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, |
@@ -871,6 +874,7 @@ static match_table_t fat_tokens = { | |||
871 | {Opt_dmask, "dmask=%o"}, | 874 | {Opt_dmask, "dmask=%o"}, |
872 | {Opt_fmask, "fmask=%o"}, | 875 | {Opt_fmask, "fmask=%o"}, |
873 | {Opt_codepage, "codepage=%u"}, | 876 | {Opt_codepage, "codepage=%u"}, |
877 | {Opt_usefree, "usefree"}, | ||
874 | {Opt_nocase, "nocase"}, | 878 | {Opt_nocase, "nocase"}, |
875 | {Opt_quiet, "quiet"}, | 879 | {Opt_quiet, "quiet"}, |
876 | {Opt_showexec, "showexec"}, | 880 | {Opt_showexec, "showexec"}, |
@@ -950,7 +954,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
950 | opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0; | 954 | opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0; |
951 | opts->utf8 = opts->unicode_xlate = 0; | 955 | opts->utf8 = opts->unicode_xlate = 0; |
952 | opts->numtail = 1; | 956 | opts->numtail = 1; |
953 | opts->nocase = 0; | 957 | opts->usefree = opts->nocase = 0; |
954 | *debug = 0; | 958 | *debug = 0; |
955 | 959 | ||
956 | if (!options) | 960 | if (!options) |
@@ -978,6 +982,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
978 | case Opt_check_n: | 982 | case Opt_check_n: |
979 | opts->name_check = 'n'; | 983 | opts->name_check = 'n'; |
980 | break; | 984 | break; |
985 | case Opt_usefree: | ||
986 | opts->usefree = 1; | ||
987 | break; | ||
981 | case Opt_nocase: | 988 | case Opt_nocase: |
982 | if (!is_vfat) | 989 | if (!is_vfat) |
983 | opts->nocase = 1; | 990 | opts->nocase = 1; |
@@ -1217,8 +1224,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1217 | } | 1224 | } |
1218 | logical_sector_size = | 1225 | logical_sector_size = |
1219 | le16_to_cpu(get_unaligned((__le16 *)&b->sector_size)); | 1226 | le16_to_cpu(get_unaligned((__le16 *)&b->sector_size)); |
1220 | if (!logical_sector_size | 1227 | if (!is_power_of_2(logical_sector_size) |
1221 | || (logical_sector_size & (logical_sector_size - 1)) | ||
1222 | || (logical_sector_size < 512) | 1228 | || (logical_sector_size < 512) |
1223 | || (PAGE_CACHE_SIZE < logical_sector_size)) { | 1229 | || (PAGE_CACHE_SIZE < logical_sector_size)) { |
1224 | if (!silent) | 1230 | if (!silent) |
@@ -1228,8 +1234,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1228 | goto out_invalid; | 1234 | goto out_invalid; |
1229 | } | 1235 | } |
1230 | sbi->sec_per_clus = b->sec_per_clus; | 1236 | sbi->sec_per_clus = b->sec_per_clus; |
1231 | if (!sbi->sec_per_clus | 1237 | if (!is_power_of_2(sbi->sec_per_clus)) { |
1232 | || (sbi->sec_per_clus & (sbi->sec_per_clus - 1))) { | ||
1233 | if (!silent) | 1238 | if (!silent) |
1234 | printk(KERN_ERR "FAT: bogus sectors per cluster %u\n", | 1239 | printk(KERN_ERR "FAT: bogus sectors per cluster %u\n", |
1235 | sbi->sec_per_clus); | 1240 | sbi->sec_per_clus); |
@@ -1305,7 +1310,9 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1305 | le32_to_cpu(fsinfo->signature2), | 1310 | le32_to_cpu(fsinfo->signature2), |
1306 | sbi->fsinfo_sector); | 1311 | sbi->fsinfo_sector); |
1307 | } else { | 1312 | } else { |
1308 | sbi->free_clusters = le32_to_cpu(fsinfo->free_clusters); | 1313 | if (sbi->options.usefree) |
1314 | sbi->free_clusters = | ||
1315 | le32_to_cpu(fsinfo->free_clusters); | ||
1309 | sbi->prev_free = le32_to_cpu(fsinfo->next_cluster); | 1316 | sbi->prev_free = le32_to_cpu(fsinfo->next_cluster); |
1310 | } | 1317 | } |
1311 | 1318 | ||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
16 | #include <linux/pipe_fs_i.h> | 15 | #include <linux/pipe_fs_i.h> |
17 | 16 | ||
diff --git a/fs/file_table.c b/fs/file_table.c index 4c17a18d8c10..d17fd691b832 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/file.h> | 10 | #include <linux/file.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/smp_lock.h> | ||
14 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
15 | #include <linux/security.h> | 14 | #include <linux/security.h> |
16 | #include <linux/eventpoll.h> | 15 | #include <linux/eventpoll.h> |
diff --git a/fs/filesystems.c b/fs/filesystems.c index 7a4f61aa05f8..f37f87262837 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c | |||
@@ -41,11 +41,12 @@ void put_filesystem(struct file_system_type *fs) | |||
41 | module_put(fs->owner); | 41 | module_put(fs->owner); |
42 | } | 42 | } |
43 | 43 | ||
44 | static struct file_system_type **find_filesystem(const char *name) | 44 | static struct file_system_type **find_filesystem(const char *name, unsigned len) |
45 | { | 45 | { |
46 | struct file_system_type **p; | 46 | struct file_system_type **p; |
47 | for (p=&file_systems; *p; p=&(*p)->next) | 47 | for (p=&file_systems; *p; p=&(*p)->next) |
48 | if (strcmp((*p)->name,name) == 0) | 48 | if (strlen((*p)->name) == len && |
49 | strncmp((*p)->name, name, len) == 0) | ||
49 | break; | 50 | break; |
50 | return p; | 51 | return p; |
51 | } | 52 | } |
@@ -68,11 +69,12 @@ int register_filesystem(struct file_system_type * fs) | |||
68 | int res = 0; | 69 | int res = 0; |
69 | struct file_system_type ** p; | 70 | struct file_system_type ** p; |
70 | 71 | ||
72 | BUG_ON(strchr(fs->name, '.')); | ||
71 | if (fs->next) | 73 | if (fs->next) |
72 | return -EBUSY; | 74 | return -EBUSY; |
73 | INIT_LIST_HEAD(&fs->fs_supers); | 75 | INIT_LIST_HEAD(&fs->fs_supers); |
74 | write_lock(&file_systems_lock); | 76 | write_lock(&file_systems_lock); |
75 | p = find_filesystem(fs->name); | 77 | p = find_filesystem(fs->name, strlen(fs->name)); |
76 | if (*p) | 78 | if (*p) |
77 | res = -EBUSY; | 79 | res = -EBUSY; |
78 | else | 80 | else |
@@ -215,19 +217,26 @@ int get_filesystem_list(char * buf) | |||
215 | struct file_system_type *get_fs_type(const char *name) | 217 | struct file_system_type *get_fs_type(const char *name) |
216 | { | 218 | { |
217 | struct file_system_type *fs; | 219 | struct file_system_type *fs; |
220 | const char *dot = strchr(name, '.'); | ||
221 | unsigned len = dot ? dot - name : strlen(name); | ||
218 | 222 | ||
219 | read_lock(&file_systems_lock); | 223 | read_lock(&file_systems_lock); |
220 | fs = *(find_filesystem(name)); | 224 | fs = *(find_filesystem(name, len)); |
221 | if (fs && !try_module_get(fs->owner)) | 225 | if (fs && !try_module_get(fs->owner)) |
222 | fs = NULL; | 226 | fs = NULL; |
223 | read_unlock(&file_systems_lock); | 227 | read_unlock(&file_systems_lock); |
224 | if (!fs && (request_module("%s", name) == 0)) { | 228 | if (!fs && (request_module("%.*s", len, name) == 0)) { |
225 | read_lock(&file_systems_lock); | 229 | read_lock(&file_systems_lock); |
226 | fs = *(find_filesystem(name)); | 230 | fs = *(find_filesystem(name, len)); |
227 | if (fs && !try_module_get(fs->owner)) | 231 | if (fs && !try_module_get(fs->owner)) |
228 | fs = NULL; | 232 | fs = NULL; |
229 | read_unlock(&file_systems_lock); | 233 | read_unlock(&file_systems_lock); |
230 | } | 234 | } |
235 | |||
236 | if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) { | ||
237 | put_filesystem(fs); | ||
238 | fs = NULL; | ||
239 | } | ||
231 | return fs; | 240 | return fs; |
232 | } | 241 | } |
233 | 242 | ||
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c index 2d71128bd8d6..f86fd3cacd5a 100644 --- a/fs/freevxfs/vxfs_bmap.c +++ b/fs/freevxfs/vxfs_bmap.c | |||
@@ -137,7 +137,7 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) | |||
137 | 137 | ||
138 | bp = sb_bread(ip->i_sb, | 138 | bp = sb_bread(ip->i_sb, |
139 | indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb))); | 139 | indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb))); |
140 | if (!buffer_mapped(bp)) | 140 | if (!bp || !buffer_mapped(bp)) |
141 | return 0; | 141 | return 0; |
142 | 142 | ||
143 | typ = ((struct vxfs_typed *)bp->b_data) + | 143 | typ = ((struct vxfs_typed *)bp->b_data) + |
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index 098a915fd9a1..d1f7c5b5b3c3 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
@@ -99,7 +99,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) | |||
99 | offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); | 99 | offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); |
100 | bp = sb_bread(sbp, block); | 100 | bp = sb_bread(sbp, block); |
101 | 101 | ||
102 | if (buffer_mapped(bp)) { | 102 | if (bp && buffer_mapped(bp)) { |
103 | struct vxfs_inode_info *vip; | 103 | struct vxfs_inode_info *vip; |
104 | struct vxfs_dinode *dip; | 104 | struct vxfs_dinode *dip; |
105 | 105 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index d8003be56e05..1397018ff476 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -636,6 +636,7 @@ static int fuse_get_sb(struct file_system_type *fs_type, | |||
636 | static struct file_system_type fuse_fs_type = { | 636 | static struct file_system_type fuse_fs_type = { |
637 | .owner = THIS_MODULE, | 637 | .owner = THIS_MODULE, |
638 | .name = "fuse", | 638 | .name = "fuse", |
639 | .fs_flags = FS_HAS_SUBTYPE, | ||
639 | .get_sb = fuse_get_sb, | 640 | .get_sb = fuse_get_sb, |
640 | .kill_sb = kill_anon_super, | 641 | .kill_sb = kill_anon_super, |
641 | }; | 642 | }; |
@@ -652,6 +653,7 @@ static int fuse_get_sb_blk(struct file_system_type *fs_type, | |||
652 | static struct file_system_type fuseblk_fs_type = { | 653 | static struct file_system_type fuseblk_fs_type = { |
653 | .owner = THIS_MODULE, | 654 | .owner = THIS_MODULE, |
654 | .name = "fuseblk", | 655 | .name = "fuseblk", |
656 | .fs_flags = FS_HAS_SUBTYPE, | ||
655 | .get_sb = fuse_get_sb_blk, | 657 | .get_sb = fuse_get_sb_blk, |
656 | .kill_sb = kill_block_super, | 658 | .kill_sb = kill_block_super, |
657 | .fs_flags = FS_REQUIRES_DEV, | 659 | .fs_flags = FS_REQUIRES_DEV, |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 39c8ae23bd9c..7b82657a9910 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -163,10 +163,7 @@ static void inode_go_sync(struct gfs2_glock *gl) | |||
163 | if (ip) { | 163 | if (ip) { |
164 | struct address_space *mapping = ip->i_inode.i_mapping; | 164 | struct address_space *mapping = ip->i_inode.i_mapping; |
165 | int error = filemap_fdatawait(mapping); | 165 | int error = filemap_fdatawait(mapping); |
166 | if (error == -ENOSPC) | 166 | mapping_set_error(mapping, error); |
167 | set_bit(AS_ENOSPC, &mapping->flags); | ||
168 | else if (error) | ||
169 | set_bit(AS_EIO, &mapping->flags); | ||
170 | } | 167 | } |
171 | clear_bit(GLF_DIRTY, &gl->gl_flags); | 168 | clear_bit(GLF_DIRTY, &gl->gl_flags); |
172 | gfs2_ail_empty_gl(gl); | 169 | gfs2_ail_empty_gl(gl); |
diff --git a/fs/gfs2/locking/nolock/main.c b/fs/gfs2/locking/nolock/main.c index 5cc1dfa7944a..0d149c8c493a 100644 --- a/fs/gfs2/locking/nolock/main.c +++ b/fs/gfs2/locking/nolock/main.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/lm_interface.h> | 16 | #include <linux/lm_interface.h> |
18 | 17 | ||
19 | struct nolock_lockspace { | 18 | struct nolock_lockspace { |
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c index c6bac6b69420..a6fdc52f554a 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/ops_dentry.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> | 12 | #include <linux/completion.h> |
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/gfs2_ondisk.h> | 14 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
17 | #include <linux/lm_interface.h> | 16 | #include <linux/lm_interface.h> |
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 329c4dcdecdb..064df8804582 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/uio.h> | 15 | #include <linux/uio.h> |
16 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
20 | #include <linux/gfs2_ondisk.h> | 19 | #include <linux/gfs2_ondisk.h> |
21 | #include <linux/ext2_fs.h> | 20 | #include <linux/ext2_fs.h> |
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 5fd0ed71f923..8a3a650abc87 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/pagemap.h> | 11 | #include <linux/pagemap.h> |
12 | #include <linux/log2.h> | ||
12 | 13 | ||
13 | #include "btree.h" | 14 | #include "btree.h" |
14 | 15 | ||
@@ -76,7 +77,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
76 | tree->depth = be16_to_cpu(head->depth); | 77 | tree->depth = be16_to_cpu(head->depth); |
77 | 78 | ||
78 | size = tree->node_size; | 79 | size = tree->node_size; |
79 | if (!size || size & (size - 1)) | 80 | if (!is_power_of_2(size)) |
80 | goto fail_page; | 81 | goto fail_page; |
81 | if (!tree->node_count) | 82 | if (!tree->node_count) |
82 | goto fail_page; | 83 | goto fail_page; |
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index a9b9e872e29a..90ebab753d30 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/log2.h> | ||
13 | 14 | ||
14 | #include "hfsplus_fs.h" | 15 | #include "hfsplus_fs.h" |
15 | #include "hfsplus_raw.h" | 16 | #include "hfsplus_raw.h" |
@@ -69,7 +70,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
69 | } | 70 | } |
70 | 71 | ||
71 | size = tree->node_size; | 72 | size = tree->node_size; |
72 | if (!size || size & (size - 1)) | 73 | if (!is_power_of_2(size)) |
73 | goto fail_page; | 74 | goto fail_page; |
74 | if (!tree->node_count) | 75 | if (!tree->node_count) |
75 | goto fail_page; | 76 | goto fail_page; |
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h index 70543b17e4c7..06e5930515fe 100644 --- a/fs/hostfs/hostfs.h +++ b/fs/hostfs/hostfs.h | |||
@@ -55,7 +55,7 @@ extern int stat_file(const char *path, unsigned long long *inode_out, | |||
55 | int *mode_out, int *nlink_out, int *uid_out, int *gid_out, | 55 | int *mode_out, int *nlink_out, int *uid_out, int *gid_out, |
56 | unsigned long long *size_out, struct timespec *atime_out, | 56 | unsigned long long *size_out, struct timespec *atime_out, |
57 | struct timespec *mtime_out, struct timespec *ctime_out, | 57 | struct timespec *mtime_out, struct timespec *ctime_out, |
58 | int *blksize_out, unsigned long long *blocks_out); | 58 | int *blksize_out, unsigned long long *blocks_out, int fd); |
59 | extern int access_file(char *path, int r, int w, int x); | 59 | extern int access_file(char *path, int r, int w, int x); |
60 | extern int open_file(char *path, int r, int w, int append); | 60 | extern int open_file(char *path, int r, int w, int append); |
61 | extern int file_type(const char *path, int *maj, int *min); | 61 | extern int file_type(const char *path, int *maj, int *min); |
@@ -71,7 +71,7 @@ extern int lseek_file(int fd, long long offset, int whence); | |||
71 | extern int fsync_file(int fd, int datasync); | 71 | extern int fsync_file(int fd, int datasync); |
72 | extern int file_create(char *name, int ur, int uw, int ux, int gr, | 72 | extern int file_create(char *name, int ur, int uw, int ux, int gr, |
73 | int gw, int gx, int or, int ow, int ox); | 73 | int gw, int gx, int or, int ow, int ox); |
74 | extern int set_attr(const char *file, struct hostfs_iattr *attrs); | 74 | extern int set_attr(const char *file, struct hostfs_iattr *attrs, int fd); |
75 | extern int make_symlink(const char *from, const char *to); | 75 | extern int make_symlink(const char *from, const char *to); |
76 | extern int unlink_file(const char *file); | 76 | extern int unlink_file(const char *file); |
77 | extern int do_mkdir(const char *file, int mode); | 77 | extern int do_mkdir(const char *file, int mode); |
@@ -87,14 +87,3 @@ extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, | |||
87 | long *spare_out); | 87 | long *spare_out); |
88 | 88 | ||
89 | #endif | 89 | #endif |
90 | |||
91 | /* | ||
92 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
93 | * Emacs will notice this stuff at the end of the file and automatically | ||
94 | * adjust the settings for this buffer only. This must remain at the end | ||
95 | * of the file. | ||
96 | * --------------------------------------------------------------------------- | ||
97 | * Local variables: | ||
98 | * c-file-style: "linux" | ||
99 | * End: | ||
100 | */ | ||
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index fd301a910122..8286491dbf31 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | * | 4 | * |
5 | * Ported the filesystem routines to 2.5. | 5 | * Ported the filesystem routines to 2.5. |
@@ -31,14 +31,14 @@ struct hostfs_inode_info { | |||
31 | 31 | ||
32 | static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) | 32 | static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) |
33 | { | 33 | { |
34 | return(list_entry(inode, struct hostfs_inode_info, vfs_inode)); | 34 | return list_entry(inode, struct hostfs_inode_info, vfs_inode); |
35 | } | 35 | } |
36 | 36 | ||
37 | #define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode) | 37 | #define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode) |
38 | 38 | ||
39 | int hostfs_d_delete(struct dentry *dentry) | 39 | int hostfs_d_delete(struct dentry *dentry) |
40 | { | 40 | { |
41 | return(1); | 41 | return 1; |
42 | } | 42 | } |
43 | 43 | ||
44 | struct dentry_operations hostfs_dentry_ops = { | 44 | struct dentry_operations hostfs_dentry_ops = { |
@@ -79,7 +79,7 @@ static int __init hostfs_args(char *options, int *add) | |||
79 | } | 79 | } |
80 | options = ptr; | 80 | options = ptr; |
81 | } | 81 | } |
82 | return(0); | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | __uml_setup("hostfs=", hostfs_args, | 85 | __uml_setup("hostfs=", hostfs_args, |
@@ -110,7 +110,8 @@ static char *dentry_name(struct dentry *dentry, int extra) | |||
110 | root = HOSTFS_I(parent->d_inode)->host_filename; | 110 | root = HOSTFS_I(parent->d_inode)->host_filename; |
111 | len += strlen(root); | 111 | len += strlen(root); |
112 | name = kmalloc(len + extra + 1, GFP_KERNEL); | 112 | name = kmalloc(len + extra + 1, GFP_KERNEL); |
113 | if(name == NULL) return(NULL); | 113 | if(name == NULL) |
114 | return NULL; | ||
114 | 115 | ||
115 | name[len] = '\0'; | 116 | name[len] = '\0'; |
116 | parent = dentry; | 117 | parent = dentry; |
@@ -122,7 +123,7 @@ static char *dentry_name(struct dentry *dentry, int extra) | |||
122 | parent = parent->d_parent; | 123 | parent = parent->d_parent; |
123 | } | 124 | } |
124 | strncpy(name, root, strlen(root)); | 125 | strncpy(name, root, strlen(root)); |
125 | return(name); | 126 | return name; |
126 | } | 127 | } |
127 | 128 | ||
128 | static char *inode_name(struct inode *ino, int extra) | 129 | static char *inode_name(struct inode *ino, int extra) |
@@ -130,7 +131,7 @@ static char *inode_name(struct inode *ino, int extra) | |||
130 | struct dentry *dentry; | 131 | struct dentry *dentry; |
131 | 132 | ||
132 | dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias); | 133 | dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias); |
133 | return(dentry_name(dentry, extra)); | 134 | return dentry_name(dentry, extra); |
134 | } | 135 | } |
135 | 136 | ||
136 | static int read_name(struct inode *ino, char *name) | 137 | static int read_name(struct inode *ino, char *name) |
@@ -147,16 +148,16 @@ static int read_name(struct inode *ino, char *name) | |||
147 | 148 | ||
148 | err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, | 149 | err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, |
149 | &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, | 150 | &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, |
150 | &ino->i_ctime, &i_blksize, &i_blocks); | 151 | &ino->i_ctime, &i_blksize, &i_blocks, -1); |
151 | if(err) | 152 | if(err) |
152 | return(err); | 153 | return err; |
153 | 154 | ||
154 | ino->i_ino = i_ino; | 155 | ino->i_ino = i_ino; |
155 | ino->i_mode = i_mode; | 156 | ino->i_mode = i_mode; |
156 | ino->i_nlink = i_nlink; | 157 | ino->i_nlink = i_nlink; |
157 | ino->i_size = i_size; | 158 | ino->i_size = i_size; |
158 | ino->i_blocks = i_blocks; | 159 | ino->i_blocks = i_blocks; |
159 | return(0); | 160 | return 0; |
160 | } | 161 | } |
161 | 162 | ||
162 | static char *follow_link(char *link) | 163 | static char *follow_link(char *link) |
@@ -181,11 +182,11 @@ static char *follow_link(char *link) | |||
181 | goto out_free; | 182 | goto out_free; |
182 | 183 | ||
183 | if(*name == '/') | 184 | if(*name == '/') |
184 | return(name); | 185 | return name; |
185 | 186 | ||
186 | end = strrchr(link, '/'); | 187 | end = strrchr(link, '/'); |
187 | if(end == NULL) | 188 | if(end == NULL) |
188 | return(name); | 189 | return name; |
189 | 190 | ||
190 | *(end + 1) = '\0'; | 191 | *(end + 1) = '\0'; |
191 | len = strlen(link) + strlen(name) + 1; | 192 | len = strlen(link) + strlen(name) + 1; |
@@ -199,12 +200,12 @@ static char *follow_link(char *link) | |||
199 | sprintf(resolved, "%s%s", link, name); | 200 | sprintf(resolved, "%s%s", link, name); |
200 | kfree(name); | 201 | kfree(name); |
201 | kfree(link); | 202 | kfree(link); |
202 | return(resolved); | 203 | return resolved; |
203 | 204 | ||
204 | out_free: | 205 | out_free: |
205 | kfree(name); | 206 | kfree(name); |
206 | out: | 207 | out: |
207 | return(ERR_PTR(n)); | 208 | return ERR_PTR(n); |
208 | } | 209 | } |
209 | 210 | ||
210 | static int read_inode(struct inode *ino) | 211 | static int read_inode(struct inode *ino) |
@@ -234,7 +235,7 @@ static int read_inode(struct inode *ino) | |||
234 | err = read_name(ino, name); | 235 | err = read_name(ino, name); |
235 | kfree(name); | 236 | kfree(name); |
236 | out: | 237 | out: |
237 | return(err); | 238 | return err; |
238 | } | 239 | } |
239 | 240 | ||
240 | int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) | 241 | int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) |
@@ -254,14 +255,15 @@ int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) | |||
254 | &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, | 255 | &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, |
255 | &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), | 256 | &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), |
256 | &sf->f_namelen, sf->f_spare); | 257 | &sf->f_namelen, sf->f_spare); |
257 | if(err) return(err); | 258 | if(err) |
259 | return err; | ||
258 | sf->f_blocks = f_blocks; | 260 | sf->f_blocks = f_blocks; |
259 | sf->f_bfree = f_bfree; | 261 | sf->f_bfree = f_bfree; |
260 | sf->f_bavail = f_bavail; | 262 | sf->f_bavail = f_bavail; |
261 | sf->f_files = f_files; | 263 | sf->f_files = f_files; |
262 | sf->f_ffree = f_ffree; | 264 | sf->f_ffree = f_ffree; |
263 | sf->f_type = HOSTFS_SUPER_MAGIC; | 265 | sf->f_type = HOSTFS_SUPER_MAGIC; |
264 | return(0); | 266 | return 0; |
265 | } | 267 | } |
266 | 268 | ||
267 | static struct inode *hostfs_alloc_inode(struct super_block *sb) | 269 | static struct inode *hostfs_alloc_inode(struct super_block *sb) |
@@ -270,13 +272,13 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb) | |||
270 | 272 | ||
271 | hi = kmalloc(sizeof(*hi), GFP_KERNEL); | 273 | hi = kmalloc(sizeof(*hi), GFP_KERNEL); |
272 | if(hi == NULL) | 274 | if(hi == NULL) |
273 | return(NULL); | 275 | return NULL; |
274 | 276 | ||
275 | *hi = ((struct hostfs_inode_info) { .host_filename = NULL, | 277 | *hi = ((struct hostfs_inode_info) { .host_filename = NULL, |
276 | .fd = -1, | 278 | .fd = -1, |
277 | .mode = 0 }); | 279 | .mode = 0 }); |
278 | inode_init_once(&hi->vfs_inode); | 280 | inode_init_once(&hi->vfs_inode); |
279 | return(&hi->vfs_inode); | 281 | return &hi->vfs_inode; |
280 | } | 282 | } |
281 | 283 | ||
282 | static void hostfs_delete_inode(struct inode *inode) | 284 | static void hostfs_delete_inode(struct inode *inode) |
@@ -325,10 +327,12 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
325 | int error, len; | 327 | int error, len; |
326 | 328 | ||
327 | name = dentry_name(file->f_path.dentry, 0); | 329 | name = dentry_name(file->f_path.dentry, 0); |
328 | if(name == NULL) return(-ENOMEM); | 330 | if(name == NULL) |
331 | return -ENOMEM; | ||
329 | dir = open_dir(name, &error); | 332 | dir = open_dir(name, &error); |
330 | kfree(name); | 333 | kfree(name); |
331 | if(dir == NULL) return(-error); | 334 | if(dir == NULL) |
335 | return -error; | ||
332 | next = file->f_pos; | 336 | next = file->f_pos; |
333 | while((name = read_dir(dir, &next, &ino, &len)) != NULL){ | 337 | while((name = read_dir(dir, &next, &ino, &len)) != NULL){ |
334 | error = (*filldir)(ent, name, len, file->f_pos, | 338 | error = (*filldir)(ent, name, len, file->f_pos, |
@@ -337,7 +341,7 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
337 | file->f_pos = next; | 341 | file->f_pos = next; |
338 | } | 342 | } |
339 | close_dir(dir); | 343 | close_dir(dir); |
340 | return(0); | 344 | return 0; |
341 | } | 345 | } |
342 | 346 | ||
343 | int hostfs_file_open(struct inode *ino, struct file *file) | 347 | int hostfs_file_open(struct inode *ino, struct file *file) |
@@ -347,7 +351,7 @@ int hostfs_file_open(struct inode *ino, struct file *file) | |||
347 | 351 | ||
348 | mode = file->f_mode & (FMODE_READ | FMODE_WRITE); | 352 | mode = file->f_mode & (FMODE_READ | FMODE_WRITE); |
349 | if((mode & HOSTFS_I(ino)->mode) == mode) | 353 | if((mode & HOSTFS_I(ino)->mode) == mode) |
350 | return(0); | 354 | return 0; |
351 | 355 | ||
352 | /* The file may already have been opened, but with the wrong access, | 356 | /* The file may already have been opened, but with the wrong access, |
353 | * so this resets things and reopens the file with the new access. | 357 | * so this resets things and reopens the file with the new access. |
@@ -367,14 +371,15 @@ int hostfs_file_open(struct inode *ino, struct file *file) | |||
367 | 371 | ||
368 | name = dentry_name(file->f_path.dentry, 0); | 372 | name = dentry_name(file->f_path.dentry, 0); |
369 | if(name == NULL) | 373 | if(name == NULL) |
370 | return(-ENOMEM); | 374 | return -ENOMEM; |
371 | 375 | ||
372 | fd = open_file(name, r, w, append); | 376 | fd = open_file(name, r, w, append); |
373 | kfree(name); | 377 | kfree(name); |
374 | if(fd < 0) return(fd); | 378 | if(fd < 0) |
379 | return fd; | ||
375 | FILE_HOSTFS_I(file)->fd = fd; | 380 | FILE_HOSTFS_I(file)->fd = fd; |
376 | 381 | ||
377 | return(0); | 382 | return 0; |
378 | } | 383 | } |
379 | 384 | ||
380 | int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 385 | int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) |
@@ -458,7 +463,7 @@ int hostfs_readpage(struct file *file, struct page *page) | |||
458 | out: | 463 | out: |
459 | kunmap(page); | 464 | kunmap(page); |
460 | unlock_page(page); | 465 | unlock_page(page); |
461 | return(err); | 466 | return err; |
462 | } | 467 | } |
463 | 468 | ||
464 | int hostfs_prepare_write(struct file *file, struct page *page, | 469 | int hostfs_prepare_write(struct file *file, struct page *page, |
@@ -485,7 +490,7 @@ int hostfs_prepare_write(struct file *file, struct page *page, | |||
485 | err = 0; | 490 | err = 0; |
486 | out: | 491 | out: |
487 | kunmap(page); | 492 | kunmap(page); |
488 | return(err); | 493 | return err; |
489 | } | 494 | } |
490 | 495 | ||
491 | int hostfs_commit_write(struct file *file, struct page *page, unsigned from, | 496 | int hostfs_commit_write(struct file *file, struct page *page, unsigned from, |
@@ -511,7 +516,7 @@ int hostfs_commit_write(struct file *file, struct page *page, unsigned from, | |||
511 | inode->i_size = start; | 516 | inode->i_size = start; |
512 | 517 | ||
513 | kunmap(page); | 518 | kunmap(page); |
514 | return(err); | 519 | return err; |
515 | } | 520 | } |
516 | 521 | ||
517 | static const struct address_space_operations hostfs_aops = { | 522 | static const struct address_space_operations hostfs_aops = { |
@@ -569,7 +574,7 @@ static int init_inode(struct inode *inode, struct dentry *dentry) | |||
569 | break; | 574 | break; |
570 | } | 575 | } |
571 | out: | 576 | out: |
572 | return(err); | 577 | return err; |
573 | } | 578 | } |
574 | 579 | ||
575 | int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, | 580 | int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, |
@@ -607,16 +612,16 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
607 | HOSTFS_I(inode)->fd = fd; | 612 | HOSTFS_I(inode)->fd = fd; |
608 | HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE; | 613 | HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE; |
609 | d_instantiate(dentry, inode); | 614 | d_instantiate(dentry, inode); |
610 | return(0); | 615 | return 0; |
611 | 616 | ||
612 | out_put: | 617 | out_put: |
613 | iput(inode); | 618 | iput(inode); |
614 | out: | 619 | out: |
615 | return(error); | 620 | return error; |
616 | } | 621 | } |
617 | 622 | ||
618 | struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, | 623 | struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, |
619 | struct nameidata *nd) | 624 | struct nameidata *nd) |
620 | { | 625 | { |
621 | struct inode *inode; | 626 | struct inode *inode; |
622 | char *name; | 627 | char *name; |
@@ -647,44 +652,45 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, | |||
647 | 652 | ||
648 | d_add(dentry, inode); | 653 | d_add(dentry, inode); |
649 | dentry->d_op = &hostfs_dentry_ops; | 654 | dentry->d_op = &hostfs_dentry_ops; |
650 | return(NULL); | 655 | return NULL; |
651 | 656 | ||
652 | out_put: | 657 | out_put: |
653 | iput(inode); | 658 | iput(inode); |
654 | out: | 659 | out: |
655 | return(ERR_PTR(err)); | 660 | return ERR_PTR(err); |
656 | } | 661 | } |
657 | 662 | ||
658 | static char *inode_dentry_name(struct inode *ino, struct dentry *dentry) | 663 | static char *inode_dentry_name(struct inode *ino, struct dentry *dentry) |
659 | { | 664 | { |
660 | char *file; | 665 | char *file; |
661 | int len; | 666 | int len; |
662 | 667 | ||
663 | file = inode_name(ino, dentry->d_name.len + 1); | 668 | file = inode_name(ino, dentry->d_name.len + 1); |
664 | if(file == NULL) return(NULL); | 669 | if(file == NULL) |
665 | strcat(file, "/"); | 670 | return NULL; |
671 | strcat(file, "/"); | ||
666 | len = strlen(file); | 672 | len = strlen(file); |
667 | strncat(file, dentry->d_name.name, dentry->d_name.len); | 673 | strncat(file, dentry->d_name.name, dentry->d_name.len); |
668 | file[len + dentry->d_name.len] = '\0'; | 674 | file[len + dentry->d_name.len] = '\0'; |
669 | return(file); | 675 | return file; |
670 | } | 676 | } |
671 | 677 | ||
672 | int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from) | 678 | int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from) |
673 | { | 679 | { |
674 | char *from_name, *to_name; | 680 | char *from_name, *to_name; |
675 | int err; | 681 | int err; |
676 | 682 | ||
677 | if((from_name = inode_dentry_name(ino, from)) == NULL) | 683 | if((from_name = inode_dentry_name(ino, from)) == NULL) |
678 | return(-ENOMEM); | 684 | return -ENOMEM; |
679 | to_name = dentry_name(to, 0); | 685 | to_name = dentry_name(to, 0); |
680 | if(to_name == NULL){ | 686 | if(to_name == NULL){ |
681 | kfree(from_name); | 687 | kfree(from_name); |
682 | return(-ENOMEM); | 688 | return -ENOMEM; |
683 | } | 689 | } |
684 | err = link_file(to_name, from_name); | 690 | err = link_file(to_name, from_name); |
685 | kfree(from_name); | 691 | kfree(from_name); |
686 | kfree(to_name); | 692 | kfree(to_name); |
687 | return(err); | 693 | return err; |
688 | } | 694 | } |
689 | 695 | ||
690 | int hostfs_unlink(struct inode *ino, struct dentry *dentry) | 696 | int hostfs_unlink(struct inode *ino, struct dentry *dentry) |
@@ -692,13 +698,14 @@ int hostfs_unlink(struct inode *ino, struct dentry *dentry) | |||
692 | char *file; | 698 | char *file; |
693 | int err; | 699 | int err; |
694 | 700 | ||
695 | if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); | 701 | if((file = inode_dentry_name(ino, dentry)) == NULL) |
702 | return -ENOMEM; | ||
696 | if(append) | 703 | if(append) |
697 | return(-EPERM); | 704 | return -EPERM; |
698 | 705 | ||
699 | err = unlink_file(file); | 706 | err = unlink_file(file); |
700 | kfree(file); | 707 | kfree(file); |
701 | return(err); | 708 | return err; |
702 | } | 709 | } |
703 | 710 | ||
704 | int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) | 711 | int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) |
@@ -706,10 +713,11 @@ int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) | |||
706 | char *file; | 713 | char *file; |
707 | int err; | 714 | int err; |
708 | 715 | ||
709 | if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); | 716 | if((file = inode_dentry_name(ino, dentry)) == NULL) |
717 | return -ENOMEM; | ||
710 | err = make_symlink(file, to); | 718 | err = make_symlink(file, to); |
711 | kfree(file); | 719 | kfree(file); |
712 | return(err); | 720 | return err; |
713 | } | 721 | } |
714 | 722 | ||
715 | int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode) | 723 | int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode) |
@@ -717,10 +725,11 @@ int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode) | |||
717 | char *file; | 725 | char *file; |
718 | int err; | 726 | int err; |
719 | 727 | ||
720 | if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); | 728 | if((file = inode_dentry_name(ino, dentry)) == NULL) |
729 | return -ENOMEM; | ||
721 | err = do_mkdir(file, mode); | 730 | err = do_mkdir(file, mode); |
722 | kfree(file); | 731 | kfree(file); |
723 | return(err); | 732 | return err; |
724 | } | 733 | } |
725 | 734 | ||
726 | int hostfs_rmdir(struct inode *ino, struct dentry *dentry) | 735 | int hostfs_rmdir(struct inode *ino, struct dentry *dentry) |
@@ -728,10 +737,11 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry) | |||
728 | char *file; | 737 | char *file; |
729 | int err; | 738 | int err; |
730 | 739 | ||
731 | if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); | 740 | if((file = inode_dentry_name(ino, dentry)) == NULL) |
741 | return -ENOMEM; | ||
732 | err = do_rmdir(file); | 742 | err = do_rmdir(file); |
733 | kfree(file); | 743 | kfree(file); |
734 | return(err); | 744 | return err; |
735 | } | 745 | } |
736 | 746 | ||
737 | int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | 747 | int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) |
@@ -764,14 +774,14 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
764 | goto out_put; | 774 | goto out_put; |
765 | 775 | ||
766 | d_instantiate(dentry, inode); | 776 | d_instantiate(dentry, inode); |
767 | return(0); | 777 | return 0; |
768 | 778 | ||
769 | out_free: | 779 | out_free: |
770 | kfree(name); | 780 | kfree(name); |
771 | out_put: | 781 | out_put: |
772 | iput(inode); | 782 | iput(inode); |
773 | out: | 783 | out: |
774 | return(err); | 784 | return err; |
775 | } | 785 | } |
776 | 786 | ||
777 | int hostfs_rename(struct inode *from_ino, struct dentry *from, | 787 | int hostfs_rename(struct inode *from_ino, struct dentry *from, |
@@ -781,15 +791,15 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from, | |||
781 | int err; | 791 | int err; |
782 | 792 | ||
783 | if((from_name = inode_dentry_name(from_ino, from)) == NULL) | 793 | if((from_name = inode_dentry_name(from_ino, from)) == NULL) |
784 | return(-ENOMEM); | 794 | return -ENOMEM; |
785 | if((to_name = inode_dentry_name(to_ino, to)) == NULL){ | 795 | if((to_name = inode_dentry_name(to_ino, to)) == NULL){ |
786 | kfree(from_name); | 796 | kfree(from_name); |
787 | return(-ENOMEM); | 797 | return -ENOMEM; |
788 | } | 798 | } |
789 | err = rename_file(from_name, to_name); | 799 | err = rename_file(from_name, to_name); |
790 | kfree(from_name); | 800 | kfree(from_name); |
791 | kfree(to_name); | 801 | kfree(to_name); |
792 | return(err); | 802 | return err; |
793 | } | 803 | } |
794 | 804 | ||
795 | int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd) | 805 | int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd) |
@@ -801,7 +811,8 @@ int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd) | |||
801 | if (desired & MAY_WRITE) w = 1; | 811 | if (desired & MAY_WRITE) w = 1; |
802 | if (desired & MAY_EXEC) x = 1; | 812 | if (desired & MAY_EXEC) x = 1; |
803 | name = inode_name(ino, 0); | 813 | name = inode_name(ino, 0); |
804 | if (name == NULL) return(-ENOMEM); | 814 | if (name == NULL) |
815 | return -ENOMEM; | ||
805 | 816 | ||
806 | if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) || | 817 | if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) || |
807 | S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode)) | 818 | S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode)) |
@@ -820,6 +831,8 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
820 | char *name; | 831 | char *name; |
821 | int err; | 832 | int err; |
822 | 833 | ||
834 | int fd = HOSTFS_I(dentry->d_inode)->fd; | ||
835 | |||
823 | err = inode_change_ok(dentry->d_inode, attr); | 836 | err = inode_change_ok(dentry->d_inode, attr); |
824 | if (err) | 837 | if (err) |
825 | return err; | 838 | return err; |
@@ -863,20 +876,21 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
863 | attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET; | 876 | attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET; |
864 | } | 877 | } |
865 | name = dentry_name(dentry, 0); | 878 | name = dentry_name(dentry, 0); |
866 | if(name == NULL) return(-ENOMEM); | 879 | if(name == NULL) |
867 | err = set_attr(name, &attrs); | 880 | return -ENOMEM; |
881 | err = set_attr(name, &attrs, fd); | ||
868 | kfree(name); | 882 | kfree(name); |
869 | if(err) | 883 | if(err) |
870 | return(err); | 884 | return err; |
871 | 885 | ||
872 | return(inode_setattr(dentry->d_inode, attr)); | 886 | return inode_setattr(dentry->d_inode, attr); |
873 | } | 887 | } |
874 | 888 | ||
875 | int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 889 | int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
876 | struct kstat *stat) | 890 | struct kstat *stat) |
877 | { | 891 | { |
878 | generic_fillattr(dentry->d_inode, stat); | 892 | generic_fillattr(dentry->d_inode, stat); |
879 | return(0); | 893 | return 0; |
880 | } | 894 | } |
881 | 895 | ||
882 | static const struct inode_operations hostfs_iops = { | 896 | static const struct inode_operations hostfs_iops = { |
@@ -915,7 +929,8 @@ int hostfs_link_readpage(struct file *file, struct page *page) | |||
915 | 929 | ||
916 | buffer = kmap(page); | 930 | buffer = kmap(page); |
917 | name = inode_name(page->mapping->host, 0); | 931 | name = inode_name(page->mapping->host, 0); |
918 | if(name == NULL) return(-ENOMEM); | 932 | if(name == NULL) |
933 | return -ENOMEM; | ||
919 | err = do_readlink(name, buffer, PAGE_CACHE_SIZE); | 934 | err = do_readlink(name, buffer, PAGE_CACHE_SIZE); |
920 | kfree(name); | 935 | kfree(name); |
921 | if(err == PAGE_CACHE_SIZE) | 936 | if(err == PAGE_CACHE_SIZE) |
@@ -928,7 +943,7 @@ int hostfs_link_readpage(struct file *file, struct page *page) | |||
928 | } | 943 | } |
929 | kunmap(page); | 944 | kunmap(page); |
930 | unlock_page(page); | 945 | unlock_page(page); |
931 | return(err); | 946 | return err; |
932 | } | 947 | } |
933 | 948 | ||
934 | static const struct address_space_operations hostfs_link_aops = { | 949 | static const struct address_space_operations hostfs_link_aops = { |
@@ -978,20 +993,20 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
978 | 993 | ||
979 | err = read_inode(root_inode); | 994 | err = read_inode(root_inode); |
980 | if(err){ | 995 | if(err){ |
981 | /* No iput in this case because the dput does that for us */ | 996 | /* No iput in this case because the dput does that for us */ |
982 | dput(sb->s_root); | 997 | dput(sb->s_root); |
983 | sb->s_root = NULL; | 998 | sb->s_root = NULL; |
984 | goto out; | 999 | goto out; |
985 | } | 1000 | } |
986 | 1001 | ||
987 | return(0); | 1002 | return 0; |
988 | 1003 | ||
989 | out_put: | 1004 | out_put: |
990 | iput(root_inode); | 1005 | iput(root_inode); |
991 | out_free: | 1006 | out_free: |
992 | kfree(host_root_path); | 1007 | kfree(host_root_path); |
993 | out: | 1008 | out: |
994 | return(err); | 1009 | return err; |
995 | } | 1010 | } |
996 | 1011 | ||
997 | static int hostfs_read_sb(struct file_system_type *type, | 1012 | static int hostfs_read_sb(struct file_system_type *type, |
@@ -1011,7 +1026,7 @@ static struct file_system_type hostfs_type = { | |||
1011 | 1026 | ||
1012 | static int __init init_hostfs(void) | 1027 | static int __init init_hostfs(void) |
1013 | { | 1028 | { |
1014 | return(register_filesystem(&hostfs_type)); | 1029 | return register_filesystem(&hostfs_type); |
1015 | } | 1030 | } |
1016 | 1031 | ||
1017 | static void __exit exit_hostfs(void) | 1032 | static void __exit exit_hostfs(void) |
@@ -1022,14 +1037,3 @@ static void __exit exit_hostfs(void) | |||
1022 | module_init(init_hostfs) | 1037 | module_init(init_hostfs) |
1023 | module_exit(exit_hostfs) | 1038 | module_exit(exit_hostfs) |
1024 | MODULE_LICENSE("GPL"); | 1039 | MODULE_LICENSE("GPL"); |
1025 | |||
1026 | /* | ||
1027 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1028 | * Emacs will notice this stuff at the end of the file and automatically | ||
1029 | * adjust the settings for this buffer only. This must remain at the end | ||
1030 | * of the file. | ||
1031 | * --------------------------------------------------------------------------- | ||
1032 | * Local variables: | ||
1033 | * c-file-style: "linux" | ||
1034 | * End: | ||
1035 | */ | ||
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index 1ed5ea389f15..5625e2481dd3 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -21,12 +21,16 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, | |||
21 | int *nlink_out, int *uid_out, int *gid_out, | 21 | int *nlink_out, int *uid_out, int *gid_out, |
22 | unsigned long long *size_out, struct timespec *atime_out, | 22 | unsigned long long *size_out, struct timespec *atime_out, |
23 | struct timespec *mtime_out, struct timespec *ctime_out, | 23 | struct timespec *mtime_out, struct timespec *ctime_out, |
24 | int *blksize_out, unsigned long long *blocks_out) | 24 | int *blksize_out, unsigned long long *blocks_out, int fd) |
25 | { | 25 | { |
26 | struct stat64 buf; | 26 | struct stat64 buf; |
27 | 27 | ||
28 | if(lstat64(path, &buf) < 0) | 28 | if(fd >= 0) { |
29 | return(-errno); | 29 | if (fstat64(fd, &buf) < 0) |
30 | return -errno; | ||
31 | } else if(lstat64(path, &buf) < 0) { | ||
32 | return -errno; | ||
33 | } | ||
30 | 34 | ||
31 | if(inode_out != NULL) *inode_out = buf.st_ino; | 35 | if(inode_out != NULL) *inode_out = buf.st_ino; |
32 | if(mode_out != NULL) *mode_out = buf.st_mode; | 36 | if(mode_out != NULL) *mode_out = buf.st_mode; |
@@ -48,7 +52,7 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, | |||
48 | } | 52 | } |
49 | if(blksize_out != NULL) *blksize_out = buf.st_blksize; | 53 | if(blksize_out != NULL) *blksize_out = buf.st_blksize; |
50 | if(blocks_out != NULL) *blocks_out = buf.st_blocks; | 54 | if(blocks_out != NULL) *blocks_out = buf.st_blocks; |
51 | return(0); | 55 | return 0; |
52 | } | 56 | } |
53 | 57 | ||
54 | int file_type(const char *path, int *maj, int *min) | 58 | int file_type(const char *path, int *maj, int *min) |
@@ -56,7 +60,7 @@ int file_type(const char *path, int *maj, int *min) | |||
56 | struct stat64 buf; | 60 | struct stat64 buf; |
57 | 61 | ||
58 | if(lstat64(path, &buf) < 0) | 62 | if(lstat64(path, &buf) < 0) |
59 | return(-errno); | 63 | return -errno; |
60 | /*We cannot pass rdev as is because glibc and the kernel disagree | 64 | /*We cannot pass rdev as is because glibc and the kernel disagree |
61 | *about its definition.*/ | 65 | *about its definition.*/ |
62 | if(maj != NULL) | 66 | if(maj != NULL) |
@@ -64,13 +68,13 @@ int file_type(const char *path, int *maj, int *min) | |||
64 | if(min != NULL) | 68 | if(min != NULL) |
65 | *min = minor(buf.st_rdev); | 69 | *min = minor(buf.st_rdev); |
66 | 70 | ||
67 | if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR); | 71 | if(S_ISDIR(buf.st_mode)) return OS_TYPE_DIR; |
68 | else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK); | 72 | else if(S_ISLNK(buf.st_mode)) return OS_TYPE_SYMLINK; |
69 | else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV); | 73 | else if(S_ISCHR(buf.st_mode)) return OS_TYPE_CHARDEV; |
70 | else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV); | 74 | else if(S_ISBLK(buf.st_mode)) return OS_TYPE_BLOCKDEV; |
71 | else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO); | 75 | else if(S_ISFIFO(buf.st_mode))return OS_TYPE_FIFO; |
72 | else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK); | 76 | else if(S_ISSOCK(buf.st_mode))return OS_TYPE_SOCK; |
73 | else return(OS_TYPE_FILE); | 77 | else return OS_TYPE_FILE; |
74 | } | 78 | } |
75 | 79 | ||
76 | int access_file(char *path, int r, int w, int x) | 80 | int access_file(char *path, int r, int w, int x) |
@@ -80,8 +84,9 @@ int access_file(char *path, int r, int w, int x) | |||
80 | if(r) mode = R_OK; | 84 | if(r) mode = R_OK; |
81 | if(w) mode |= W_OK; | 85 | if(w) mode |= W_OK; |
82 | if(x) mode |= X_OK; | 86 | if(x) mode |= X_OK; |
83 | if(access(path, mode) != 0) return(-errno); | 87 | if(access(path, mode) != 0) |
84 | else return(0); | 88 | return -errno; |
89 | else return 0; | ||
85 | } | 90 | } |
86 | 91 | ||
87 | int open_file(char *path, int r, int w, int append) | 92 | int open_file(char *path, int r, int w, int append) |
@@ -99,8 +104,9 @@ int open_file(char *path, int r, int w, int append) | |||
99 | if(append) | 104 | if(append) |
100 | mode |= O_APPEND; | 105 | mode |= O_APPEND; |
101 | fd = open64(path, mode); | 106 | fd = open64(path, mode); |
102 | if(fd < 0) return(-errno); | 107 | if(fd < 0) |
103 | else return(fd); | 108 | return -errno; |
109 | else return fd; | ||
104 | } | 110 | } |
105 | 111 | ||
106 | void *open_dir(char *path, int *err_out) | 112 | void *open_dir(char *path, int *err_out) |
@@ -109,8 +115,9 @@ void *open_dir(char *path, int *err_out) | |||
109 | 115 | ||
110 | dir = opendir(path); | 116 | dir = opendir(path); |
111 | *err_out = errno; | 117 | *err_out = errno; |
112 | if(dir == NULL) return(NULL); | 118 | if(dir == NULL) |
113 | return(dir); | 119 | return NULL; |
120 | return dir; | ||
114 | } | 121 | } |
115 | 122 | ||
116 | char *read_dir(void *stream, unsigned long long *pos, | 123 | char *read_dir(void *stream, unsigned long long *pos, |
@@ -121,11 +128,12 @@ char *read_dir(void *stream, unsigned long long *pos, | |||
121 | 128 | ||
122 | seekdir(dir, *pos); | 129 | seekdir(dir, *pos); |
123 | ent = readdir(dir); | 130 | ent = readdir(dir); |
124 | if(ent == NULL) return(NULL); | 131 | if(ent == NULL) |
132 | return NULL; | ||
125 | *len_out = strlen(ent->d_name); | 133 | *len_out = strlen(ent->d_name); |
126 | *ino_out = ent->d_ino; | 134 | *ino_out = ent->d_ino; |
127 | *pos = telldir(dir); | 135 | *pos = telldir(dir); |
128 | return(ent->d_name); | 136 | return ent->d_name; |
129 | } | 137 | } |
130 | 138 | ||
131 | int read_file(int fd, unsigned long long *offset, char *buf, int len) | 139 | int read_file(int fd, unsigned long long *offset, char *buf, int len) |
@@ -133,9 +141,10 @@ int read_file(int fd, unsigned long long *offset, char *buf, int len) | |||
133 | int n; | 141 | int n; |
134 | 142 | ||
135 | n = pread64(fd, buf, len, *offset); | 143 | n = pread64(fd, buf, len, *offset); |
136 | if(n < 0) return(-errno); | 144 | if(n < 0) |
145 | return -errno; | ||
137 | *offset += n; | 146 | *offset += n; |
138 | return(n); | 147 | return n; |
139 | } | 148 | } |
140 | 149 | ||
141 | int write_file(int fd, unsigned long long *offset, const char *buf, int len) | 150 | int write_file(int fd, unsigned long long *offset, const char *buf, int len) |
@@ -143,9 +152,10 @@ int write_file(int fd, unsigned long long *offset, const char *buf, int len) | |||
143 | int n; | 152 | int n; |
144 | 153 | ||
145 | n = pwrite64(fd, buf, len, *offset); | 154 | n = pwrite64(fd, buf, len, *offset); |
146 | if(n < 0) return(-errno); | 155 | if(n < 0) |
156 | return -errno; | ||
147 | *offset += n; | 157 | *offset += n; |
148 | return(n); | 158 | return n; |
149 | } | 159 | } |
150 | 160 | ||
151 | int lseek_file(int fd, long long offset, int whence) | 161 | int lseek_file(int fd, long long offset, int whence) |
@@ -154,8 +164,8 @@ int lseek_file(int fd, long long offset, int whence) | |||
154 | 164 | ||
155 | ret = lseek64(fd, offset, whence); | 165 | ret = lseek64(fd, offset, whence); |
156 | if(ret < 0) | 166 | if(ret < 0) |
157 | return(-errno); | 167 | return -errno; |
158 | return(0); | 168 | return 0; |
159 | } | 169 | } |
160 | 170 | ||
161 | int fsync_file(int fd, int datasync) | 171 | int fsync_file(int fd, int datasync) |
@@ -198,65 +208,90 @@ int file_create(char *name, int ur, int uw, int ux, int gr, | |||
198 | mode |= ox ? S_IXOTH : 0; | 208 | mode |= ox ? S_IXOTH : 0; |
199 | fd = open64(name, O_CREAT | O_RDWR, mode); | 209 | fd = open64(name, O_CREAT | O_RDWR, mode); |
200 | if(fd < 0) | 210 | if(fd < 0) |
201 | return(-errno); | 211 | return -errno; |
202 | return(fd); | 212 | return fd; |
203 | } | 213 | } |
204 | 214 | ||
205 | int set_attr(const char *file, struct hostfs_iattr *attrs) | 215 | int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) |
206 | { | 216 | { |
207 | struct utimbuf buf; | 217 | struct timeval times[2]; |
218 | struct timespec atime_ts, mtime_ts; | ||
208 | int err, ma; | 219 | int err, ma; |
209 | 220 | ||
210 | if(attrs->ia_valid & HOSTFS_ATTR_MODE){ | 221 | if (attrs->ia_valid & HOSTFS_ATTR_MODE) { |
211 | if(chmod(file, attrs->ia_mode) != 0) return(-errno); | 222 | if (fd >= 0) { |
212 | } | 223 | if (fchmod(fd, attrs->ia_mode) != 0) |
213 | if(attrs->ia_valid & HOSTFS_ATTR_UID){ | 224 | return (-errno); |
214 | if(chown(file, attrs->ia_uid, -1)) return(-errno); | 225 | } else if (chmod(file, attrs->ia_mode) != 0) { |
226 | return -errno; | ||
227 | } | ||
215 | } | 228 | } |
216 | if(attrs->ia_valid & HOSTFS_ATTR_GID){ | 229 | if (attrs->ia_valid & HOSTFS_ATTR_UID) { |
217 | if(chown(file, -1, attrs->ia_gid)) return(-errno); | 230 | if (fd >= 0) { |
231 | if (fchown(fd, attrs->ia_uid, -1)) | ||
232 | return -errno; | ||
233 | } else if(chown(file, attrs->ia_uid, -1)) { | ||
234 | return -errno; | ||
235 | } | ||
218 | } | 236 | } |
219 | if(attrs->ia_valid & HOSTFS_ATTR_SIZE){ | 237 | if (attrs->ia_valid & HOSTFS_ATTR_GID) { |
220 | if(truncate(file, attrs->ia_size)) return(-errno); | 238 | if (fd >= 0) { |
239 | if (fchown(fd, -1, attrs->ia_gid)) | ||
240 | return -errno; | ||
241 | } else if (chown(file, -1, attrs->ia_gid)) { | ||
242 | return -errno; | ||
243 | } | ||
221 | } | 244 | } |
222 | ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET; | 245 | if (attrs->ia_valid & HOSTFS_ATTR_SIZE) { |
223 | if((attrs->ia_valid & ma) == ma){ | 246 | if (fd >= 0) { |
224 | buf.actime = attrs->ia_atime.tv_sec; | 247 | if (ftruncate(fd, attrs->ia_size)) |
225 | buf.modtime = attrs->ia_mtime.tv_sec; | 248 | return -errno; |
226 | if(utime(file, &buf) != 0) return(-errno); | 249 | } else if (truncate(file, attrs->ia_size)) { |
250 | return -errno; | ||
251 | } | ||
227 | } | 252 | } |
228 | else { | 253 | |
229 | struct timespec ts; | 254 | /* Update accessed and/or modified time, in two parts: first set |
230 | 255 | * times according to the changes to perform, and then call futimes() | |
231 | if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){ | 256 | * or utimes() to apply them. */ |
232 | err = stat_file(file, NULL, NULL, NULL, NULL, NULL, | 257 | ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET); |
233 | NULL, NULL, &ts, NULL, NULL, NULL); | 258 | if (attrs->ia_valid & ma) { |
234 | if(err != 0) | 259 | err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, |
235 | return(err); | 260 | &atime_ts, &mtime_ts, NULL, NULL, NULL, fd); |
236 | buf.actime = attrs->ia_atime.tv_sec; | 261 | if (err != 0) |
237 | buf.modtime = ts.tv_sec; | 262 | return err; |
238 | if(utime(file, &buf) != 0) | 263 | |
239 | return(-errno); | 264 | times[0].tv_sec = atime_ts.tv_sec; |
265 | times[0].tv_usec = atime_ts.tv_nsec * 1000; | ||
266 | times[1].tv_sec = mtime_ts.tv_sec; | ||
267 | times[1].tv_usec = mtime_ts.tv_nsec * 1000; | ||
268 | |||
269 | if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) { | ||
270 | times[0].tv_sec = attrs->ia_atime.tv_sec; | ||
271 | times[0].tv_usec = attrs->ia_atime.tv_nsec * 1000; | ||
272 | } | ||
273 | if (attrs->ia_valid & HOSTFS_ATTR_MTIME_SET) { | ||
274 | times[1].tv_sec = attrs->ia_mtime.tv_sec; | ||
275 | times[1].tv_usec = attrs->ia_mtime.tv_nsec * 1000; | ||
240 | } | 276 | } |
241 | if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){ | 277 | |
242 | err = stat_file(file, NULL, NULL, NULL, NULL, NULL, | 278 | if (fd >= 0) { |
243 | NULL, &ts, NULL, NULL, NULL, NULL); | 279 | if (futimes(fd, times) != 0) |
244 | if(err != 0) | 280 | return -errno; |
245 | return(err); | 281 | } else if (utimes(file, times) != 0) { |
246 | buf.actime = ts.tv_sec; | 282 | return -errno; |
247 | buf.modtime = attrs->ia_mtime.tv_sec; | ||
248 | if(utime(file, &buf) != 0) | ||
249 | return(-errno); | ||
250 | } | 283 | } |
251 | } | 284 | } |
285 | |||
252 | if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ; | 286 | if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ; |
253 | if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){ | 287 | if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){ |
254 | err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, | 288 | err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, |
255 | &attrs->ia_atime, &attrs->ia_mtime, NULL, | 289 | &attrs->ia_atime, &attrs->ia_mtime, NULL, |
256 | NULL, NULL); | 290 | NULL, NULL, fd); |
257 | if(err != 0) return(err); | 291 | if(err != 0) |
292 | return err; | ||
258 | } | 293 | } |
259 | return(0); | 294 | return 0; |
260 | } | 295 | } |
261 | 296 | ||
262 | int make_symlink(const char *from, const char *to) | 297 | int make_symlink(const char *from, const char *to) |
@@ -264,8 +299,9 @@ int make_symlink(const char *from, const char *to) | |||
264 | int err; | 299 | int err; |
265 | 300 | ||
266 | err = symlink(to, from); | 301 | err = symlink(to, from); |
267 | if(err) return(-errno); | 302 | if(err) |
268 | return(0); | 303 | return -errno; |
304 | return 0; | ||
269 | } | 305 | } |
270 | 306 | ||
271 | int unlink_file(const char *file) | 307 | int unlink_file(const char *file) |
@@ -273,8 +309,9 @@ int unlink_file(const char *file) | |||
273 | int err; | 309 | int err; |
274 | 310 | ||
275 | err = unlink(file); | 311 | err = unlink(file); |
276 | if(err) return(-errno); | 312 | if(err) |
277 | return(0); | 313 | return -errno; |
314 | return 0; | ||
278 | } | 315 | } |
279 | 316 | ||
280 | int do_mkdir(const char *file, int mode) | 317 | int do_mkdir(const char *file, int mode) |
@@ -282,8 +319,9 @@ int do_mkdir(const char *file, int mode) | |||
282 | int err; | 319 | int err; |
283 | 320 | ||
284 | err = mkdir(file, mode); | 321 | err = mkdir(file, mode); |
285 | if(err) return(-errno); | 322 | if(err) |
286 | return(0); | 323 | return -errno; |
324 | return 0; | ||
287 | } | 325 | } |
288 | 326 | ||
289 | int do_rmdir(const char *file) | 327 | int do_rmdir(const char *file) |
@@ -291,8 +329,9 @@ int do_rmdir(const char *file) | |||
291 | int err; | 329 | int err; |
292 | 330 | ||
293 | err = rmdir(file); | 331 | err = rmdir(file); |
294 | if(err) return(-errno); | 332 | if(err) |
295 | return(0); | 333 | return -errno; |
334 | return 0; | ||
296 | } | 335 | } |
297 | 336 | ||
298 | int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor) | 337 | int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor) |
@@ -300,8 +339,9 @@ int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor) | |||
300 | int err; | 339 | int err; |
301 | 340 | ||
302 | err = mknod(file, mode, makedev(major, minor)); | 341 | err = mknod(file, mode, makedev(major, minor)); |
303 | if(err) return(-errno); | 342 | if(err) |
304 | return(0); | 343 | return -errno; |
344 | return 0; | ||
305 | } | 345 | } |
306 | 346 | ||
307 | int link_file(const char *to, const char *from) | 347 | int link_file(const char *to, const char *from) |
@@ -309,8 +349,9 @@ int link_file(const char *to, const char *from) | |||
309 | int err; | 349 | int err; |
310 | 350 | ||
311 | err = link(to, from); | 351 | err = link(to, from); |
312 | if(err) return(-errno); | 352 | if(err) |
313 | return(0); | 353 | return -errno; |
354 | return 0; | ||
314 | } | 355 | } |
315 | 356 | ||
316 | int do_readlink(char *file, char *buf, int size) | 357 | int do_readlink(char *file, char *buf, int size) |
@@ -319,10 +360,10 @@ int do_readlink(char *file, char *buf, int size) | |||
319 | 360 | ||
320 | n = readlink(file, buf, size); | 361 | n = readlink(file, buf, size); |
321 | if(n < 0) | 362 | if(n < 0) |
322 | return(-errno); | 363 | return -errno; |
323 | if(n < size) | 364 | if(n < size) |
324 | buf[n] = '\0'; | 365 | buf[n] = '\0'; |
325 | return(n); | 366 | return n; |
326 | } | 367 | } |
327 | 368 | ||
328 | int rename_file(char *from, char *to) | 369 | int rename_file(char *from, char *to) |
@@ -330,8 +371,9 @@ int rename_file(char *from, char *to) | |||
330 | int err; | 371 | int err; |
331 | 372 | ||
332 | err = rename(from, to); | 373 | err = rename(from, to); |
333 | if(err < 0) return(-errno); | 374 | if(err < 0) |
334 | return(0); | 375 | return -errno; |
376 | return 0; | ||
335 | } | 377 | } |
336 | 378 | ||
337 | int do_statfs(char *root, long *bsize_out, long long *blocks_out, | 379 | int do_statfs(char *root, long *bsize_out, long long *blocks_out, |
@@ -344,7 +386,9 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out, | |||
344 | int err; | 386 | int err; |
345 | 387 | ||
346 | err = statfs64(root, &buf); | 388 | err = statfs64(root, &buf); |
347 | if(err < 0) return(-errno); | 389 | if(err < 0) |
390 | return -errno; | ||
391 | |||
348 | *bsize_out = buf.f_bsize; | 392 | *bsize_out = buf.f_bsize; |
349 | *blocks_out = buf.f_blocks; | 393 | *blocks_out = buf.f_blocks; |
350 | *bfree_out = buf.f_bfree; | 394 | *bfree_out = buf.f_bfree; |
@@ -360,16 +404,5 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out, | |||
360 | spare_out[2] = buf.f_spare[2]; | 404 | spare_out[2] = buf.f_spare[2]; |
361 | spare_out[3] = buf.f_spare[3]; | 405 | spare_out[3] = buf.f_spare[3]; |
362 | spare_out[4] = buf.f_spare[4]; | 406 | spare_out[4] = buf.f_spare[4]; |
363 | return(0); | 407 | return 0; |
364 | } | 408 | } |
365 | |||
366 | /* | ||
367 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
368 | * Emacs will notice this stuff at the end of the file and automatically | ||
369 | * adjust the settings for this buffer only. This must remain at the end | ||
370 | * of the file. | ||
371 | * --------------------------------------------------------------------------- | ||
372 | * Local variables: | ||
373 | * c-file-style: "linux" | ||
374 | * End: | ||
375 | */ | ||
diff --git a/fs/inode.c b/fs/inode.c index b4296bf62739..df2ef15d03d2 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -250,7 +250,7 @@ void clear_inode(struct inode *inode) | |||
250 | BUG_ON(inode->i_state & I_CLEAR); | 250 | BUG_ON(inode->i_state & I_CLEAR); |
251 | wait_on_inode(inode); | 251 | wait_on_inode(inode); |
252 | DQUOT_DROP(inode); | 252 | DQUOT_DROP(inode); |
253 | if (inode->i_sb && inode->i_sb->s_op->clear_inode) | 253 | if (inode->i_sb->s_op->clear_inode) |
254 | inode->i_sb->s_op->clear_inode(inode); | 254 | inode->i_sb->s_op->clear_inode(inode); |
255 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) | 255 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) |
256 | bd_forget(inode); | 256 | bd_forget(inode); |
@@ -275,7 +275,7 @@ static void dispose_list(struct list_head *head) | |||
275 | while (!list_empty(head)) { | 275 | while (!list_empty(head)) { |
276 | struct inode *inode; | 276 | struct inode *inode; |
277 | 277 | ||
278 | inode = list_entry(head->next, struct inode, i_list); | 278 | inode = list_first_entry(head, struct inode, i_list); |
279 | list_del(&inode->i_list); | 279 | list_del(&inode->i_list); |
280 | 280 | ||
281 | if (inode->i_data.nrpages) | 281 | if (inode->i_data.nrpages) |
@@ -524,7 +524,12 @@ repeat: | |||
524 | */ | 524 | */ |
525 | struct inode *new_inode(struct super_block *sb) | 525 | struct inode *new_inode(struct super_block *sb) |
526 | { | 526 | { |
527 | static unsigned long last_ino; | 527 | /* |
528 | * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW | ||
529 | * error if st_ino won't fit in target struct field. Use 32bit counter | ||
530 | * here to attempt to avoid that. | ||
531 | */ | ||
532 | static unsigned int last_ino; | ||
528 | struct inode * inode; | 533 | struct inode * inode; |
529 | 534 | ||
530 | spin_lock_prefetch(&inode_lock); | 535 | spin_lock_prefetch(&inode_lock); |
@@ -683,27 +688,28 @@ static unsigned long hash(struct super_block *sb, unsigned long hashval) | |||
683 | */ | 688 | */ |
684 | ino_t iunique(struct super_block *sb, ino_t max_reserved) | 689 | ino_t iunique(struct super_block *sb, ino_t max_reserved) |
685 | { | 690 | { |
686 | static ino_t counter; | 691 | /* |
692 | * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW | ||
693 | * error if st_ino won't fit in target struct field. Use 32bit counter | ||
694 | * here to attempt to avoid that. | ||
695 | */ | ||
696 | static unsigned int counter; | ||
687 | struct inode *inode; | 697 | struct inode *inode; |
688 | struct hlist_head * head; | 698 | struct hlist_head *head; |
689 | ino_t res; | 699 | ino_t res; |
700 | |||
690 | spin_lock(&inode_lock); | 701 | spin_lock(&inode_lock); |
691 | retry: | 702 | do { |
692 | if (counter > max_reserved) { | 703 | if (counter <= max_reserved) |
693 | head = inode_hashtable + hash(sb,counter); | 704 | counter = max_reserved + 1; |
694 | res = counter++; | 705 | res = counter++; |
706 | head = inode_hashtable + hash(sb, res); | ||
695 | inode = find_inode_fast(sb, head, res); | 707 | inode = find_inode_fast(sb, head, res); |
696 | if (!inode) { | 708 | } while (inode != NULL); |
697 | spin_unlock(&inode_lock); | 709 | spin_unlock(&inode_lock); |
698 | return res; | ||
699 | } | ||
700 | } else { | ||
701 | counter = max_reserved + 1; | ||
702 | } | ||
703 | goto retry; | ||
704 | |||
705 | } | ||
706 | 710 | ||
711 | return res; | ||
712 | } | ||
707 | EXPORT_SYMBOL(iunique); | 713 | EXPORT_SYMBOL(iunique); |
708 | 714 | ||
709 | struct inode *igrab(struct inode *inode) | 715 | struct inode *igrab(struct inode *inode) |
@@ -1040,7 +1046,7 @@ static void generic_forget_inode(struct inode *inode) | |||
1040 | if (!(inode->i_state & (I_DIRTY|I_LOCK))) | 1046 | if (!(inode->i_state & (I_DIRTY|I_LOCK))) |
1041 | list_move(&inode->i_list, &inode_unused); | 1047 | list_move(&inode->i_list, &inode_unused); |
1042 | inodes_stat.nr_unused++; | 1048 | inodes_stat.nr_unused++; |
1043 | if (!sb || (sb->s_flags & MS_ACTIVE)) { | 1049 | if (sb->s_flags & MS_ACTIVE) { |
1044 | spin_unlock(&inode_lock); | 1050 | spin_unlock(&inode_lock); |
1045 | return; | 1051 | return; |
1046 | } | 1052 | } |
diff --git a/fs/inotify.c b/fs/inotify.c index f5099d86fd91..7457501b9565 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -509,7 +509,7 @@ void inotify_destroy(struct inotify_handle *ih) | |||
509 | mutex_unlock(&ih->mutex); | 509 | mutex_unlock(&ih->mutex); |
510 | break; | 510 | break; |
511 | } | 511 | } |
512 | watch = list_entry(watches->next, struct inotify_watch, h_list); | 512 | watch = list_first_entry(watches, struct inotify_watch, h_list); |
513 | get_inotify_watch(watch); | 513 | get_inotify_watch(watch); |
514 | mutex_unlock(&ih->mutex); | 514 | mutex_unlock(&ih->mutex); |
515 | 515 | ||
diff --git a/fs/internal.h b/fs/internal.h index ea00126c9a59..392e8ccd6fc4 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -9,8 +9,6 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/ioctl32.h> | ||
13 | |||
14 | struct super_block; | 12 | struct super_block; |
15 | 13 | ||
16 | /* | 14 | /* |
@@ -42,14 +40,6 @@ static inline int sb_is_blkdev_sb(struct super_block *sb) | |||
42 | extern void __init chrdev_init(void); | 40 | extern void __init chrdev_init(void); |
43 | 41 | ||
44 | /* | 42 | /* |
45 | * compat_ioctl.c | ||
46 | */ | ||
47 | #ifdef CONFIG_COMPAT | ||
48 | extern struct ioctl_trans ioctl_start[]; | ||
49 | extern int ioctl_table_size; | ||
50 | #endif | ||
51 | |||
52 | /* | ||
53 | * namespace.c | 43 | * namespace.c |
54 | */ | 44 | */ |
55 | extern int copy_mount_options(const void __user *, unsigned long *); | 45 | extern int copy_mount_options(const void __user *, unsigned long *); |
diff --git a/fs/ioctl.c b/fs/ioctl.c index ff61772ceedd..479c1038ed4a 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -67,8 +67,6 @@ static int file_ioctl(struct file *filp, unsigned int cmd, | |||
67 | return put_user(res, p); | 67 | return put_user(res, p); |
68 | } | 68 | } |
69 | case FIGETBSZ: | 69 | case FIGETBSZ: |
70 | if (inode->i_sb == NULL) | ||
71 | return -EBADF; | ||
72 | return put_user(inode->i_sb->s_blocksize, p); | 70 | return put_user(inode->i_sb->s_blocksize, p); |
73 | case FIONREAD: | 71 | case FIONREAD: |
74 | return put_user(i_size_read(inode) - filp->f_pos, p); | 72 | return put_user(i_size_read(inode) - filp->f_pos, p); |
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index be4648bc7a2f..1facfaff97cb 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/smp_lock.h> | ||
24 | 23 | ||
25 | /* | 24 | /* |
26 | * Default IO end handler for temporary BJ_IO buffer_heads. | 25 | * Default IO end handler for temporary BJ_IO buffer_heads. |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 10fff9443938..46fe7439fb91 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/jbd.h> | 28 | #include <linux/jbd.h> |
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
33 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
34 | #include <linux/freezer.h> | 33 | #include <linux/freezer.h> |
@@ -211,10 +210,16 @@ end_loop: | |||
211 | return 0; | 210 | return 0; |
212 | } | 211 | } |
213 | 212 | ||
214 | static void journal_start_thread(journal_t *journal) | 213 | static int journal_start_thread(journal_t *journal) |
215 | { | 214 | { |
216 | kthread_run(kjournald, journal, "kjournald"); | 215 | struct task_struct *t; |
216 | |||
217 | t = kthread_run(kjournald, journal, "kjournald"); | ||
218 | if (IS_ERR(t)) | ||
219 | return PTR_ERR(t); | ||
220 | |||
217 | wait_event(journal->j_wait_done_commit, journal->j_task != 0); | 221 | wait_event(journal->j_wait_done_commit, journal->j_task != 0); |
222 | return 0; | ||
218 | } | 223 | } |
219 | 224 | ||
220 | static void journal_kill_thread(journal_t *journal) | 225 | static void journal_kill_thread(journal_t *journal) |
@@ -840,8 +845,7 @@ static int journal_reset(journal_t *journal) | |||
840 | 845 | ||
841 | /* Add the dynamic fields and write it to disk. */ | 846 | /* Add the dynamic fields and write it to disk. */ |
842 | journal_update_superblock(journal, 1); | 847 | journal_update_superblock(journal, 1); |
843 | journal_start_thread(journal); | 848 | return journal_start_thread(journal); |
844 | return 0; | ||
845 | } | 849 | } |
846 | 850 | ||
847 | /** | 851 | /** |
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index d204ab394f36..a68cbb605022 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #include <linux/errno.h> | 66 | #include <linux/errno.h> |
67 | #include <linux/slab.h> | 67 | #include <linux/slab.h> |
68 | #include <linux/list.h> | 68 | #include <linux/list.h> |
69 | #include <linux/smp_lock.h> | ||
70 | #include <linux/init.h> | 69 | #include <linux/init.h> |
71 | #endif | 70 | #endif |
72 | 71 | ||
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index cceaf57e3778..f9822fc07851 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
28 | #include <linux/highmem.h> | 27 | #include <linux/highmem.h> |
29 | 28 | ||
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 6bd8005e3d34..2856e1100a5f 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/smp_lock.h> | ||
24 | 23 | ||
25 | /* | 24 | /* |
26 | * Default IO end handler for temporary BJ_IO buffer_heads. | 25 | * Default IO end handler for temporary BJ_IO buffer_heads. |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 44fc32bfd7f1..78d63b818f0b 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/jbd2.h> | 28 | #include <linux/jbd2.h> |
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
33 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
34 | #include <linux/freezer.h> | 33 | #include <linux/freezer.h> |
@@ -211,10 +210,16 @@ end_loop: | |||
211 | return 0; | 210 | return 0; |
212 | } | 211 | } |
213 | 212 | ||
214 | static void jbd2_journal_start_thread(journal_t *journal) | 213 | static int jbd2_journal_start_thread(journal_t *journal) |
215 | { | 214 | { |
216 | kthread_run(kjournald2, journal, "kjournald2"); | 215 | struct task_struct *t; |
216 | |||
217 | t = kthread_run(kjournald2, journal, "kjournald2"); | ||
218 | if (IS_ERR(t)) | ||
219 | return PTR_ERR(t); | ||
220 | |||
217 | wait_event(journal->j_wait_done_commit, journal->j_task != 0); | 221 | wait_event(journal->j_wait_done_commit, journal->j_task != 0); |
222 | return 0; | ||
218 | } | 223 | } |
219 | 224 | ||
220 | static void journal_kill_thread(journal_t *journal) | 225 | static void journal_kill_thread(journal_t *journal) |
@@ -840,8 +845,7 @@ static int journal_reset(journal_t *journal) | |||
840 | 845 | ||
841 | /* Add the dynamic fields and write it to disk. */ | 846 | /* Add the dynamic fields and write it to disk. */ |
842 | jbd2_journal_update_superblock(journal, 1); | 847 | jbd2_journal_update_superblock(journal, 1); |
843 | jbd2_journal_start_thread(journal); | 848 | return jbd2_journal_start_thread(journal); |
844 | return 0; | ||
845 | } | 849 | } |
846 | 850 | ||
847 | /** | 851 | /** |
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index f506646ad0ff..1e864dcc49ea 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #include <linux/errno.h> | 66 | #include <linux/errno.h> |
67 | #include <linux/slab.h> | 67 | #include <linux/slab.h> |
68 | #include <linux/list.h> | 68 | #include <linux/list.h> |
69 | #include <linux/smp_lock.h> | ||
70 | #include <linux/init.h> | 69 | #include <linux/init.h> |
71 | #endif | 70 | #endif |
72 | 71 | ||
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 3a8700153cb0..e347d8c078bc 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
28 | #include <linux/highmem.h> | 27 | #include <linux/highmem.h> |
29 | 28 | ||
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index e285022f006c..3467dde27e5a 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -55,7 +55,6 @@ void jfs_read_inode(struct inode *inode) | |||
55 | inode->i_op = &jfs_file_inode_operations; | 55 | inode->i_op = &jfs_file_inode_operations; |
56 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | 56 | init_special_inode(inode, inode->i_mode, inode->i_rdev); |
57 | } | 57 | } |
58 | jfs_set_inode_flags(inode); | ||
59 | } | 58 | } |
60 | 59 | ||
61 | /* | 60 | /* |
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index ed814b1ff4d9..fe063af6fd2f 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c | |||
@@ -59,6 +59,7 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, | |||
59 | 59 | ||
60 | switch (cmd) { | 60 | switch (cmd) { |
61 | case JFS_IOC_GETFLAGS: | 61 | case JFS_IOC_GETFLAGS: |
62 | jfs_get_inode_flags(jfs_inode); | ||
62 | flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE; | 63 | flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE; |
63 | flags = jfs_map_ext2(flags, 0); | 64 | flags = jfs_map_ext2(flags, 0); |
64 | return put_user(flags, (int __user *) arg); | 65 | return put_user(flags, (int __user *) arg); |
@@ -78,6 +79,7 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, | |||
78 | if (!S_ISDIR(inode->i_mode)) | 79 | if (!S_ISDIR(inode->i_mode)) |
79 | flags &= ~JFS_DIRSYNC_FL; | 80 | flags &= ~JFS_DIRSYNC_FL; |
80 | 81 | ||
82 | jfs_get_inode_flags(jfs_inode); | ||
81 | oldflags = jfs_inode->mode2; | 83 | oldflags = jfs_inode->mode2; |
82 | 84 | ||
83 | /* | 85 | /* |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index aa5124b643b1..c465607be991 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -3078,6 +3078,7 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) | |||
3078 | 3078 | ||
3079 | jfs_ip->fileset = le32_to_cpu(dip->di_fileset); | 3079 | jfs_ip->fileset = le32_to_cpu(dip->di_fileset); |
3080 | jfs_ip->mode2 = le32_to_cpu(dip->di_mode); | 3080 | jfs_ip->mode2 = le32_to_cpu(dip->di_mode); |
3081 | jfs_set_inode_flags(ip); | ||
3081 | 3082 | ||
3082 | ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; | 3083 | ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; |
3083 | if (sbi->umask != -1) { | 3084 | if (sbi->umask != -1) { |
@@ -3174,6 +3175,7 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip) | |||
3174 | dip->di_gid = cpu_to_le32(ip->i_gid); | 3175 | dip->di_gid = cpu_to_le32(ip->i_gid); |
3175 | else | 3176 | else |
3176 | dip->di_gid = cpu_to_le32(jfs_ip->saved_gid); | 3177 | dip->di_gid = cpu_to_le32(jfs_ip->saved_gid); |
3178 | jfs_get_inode_flags(jfs_ip); | ||
3177 | /* | 3179 | /* |
3178 | * mode2 is only needed for storing the higher order bits. | 3180 | * mode2 is only needed for storing the higher order bits. |
3179 | * Trust i_mode for the lower order ones | 3181 | * Trust i_mode for the lower order ones |
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 4c67ed97682b..ed6574bee51a 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c | |||
@@ -45,6 +45,24 @@ void jfs_set_inode_flags(struct inode *inode) | |||
45 | inode->i_flags |= S_SYNC; | 45 | inode->i_flags |= S_SYNC; |
46 | } | 46 | } |
47 | 47 | ||
48 | void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip) | ||
49 | { | ||
50 | unsigned int flags = jfs_ip->vfs_inode.i_flags; | ||
51 | |||
52 | jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL | | ||
53 | JFS_DIRSYNC_FL | JFS_SYNC_FL); | ||
54 | if (flags & S_IMMUTABLE) | ||
55 | jfs_ip->mode2 |= JFS_IMMUTABLE_FL; | ||
56 | if (flags & S_APPEND) | ||
57 | jfs_ip->mode2 |= JFS_APPEND_FL; | ||
58 | if (flags & S_NOATIME) | ||
59 | jfs_ip->mode2 |= JFS_NOATIME_FL; | ||
60 | if (flags & S_DIRSYNC) | ||
61 | jfs_ip->mode2 |= JFS_DIRSYNC_FL; | ||
62 | if (flags & S_SYNC) | ||
63 | jfs_ip->mode2 |= JFS_SYNC_FL; | ||
64 | } | ||
65 | |||
48 | /* | 66 | /* |
49 | * NAME: ialloc() | 67 | * NAME: ialloc() |
50 | * | 68 | * |
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 6802837f757e..2374b595f2e1 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
@@ -31,6 +31,7 @@ extern void jfs_truncate(struct inode *); | |||
31 | extern void jfs_truncate_nolock(struct inode *, loff_t); | 31 | extern void jfs_truncate_nolock(struct inode *, loff_t); |
32 | extern void jfs_free_zero_link(struct inode *); | 32 | extern void jfs_free_zero_link(struct inode *); |
33 | extern struct dentry *jfs_get_parent(struct dentry *dentry); | 33 | extern struct dentry *jfs_get_parent(struct dentry *dentry); |
34 | extern void jfs_get_inode_flags(struct jfs_inode_info *); | ||
34 | extern void jfs_set_inode_flags(struct inode *); | 35 | extern void jfs_set_inode_flags(struct inode *); |
35 | extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); | 36 | extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); |
36 | 37 | ||
diff --git a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h index df48ece4b7a3..ecf04882265e 100644 --- a/fs/jfs/jfs_lock.h +++ b/fs/jfs/jfs_lock.h | |||
@@ -45,7 +45,7 @@ do { \ | |||
45 | io_schedule(); \ | 45 | io_schedule(); \ |
46 | lock_cmd; \ | 46 | lock_cmd; \ |
47 | } \ | 47 | } \ |
48 | current->state = TASK_RUNNING; \ | 48 | __set_current_state(TASK_RUNNING); \ |
49 | remove_wait_queue(&wq, &__wait); \ | 49 | remove_wait_queue(&wq, &__wait); \ |
50 | } while (0) | 50 | } while (0) |
51 | 51 | ||
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 5065baa530b6..6a3f00dc8c83 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -62,7 +62,6 @@ | |||
62 | #include <linux/fs.h> | 62 | #include <linux/fs.h> |
63 | #include <linux/blkdev.h> | 63 | #include <linux/blkdev.h> |
64 | #include <linux/interrupt.h> | 64 | #include <linux/interrupt.h> |
65 | #include <linux/smp_lock.h> | ||
66 | #include <linux/completion.h> | 65 | #include <linux/completion.h> |
67 | #include <linux/kthread.h> | 66 | #include <linux/kthread.h> |
68 | #include <linux/buffer_head.h> /* for sync_blockdev() */ | 67 | #include <linux/buffer_head.h> /* for sync_blockdev() */ |
@@ -1590,7 +1589,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait) | |||
1590 | set_current_state(TASK_UNINTERRUPTIBLE); | 1589 | set_current_state(TASK_UNINTERRUPTIBLE); |
1591 | LOGGC_UNLOCK(log); | 1590 | LOGGC_UNLOCK(log); |
1592 | schedule(); | 1591 | schedule(); |
1593 | current->state = TASK_RUNNING; | 1592 | __set_current_state(TASK_RUNNING); |
1594 | LOGGC_LOCK(log); | 1593 | LOGGC_LOCK(log); |
1595 | remove_wait_queue(&target->gcwait, &__wait); | 1594 | remove_wait_queue(&target->gcwait, &__wait); |
1596 | } | 1595 | } |
@@ -2354,14 +2353,15 @@ int jfsIOWait(void *arg) | |||
2354 | lbmStartIO(bp); | 2353 | lbmStartIO(bp); |
2355 | spin_lock_irq(&log_redrive_lock); | 2354 | spin_lock_irq(&log_redrive_lock); |
2356 | } | 2355 | } |
2357 | spin_unlock_irq(&log_redrive_lock); | ||
2358 | 2356 | ||
2359 | if (freezing(current)) { | 2357 | if (freezing(current)) { |
2358 | spin_unlock_irq(&log_redrive_lock); | ||
2360 | refrigerator(); | 2359 | refrigerator(); |
2361 | } else { | 2360 | } else { |
2362 | set_current_state(TASK_INTERRUPTIBLE); | 2361 | set_current_state(TASK_INTERRUPTIBLE); |
2362 | spin_unlock_irq(&log_redrive_lock); | ||
2363 | schedule(); | 2363 | schedule(); |
2364 | current->state = TASK_RUNNING; | 2364 | __set_current_state(TASK_RUNNING); |
2365 | } | 2365 | } |
2366 | } while (!kthread_should_stop()); | 2366 | } while (!kthread_should_stop()); |
2367 | 2367 | ||
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 03893acbfda4..25430d0b0d59 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -44,7 +44,6 @@ | |||
44 | 44 | ||
45 | #include <linux/fs.h> | 45 | #include <linux/fs.h> |
46 | #include <linux/vmalloc.h> | 46 | #include <linux/vmalloc.h> |
47 | #include <linux/smp_lock.h> | ||
48 | #include <linux/completion.h> | 47 | #include <linux/completion.h> |
49 | #include <linux/freezer.h> | 48 | #include <linux/freezer.h> |
50 | #include <linux/module.h> | 49 | #include <linux/module.h> |
@@ -136,7 +135,7 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event) | |||
136 | set_current_state(TASK_UNINTERRUPTIBLE); | 135 | set_current_state(TASK_UNINTERRUPTIBLE); |
137 | TXN_UNLOCK(); | 136 | TXN_UNLOCK(); |
138 | io_schedule(); | 137 | io_schedule(); |
139 | current->state = TASK_RUNNING; | 138 | __set_current_state(TASK_RUNNING); |
140 | remove_wait_queue(event, &wait); | 139 | remove_wait_queue(event, &wait); |
141 | } | 140 | } |
142 | 141 | ||
@@ -2798,7 +2797,7 @@ int jfs_lazycommit(void *arg) | |||
2798 | set_current_state(TASK_INTERRUPTIBLE); | 2797 | set_current_state(TASK_INTERRUPTIBLE); |
2799 | LAZY_UNLOCK(flags); | 2798 | LAZY_UNLOCK(flags); |
2800 | schedule(); | 2799 | schedule(); |
2801 | current->state = TASK_RUNNING; | 2800 | __set_current_state(TASK_RUNNING); |
2802 | remove_wait_queue(&jfs_commit_thread_wait, &wq); | 2801 | remove_wait_queue(&jfs_commit_thread_wait, &wq); |
2803 | } | 2802 | } |
2804 | } while (!kthread_should_stop()); | 2803 | } while (!kthread_should_stop()); |
@@ -2990,7 +2989,7 @@ int jfs_sync(void *arg) | |||
2990 | set_current_state(TASK_INTERRUPTIBLE); | 2989 | set_current_state(TASK_INTERRUPTIBLE); |
2991 | TXN_UNLOCK(); | 2990 | TXN_UNLOCK(); |
2992 | schedule(); | 2991 | schedule(); |
2993 | current->state = TASK_RUNNING; | 2992 | __set_current_state(TASK_RUNNING); |
2994 | } | 2993 | } |
2995 | } while (!kthread_should_stop()); | 2994 | } while (!kthread_should_stop()); |
2996 | 2995 | ||
diff --git a/fs/libfs.c b/fs/libfs.c index d93842d3c0a0..1247ee90253a 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -220,6 +220,12 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name, | |||
220 | root = new_inode(s); | 220 | root = new_inode(s); |
221 | if (!root) | 221 | if (!root) |
222 | goto Enomem; | 222 | goto Enomem; |
223 | /* | ||
224 | * since this is the first inode, make it number 1. New inodes created | ||
225 | * after this must take care not to collide with it (by passing | ||
226 | * max_reserved of 1 to iunique). | ||
227 | */ | ||
228 | root->i_ino = 1; | ||
223 | root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; | 229 | root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; |
224 | root->i_uid = root->i_gid = 0; | 230 | root->i_uid = root->i_gid = 0; |
225 | root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; | 231 | root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; |
@@ -360,6 +366,11 @@ int simple_commit_write(struct file *file, struct page *page, | |||
360 | return 0; | 366 | return 0; |
361 | } | 367 | } |
362 | 368 | ||
369 | /* | ||
370 | * the inodes created here are not hashed. If you use iunique to generate | ||
371 | * unique inode values later for this filesystem, then you must take care | ||
372 | * to pass it an appropriate max_reserved value to avoid collisions. | ||
373 | */ | ||
363 | int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files) | 374 | int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files) |
364 | { | 375 | { |
365 | struct inode *inode; | 376 | struct inode *inode; |
@@ -376,6 +387,11 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files | |||
376 | inode = new_inode(s); | 387 | inode = new_inode(s); |
377 | if (!inode) | 388 | if (!inode) |
378 | return -ENOMEM; | 389 | return -ENOMEM; |
390 | /* | ||
391 | * because the root inode is 1, the files array must not contain an | ||
392 | * entry at index 1 | ||
393 | */ | ||
394 | inode->i_ino = 1; | ||
379 | inode->i_mode = S_IFDIR | 0755; | 395 | inode->i_mode = S_IFDIR | 0755; |
380 | inode->i_uid = inode->i_gid = 0; | 396 | inode->i_uid = inode->i_gid = 0; |
381 | inode->i_blocks = 0; | 397 | inode->i_blocks = 0; |
@@ -391,6 +407,13 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files | |||
391 | for (i = 0; !files->name || files->name[0]; i++, files++) { | 407 | for (i = 0; !files->name || files->name[0]; i++, files++) { |
392 | if (!files->name) | 408 | if (!files->name) |
393 | continue; | 409 | continue; |
410 | |||
411 | /* warn if it tries to conflict with the root inode */ | ||
412 | if (unlikely(i == 1)) | ||
413 | printk(KERN_WARNING "%s: %s passed in a files array" | ||
414 | "with an index of 1!\n", __func__, | ||
415 | s->s_type->name); | ||
416 | |||
394 | dentry = d_alloc_name(root, files->name); | 417 | dentry = d_alloc_name(root, files->name); |
395 | if (!dentry) | 418 | if (!dentry) |
396 | goto out; | 419 | goto out; |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index a5c019e1a447..a10343bed160 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
13 | #include <linux/nfs_fs.h> | 13 | #include <linux/nfs_fs.h> |
14 | #include <linux/utsname.h> | 14 | #include <linux/utsname.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/freezer.h> | 15 | #include <linux/freezer.h> |
17 | #include <linux/sunrpc/clnt.h> | 16 | #include <linux/sunrpc/clnt.h> |
18 | #include <linux/sunrpc/svc.h> | 17 | #include <linux/sunrpc/svc.h> |
diff --git a/fs/mpage.c b/fs/mpage.c index 692a3e578fc8..fa2441f57b41 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -663,12 +663,7 @@ confused: | |||
663 | /* | 663 | /* |
664 | * The caller has a ref on the inode, so *mapping is stable | 664 | * The caller has a ref on the inode, so *mapping is stable |
665 | */ | 665 | */ |
666 | if (*ret) { | 666 | mapping_set_error(mapping, *ret); |
667 | if (*ret == -ENOSPC) | ||
668 | set_bit(AS_ENOSPC, &mapping->flags); | ||
669 | else | ||
670 | set_bit(AS_EIO, &mapping->flags); | ||
671 | } | ||
672 | out: | 667 | out: |
673 | return bio; | 668 | return bio; |
674 | } | 669 | } |
@@ -776,14 +771,7 @@ retry: | |||
776 | 771 | ||
777 | if (writepage) { | 772 | if (writepage) { |
778 | ret = (*writepage)(page, wbc); | 773 | ret = (*writepage)(page, wbc); |
779 | if (ret) { | 774 | mapping_set_error(mapping, ret); |
780 | if (ret == -ENOSPC) | ||
781 | set_bit(AS_ENOSPC, | ||
782 | &mapping->flags); | ||
783 | else | ||
784 | set_bit(AS_EIO, | ||
785 | &mapping->flags); | ||
786 | } | ||
787 | } else { | 775 | } else { |
788 | bio = __mpage_writepage(bio, page, get_block, | 776 | bio = __mpage_writepage(bio, page, get_block, |
789 | &last_block_in_bio, &ret, wbc, | 777 | &last_block_in_bio, &ret, wbc, |
diff --git a/fs/namei.c b/fs/namei.c index 94b2f60aec22..856b2f5da51d 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/quotaops.h> | 22 | #include <linux/quotaops.h> |
23 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
24 | #include <linux/fsnotify.h> | 24 | #include <linux/fsnotify.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/personality.h> | 25 | #include <linux/personality.h> |
27 | #include <linux/security.h> | 26 | #include <linux/security.h> |
28 | #include <linux/syscalls.h> | 27 | #include <linux/syscalls.h> |
@@ -1350,17 +1349,6 @@ struct dentry *lookup_one_len_kern(const char *name, struct dentry *base, int le | |||
1350 | return __lookup_hash_kern(&this, base, NULL); | 1349 | return __lookup_hash_kern(&this, base, NULL); |
1351 | } | 1350 | } |
1352 | 1351 | ||
1353 | /* | ||
1354 | * namei() | ||
1355 | * | ||
1356 | * is used by most simple commands to get the inode of a specified name. | ||
1357 | * Open, link etc use their own routines, but this is enough for things | ||
1358 | * like 'chmod' etc. | ||
1359 | * | ||
1360 | * namei exists in two versions: namei/lnamei. The only difference is | ||
1361 | * that namei follows links, while lnamei does not. | ||
1362 | * SMP-safe | ||
1363 | */ | ||
1364 | int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags, | 1352 | int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags, |
1365 | struct nameidata *nd) | 1353 | struct nameidata *nd) |
1366 | { | 1354 | { |
diff --git a/fs/namespace.c b/fs/namespace.c index fd999cab7b57..b696e3a0d18f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -377,6 +377,10 @@ static int show_vfsmnt(struct seq_file *m, void *v) | |||
377 | seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); | 377 | seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); |
378 | seq_putc(m, ' '); | 378 | seq_putc(m, ' '); |
379 | mangle(m, mnt->mnt_sb->s_type->name); | 379 | mangle(m, mnt->mnt_sb->s_type->name); |
380 | if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) { | ||
381 | seq_putc(m, '.'); | ||
382 | mangle(m, mnt->mnt_sb->s_subtype); | ||
383 | } | ||
380 | seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); | 384 | seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); |
381 | for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { | 385 | for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { |
382 | if (mnt->mnt_sb->s_flags & fs_infop->flag) | 386 | if (mnt->mnt_sb->s_flags & fs_infop->flag) |
@@ -495,7 +499,7 @@ void release_mounts(struct list_head *head) | |||
495 | { | 499 | { |
496 | struct vfsmount *mnt; | 500 | struct vfsmount *mnt; |
497 | while (!list_empty(head)) { | 501 | while (!list_empty(head)) { |
498 | mnt = list_entry(head->next, struct vfsmount, mnt_hash); | 502 | mnt = list_first_entry(head, struct vfsmount, mnt_hash); |
499 | list_del_init(&mnt->mnt_hash); | 503 | list_del_init(&mnt->mnt_hash); |
500 | if (mnt->mnt_parent != mnt) { | 504 | if (mnt->mnt_parent != mnt) { |
501 | struct dentry *dentry; | 505 | struct dentry *dentry; |
@@ -882,6 +886,9 @@ static int do_change_type(struct nameidata *nd, int flag) | |||
882 | int recurse = flag & MS_REC; | 886 | int recurse = flag & MS_REC; |
883 | int type = flag & ~MS_REC; | 887 | int type = flag & ~MS_REC; |
884 | 888 | ||
889 | if (!capable(CAP_SYS_ADMIN)) | ||
890 | return -EPERM; | ||
891 | |||
885 | if (nd->dentry != nd->mnt->mnt_root) | 892 | if (nd->dentry != nd->mnt->mnt_root) |
886 | return -EINVAL; | 893 | return -EINVAL; |
887 | 894 | ||
@@ -1173,7 +1180,7 @@ static void expire_mount_list(struct list_head *graveyard, struct list_head *mou | |||
1173 | 1180 | ||
1174 | while (!list_empty(graveyard)) { | 1181 | while (!list_empty(graveyard)) { |
1175 | LIST_HEAD(umounts); | 1182 | LIST_HEAD(umounts); |
1176 | mnt = list_entry(graveyard->next, struct vfsmount, mnt_expire); | 1183 | mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire); |
1177 | list_del_init(&mnt->mnt_expire); | 1184 | list_del_init(&mnt->mnt_expire); |
1178 | 1185 | ||
1179 | /* don't do anything if the namespace is dead - all the | 1186 | /* don't do anything if the namespace is dead - all the |
@@ -1441,10 +1448,9 @@ dput_out: | |||
1441 | * Allocate a new namespace structure and populate it with contents | 1448 | * Allocate a new namespace structure and populate it with contents |
1442 | * copied from the namespace of the passed in task structure. | 1449 | * copied from the namespace of the passed in task structure. |
1443 | */ | 1450 | */ |
1444 | struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk, | 1451 | static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, |
1445 | struct fs_struct *fs) | 1452 | struct fs_struct *fs) |
1446 | { | 1453 | { |
1447 | struct mnt_namespace *mnt_ns = tsk->nsproxy->mnt_ns; | ||
1448 | struct mnt_namespace *new_ns; | 1454 | struct mnt_namespace *new_ns; |
1449 | struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; | 1455 | struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; |
1450 | struct vfsmount *p, *q; | 1456 | struct vfsmount *p, *q; |
@@ -1509,36 +1515,21 @@ struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk, | |||
1509 | return new_ns; | 1515 | return new_ns; |
1510 | } | 1516 | } |
1511 | 1517 | ||
1512 | int copy_mnt_ns(int flags, struct task_struct *tsk) | 1518 | struct mnt_namespace *copy_mnt_ns(int flags, struct mnt_namespace *ns, |
1519 | struct fs_struct *new_fs) | ||
1513 | { | 1520 | { |
1514 | struct mnt_namespace *ns = tsk->nsproxy->mnt_ns; | ||
1515 | struct mnt_namespace *new_ns; | 1521 | struct mnt_namespace *new_ns; |
1516 | int err = 0; | ||
1517 | |||
1518 | if (!ns) | ||
1519 | return 0; | ||
1520 | 1522 | ||
1523 | BUG_ON(!ns); | ||
1521 | get_mnt_ns(ns); | 1524 | get_mnt_ns(ns); |
1522 | 1525 | ||
1523 | if (!(flags & CLONE_NEWNS)) | 1526 | if (!(flags & CLONE_NEWNS)) |
1524 | return 0; | 1527 | return ns; |
1525 | 1528 | ||
1526 | if (!capable(CAP_SYS_ADMIN)) { | 1529 | new_ns = dup_mnt_ns(ns, new_fs); |
1527 | err = -EPERM; | ||
1528 | goto out; | ||
1529 | } | ||
1530 | |||
1531 | new_ns = dup_mnt_ns(tsk, tsk->fs); | ||
1532 | if (!new_ns) { | ||
1533 | err = -ENOMEM; | ||
1534 | goto out; | ||
1535 | } | ||
1536 | 1530 | ||
1537 | tsk->nsproxy->mnt_ns = new_ns; | ||
1538 | |||
1539 | out: | ||
1540 | put_mnt_ns(ns); | 1531 | put_mnt_ns(ns); |
1541 | return err; | 1532 | return new_ns; |
1542 | } | 1533 | } |
1543 | 1534 | ||
1544 | asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, | 1535 | asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, |
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 6b1f6d27099a..addfd3147ea7 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/vmalloc.h> | 19 | #include <linux/vmalloc.h> |
20 | #include <linux/smp_lock.h> | ||
21 | 20 | ||
22 | #include <linux/ncp_fs.h> | 21 | #include <linux/ncp_fs.h> |
23 | #include "ncplib_kernel.h" | 22 | #include "ncplib_kernel.h" |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 5bd03b97002e..50c6821bad26 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/nfs_mount.h> | 27 | #include <linux/nfs_mount.h> |
28 | #include <linux/nfs4_mount.h> | 28 | #include <linux/nfs4_mount.h> |
29 | #include <linux/lockd/bind.h> | 29 | #include <linux/lockd/bind.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
32 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
33 | #include <linux/nfs_idmap.h> | 32 | #include <linux/nfs_idmap.h> |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 889de60f8a84..345aa5c0f382 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
42 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
43 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
44 | #include <linux/smp_lock.h> | ||
45 | #include <linux/file.h> | 44 | #include <linux/file.h> |
46 | #include <linux/pagemap.h> | 45 | #include <linux/pagemap.h> |
47 | #include <linux/kref.h> | 46 | #include <linux/kref.h> |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 6ef268f7c300..234778576f09 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/nfs_mount.h> | 25 | #include <linux/nfs_mount.h> |
26 | #include <linux/nfs4_mount.h> | 26 | #include <linux/nfs4_mount.h> |
27 | #include <linux/lockd/bind.h> | 27 | #include <linux/lockd/bind.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
30 | #include <linux/mount.h> | 29 | #include <linux/mount.h> |
31 | #include <linux/nfs_idmap.h> | 30 | #include <linux/nfs_idmap.h> |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 7d0371e2bad5..45268d6def2e 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/nfs_fs.h> | 16 | #include <linux/nfs_fs.h> |
17 | #include <linux/nfs_page.h> | 17 | #include <linux/nfs_page.h> |
18 | #include <linux/lockd/bind.h> | 18 | #include <linux/lockd/bind.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/nfs_mount.h> | 19 | #include <linux/nfs_mount.h> |
21 | 20 | ||
22 | #include "iostat.h" | 21 | #include "iostat.h" |
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index f5f4430fb2a4..0505ca124034 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -43,7 +43,6 @@ | |||
43 | * child task framework of the RPC layer? | 43 | * child task framework of the RPC layer? |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include <linux/smp_lock.h> | ||
47 | #include <linux/mm.h> | 46 | #include <linux/mm.h> |
48 | #include <linux/pagemap.h> | 47 | #include <linux/pagemap.h> |
49 | #include <linux/sunrpc/sched.h> | 48 | #include <linux/sunrpc/sched.h> |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 1dcf56de9482..7be0ee2782cb 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/nfs_fs.h> | 43 | #include <linux/nfs_fs.h> |
44 | #include <linux/nfs_page.h> | 44 | #include <linux/nfs_page.h> |
45 | #include <linux/lockd/bind.h> | 45 | #include <linux/lockd/bind.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include "internal.h" | 46 | #include "internal.h" |
48 | 47 | ||
49 | #define NFSDBG_FACILITY NFSDBG_PROC | 48 | #define NFSDBG_FACILITY NFSDBG_PROC |
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index bc2821331c29..83e865a16ad1 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/namei.h> | 25 | #include <linux/namei.h> |
27 | 26 | ||
28 | /* Symlink caching in the page cache is even more simplistic | 27 | /* Symlink caching in the page cache is even more simplistic |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 5d44b8bd1070..de92b9509d94 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/backing-dev.h> | 21 | #include <linux/backing-dev.h> |
22 | 22 | ||
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <linux/smp_lock.h> | ||
25 | 24 | ||
26 | #include "delegation.h" | 25 | #include "delegation.h" |
27 | #include "internal.h" | 26 | #include "internal.h" |
@@ -225,7 +224,7 @@ static int nfs_set_page_writeback(struct page *page) | |||
225 | struct inode *inode = page->mapping->host; | 224 | struct inode *inode = page->mapping->host; |
226 | struct nfs_server *nfss = NFS_SERVER(inode); | 225 | struct nfs_server *nfss = NFS_SERVER(inode); |
227 | 226 | ||
228 | if (atomic_inc_return(&nfss->writeback) > | 227 | if (atomic_long_inc_return(&nfss->writeback) > |
229 | NFS_CONGESTION_ON_THRESH) | 228 | NFS_CONGESTION_ON_THRESH) |
230 | set_bdi_congested(&nfss->backing_dev_info, WRITE); | 229 | set_bdi_congested(&nfss->backing_dev_info, WRITE); |
231 | } | 230 | } |
@@ -238,7 +237,7 @@ static void nfs_end_page_writeback(struct page *page) | |||
238 | struct nfs_server *nfss = NFS_SERVER(inode); | 237 | struct nfs_server *nfss = NFS_SERVER(inode); |
239 | 238 | ||
240 | end_page_writeback(page); | 239 | end_page_writeback(page); |
241 | if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) { | 240 | if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) { |
242 | clear_bdi_congested(&nfss->backing_dev_info, WRITE); | 241 | clear_bdi_congested(&nfss->backing_dev_info, WRITE); |
243 | congestion_end(WRITE); | 242 | congestion_end(WRITE); |
244 | } | 243 | } |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index e4a83d727afd..45aa21ce6784 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/nfs4.h> | 46 | #include <linux/nfs4.h> |
47 | #include <linux/nfs_fs.h> | 47 | #include <linux/nfs_fs.h> |
48 | #include <linux/nfs_page.h> | 48 | #include <linux/nfs_page.h> |
49 | #include <linux/smp_lock.h> | ||
50 | #include <linux/sunrpc/cache.h> | 49 | #include <linux/sunrpc/cache.h> |
51 | #include <linux/nfsd_idmap.h> | 50 | #include <linux/nfsd_idmap.h> |
52 | #include <linux/list.h> | 51 | #include <linux/list.h> |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 5d090f11f2be..15809dfd88a5 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -44,7 +44,6 @@ | |||
44 | 44 | ||
45 | #include <linux/param.h> | 45 | #include <linux/param.h> |
46 | #include <linux/smp.h> | 46 | #include <linux/smp.h> |
47 | #include <linux/smp_lock.h> | ||
48 | #include <linux/fs.h> | 47 | #include <linux/fs.h> |
49 | #include <linux/namei.h> | 48 | #include <linux/namei.h> |
50 | #include <linux/vfs.h> | 49 | #include <linux/vfs.h> |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 8d995bcef806..739dd3c5c3b2 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -10,7 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/smp_lock.h> | ||
14 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
15 | #include <linux/unistd.h> | 14 | #include <linux/unistd.h> |
16 | #include <linux/string.h> | 15 | #include <linux/string.h> |
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 74f99a6a369b..34314b33dbd4 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c | |||
@@ -20,7 +20,6 @@ | |||
20 | * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/smp_lock.h> | ||
24 | #include <linux/buffer_head.h> | 23 | #include <linux/buffer_head.h> |
25 | 24 | ||
26 | #include "dir.h" | 25 | #include "dir.h" |
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index dbbac5593106..621de369e6f8 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -2129,28 +2129,13 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb, | |||
2129 | struct address_space *mapping = file->f_mapping; | 2129 | struct address_space *mapping = file->f_mapping; |
2130 | struct inode *inode = mapping->host; | 2130 | struct inode *inode = mapping->host; |
2131 | loff_t pos; | 2131 | loff_t pos; |
2132 | unsigned long seg; | ||
2133 | size_t count; /* after file limit checks */ | 2132 | size_t count; /* after file limit checks */ |
2134 | ssize_t written, err; | 2133 | ssize_t written, err; |
2135 | 2134 | ||
2136 | count = 0; | 2135 | count = 0; |
2137 | for (seg = 0; seg < nr_segs; seg++) { | 2136 | err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); |
2138 | const struct iovec *iv = &iov[seg]; | 2137 | if (err) |
2139 | /* | 2138 | return err; |
2140 | * If any segment has a negative length, or the cumulative | ||
2141 | * length ever wraps negative then return -EINVAL. | ||
2142 | */ | ||
2143 | count += iv->iov_len; | ||
2144 | if (unlikely((ssize_t)(count|iv->iov_len) < 0)) | ||
2145 | return -EINVAL; | ||
2146 | if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len)) | ||
2147 | continue; | ||
2148 | if (!seg) | ||
2149 | return -EFAULT; | ||
2150 | nr_segs = seg; | ||
2151 | count -= iv->iov_len; /* This segment is no good */ | ||
2152 | break; | ||
2153 | } | ||
2154 | pos = *ppos; | 2139 | pos = *ppos; |
2155 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); | 2140 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); |
2156 | /* We can write back this queue in page reclaim. */ | 2141 | /* We can write back this queue in page reclaim. */ |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index f8bf8da67ee8..074791ce4ab2 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/pagemap.h> | 27 | #include <linux/pagemap.h> |
28 | #include <linux/quotaops.h> | 28 | #include <linux/quotaops.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/smp_lock.h> | ||
31 | 30 | ||
32 | #include "aops.h" | 31 | #include "aops.h" |
33 | #include "attrib.h" | 32 | #include "attrib.h" |
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index d4e46d067edd..5671cf9d6383 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/string.h> | 44 | #include <linux/string.h> |
45 | #include <linux/smp_lock.h> | ||
46 | #include <linux/backing-dev.h> | 45 | #include <linux/backing-dev.h> |
47 | 46 | ||
48 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 024777abc8e3..d1bd305ef0d7 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/crc32.h> | 30 | #include <linux/crc32.h> |
32 | #include <linux/kthread.h> | 31 | #include <linux/kthread.h> |
33 | #include <linux/pagemap.h> | 32 | #include <linux/pagemap.h> |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index bc844bfe607c..c53a6763bbbe 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
31 | #include <linux/smp_lock.h> | ||
32 | 31 | ||
33 | #include <asm/byteorder.h> | 32 | #include <asm/byteorder.h> |
34 | 33 | ||
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index d921a28329dc..d8b79067dc14 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/smp_lock.h> | ||
30 | 29 | ||
31 | #define MLOG_MASK_PREFIX ML_SUPER | 30 | #define MLOG_MASK_PREFIX ML_SUPER |
32 | #include <cluster/masklog.h> | 31 | #include <cluster/masklog.h> |
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c index 4f82a2f0efef..66a13ee63d4c 100644 --- a/fs/ocfs2/vote.c +++ b/fs/ocfs2/vote.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
31 | 30 | ||
32 | #include <cluster/heartbeat.h> | 31 | #include <cluster/heartbeat.h> |
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/file.h> | 9 | #include <linux/file.h> |
10 | #include <linux/smp_lock.h> | ||
11 | #include <linux/quotaops.h> | 10 | #include <linux/quotaops.h> |
12 | #include <linux/fsnotify.h> | 11 | #include <linux/fsnotify.h> |
13 | #include <linux/module.h> | 12 | #include <linux/module.h> |
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index 6e8bb66fe619..01207042048b 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig | |||
@@ -236,3 +236,12 @@ config EFI_PARTITION | |||
236 | help | 236 | help |
237 | Say Y here if you would like to use hard disks under Linux which | 237 | Say Y here if you would like to use hard disks under Linux which |
238 | were partitioned using EFI GPT. | 238 | were partitioned using EFI GPT. |
239 | |||
240 | config SYSV68_PARTITION | ||
241 | bool "SYSV68 partition table support" if PARTITION_ADVANCED | ||
242 | default y if M68K | ||
243 | help | ||
244 | Say Y here if you would like to be able to read the hard disk | ||
245 | partition table format used by Motorola Delta machines (using | ||
246 | sysv68). | ||
247 | Otherwise, say N. | ||
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index 67e665fdb7fc..03af8eac51da 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile | |||
@@ -17,3 +17,4 @@ obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o | |||
17 | obj-$(CONFIG_IBM_PARTITION) += ibm.o | 17 | obj-$(CONFIG_IBM_PARTITION) += ibm.o |
18 | obj-$(CONFIG_EFI_PARTITION) += efi.o | 18 | obj-$(CONFIG_EFI_PARTITION) += efi.o |
19 | obj-$(CONFIG_KARMA_PARTITION) += karma.o | 19 | obj-$(CONFIG_KARMA_PARTITION) += karma.o |
20 | obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o | ||
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 6b9dae3f0e6c..9a3a058f3553 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "ultrix.h" | 34 | #include "ultrix.h" |
35 | #include "efi.h" | 35 | #include "efi.h" |
36 | #include "karma.h" | 36 | #include "karma.h" |
37 | #include "sysv68.h" | ||
37 | 38 | ||
38 | #ifdef CONFIG_BLK_DEV_MD | 39 | #ifdef CONFIG_BLK_DEV_MD |
39 | extern void md_autodetect_dev(dev_t dev); | 40 | extern void md_autodetect_dev(dev_t dev); |
@@ -105,6 +106,9 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) = | |||
105 | #ifdef CONFIG_KARMA_PARTITION | 106 | #ifdef CONFIG_KARMA_PARTITION |
106 | karma_partition, | 107 | karma_partition, |
107 | #endif | 108 | #endif |
109 | #ifdef CONFIG_SYSV68_PARTITION | ||
110 | sysv68_partition, | ||
111 | #endif | ||
108 | NULL | 112 | NULL |
109 | }; | 113 | }; |
110 | 114 | ||
diff --git a/fs/partitions/sysv68.c b/fs/partitions/sysv68.c new file mode 100644 index 000000000000..4eba27b78643 --- /dev/null +++ b/fs/partitions/sysv68.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * fs/partitions/sysv68.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Philippe De Muyter <phdm@macqel.be> | ||
5 | */ | ||
6 | |||
7 | #include "check.h" | ||
8 | #include "sysv68.h" | ||
9 | |||
10 | /* | ||
11 | * Volume ID structure: on first 256-bytes sector of disk | ||
12 | */ | ||
13 | |||
14 | struct volumeid { | ||
15 | u8 vid_unused[248]; | ||
16 | u8 vid_mac[8]; /* ASCII string "MOTOROLA" */ | ||
17 | }; | ||
18 | |||
19 | /* | ||
20 | * config block: second 256-bytes sector on disk | ||
21 | */ | ||
22 | |||
23 | struct dkconfig { | ||
24 | u8 ios_unused0[128]; | ||
25 | __be32 ios_slcblk; /* Slice table block number */ | ||
26 | __be16 ios_slccnt; /* Number of entries in slice table */ | ||
27 | u8 ios_unused1[122]; | ||
28 | }; | ||
29 | |||
30 | /* | ||
31 | * combined volumeid and dkconfig block | ||
32 | */ | ||
33 | |||
34 | struct dkblk0 { | ||
35 | struct volumeid dk_vid; | ||
36 | struct dkconfig dk_ios; | ||
37 | }; | ||
38 | |||
39 | /* | ||
40 | * Slice Table Structure | ||
41 | */ | ||
42 | |||
43 | struct slice { | ||
44 | __be32 nblocks; /* slice size (in blocks) */ | ||
45 | __be32 blkoff; /* block offset of slice */ | ||
46 | }; | ||
47 | |||
48 | |||
49 | int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev) | ||
50 | { | ||
51 | int i, slices; | ||
52 | int slot = 1; | ||
53 | Sector sect; | ||
54 | unsigned char *data; | ||
55 | struct dkblk0 *b; | ||
56 | struct slice *slice; | ||
57 | |||
58 | data = read_dev_sector(bdev, 0, §); | ||
59 | if (!data) | ||
60 | return -1; | ||
61 | |||
62 | b = (struct dkblk0 *)data; | ||
63 | if (memcmp(b->dk_vid.vid_mac, "MOTOROLA", sizeof(b->dk_vid.vid_mac))) { | ||
64 | put_dev_sector(sect); | ||
65 | return 0; | ||
66 | } | ||
67 | slices = be16_to_cpu(b->dk_ios.ios_slccnt); | ||
68 | i = be32_to_cpu(b->dk_ios.ios_slcblk); | ||
69 | put_dev_sector(sect); | ||
70 | |||
71 | data = read_dev_sector(bdev, i, §); | ||
72 | if (!data) | ||
73 | return -1; | ||
74 | |||
75 | slices -= 1; /* last slice is the whole disk */ | ||
76 | printk("sysV68: %s(s%u)", state->name, slices); | ||
77 | slice = (struct slice *)data; | ||
78 | for (i = 0; i < slices; i++, slice++) { | ||
79 | if (slot == state->limit) | ||
80 | break; | ||
81 | if (be32_to_cpu(slice->nblocks)) { | ||
82 | put_partition(state, slot, | ||
83 | be32_to_cpu(slice->blkoff), | ||
84 | be32_to_cpu(slice->nblocks)); | ||
85 | printk("(s%u)", i); | ||
86 | } | ||
87 | slot++; | ||
88 | } | ||
89 | printk("\n"); | ||
90 | put_dev_sector(sect); | ||
91 | return 1; | ||
92 | } | ||
diff --git a/fs/partitions/sysv68.h b/fs/partitions/sysv68.h new file mode 100644 index 000000000000..fa733f68431b --- /dev/null +++ b/fs/partitions/sysv68.h | |||
@@ -0,0 +1 @@ | |||
extern int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev); | |||
@@ -841,8 +841,18 @@ static int pipefs_delete_dentry(struct dentry *dentry) | |||
841 | return 0; | 841 | return 0; |
842 | } | 842 | } |
843 | 843 | ||
844 | /* | ||
845 | * pipefs_dname() is called from d_path(). | ||
846 | */ | ||
847 | static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen) | ||
848 | { | ||
849 | return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]", | ||
850 | dentry->d_inode->i_ino); | ||
851 | } | ||
852 | |||
844 | static struct dentry_operations pipefs_dentry_operations = { | 853 | static struct dentry_operations pipefs_dentry_operations = { |
845 | .d_delete = pipefs_delete_dentry, | 854 | .d_delete = pipefs_delete_dentry, |
855 | .d_dname = pipefs_dname, | ||
846 | }; | 856 | }; |
847 | 857 | ||
848 | static struct inode * get_pipe_inode(void) | 858 | static struct inode * get_pipe_inode(void) |
@@ -888,8 +898,7 @@ struct file *create_write_pipe(void) | |||
888 | struct inode *inode; | 898 | struct inode *inode; |
889 | struct file *f; | 899 | struct file *f; |
890 | struct dentry *dentry; | 900 | struct dentry *dentry; |
891 | char name[32]; | 901 | struct qstr name = { .name = "" }; |
892 | struct qstr this; | ||
893 | 902 | ||
894 | f = get_empty_filp(); | 903 | f = get_empty_filp(); |
895 | if (!f) | 904 | if (!f) |
@@ -899,11 +908,8 @@ struct file *create_write_pipe(void) | |||
899 | if (!inode) | 908 | if (!inode) |
900 | goto err_file; | 909 | goto err_file; |
901 | 910 | ||
902 | this.len = sprintf(name, "[%lu]", inode->i_ino); | ||
903 | this.name = name; | ||
904 | this.hash = 0; | ||
905 | err = -ENOMEM; | 911 | err = -ENOMEM; |
906 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 912 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); |
907 | if (!dentry) | 913 | if (!dentry) |
908 | goto err_inode; | 914 | goto err_inode; |
909 | 915 | ||
diff --git a/fs/pnode.c b/fs/pnode.c index 56aacead8362..89940f243fc2 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -59,7 +59,7 @@ static int do_make_slave(struct vfsmount *mnt) | |||
59 | } else { | 59 | } else { |
60 | struct list_head *p = &mnt->mnt_slave_list; | 60 | struct list_head *p = &mnt->mnt_slave_list; |
61 | while (!list_empty(p)) { | 61 | while (!list_empty(p)) { |
62 | slave_mnt = list_entry(p->next, | 62 | slave_mnt = list_first_entry(p, |
63 | struct vfsmount, mnt_slave); | 63 | struct vfsmount, mnt_slave); |
64 | list_del_init(&slave_mnt->mnt_slave); | 64 | list_del_init(&slave_mnt->mnt_slave); |
65 | slave_mnt->mnt_master = NULL; | 65 | slave_mnt->mnt_master = NULL; |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 07c9cdbcdcac..74f30e0c0381 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -410,9 +410,9 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
410 | /* convert nsec -> ticks */ | 410 | /* convert nsec -> ticks */ |
411 | start_time = nsec_to_clock_t(start_time); | 411 | start_time = nsec_to_clock_t(start_time); |
412 | 412 | ||
413 | res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ | 413 | res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %lu \ |
414 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ | 414 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ |
415 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n", | 415 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu\n", |
416 | task->pid, | 416 | task->pid, |
417 | tcomm, | 417 | tcomm, |
418 | state, | 418 | state, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index ec158dd02b3a..3c41149dea88 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -61,9 +61,9 @@ | |||
61 | #include <linux/namei.h> | 61 | #include <linux/namei.h> |
62 | #include <linux/mnt_namespace.h> | 62 | #include <linux/mnt_namespace.h> |
63 | #include <linux/mm.h> | 63 | #include <linux/mm.h> |
64 | #include <linux/smp_lock.h> | ||
65 | #include <linux/rcupdate.h> | 64 | #include <linux/rcupdate.h> |
66 | #include <linux/kallsyms.h> | 65 | #include <linux/kallsyms.h> |
66 | #include <linux/module.h> | ||
67 | #include <linux/mount.h> | 67 | #include <linux/mount.h> |
68 | #include <linux/security.h> | 68 | #include <linux/security.h> |
69 | #include <linux/ptrace.h> | 69 | #include <linux/ptrace.h> |
@@ -90,8 +90,8 @@ | |||
90 | #define PROC_NUMBUF 13 | 90 | #define PROC_NUMBUF 13 |
91 | 91 | ||
92 | struct pid_entry { | 92 | struct pid_entry { |
93 | int len; | ||
94 | char *name; | 93 | char *name; |
94 | int len; | ||
95 | mode_t mode; | 95 | mode_t mode; |
96 | const struct inode_operations *iop; | 96 | const struct inode_operations *iop; |
97 | const struct file_operations *fop; | 97 | const struct file_operations *fop; |
@@ -99,8 +99,8 @@ struct pid_entry { | |||
99 | }; | 99 | }; |
100 | 100 | ||
101 | #define NOD(NAME, MODE, IOP, FOP, OP) { \ | 101 | #define NOD(NAME, MODE, IOP, FOP, OP) { \ |
102 | .len = sizeof(NAME) - 1, \ | ||
103 | .name = (NAME), \ | 102 | .name = (NAME), \ |
103 | .len = sizeof(NAME) - 1, \ | ||
104 | .mode = MODE, \ | 104 | .mode = MODE, \ |
105 | .iop = IOP, \ | 105 | .iop = IOP, \ |
106 | .fop = FOP, \ | 106 | .fop = FOP, \ |
@@ -123,6 +123,9 @@ struct pid_entry { | |||
123 | NULL, &proc_info_file_operations, \ | 123 | NULL, &proc_info_file_operations, \ |
124 | { .proc_read = &proc_##OTYPE } ) | 124 | { .proc_read = &proc_##OTYPE } ) |
125 | 125 | ||
126 | int maps_protect; | ||
127 | EXPORT_SYMBOL(maps_protect); | ||
128 | |||
126 | static struct fs_struct *get_fs_struct(struct task_struct *task) | 129 | static struct fs_struct *get_fs_struct(struct task_struct *task) |
127 | { | 130 | { |
128 | struct fs_struct *fs; | 131 | struct fs_struct *fs; |
@@ -275,17 +278,15 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer) | |||
275 | */ | 278 | */ |
276 | static int proc_pid_wchan(struct task_struct *task, char *buffer) | 279 | static int proc_pid_wchan(struct task_struct *task, char *buffer) |
277 | { | 280 | { |
278 | char *modname; | 281 | unsigned long wchan; |
279 | const char *sym_name; | 282 | char symname[KSYM_NAME_LEN+1]; |
280 | unsigned long wchan, size, offset; | ||
281 | char namebuf[KSYM_NAME_LEN+1]; | ||
282 | 283 | ||
283 | wchan = get_wchan(task); | 284 | wchan = get_wchan(task); |
284 | 285 | ||
285 | sym_name = kallsyms_lookup(wchan, &size, &offset, &modname, namebuf); | 286 | if (lookup_symbol_name(wchan, symname) < 0) |
286 | if (sym_name) | 287 | return sprintf(buffer, "%lu", wchan); |
287 | return sprintf(buffer, "%s", sym_name); | 288 | else |
288 | return sprintf(buffer, "%lu", wchan); | 289 | return sprintf(buffer, "%s", symname); |
289 | } | 290 | } |
290 | #endif /* CONFIG_KALLSYMS */ | 291 | #endif /* CONFIG_KALLSYMS */ |
291 | 292 | ||
@@ -310,7 +311,9 @@ static int proc_oom_score(struct task_struct *task, char *buffer) | |||
310 | struct timespec uptime; | 311 | struct timespec uptime; |
311 | 312 | ||
312 | do_posix_clock_monotonic_gettime(&uptime); | 313 | do_posix_clock_monotonic_gettime(&uptime); |
314 | read_lock(&tasklist_lock); | ||
313 | points = badness(task, uptime.tv_sec); | 315 | points = badness(task, uptime.tv_sec); |
316 | read_unlock(&tasklist_lock); | ||
314 | return sprintf(buffer, "%lu\n", points); | 317 | return sprintf(buffer, "%lu\n", points); |
315 | } | 318 | } |
316 | 319 | ||
@@ -344,11 +347,8 @@ static int proc_setattr(struct dentry *dentry, struct iattr *attr) | |||
344 | return -EPERM; | 347 | return -EPERM; |
345 | 348 | ||
346 | error = inode_change_ok(inode, attr); | 349 | error = inode_change_ok(inode, attr); |
347 | if (!error) { | 350 | if (!error) |
348 | error = security_inode_setattr(dentry, attr); | 351 | error = inode_setattr(inode, attr); |
349 | if (!error) | ||
350 | error = inode_setattr(inode, attr); | ||
351 | } | ||
352 | return error; | 352 | return error; |
353 | } | 353 | } |
354 | 354 | ||
@@ -660,7 +660,6 @@ static ssize_t oom_adjust_read(struct file *file, char __user *buf, | |||
660 | char buffer[PROC_NUMBUF]; | 660 | char buffer[PROC_NUMBUF]; |
661 | size_t len; | 661 | size_t len; |
662 | int oom_adjust; | 662 | int oom_adjust; |
663 | loff_t __ppos = *ppos; | ||
664 | 663 | ||
665 | if (!task) | 664 | if (!task) |
666 | return -ESRCH; | 665 | return -ESRCH; |
@@ -668,14 +667,8 @@ static ssize_t oom_adjust_read(struct file *file, char __user *buf, | |||
668 | put_task_struct(task); | 667 | put_task_struct(task); |
669 | 668 | ||
670 | len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust); | 669 | len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust); |
671 | if (__ppos >= len) | 670 | |
672 | return 0; | 671 | return simple_read_from_buffer(buf, count, ppos, buffer, len); |
673 | if (count > len-__ppos) | ||
674 | count = len-__ppos; | ||
675 | if (copy_to_user(buf, buffer + __ppos, count)) | ||
676 | return -EFAULT; | ||
677 | *ppos = __ppos + count; | ||
678 | return count; | ||
679 | } | 672 | } |
680 | 673 | ||
681 | static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | 674 | static ssize_t oom_adjust_write(struct file *file, const char __user *buf, |
@@ -823,7 +816,6 @@ static ssize_t seccomp_read(struct file *file, char __user *buf, | |||
823 | { | 816 | { |
824 | struct task_struct *tsk = get_proc_task(file->f_dentry->d_inode); | 817 | struct task_struct *tsk = get_proc_task(file->f_dentry->d_inode); |
825 | char __buf[20]; | 818 | char __buf[20]; |
826 | loff_t __ppos = *ppos; | ||
827 | size_t len; | 819 | size_t len; |
828 | 820 | ||
829 | if (!tsk) | 821 | if (!tsk) |
@@ -831,14 +823,8 @@ static ssize_t seccomp_read(struct file *file, char __user *buf, | |||
831 | /* no need to print the trailing zero, so use only len */ | 823 | /* no need to print the trailing zero, so use only len */ |
832 | len = sprintf(__buf, "%u\n", tsk->seccomp.mode); | 824 | len = sprintf(__buf, "%u\n", tsk->seccomp.mode); |
833 | put_task_struct(tsk); | 825 | put_task_struct(tsk); |
834 | if (__ppos >= len) | 826 | |
835 | return 0; | 827 | return simple_read_from_buffer(buf, count, ppos, __buf, len); |
836 | if (count > len - __ppos) | ||
837 | count = len - __ppos; | ||
838 | if (copy_to_user(buf, __buf + __ppos, count)) | ||
839 | return -EFAULT; | ||
840 | *ppos = __ppos + count; | ||
841 | return count; | ||
842 | } | 828 | } |
843 | 829 | ||
844 | static ssize_t seccomp_write(struct file *file, const char __user *buf, | 830 | static ssize_t seccomp_write(struct file *file, const char __user *buf, |
@@ -897,7 +883,6 @@ static ssize_t proc_fault_inject_read(struct file * file, char __user * buf, | |||
897 | char buffer[PROC_NUMBUF]; | 883 | char buffer[PROC_NUMBUF]; |
898 | size_t len; | 884 | size_t len; |
899 | int make_it_fail; | 885 | int make_it_fail; |
900 | loff_t __ppos = *ppos; | ||
901 | 886 | ||
902 | if (!task) | 887 | if (!task) |
903 | return -ESRCH; | 888 | return -ESRCH; |
@@ -905,14 +890,8 @@ static ssize_t proc_fault_inject_read(struct file * file, char __user * buf, | |||
905 | put_task_struct(task); | 890 | put_task_struct(task); |
906 | 891 | ||
907 | len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail); | 892 | len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail); |
908 | if (__ppos >= len) | 893 | |
909 | return 0; | 894 | return simple_read_from_buffer(buf, count, ppos, buffer, len); |
910 | if (count > len-__ppos) | ||
911 | count = len-__ppos; | ||
912 | if (copy_to_user(buf, buffer + __ppos, count)) | ||
913 | return -EFAULT; | ||
914 | *ppos = __ppos + count; | ||
915 | return count; | ||
916 | } | 895 | } |
917 | 896 | ||
918 | static ssize_t proc_fault_inject_write(struct file * file, | 897 | static ssize_t proc_fault_inject_write(struct file * file, |
@@ -975,7 +954,7 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, | |||
975 | 954 | ||
976 | if (!tmp) | 955 | if (!tmp) |
977 | return -ENOMEM; | 956 | return -ENOMEM; |
978 | 957 | ||
979 | inode = dentry->d_inode; | 958 | inode = dentry->d_inode; |
980 | path = d_path(dentry, mnt, tmp, PAGE_SIZE); | 959 | path = d_path(dentry, mnt, tmp, PAGE_SIZE); |
981 | len = PTR_ERR(path); | 960 | len = PTR_ERR(path); |
@@ -1155,7 +1134,8 @@ static struct dentry_operations pid_dentry_operations = | |||
1155 | 1134 | ||
1156 | /* Lookups */ | 1135 | /* Lookups */ |
1157 | 1136 | ||
1158 | typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *); | 1137 | typedef struct dentry *instantiate_t(struct inode *, struct dentry *, |
1138 | struct task_struct *, const void *); | ||
1159 | 1139 | ||
1160 | /* | 1140 | /* |
1161 | * Fill a directory entry. | 1141 | * Fill a directory entry. |
@@ -1171,7 +1151,7 @@ typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct tas | |||
1171 | */ | 1151 | */ |
1172 | static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 1152 | static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, |
1173 | char *name, int len, | 1153 | char *name, int len, |
1174 | instantiate_t instantiate, struct task_struct *task, void *ptr) | 1154 | instantiate_t instantiate, struct task_struct *task, const void *ptr) |
1175 | { | 1155 | { |
1176 | struct dentry *child, *dir = filp->f_path.dentry; | 1156 | struct dentry *child, *dir = filp->f_path.dentry; |
1177 | struct inode *inode; | 1157 | struct inode *inode; |
@@ -1233,7 +1213,10 @@ out: | |||
1233 | return ~0U; | 1213 | return ~0U; |
1234 | } | 1214 | } |
1235 | 1215 | ||
1236 | static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 1216 | #define PROC_FDINFO_MAX 64 |
1217 | |||
1218 | static int proc_fd_info(struct inode *inode, struct dentry **dentry, | ||
1219 | struct vfsmount **mnt, char *info) | ||
1237 | { | 1220 | { |
1238 | struct task_struct *task = get_proc_task(inode); | 1221 | struct task_struct *task = get_proc_task(inode); |
1239 | struct files_struct *files = NULL; | 1222 | struct files_struct *files = NULL; |
@@ -1252,8 +1235,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm | |||
1252 | spin_lock(&files->file_lock); | 1235 | spin_lock(&files->file_lock); |
1253 | file = fcheck_files(files, fd); | 1236 | file = fcheck_files(files, fd); |
1254 | if (file) { | 1237 | if (file) { |
1255 | *mnt = mntget(file->f_path.mnt); | 1238 | if (mnt) |
1256 | *dentry = dget(file->f_path.dentry); | 1239 | *mnt = mntget(file->f_path.mnt); |
1240 | if (dentry) | ||
1241 | *dentry = dget(file->f_path.dentry); | ||
1242 | if (info) | ||
1243 | snprintf(info, PROC_FDINFO_MAX, | ||
1244 | "pos:\t%lli\n" | ||
1245 | "flags:\t0%o\n", | ||
1246 | (long long) file->f_pos, | ||
1247 | file->f_flags); | ||
1257 | spin_unlock(&files->file_lock); | 1248 | spin_unlock(&files->file_lock); |
1258 | put_files_struct(files); | 1249 | put_files_struct(files); |
1259 | return 0; | 1250 | return 0; |
@@ -1264,6 +1255,12 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm | |||
1264 | return -ENOENT; | 1255 | return -ENOENT; |
1265 | } | 1256 | } |
1266 | 1257 | ||
1258 | static int proc_fd_link(struct inode *inode, struct dentry **dentry, | ||
1259 | struct vfsmount **mnt) | ||
1260 | { | ||
1261 | return proc_fd_info(inode, dentry, mnt, NULL); | ||
1262 | } | ||
1263 | |||
1267 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | 1264 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) |
1268 | { | 1265 | { |
1269 | struct inode *inode = dentry->d_inode; | 1266 | struct inode *inode = dentry->d_inode; |
@@ -1306,9 +1303,9 @@ static struct dentry_operations tid_fd_dentry_operations = | |||
1306 | }; | 1303 | }; |
1307 | 1304 | ||
1308 | static struct dentry *proc_fd_instantiate(struct inode *dir, | 1305 | static struct dentry *proc_fd_instantiate(struct inode *dir, |
1309 | struct dentry *dentry, struct task_struct *task, void *ptr) | 1306 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
1310 | { | 1307 | { |
1311 | unsigned fd = *(unsigned *)ptr; | 1308 | unsigned fd = *(const unsigned *)ptr; |
1312 | struct file *file; | 1309 | struct file *file; |
1313 | struct files_struct *files; | 1310 | struct files_struct *files; |
1314 | struct inode *inode; | 1311 | struct inode *inode; |
@@ -1359,7 +1356,9 @@ out_iput: | |||
1359 | goto out; | 1356 | goto out; |
1360 | } | 1357 | } |
1361 | 1358 | ||
1362 | static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) | 1359 | static struct dentry *proc_lookupfd_common(struct inode *dir, |
1360 | struct dentry *dentry, | ||
1361 | instantiate_t instantiate) | ||
1363 | { | 1362 | { |
1364 | struct task_struct *task = get_proc_task(dir); | 1363 | struct task_struct *task = get_proc_task(dir); |
1365 | unsigned fd = name_to_int(dentry); | 1364 | unsigned fd = name_to_int(dentry); |
@@ -1370,23 +1369,15 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1370 | if (fd == ~0U) | 1369 | if (fd == ~0U) |
1371 | goto out; | 1370 | goto out; |
1372 | 1371 | ||
1373 | result = proc_fd_instantiate(dir, dentry, task, &fd); | 1372 | result = instantiate(dir, dentry, task, &fd); |
1374 | out: | 1373 | out: |
1375 | put_task_struct(task); | 1374 | put_task_struct(task); |
1376 | out_no_task: | 1375 | out_no_task: |
1377 | return result; | 1376 | return result; |
1378 | } | 1377 | } |
1379 | 1378 | ||
1380 | static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 1379 | static int proc_readfd_common(struct file * filp, void * dirent, |
1381 | struct task_struct *task, int fd) | 1380 | filldir_t filldir, instantiate_t instantiate) |
1382 | { | ||
1383 | char name[PROC_NUMBUF]; | ||
1384 | int len = snprintf(name, sizeof(name), "%d", fd); | ||
1385 | return proc_fill_cache(filp, dirent, filldir, name, len, | ||
1386 | proc_fd_instantiate, task, &fd); | ||
1387 | } | ||
1388 | |||
1389 | static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) | ||
1390 | { | 1381 | { |
1391 | struct dentry *dentry = filp->f_path.dentry; | 1382 | struct dentry *dentry = filp->f_path.dentry; |
1392 | struct inode *inode = dentry->d_inode; | 1383 | struct inode *inode = dentry->d_inode; |
@@ -1422,12 +1413,17 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) | |||
1422 | for (fd = filp->f_pos-2; | 1413 | for (fd = filp->f_pos-2; |
1423 | fd < fdt->max_fds; | 1414 | fd < fdt->max_fds; |
1424 | fd++, filp->f_pos++) { | 1415 | fd++, filp->f_pos++) { |
1416 | char name[PROC_NUMBUF]; | ||
1417 | int len; | ||
1425 | 1418 | ||
1426 | if (!fcheck_files(files, fd)) | 1419 | if (!fcheck_files(files, fd)) |
1427 | continue; | 1420 | continue; |
1428 | rcu_read_unlock(); | 1421 | rcu_read_unlock(); |
1429 | 1422 | ||
1430 | if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) { | 1423 | len = snprintf(name, sizeof(name), "%d", fd); |
1424 | if (proc_fill_cache(filp, dirent, filldir, | ||
1425 | name, len, instantiate, | ||
1426 | p, &fd) < 0) { | ||
1431 | rcu_read_lock(); | 1427 | rcu_read_lock(); |
1432 | break; | 1428 | break; |
1433 | } | 1429 | } |
@@ -1442,23 +1438,119 @@ out_no_task: | |||
1442 | return retval; | 1438 | return retval; |
1443 | } | 1439 | } |
1444 | 1440 | ||
1441 | static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, | ||
1442 | struct nameidata *nd) | ||
1443 | { | ||
1444 | return proc_lookupfd_common(dir, dentry, proc_fd_instantiate); | ||
1445 | } | ||
1446 | |||
1447 | static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir) | ||
1448 | { | ||
1449 | return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate); | ||
1450 | } | ||
1451 | |||
1452 | static ssize_t proc_fdinfo_read(struct file *file, char __user *buf, | ||
1453 | size_t len, loff_t *ppos) | ||
1454 | { | ||
1455 | char tmp[PROC_FDINFO_MAX]; | ||
1456 | int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp); | ||
1457 | if (!err) | ||
1458 | err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); | ||
1459 | return err; | ||
1460 | } | ||
1461 | |||
1462 | static const struct file_operations proc_fdinfo_file_operations = { | ||
1463 | .open = nonseekable_open, | ||
1464 | .read = proc_fdinfo_read, | ||
1465 | }; | ||
1466 | |||
1445 | static const struct file_operations proc_fd_operations = { | 1467 | static const struct file_operations proc_fd_operations = { |
1446 | .read = generic_read_dir, | 1468 | .read = generic_read_dir, |
1447 | .readdir = proc_readfd, | 1469 | .readdir = proc_readfd, |
1448 | }; | 1470 | }; |
1449 | 1471 | ||
1450 | /* | 1472 | /* |
1473 | * /proc/pid/fd needs a special permission handler so that a process can still | ||
1474 | * access /proc/self/fd after it has executed a setuid(). | ||
1475 | */ | ||
1476 | static int proc_fd_permission(struct inode *inode, int mask, | ||
1477 | struct nameidata *nd) | ||
1478 | { | ||
1479 | int rv; | ||
1480 | |||
1481 | rv = generic_permission(inode, mask, NULL); | ||
1482 | if (rv == 0) | ||
1483 | return 0; | ||
1484 | if (task_pid(current) == proc_pid(inode)) | ||
1485 | rv = 0; | ||
1486 | return rv; | ||
1487 | } | ||
1488 | |||
1489 | /* | ||
1451 | * proc directories can do almost nothing.. | 1490 | * proc directories can do almost nothing.. |
1452 | */ | 1491 | */ |
1453 | static const struct inode_operations proc_fd_inode_operations = { | 1492 | static const struct inode_operations proc_fd_inode_operations = { |
1454 | .lookup = proc_lookupfd, | 1493 | .lookup = proc_lookupfd, |
1494 | .permission = proc_fd_permission, | ||
1455 | .setattr = proc_setattr, | 1495 | .setattr = proc_setattr, |
1456 | }; | 1496 | }; |
1457 | 1497 | ||
1498 | static struct dentry *proc_fdinfo_instantiate(struct inode *dir, | ||
1499 | struct dentry *dentry, struct task_struct *task, const void *ptr) | ||
1500 | { | ||
1501 | unsigned fd = *(unsigned *)ptr; | ||
1502 | struct inode *inode; | ||
1503 | struct proc_inode *ei; | ||
1504 | struct dentry *error = ERR_PTR(-ENOENT); | ||
1505 | |||
1506 | inode = proc_pid_make_inode(dir->i_sb, task); | ||
1507 | if (!inode) | ||
1508 | goto out; | ||
1509 | ei = PROC_I(inode); | ||
1510 | ei->fd = fd; | ||
1511 | inode->i_mode = S_IFREG | S_IRUSR; | ||
1512 | inode->i_fop = &proc_fdinfo_file_operations; | ||
1513 | dentry->d_op = &tid_fd_dentry_operations; | ||
1514 | d_add(dentry, inode); | ||
1515 | /* Close the race of the process dying before we return the dentry */ | ||
1516 | if (tid_fd_revalidate(dentry, NULL)) | ||
1517 | error = NULL; | ||
1518 | |||
1519 | out: | ||
1520 | return error; | ||
1521 | } | ||
1522 | |||
1523 | static struct dentry *proc_lookupfdinfo(struct inode *dir, | ||
1524 | struct dentry *dentry, | ||
1525 | struct nameidata *nd) | ||
1526 | { | ||
1527 | return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate); | ||
1528 | } | ||
1529 | |||
1530 | static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir) | ||
1531 | { | ||
1532 | return proc_readfd_common(filp, dirent, filldir, | ||
1533 | proc_fdinfo_instantiate); | ||
1534 | } | ||
1535 | |||
1536 | static const struct file_operations proc_fdinfo_operations = { | ||
1537 | .read = generic_read_dir, | ||
1538 | .readdir = proc_readfdinfo, | ||
1539 | }; | ||
1540 | |||
1541 | /* | ||
1542 | * proc directories can do almost nothing.. | ||
1543 | */ | ||
1544 | static const struct inode_operations proc_fdinfo_inode_operations = { | ||
1545 | .lookup = proc_lookupfdinfo, | ||
1546 | .setattr = proc_setattr, | ||
1547 | }; | ||
1548 | |||
1549 | |||
1458 | static struct dentry *proc_pident_instantiate(struct inode *dir, | 1550 | static struct dentry *proc_pident_instantiate(struct inode *dir, |
1459 | struct dentry *dentry, struct task_struct *task, void *ptr) | 1551 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
1460 | { | 1552 | { |
1461 | struct pid_entry *p = ptr; | 1553 | const struct pid_entry *p = ptr; |
1462 | struct inode *inode; | 1554 | struct inode *inode; |
1463 | struct proc_inode *ei; | 1555 | struct proc_inode *ei; |
1464 | struct dentry *error = ERR_PTR(-EINVAL); | 1556 | struct dentry *error = ERR_PTR(-EINVAL); |
@@ -1487,13 +1579,13 @@ out: | |||
1487 | 1579 | ||
1488 | static struct dentry *proc_pident_lookup(struct inode *dir, | 1580 | static struct dentry *proc_pident_lookup(struct inode *dir, |
1489 | struct dentry *dentry, | 1581 | struct dentry *dentry, |
1490 | struct pid_entry *ents, | 1582 | const struct pid_entry *ents, |
1491 | unsigned int nents) | 1583 | unsigned int nents) |
1492 | { | 1584 | { |
1493 | struct inode *inode; | 1585 | struct inode *inode; |
1494 | struct dentry *error; | 1586 | struct dentry *error; |
1495 | struct task_struct *task = get_proc_task(dir); | 1587 | struct task_struct *task = get_proc_task(dir); |
1496 | struct pid_entry *p, *last; | 1588 | const struct pid_entry *p, *last; |
1497 | 1589 | ||
1498 | error = ERR_PTR(-ENOENT); | 1590 | error = ERR_PTR(-ENOENT); |
1499 | inode = NULL; | 1591 | inode = NULL; |
@@ -1522,8 +1614,8 @@ out_no_task: | |||
1522 | return error; | 1614 | return error; |
1523 | } | 1615 | } |
1524 | 1616 | ||
1525 | static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 1617 | static int proc_pident_fill_cache(struct file *filp, void *dirent, |
1526 | struct task_struct *task, struct pid_entry *p) | 1618 | filldir_t filldir, struct task_struct *task, const struct pid_entry *p) |
1527 | { | 1619 | { |
1528 | return proc_fill_cache(filp, dirent, filldir, p->name, p->len, | 1620 | return proc_fill_cache(filp, dirent, filldir, p->name, p->len, |
1529 | proc_pident_instantiate, task, p); | 1621 | proc_pident_instantiate, task, p); |
@@ -1531,14 +1623,14 @@ static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t fil | |||
1531 | 1623 | ||
1532 | static int proc_pident_readdir(struct file *filp, | 1624 | static int proc_pident_readdir(struct file *filp, |
1533 | void *dirent, filldir_t filldir, | 1625 | void *dirent, filldir_t filldir, |
1534 | struct pid_entry *ents, unsigned int nents) | 1626 | const struct pid_entry *ents, unsigned int nents) |
1535 | { | 1627 | { |
1536 | int i; | 1628 | int i; |
1537 | int pid; | 1629 | int pid; |
1538 | struct dentry *dentry = filp->f_path.dentry; | 1630 | struct dentry *dentry = filp->f_path.dentry; |
1539 | struct inode *inode = dentry->d_inode; | 1631 | struct inode *inode = dentry->d_inode; |
1540 | struct task_struct *task = get_proc_task(inode); | 1632 | struct task_struct *task = get_proc_task(inode); |
1541 | struct pid_entry *p, *last; | 1633 | const struct pid_entry *p, *last; |
1542 | ino_t ino; | 1634 | ino_t ino; |
1543 | int ret; | 1635 | int ret; |
1544 | 1636 | ||
@@ -1653,7 +1745,7 @@ static const struct file_operations proc_pid_attr_operations = { | |||
1653 | .write = proc_pid_attr_write, | 1745 | .write = proc_pid_attr_write, |
1654 | }; | 1746 | }; |
1655 | 1747 | ||
1656 | static struct pid_entry attr_dir_stuff[] = { | 1748 | static const struct pid_entry attr_dir_stuff[] = { |
1657 | REG("current", S_IRUGO|S_IWUGO, pid_attr), | 1749 | REG("current", S_IRUGO|S_IWUGO, pid_attr), |
1658 | REG("prev", S_IRUGO, pid_attr), | 1750 | REG("prev", S_IRUGO, pid_attr), |
1659 | REG("exec", S_IRUGO|S_IWUGO, pid_attr), | 1751 | REG("exec", S_IRUGO|S_IWUGO, pid_attr), |
@@ -1719,7 +1811,7 @@ static const struct inode_operations proc_self_inode_operations = { | |||
1719 | * that properly belong to the /proc filesystem, as they describe | 1811 | * that properly belong to the /proc filesystem, as they describe |
1720 | * describe something that is process related. | 1812 | * describe something that is process related. |
1721 | */ | 1813 | */ |
1722 | static struct pid_entry proc_base_stuff[] = { | 1814 | static const struct pid_entry proc_base_stuff[] = { |
1723 | NOD("self", S_IFLNK|S_IRWXUGO, | 1815 | NOD("self", S_IFLNK|S_IRWXUGO, |
1724 | &proc_self_inode_operations, NULL, {}), | 1816 | &proc_self_inode_operations, NULL, {}), |
1725 | }; | 1817 | }; |
@@ -1748,9 +1840,9 @@ static struct dentry_operations proc_base_dentry_operations = | |||
1748 | }; | 1840 | }; |
1749 | 1841 | ||
1750 | static struct dentry *proc_base_instantiate(struct inode *dir, | 1842 | static struct dentry *proc_base_instantiate(struct inode *dir, |
1751 | struct dentry *dentry, struct task_struct *task, void *ptr) | 1843 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
1752 | { | 1844 | { |
1753 | struct pid_entry *p = ptr; | 1845 | const struct pid_entry *p = ptr; |
1754 | struct inode *inode; | 1846 | struct inode *inode; |
1755 | struct proc_inode *ei; | 1847 | struct proc_inode *ei; |
1756 | struct dentry *error = ERR_PTR(-EINVAL); | 1848 | struct dentry *error = ERR_PTR(-EINVAL); |
@@ -1798,7 +1890,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | |||
1798 | { | 1890 | { |
1799 | struct dentry *error; | 1891 | struct dentry *error; |
1800 | struct task_struct *task = get_proc_task(dir); | 1892 | struct task_struct *task = get_proc_task(dir); |
1801 | struct pid_entry *p, *last; | 1893 | const struct pid_entry *p, *last; |
1802 | 1894 | ||
1803 | error = ERR_PTR(-ENOENT); | 1895 | error = ERR_PTR(-ENOENT); |
1804 | 1896 | ||
@@ -1824,8 +1916,8 @@ out_no_task: | |||
1824 | return error; | 1916 | return error; |
1825 | } | 1917 | } |
1826 | 1918 | ||
1827 | static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 1919 | static int proc_base_fill_cache(struct file *filp, void *dirent, |
1828 | struct task_struct *task, struct pid_entry *p) | 1920 | filldir_t filldir, struct task_struct *task, const struct pid_entry *p) |
1829 | { | 1921 | { |
1830 | return proc_fill_cache(filp, dirent, filldir, p->name, p->len, | 1922 | return proc_fill_cache(filp, dirent, filldir, p->name, p->len, |
1831 | proc_base_instantiate, task, p); | 1923 | proc_base_instantiate, task, p); |
@@ -1862,9 +1954,10 @@ static int proc_pid_io_accounting(struct task_struct *task, char *buffer) | |||
1862 | static const struct file_operations proc_task_operations; | 1954 | static const struct file_operations proc_task_operations; |
1863 | static const struct inode_operations proc_task_inode_operations; | 1955 | static const struct inode_operations proc_task_inode_operations; |
1864 | 1956 | ||
1865 | static struct pid_entry tgid_base_stuff[] = { | 1957 | static const struct pid_entry tgid_base_stuff[] = { |
1866 | DIR("task", S_IRUGO|S_IXUGO, task), | 1958 | DIR("task", S_IRUGO|S_IXUGO, task), |
1867 | DIR("fd", S_IRUSR|S_IXUSR, fd), | 1959 | DIR("fd", S_IRUSR|S_IXUSR, fd), |
1960 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | ||
1868 | INF("environ", S_IRUSR, pid_environ), | 1961 | INF("environ", S_IRUSR, pid_environ), |
1869 | INF("auxv", S_IRUSR, pid_auxv), | 1962 | INF("auxv", S_IRUSR, pid_auxv), |
1870 | INF("status", S_IRUGO, pid_status), | 1963 | INF("status", S_IRUGO, pid_status), |
@@ -2005,7 +2098,7 @@ out: | |||
2005 | 2098 | ||
2006 | static struct dentry *proc_pid_instantiate(struct inode *dir, | 2099 | static struct dentry *proc_pid_instantiate(struct inode *dir, |
2007 | struct dentry * dentry, | 2100 | struct dentry * dentry, |
2008 | struct task_struct *task, void *ptr) | 2101 | struct task_struct *task, const void *ptr) |
2009 | { | 2102 | { |
2010 | struct dentry *error = ERR_PTR(-ENOENT); | 2103 | struct dentry *error = ERR_PTR(-ENOENT); |
2011 | struct inode *inode; | 2104 | struct inode *inode; |
@@ -2018,7 +2111,7 @@ static struct dentry *proc_pid_instantiate(struct inode *dir, | |||
2018 | inode->i_op = &proc_tgid_base_inode_operations; | 2111 | inode->i_op = &proc_tgid_base_inode_operations; |
2019 | inode->i_fop = &proc_tgid_base_operations; | 2112 | inode->i_fop = &proc_tgid_base_operations; |
2020 | inode->i_flags|=S_IMMUTABLE; | 2113 | inode->i_flags|=S_IMMUTABLE; |
2021 | inode->i_nlink = 4; | 2114 | inode->i_nlink = 5; |
2022 | #ifdef CONFIG_SECURITY | 2115 | #ifdef CONFIG_SECURITY |
2023 | inode->i_nlink += 1; | 2116 | inode->i_nlink += 1; |
2024 | #endif | 2117 | #endif |
@@ -2120,7 +2213,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
2120 | goto out_no_task; | 2213 | goto out_no_task; |
2121 | 2214 | ||
2122 | for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { | 2215 | for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { |
2123 | struct pid_entry *p = &proc_base_stuff[nr]; | 2216 | const struct pid_entry *p = &proc_base_stuff[nr]; |
2124 | if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) | 2217 | if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) |
2125 | goto out; | 2218 | goto out; |
2126 | } | 2219 | } |
@@ -2146,8 +2239,9 @@ out_no_task: | |||
2146 | /* | 2239 | /* |
2147 | * Tasks | 2240 | * Tasks |
2148 | */ | 2241 | */ |
2149 | static struct pid_entry tid_base_stuff[] = { | 2242 | static const struct pid_entry tid_base_stuff[] = { |
2150 | DIR("fd", S_IRUSR|S_IXUSR, fd), | 2243 | DIR("fd", S_IRUSR|S_IXUSR, fd), |
2244 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | ||
2151 | INF("environ", S_IRUSR, pid_environ), | 2245 | INF("environ", S_IRUSR, pid_environ), |
2152 | INF("auxv", S_IRUSR, pid_auxv), | 2246 | INF("auxv", S_IRUSR, pid_auxv), |
2153 | INF("status", S_IRUGO, pid_status), | 2247 | INF("status", S_IRUGO, pid_status), |
@@ -2216,7 +2310,7 @@ static const struct inode_operations proc_tid_base_inode_operations = { | |||
2216 | }; | 2310 | }; |
2217 | 2311 | ||
2218 | static struct dentry *proc_task_instantiate(struct inode *dir, | 2312 | static struct dentry *proc_task_instantiate(struct inode *dir, |
2219 | struct dentry *dentry, struct task_struct *task, void *ptr) | 2313 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
2220 | { | 2314 | { |
2221 | struct dentry *error = ERR_PTR(-ENOENT); | 2315 | struct dentry *error = ERR_PTR(-ENOENT); |
2222 | struct inode *inode; | 2316 | struct inode *inode; |
@@ -2228,7 +2322,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir, | |||
2228 | inode->i_op = &proc_tid_base_inode_operations; | 2322 | inode->i_op = &proc_tid_base_inode_operations; |
2229 | inode->i_fop = &proc_tid_base_operations; | 2323 | inode->i_fop = &proc_tid_base_operations; |
2230 | inode->i_flags|=S_IMMUTABLE; | 2324 | inode->i_flags|=S_IMMUTABLE; |
2231 | inode->i_nlink = 3; | 2325 | inode->i_nlink = 4; |
2232 | #ifdef CONFIG_SECURITY | 2326 | #ifdef CONFIG_SECURITY |
2233 | inode->i_nlink += 1; | 2327 | inode->i_nlink += 1; |
2234 | #endif | 2328 | #endif |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 775fb21294d8..8a40e15f5ecb 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -398,6 +398,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam | |||
398 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { | 398 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
399 | unsigned int ino = de->low_ino; | 399 | unsigned int ino = de->low_ino; |
400 | 400 | ||
401 | de_get(de); | ||
401 | spin_unlock(&proc_subdir_lock); | 402 | spin_unlock(&proc_subdir_lock); |
402 | error = -EINVAL; | 403 | error = -EINVAL; |
403 | inode = proc_get_inode(dir->i_sb, ino, de); | 404 | inode = proc_get_inode(dir->i_sb, ino, de); |
@@ -414,6 +415,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam | |||
414 | d_add(dentry, inode); | 415 | d_add(dentry, inode); |
415 | return NULL; | 416 | return NULL; |
416 | } | 417 | } |
418 | de_put(de); | ||
417 | return ERR_PTR(error); | 419 | return ERR_PTR(error); |
418 | } | 420 | } |
419 | 421 | ||
@@ -476,14 +478,21 @@ int proc_readdir(struct file * filp, | |||
476 | } | 478 | } |
477 | 479 | ||
478 | do { | 480 | do { |
481 | struct proc_dir_entry *next; | ||
482 | |||
479 | /* filldir passes info to user space */ | 483 | /* filldir passes info to user space */ |
484 | de_get(de); | ||
480 | spin_unlock(&proc_subdir_lock); | 485 | spin_unlock(&proc_subdir_lock); |
481 | if (filldir(dirent, de->name, de->namelen, filp->f_pos, | 486 | if (filldir(dirent, de->name, de->namelen, filp->f_pos, |
482 | de->low_ino, de->mode >> 12) < 0) | 487 | de->low_ino, de->mode >> 12) < 0) { |
488 | de_put(de); | ||
483 | goto out; | 489 | goto out; |
490 | } | ||
484 | spin_lock(&proc_subdir_lock); | 491 | spin_lock(&proc_subdir_lock); |
485 | filp->f_pos++; | 492 | filp->f_pos++; |
486 | de = de->next; | 493 | next = de->next; |
494 | de_put(de); | ||
495 | de = next; | ||
487 | } while (de); | 496 | } while (de); |
488 | spin_unlock(&proc_subdir_lock); | 497 | spin_unlock(&proc_subdir_lock); |
489 | } | 498 | } |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 22b1158389ae..b8171907c83b 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include "internal.h" | 22 | #include "internal.h" |
23 | 23 | ||
24 | static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de) | 24 | struct proc_dir_entry *de_get(struct proc_dir_entry *de) |
25 | { | 25 | { |
26 | if (de) | 26 | if (de) |
27 | atomic_inc(&de->count); | 27 | atomic_inc(&de->count); |
@@ -31,7 +31,7 @@ static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de) | |||
31 | /* | 31 | /* |
32 | * Decrements the use count and checks for deferred deletion. | 32 | * Decrements the use count and checks for deferred deletion. |
33 | */ | 33 | */ |
34 | static void de_put(struct proc_dir_entry *de) | 34 | void de_put(struct proc_dir_entry *de) |
35 | { | 35 | { |
36 | if (de) { | 36 | if (de) { |
37 | lock_kernel(); | 37 | lock_kernel(); |
@@ -146,13 +146,6 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
146 | { | 146 | { |
147 | struct inode * inode; | 147 | struct inode * inode; |
148 | 148 | ||
149 | /* | ||
150 | * Increment the use count so the dir entry can't disappear. | ||
151 | */ | ||
152 | de_get(de); | ||
153 | |||
154 | WARN_ON(de && de->deleted); | ||
155 | |||
156 | if (de != NULL && !try_module_get(de->owner)) | 149 | if (de != NULL && !try_module_get(de->owner)) |
157 | goto out_mod; | 150 | goto out_mod; |
158 | 151 | ||
@@ -184,7 +177,6 @@ out_ino: | |||
184 | if (de != NULL) | 177 | if (de != NULL) |
185 | module_put(de->owner); | 178 | module_put(de->owner); |
186 | out_mod: | 179 | out_mod: |
187 | de_put(de); | ||
188 | return NULL; | 180 | return NULL; |
189 | } | 181 | } |
190 | 182 | ||
@@ -199,6 +191,7 @@ int proc_fill_super(struct super_block *s, void *data, int silent) | |||
199 | s->s_op = &proc_sops; | 191 | s->s_op = &proc_sops; |
200 | s->s_time_gran = 1; | 192 | s->s_time_gran = 1; |
201 | 193 | ||
194 | de_get(&proc_root); | ||
202 | root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); | 195 | root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); |
203 | if (!root_inode) | 196 | if (!root_inode) |
204 | goto out_no_root; | 197 | goto out_no_root; |
@@ -212,6 +205,7 @@ int proc_fill_super(struct super_block *s, void *data, int silent) | |||
212 | out_no_root: | 205 | out_no_root: |
213 | printk("proc_read_super: get root inode failed\n"); | 206 | printk("proc_read_super: get root inode failed\n"); |
214 | iput(root_inode); | 207 | iput(root_inode); |
208 | de_put(&proc_root); | ||
215 | return -ENOMEM; | 209 | return -ENOMEM; |
216 | } | 210 | } |
217 | MODULE_LICENSE("GPL"); | 211 | MODULE_LICENSE("GPL"); |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index f771889183c3..b215c3524fa6 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -37,6 +37,8 @@ do { \ | |||
37 | extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *); | 37 | extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *); |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | extern int maps_protect; | ||
41 | |||
40 | extern void create_seq_entry(char *name, mode_t mode, const struct file_operations *f); | 42 | extern void create_seq_entry(char *name, mode_t mode, const struct file_operations *f); |
41 | extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **); | 43 | extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **); |
42 | extern int proc_tid_stat(struct task_struct *, char *); | 44 | extern int proc_tid_stat(struct task_struct *, char *); |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 75ec6523d29a..5fd49e47f83a 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/signal.h> | 35 | #include <linux/signal.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/smp_lock.h> | ||
39 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
40 | #include <linux/times.h> | 39 | #include <linux/times.h> |
41 | #include <linux/profile.h> | 40 | #include <linux/profile.h> |
@@ -429,18 +428,11 @@ static int slabstats_open(struct inode *inode, struct file *file) | |||
429 | return ret; | 428 | return ret; |
430 | } | 429 | } |
431 | 430 | ||
432 | static int slabstats_release(struct inode *inode, struct file *file) | ||
433 | { | ||
434 | struct seq_file *m = file->private_data; | ||
435 | kfree(m->private); | ||
436 | return seq_release(inode, file); | ||
437 | } | ||
438 | |||
439 | static const struct file_operations proc_slabstats_operations = { | 431 | static const struct file_operations proc_slabstats_operations = { |
440 | .open = slabstats_open, | 432 | .open = slabstats_open, |
441 | .read = seq_read, | 433 | .read = seq_read, |
442 | .llseek = seq_lseek, | 434 | .llseek = seq_lseek, |
443 | .release = slabstats_release, | 435 | .release = seq_release_private, |
444 | }; | 436 | }; |
445 | #endif | 437 | #endif |
446 | #endif | 438 | #endif |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 20e8cbb34364..680c429bfa22 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -429,11 +429,8 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) | |||
429 | return -EPERM; | 429 | return -EPERM; |
430 | 430 | ||
431 | error = inode_change_ok(inode, attr); | 431 | error = inode_change_ok(inode, attr); |
432 | if (!error) { | 432 | if (!error) |
433 | error = security_inode_setattr(dentry, attr); | 433 | error = inode_setattr(inode, attr); |
434 | if (!error) | ||
435 | error = inode_setattr(inode, attr); | ||
436 | } | ||
437 | 434 | ||
438 | return error; | 435 | return error; |
439 | } | 436 | } |
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index c1bbfbeb035e..b3a473b0a191 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c | |||
@@ -108,6 +108,8 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
108 | { | 108 | { |
109 | struct list_head *p; | 109 | struct list_head *p; |
110 | loff_t l = *pos; | 110 | loff_t l = *pos; |
111 | |||
112 | mutex_lock(&tty_mutex); | ||
111 | list_for_each(p, &tty_drivers) | 113 | list_for_each(p, &tty_drivers) |
112 | if (!l--) | 114 | if (!l--) |
113 | return list_entry(p, struct tty_driver, tty_drivers); | 115 | return list_entry(p, struct tty_driver, tty_drivers); |
@@ -124,6 +126,7 @@ static void *t_next(struct seq_file *m, void *v, loff_t *pos) | |||
124 | 126 | ||
125 | static void t_stop(struct seq_file *m, void *v) | 127 | static void t_stop(struct seq_file *m, void *v) |
126 | { | 128 | { |
129 | mutex_unlock(&tty_mutex); | ||
127 | } | 130 | } |
128 | 131 | ||
129 | static struct seq_operations tty_drivers_op = { | 132 | static struct seq_operations tty_drivers_op = { |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 4008c060f7ef..c24d81a5a040 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/mount.h> | 3 | #include <linux/mount.h> |
4 | #include <linux/seq_file.h> | 4 | #include <linux/seq_file.h> |
5 | #include <linux/highmem.h> | 5 | #include <linux/highmem.h> |
6 | #include <linux/ptrace.h> | ||
6 | #include <linux/pagemap.h> | 7 | #include <linux/pagemap.h> |
7 | #include <linux/mempolicy.h> | 8 | #include <linux/mempolicy.h> |
8 | 9 | ||
@@ -142,6 +143,9 @@ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats | |||
142 | dev_t dev = 0; | 143 | dev_t dev = 0; |
143 | int len; | 144 | int len; |
144 | 145 | ||
146 | if (maps_protect && !ptrace_may_attach(task)) | ||
147 | return -EACCES; | ||
148 | |||
145 | if (file) { | 149 | if (file) { |
146 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | 150 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
147 | dev = inode->i_sb->s_dev; | 151 | dev = inode->i_sb->s_dev; |
@@ -512,11 +516,22 @@ const struct file_operations proc_maps_operations = { | |||
512 | #ifdef CONFIG_NUMA | 516 | #ifdef CONFIG_NUMA |
513 | extern int show_numa_map(struct seq_file *m, void *v); | 517 | extern int show_numa_map(struct seq_file *m, void *v); |
514 | 518 | ||
519 | static int show_numa_map_checked(struct seq_file *m, void *v) | ||
520 | { | ||
521 | struct proc_maps_private *priv = m->private; | ||
522 | struct task_struct *task = priv->task; | ||
523 | |||
524 | if (maps_protect && !ptrace_may_attach(task)) | ||
525 | return -EACCES; | ||
526 | |||
527 | return show_numa_map(m, v); | ||
528 | } | ||
529 | |||
515 | static struct seq_operations proc_pid_numa_maps_op = { | 530 | static struct seq_operations proc_pid_numa_maps_op = { |
516 | .start = m_start, | 531 | .start = m_start, |
517 | .next = m_next, | 532 | .next = m_next, |
518 | .stop = m_stop, | 533 | .stop = m_stop, |
519 | .show = show_numa_map | 534 | .show = show_numa_map_checked |
520 | }; | 535 | }; |
521 | 536 | ||
522 | static int numa_maps_open(struct inode *inode, struct file *file) | 537 | static int numa_maps_open(struct inode *inode, struct file *file) |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 7cddf6b8635a..d8b8c7183c24 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/mm.h> | 2 | #include <linux/mm.h> |
3 | #include <linux/file.h> | 3 | #include <linux/file.h> |
4 | #include <linux/mount.h> | 4 | #include <linux/mount.h> |
5 | #include <linux/ptrace.h> | ||
5 | #include <linux/seq_file.h> | 6 | #include <linux/seq_file.h> |
6 | #include "internal.h" | 7 | #include "internal.h" |
7 | 8 | ||
@@ -143,6 +144,12 @@ out: | |||
143 | static int show_map(struct seq_file *m, void *_vml) | 144 | static int show_map(struct seq_file *m, void *_vml) |
144 | { | 145 | { |
145 | struct vm_list_struct *vml = _vml; | 146 | struct vm_list_struct *vml = _vml; |
147 | struct proc_maps_private *priv = m->private; | ||
148 | struct task_struct *task = priv->task; | ||
149 | |||
150 | if (maps_protect && !ptrace_may_attach(task)) | ||
151 | return -EACCES; | ||
152 | |||
146 | return nommu_vma_show(m, vml->vma); | 153 | return nommu_vma_show(m, vml->vma); |
147 | } | 154 | } |
148 | 155 | ||
diff --git a/fs/quota.c b/fs/quota.c index b9dae76a0b6e..e9d88fd0eca8 100644 --- a/fs/quota.c +++ b/fs/quota.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <asm/current.h> | 11 | #include <asm/current.h> |
12 | #include <asm/uaccess.h> | 12 | #include <asm/uaccess.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/security.h> | 14 | #include <linux/security.h> |
16 | #include <linux/syscalls.h> | 15 | #include <linux/syscalls.h> |
17 | #include <linux/buffer_head.h> | 16 | #include <linux/buffer_head.h> |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index d3fd7c6732d2..3b481d557edb 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/highmem.h> | 16 | #include <linux/highmem.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/backing-dev.h> | 19 | #include <linux/backing-dev.h> |
21 | #include <linux/ramfs.h> | 20 | #include <linux/ramfs.h> |
22 | #include <linux/quotaops.h> | 21 | #include <linux/quotaops.h> |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index ff1f7639707b..4ace5d72eae1 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/time.h> | 30 | #include <linux/time.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/backing-dev.h> | 33 | #include <linux/backing-dev.h> |
35 | #include <linux/ramfs.h> | 34 | #include <linux/ramfs.h> |
36 | 35 | ||
diff --git a/fs/read_write.c b/fs/read_write.c index 1f8dc373ede7..4d03008f015b 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -37,10 +37,10 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) | |||
37 | 37 | ||
38 | mutex_lock(&inode->i_mutex); | 38 | mutex_lock(&inode->i_mutex); |
39 | switch (origin) { | 39 | switch (origin) { |
40 | case 2: | 40 | case SEEK_END: |
41 | offset += inode->i_size; | 41 | offset += inode->i_size; |
42 | break; | 42 | break; |
43 | case 1: | 43 | case SEEK_CUR: |
44 | offset += file->f_pos; | 44 | offset += file->f_pos; |
45 | } | 45 | } |
46 | retval = -EINVAL; | 46 | retval = -EINVAL; |
@@ -63,10 +63,10 @@ loff_t remote_llseek(struct file *file, loff_t offset, int origin) | |||
63 | 63 | ||
64 | lock_kernel(); | 64 | lock_kernel(); |
65 | switch (origin) { | 65 | switch (origin) { |
66 | case 2: | 66 | case SEEK_END: |
67 | offset += i_size_read(file->f_path.dentry->d_inode); | 67 | offset += i_size_read(file->f_path.dentry->d_inode); |
68 | break; | 68 | break; |
69 | case 1: | 69 | case SEEK_CUR: |
70 | offset += file->f_pos; | 70 | offset += file->f_pos; |
71 | } | 71 | } |
72 | retval = -EINVAL; | 72 | retval = -EINVAL; |
@@ -94,10 +94,10 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin) | |||
94 | 94 | ||
95 | lock_kernel(); | 95 | lock_kernel(); |
96 | switch (origin) { | 96 | switch (origin) { |
97 | case 2: | 97 | case SEEK_END: |
98 | offset += i_size_read(file->f_path.dentry->d_inode); | 98 | offset += i_size_read(file->f_path.dentry->d_inode); |
99 | break; | 99 | break; |
100 | case 1: | 100 | case SEEK_CUR: |
101 | offset += file->f_pos; | 101 | offset += file->f_pos; |
102 | } | 102 | } |
103 | retval = -EINVAL; | 103 | retval = -EINVAL; |
@@ -139,7 +139,7 @@ asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) | |||
139 | goto bad; | 139 | goto bad; |
140 | 140 | ||
141 | retval = -EINVAL; | 141 | retval = -EINVAL; |
142 | if (origin <= 2) { | 142 | if (origin <= SEEK_MAX) { |
143 | loff_t res = vfs_llseek(file, offset, origin); | 143 | loff_t res = vfs_llseek(file, offset, origin); |
144 | retval = res; | 144 | retval = res; |
145 | if (res != (loff_t)retval) | 145 | if (res != (loff_t)retval) |
@@ -166,7 +166,7 @@ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, | |||
166 | goto bad; | 166 | goto bad; |
167 | 167 | ||
168 | retval = -EINVAL; | 168 | retval = -EINVAL; |
169 | if (origin > 2) | 169 | if (origin > SEEK_MAX) |
170 | goto out_putf; | 170 | goto out_putf; |
171 | 171 | ||
172 | offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, | 172 | offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, |
diff --git a/fs/readdir.c b/fs/readdir.c index f39f5b313252..efe52e676577 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -4,13 +4,13 @@ | |||
4 | * Copyright (C) 1995 Linus Torvalds | 4 | * Copyright (C) 1995 Linus Torvalds |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | 8 | #include <linux/module.h> |
8 | #include <linux/time.h> | 9 | #include <linux/time.h> |
9 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
10 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
11 | #include <linux/stat.h> | 12 | #include <linux/stat.h> |
12 | #include <linux/file.h> | 13 | #include <linux/file.h> |
13 | #include <linux/smp_lock.h> | ||
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/dirent.h> | 15 | #include <linux/dirent.h> |
16 | #include <linux/security.h> | 16 | #include <linux/security.h> |
@@ -52,7 +52,6 @@ EXPORT_SYMBOL(vfs_readdir); | |||
52 | * case (the low-level handlers don't need to care about this). | 52 | * case (the low-level handlers don't need to care about this). |
53 | */ | 53 | */ |
54 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) | 54 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) |
55 | #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) | ||
56 | 55 | ||
57 | #ifdef __ARCH_WANT_OLD_READDIR | 56 | #ifdef __ARCH_WANT_OLD_READDIR |
58 | 57 | ||
@@ -147,7 +146,7 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, | |||
147 | struct linux_dirent __user * dirent; | 146 | struct linux_dirent __user * dirent; |
148 | struct getdents_callback * buf = (struct getdents_callback *) __buf; | 147 | struct getdents_callback * buf = (struct getdents_callback *) __buf; |
149 | unsigned long d_ino; | 148 | unsigned long d_ino; |
150 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); | 149 | int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(long)); |
151 | 150 | ||
152 | buf->error = -EINVAL; /* only used if we fail.. */ | 151 | buf->error = -EINVAL; /* only used if we fail.. */ |
153 | if (reclen > buf->count) | 152 | if (reclen > buf->count) |
@@ -220,8 +219,6 @@ out: | |||
220 | return error; | 219 | return error; |
221 | } | 220 | } |
222 | 221 | ||
223 | #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) | ||
224 | |||
225 | struct getdents_callback64 { | 222 | struct getdents_callback64 { |
226 | struct linux_dirent64 __user * current_dir; | 223 | struct linux_dirent64 __user * current_dir; |
227 | struct linux_dirent64 __user * previous; | 224 | struct linux_dirent64 __user * previous; |
@@ -234,7 +231,7 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, | |||
234 | { | 231 | { |
235 | struct linux_dirent64 __user *dirent; | 232 | struct linux_dirent64 __user *dirent; |
236 | struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; | 233 | struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; |
237 | int reclen = ROUND_UP64(NAME_OFFSET(dirent) + namlen + 1); | 234 | int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(u64)); |
238 | 235 | ||
239 | buf->error = -EINVAL; /* only used if we fail.. */ | 236 | buf->error = -EINVAL; /* only used if we fail.. */ |
240 | if (reclen > buf->count) | 237 | if (reclen > buf->count) |
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 96a2f8889da3..9c23fee3bae9 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/fs.h> | 7 | #include <linux/fs.h> |
8 | #include <linux/reiserfs_fs.h> | 8 | #include <linux/reiserfs_fs.h> |
9 | #include <linux/stat.h> | 9 | #include <linux/stat.h> |
10 | #include <linux/smp_lock.h> | ||
11 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
12 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
13 | 12 | ||
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index abfada2f52db..ab45db529c80 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/reiserfs_fs.h> | 6 | #include <linux/reiserfs_fs.h> |
7 | #include <linux/reiserfs_acl.h> | 7 | #include <linux/reiserfs_acl.h> |
8 | #include <linux/reiserfs_xattr.h> | 8 | #include <linux/reiserfs_xattr.h> |
9 | #include <linux/smp_lock.h> | ||
10 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
11 | #include <linux/pagemap.h> | 10 | #include <linux/pagemap.h> |
12 | #include <linux/swap.h> | 11 | #include <linux/swap.h> |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 7280a23ef344..e073fd86cf60 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -2918,7 +2918,7 @@ static void queue_log_writer(struct super_block *s) | |||
2918 | set_current_state(TASK_UNINTERRUPTIBLE); | 2918 | set_current_state(TASK_UNINTERRUPTIBLE); |
2919 | if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) | 2919 | if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) |
2920 | schedule(); | 2920 | schedule(); |
2921 | current->state = TASK_RUNNING; | 2921 | __set_current_state(TASK_RUNNING); |
2922 | remove_wait_queue(&journal->j_join_wait, &wait); | 2922 | remove_wait_queue(&journal->j_join_wait, &wait); |
2923 | } | 2923 | } |
2924 | 2924 | ||
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index a2161840bc7c..b378eea332ca 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/reiserfs_fs.h> | 16 | #include <linux/reiserfs_fs.h> |
17 | #include <linux/reiserfs_acl.h> | 17 | #include <linux/reiserfs_acl.h> |
18 | #include <linux/reiserfs_xattr.h> | 18 | #include <linux/reiserfs_xattr.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/quotaops.h> | 19 | #include <linux/quotaops.h> |
21 | 20 | ||
22 | #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } | 21 | #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index ecc9943202fc..9aa7a06e093f 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -16,11 +16,10 @@ | |||
16 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
17 | #include <linux/reiserfs_fs.h> | 17 | #include <linux/reiserfs_fs.h> |
18 | #include <linux/reiserfs_fs_sb.h> | 18 | #include <linux/reiserfs_fs_sb.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
21 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
22 | 21 | ||
23 | #if defined( REISERFS_PROC_INFO ) | 22 | #ifdef CONFIG_REISERFS_PROC_INFO |
24 | 23 | ||
25 | /* | 24 | /* |
26 | * LOCKING: | 25 | * LOCKING: |
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 315684793d1d..976cc7887a0d 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c | |||
@@ -131,6 +131,10 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
131 | /* don't use read_bitmap_block since it will cache | 131 | /* don't use read_bitmap_block since it will cache |
132 | * the uninitialized bitmap */ | 132 | * the uninitialized bitmap */ |
133 | bh = sb_bread(s, i * s->s_blocksize * 8); | 133 | bh = sb_bread(s, i * s->s_blocksize * 8); |
134 | if (!bh) { | ||
135 | vfree(bitmap); | ||
136 | return -EIO; | ||
137 | } | ||
134 | memset(bh->b_data, 0, sb_blocksize(sb)); | 138 | memset(bh->b_data, 0, sb_blocksize(sb)); |
135 | reiserfs_test_and_set_le_bit(0, bh->b_data); | 139 | reiserfs_test_and_set_le_bit(0, bh->b_data); |
136 | reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); | 140 | reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); |
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index afb21ea45302..b6f12593c39d 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c | |||
@@ -53,7 +53,6 @@ | |||
53 | #include <linux/string.h> | 53 | #include <linux/string.h> |
54 | #include <linux/pagemap.h> | 54 | #include <linux/pagemap.h> |
55 | #include <linux/reiserfs_fs.h> | 55 | #include <linux/reiserfs_fs.h> |
56 | #include <linux/smp_lock.h> | ||
57 | #include <linux/buffer_head.h> | 56 | #include <linux/buffer_head.h> |
58 | #include <linux/quotaops.h> | 57 | #include <linux/quotaops.h> |
59 | 58 | ||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 7054aaef0493..c7762140c425 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/reiserfs_fs.h> | 18 | #include <linux/reiserfs_fs.h> |
19 | #include <linux/reiserfs_acl.h> | 19 | #include <linux/reiserfs_acl.h> |
20 | #include <linux/reiserfs_xattr.h> | 20 | #include <linux/reiserfs_xattr.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/init.h> | 21 | #include <linux/init.h> |
23 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
24 | #include <linux/buffer_head.h> | 23 | #include <linux/buffer_head.h> |
@@ -433,12 +432,13 @@ int remove_save_link(struct inode *inode, int truncate) | |||
433 | static void reiserfs_kill_sb(struct super_block *s) | 432 | static void reiserfs_kill_sb(struct super_block *s) |
434 | { | 433 | { |
435 | if (REISERFS_SB(s)) { | 434 | if (REISERFS_SB(s)) { |
435 | #ifdef CONFIG_REISERFS_FS_XATTR | ||
436 | if (REISERFS_SB(s)->xattr_root) { | 436 | if (REISERFS_SB(s)->xattr_root) { |
437 | d_invalidate(REISERFS_SB(s)->xattr_root); | 437 | d_invalidate(REISERFS_SB(s)->xattr_root); |
438 | dput(REISERFS_SB(s)->xattr_root); | 438 | dput(REISERFS_SB(s)->xattr_root); |
439 | REISERFS_SB(s)->xattr_root = NULL; | 439 | REISERFS_SB(s)->xattr_root = NULL; |
440 | } | 440 | } |
441 | 441 | #endif | |
442 | if (REISERFS_SB(s)->priv_root) { | 442 | if (REISERFS_SB(s)->priv_root) { |
443 | d_invalidate(REISERFS_SB(s)->priv_root); | 443 | d_invalidate(REISERFS_SB(s)->priv_root); |
444 | dput(REISERFS_SB(s)->priv_root); | 444 | dput(REISERFS_SB(s)->priv_root); |
@@ -1562,9 +1562,10 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1562 | REISERFS_SB(s)->s_alloc_options.preallocmin = 0; | 1562 | REISERFS_SB(s)->s_alloc_options.preallocmin = 0; |
1563 | /* Preallocate by 16 blocks (17-1) at once */ | 1563 | /* Preallocate by 16 blocks (17-1) at once */ |
1564 | REISERFS_SB(s)->s_alloc_options.preallocsize = 17; | 1564 | REISERFS_SB(s)->s_alloc_options.preallocsize = 17; |
1565 | #ifdef CONFIG_REISERFS_FS_XATTR | ||
1565 | /* Initialize the rwsem for xattr dir */ | 1566 | /* Initialize the rwsem for xattr dir */ |
1566 | init_rwsem(&REISERFS_SB(s)->xattr_dir_sem); | 1567 | init_rwsem(&REISERFS_SB(s)->xattr_dir_sem); |
1567 | 1568 | #endif | |
1568 | /* setup default block allocator options */ | 1569 | /* setup default block allocator options */ |
1569 | reiserfs_init_alloc_options(s); | 1570 | reiserfs_init_alloc_options(s); |
1570 | 1571 | ||
diff --git a/fs/select.c b/fs/select.c index fe0893afd931..d86224154dec 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -14,10 +14,10 @@ | |||
14 | * of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian). | 14 | * of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian). |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/kernel.h> | ||
17 | #include <linux/syscalls.h> | 18 | #include <linux/syscalls.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/poll.h> | 21 | #include <linux/poll.h> |
22 | #include <linux/personality.h> /* for STICKY_TIMEOUTS */ | 22 | #include <linux/personality.h> /* for STICKY_TIMEOUTS */ |
23 | #include <linux/file.h> | 23 | #include <linux/file.h> |
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
28 | 28 | ||
29 | #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) | ||
30 | #define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) | 29 | #define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) |
31 | 30 | ||
32 | struct poll_table_page { | 31 | struct poll_table_page { |
@@ -399,7 +398,7 @@ asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
399 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) | 398 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) |
400 | timeout = -1; /* infinite */ | 399 | timeout = -1; /* infinite */ |
401 | else { | 400 | else { |
402 | timeout = ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ); | 401 | timeout = DIV_ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ); |
403 | timeout += tv.tv_sec * HZ; | 402 | timeout += tv.tv_sec * HZ; |
404 | } | 403 | } |
405 | } | 404 | } |
@@ -454,7 +453,7 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp, | |||
454 | if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS) | 453 | if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS) |
455 | timeout = -1; /* infinite */ | 454 | timeout = -1; /* infinite */ |
456 | else { | 455 | else { |
457 | timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ); | 456 | timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ); |
458 | timeout += ts.tv_sec * HZ; | 457 | timeout += ts.tv_sec * HZ; |
459 | } | 458 | } |
460 | } | 459 | } |
@@ -776,7 +775,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, | |||
776 | if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS) | 775 | if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS) |
777 | timeout = -1; /* infinite */ | 776 | timeout = -1; /* infinite */ |
778 | else { | 777 | else { |
779 | timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ); | 778 | timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ); |
780 | timeout += ts.tv_sec * HZ; | 779 | timeout += ts.tv_sec * HZ; |
781 | } | 780 | } |
782 | } | 781 | } |
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c index 723f7c667661..c288fbe7953d 100644 --- a/fs/smbfs/request.c +++ b/fs/smbfs/request.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Please add a note about your changes to smbfs in the ChangeLog file. | 6 | * Please add a note about your changes to smbfs in the ChangeLog file. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/kernel.h> | ||
9 | #include <linux/types.h> | 10 | #include <linux/types.h> |
10 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
@@ -22,8 +23,6 @@ | |||
22 | /* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */ | 23 | /* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */ |
23 | #define SMB_SLAB_DEBUG 0 | 24 | #define SMB_SLAB_DEBUG 0 |
24 | 25 | ||
25 | #define ROUND_UP(x) (((x)+3) & ~3) | ||
26 | |||
27 | /* cache for request structures */ | 26 | /* cache for request structures */ |
28 | static struct kmem_cache *req_cachep; | 27 | static struct kmem_cache *req_cachep; |
29 | 28 | ||
@@ -200,8 +199,8 @@ static int smb_setup_trans2request(struct smb_request *req) | |||
200 | 199 | ||
201 | const int smb_parameters = 15; | 200 | const int smb_parameters = 15; |
202 | const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2; | 201 | const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2; |
203 | const int oparam = ROUND_UP(header + 3); | 202 | const int oparam = ALIGN(header + 3, sizeof(u32)); |
204 | const int odata = ROUND_UP(oparam + req->rq_lparm); | 203 | const int odata = ALIGN(oparam + req->rq_lparm, sizeof(u32)); |
205 | const int bcc = (req->rq_data ? odata + req->rq_ldata : | 204 | const int bcc = (req->rq_data ? odata + req->rq_ldata : |
206 | oparam + req->rq_lparm) - header; | 205 | oparam + req->rq_lparm) - header; |
207 | 206 | ||
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c index 89eaf31f1d46..67176af8515f 100644 --- a/fs/smbfs/smbiod.c +++ b/fs/smbfs/smbiod.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/file.h> | 17 | #include <linux/file.h> |
18 | #include <linux/dcache.h> | 18 | #include <linux/dcache.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
21 | #include <linux/net.h> | 20 | #include <linux/net.h> |
22 | #include <linux/kthread.h> | 21 | #include <linux/kthread.h> |
@@ -299,8 +298,6 @@ out: | |||
299 | */ | 298 | */ |
300 | static int smbiod(void *unused) | 299 | static int smbiod(void *unused) |
301 | { | 300 | { |
302 | allow_signal(SIGKILL); | ||
303 | |||
304 | VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid); | 301 | VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid); |
305 | 302 | ||
306 | for (;;) { | 303 | for (;;) { |
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index 92ea6b2367d7..e48bd8235a8e 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/net.h> | 17 | #include <linux/net.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
22 | #include <net/scm.h> | 21 | #include <net/scm.h> |
23 | #include <net/tcp_states.h> | 22 | #include <net/tcp_states.h> |
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c index fea20ceb8a5f..00b2909bd469 100644 --- a/fs/smbfs/symlink.c +++ b/fs/smbfs/symlink.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/pagemap.h> | 15 | #include <linux/pagemap.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/net.h> | 16 | #include <linux/net.h> |
18 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
19 | 18 | ||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
10 | #include <linux/file.h> | 10 | #include <linux/file.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/highuid.h> | 11 | #include <linux/highuid.h> |
13 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
14 | #include <linux/namei.h> | 13 | #include <linux/namei.h> |
diff --git a/fs/super.c b/fs/super.c index 8341e4e1d738..5260d620c555 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -107,6 +107,7 @@ out: | |||
107 | static inline void destroy_super(struct super_block *s) | 107 | static inline void destroy_super(struct super_block *s) |
108 | { | 108 | { |
109 | security_sb_free(s); | 109 | security_sb_free(s); |
110 | kfree(s->s_subtype); | ||
110 | kfree(s); | 111 | kfree(s); |
111 | } | 112 | } |
112 | 113 | ||
@@ -907,6 +908,29 @@ out: | |||
907 | 908 | ||
908 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | 909 | EXPORT_SYMBOL_GPL(vfs_kern_mount); |
909 | 910 | ||
911 | static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) | ||
912 | { | ||
913 | int err; | ||
914 | const char *subtype = strchr(fstype, '.'); | ||
915 | if (subtype) { | ||
916 | subtype++; | ||
917 | err = -EINVAL; | ||
918 | if (!subtype[0]) | ||
919 | goto err; | ||
920 | } else | ||
921 | subtype = ""; | ||
922 | |||
923 | mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL); | ||
924 | err = -ENOMEM; | ||
925 | if (!mnt->mnt_sb->s_subtype) | ||
926 | goto err; | ||
927 | return mnt; | ||
928 | |||
929 | err: | ||
930 | mntput(mnt); | ||
931 | return ERR_PTR(err); | ||
932 | } | ||
933 | |||
910 | struct vfsmount * | 934 | struct vfsmount * |
911 | do_kern_mount(const char *fstype, int flags, const char *name, void *data) | 935 | do_kern_mount(const char *fstype, int flags, const char *name, void *data) |
912 | { | 936 | { |
@@ -915,6 +939,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data) | |||
915 | if (!type) | 939 | if (!type) |
916 | return ERR_PTR(-ENODEV); | 940 | return ERR_PTR(-ENODEV); |
917 | mnt = vfs_kern_mount(type, flags, name, data); | 941 | mnt = vfs_kern_mount(type, flags, name, data); |
942 | if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && | ||
943 | !mnt->mnt_sb->s_subtype) | ||
944 | mnt = fs_set_subtype(mnt, fstype); | ||
918 | put_filesystem(type); | 945 | put_filesystem(type); |
919 | return mnt; | 946 | return mnt; |
920 | } | 947 | } |
@@ -229,7 +229,7 @@ asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | |||
229 | !S_ISLNK(i_mode)) | 229 | !S_ISLNK(i_mode)) |
230 | goto out_put; | 230 | goto out_put; |
231 | 231 | ||
232 | ret = do_sync_file_range(file, offset, endbyte, flags); | 232 | ret = do_sync_mapping_range(file->f_mapping, offset, endbyte, flags); |
233 | out_put: | 233 | out_put: |
234 | fput_light(file, fput_needed); | 234 | fput_light(file, fput_needed); |
235 | out: | 235 | out: |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 4e48abbd2b5d..6bd850b7641a 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -13,7 +13,6 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/pagemap.h> | 15 | #include <linux/pagemap.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include "sysv.h" | 16 | #include "sysv.h" |
18 | 17 | ||
19 | static int add_nondir(struct dentry *dentry, struct inode *inode) | 18 | static int add_nondir(struct dentry *dentry, struct inode *inode) |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index ea521f846d97..4cec91015681 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -427,9 +427,9 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
427 | { | 427 | { |
428 | struct udf_sb_info *sbi = UDF_SB(sb); | 428 | struct udf_sb_info *sbi = UDF_SB(sb); |
429 | uint32_t start, end; | 429 | uint32_t start, end; |
430 | uint32_t nextoffset, oextoffset, elen; | 430 | uint32_t elen; |
431 | kernel_lb_addr nbloc, obloc, eloc; | 431 | kernel_lb_addr eloc; |
432 | struct buffer_head *obh, *nbh; | 432 | struct extent_position oepos, epos; |
433 | int8_t etype; | 433 | int8_t etype; |
434 | int i; | 434 | int i; |
435 | 435 | ||
@@ -457,14 +457,13 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
457 | start = bloc.logicalBlockNum + offset; | 457 | start = bloc.logicalBlockNum + offset; |
458 | end = bloc.logicalBlockNum + offset + count - 1; | 458 | end = bloc.logicalBlockNum + offset + count - 1; |
459 | 459 | ||
460 | oextoffset = nextoffset = sizeof(struct unallocSpaceEntry); | 460 | epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry); |
461 | elen = 0; | 461 | elen = 0; |
462 | obloc = nbloc = UDF_I_LOCATION(table); | 462 | epos.block = oepos.block = UDF_I_LOCATION(table); |
463 | 463 | epos.bh = oepos.bh = NULL; | |
464 | obh = nbh = NULL; | ||
465 | 464 | ||
466 | while (count && (etype = | 465 | while (count && (etype = |
467 | udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) | 466 | udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
468 | { | 467 | { |
469 | if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == | 468 | if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == |
470 | start)) | 469 | start)) |
@@ -482,7 +481,7 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
482 | start += count; | 481 | start += count; |
483 | count = 0; | 482 | count = 0; |
484 | } | 483 | } |
485 | udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1); | 484 | udf_write_aext(table, &oepos, eloc, elen, 1); |
486 | } | 485 | } |
487 | else if (eloc.logicalBlockNum == (end + 1)) | 486 | else if (eloc.logicalBlockNum == (end + 1)) |
488 | { | 487 | { |
@@ -502,20 +501,20 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
502 | end -= count; | 501 | end -= count; |
503 | count = 0; | 502 | count = 0; |
504 | } | 503 | } |
505 | udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1); | 504 | udf_write_aext(table, &oepos, eloc, elen, 1); |
506 | } | 505 | } |
507 | 506 | ||
508 | if (nbh != obh) | 507 | if (epos.bh != oepos.bh) |
509 | { | 508 | { |
510 | i = -1; | 509 | i = -1; |
511 | obloc = nbloc; | 510 | oepos.block = epos.block; |
512 | udf_release_data(obh); | 511 | brelse(oepos.bh); |
513 | atomic_inc(&nbh->b_count); | 512 | get_bh(epos.bh); |
514 | obh = nbh; | 513 | oepos.bh = epos.bh; |
515 | oextoffset = 0; | 514 | oepos.offset = 0; |
516 | } | 515 | } |
517 | else | 516 | else |
518 | oextoffset = nextoffset; | 517 | oepos.offset = epos.offset; |
519 | } | 518 | } |
520 | 519 | ||
521 | if (count) | 520 | if (count) |
@@ -547,55 +546,53 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
547 | adsize = sizeof(long_ad); | 546 | adsize = sizeof(long_ad); |
548 | else | 547 | else |
549 | { | 548 | { |
550 | udf_release_data(obh); | 549 | brelse(oepos.bh); |
551 | udf_release_data(nbh); | 550 | brelse(epos.bh); |
552 | goto error_return; | 551 | goto error_return; |
553 | } | 552 | } |
554 | 553 | ||
555 | if (nextoffset + (2 * adsize) > sb->s_blocksize) | 554 | if (epos.offset + (2 * adsize) > sb->s_blocksize) |
556 | { | 555 | { |
557 | char *sptr, *dptr; | 556 | char *sptr, *dptr; |
558 | int loffset; | 557 | int loffset; |
559 | 558 | ||
560 | udf_release_data(obh); | 559 | brelse(oepos.bh); |
561 | obh = nbh; | 560 | oepos = epos; |
562 | obloc = nbloc; | ||
563 | oextoffset = nextoffset; | ||
564 | 561 | ||
565 | /* Steal a block from the extent being free'd */ | 562 | /* Steal a block from the extent being free'd */ |
566 | nbloc.logicalBlockNum = eloc.logicalBlockNum; | 563 | epos.block.logicalBlockNum = eloc.logicalBlockNum; |
567 | eloc.logicalBlockNum ++; | 564 | eloc.logicalBlockNum ++; |
568 | elen -= sb->s_blocksize; | 565 | elen -= sb->s_blocksize; |
569 | 566 | ||
570 | if (!(nbh = udf_tread(sb, | 567 | if (!(epos.bh = udf_tread(sb, |
571 | udf_get_lb_pblock(sb, nbloc, 0)))) | 568 | udf_get_lb_pblock(sb, epos.block, 0)))) |
572 | { | 569 | { |
573 | udf_release_data(obh); | 570 | brelse(oepos.bh); |
574 | goto error_return; | 571 | goto error_return; |
575 | } | 572 | } |
576 | aed = (struct allocExtDesc *)(nbh->b_data); | 573 | aed = (struct allocExtDesc *)(epos.bh->b_data); |
577 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); | 574 | aed->previousAllocExtLocation = cpu_to_le32(oepos.block.logicalBlockNum); |
578 | if (nextoffset + adsize > sb->s_blocksize) | 575 | if (epos.offset + adsize > sb->s_blocksize) |
579 | { | 576 | { |
580 | loffset = nextoffset; | 577 | loffset = epos.offset; |
581 | aed->lengthAllocDescs = cpu_to_le32(adsize); | 578 | aed->lengthAllocDescs = cpu_to_le32(adsize); |
582 | sptr = UDF_I_DATA(inode) + nextoffset - | 579 | sptr = UDF_I_DATA(inode) + epos.offset - |
583 | udf_file_entry_alloc_offset(inode) + | 580 | udf_file_entry_alloc_offset(inode) + |
584 | UDF_I_LENEATTR(inode) - adsize; | 581 | UDF_I_LENEATTR(inode) - adsize; |
585 | dptr = nbh->b_data + sizeof(struct allocExtDesc); | 582 | dptr = epos.bh->b_data + sizeof(struct allocExtDesc); |
586 | memcpy(dptr, sptr, adsize); | 583 | memcpy(dptr, sptr, adsize); |
587 | nextoffset = sizeof(struct allocExtDesc) + adsize; | 584 | epos.offset = sizeof(struct allocExtDesc) + adsize; |
588 | } | 585 | } |
589 | else | 586 | else |
590 | { | 587 | { |
591 | loffset = nextoffset + adsize; | 588 | loffset = epos.offset + adsize; |
592 | aed->lengthAllocDescs = cpu_to_le32(0); | 589 | aed->lengthAllocDescs = cpu_to_le32(0); |
593 | sptr = (obh)->b_data + nextoffset; | 590 | sptr = oepos.bh->b_data + epos.offset; |
594 | nextoffset = sizeof(struct allocExtDesc); | 591 | epos.offset = sizeof(struct allocExtDesc); |
595 | 592 | ||
596 | if (obh) | 593 | if (oepos.bh) |
597 | { | 594 | { |
598 | aed = (struct allocExtDesc *)(obh)->b_data; | 595 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
599 | aed->lengthAllocDescs = | 596 | aed->lengthAllocDescs = |
600 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 597 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
601 | } | 598 | } |
@@ -606,11 +603,11 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
606 | } | 603 | } |
607 | } | 604 | } |
608 | if (UDF_SB_UDFREV(sb) >= 0x0200) | 605 | if (UDF_SB_UDFREV(sb) >= 0x0200) |
609 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, | 606 | udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1, |
610 | nbloc.logicalBlockNum, sizeof(tag)); | 607 | epos.block.logicalBlockNum, sizeof(tag)); |
611 | else | 608 | else |
612 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, | 609 | udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1, |
613 | nbloc.logicalBlockNum, sizeof(tag)); | 610 | epos.block.logicalBlockNum, sizeof(tag)); |
614 | switch (UDF_I_ALLOCTYPE(table)) | 611 | switch (UDF_I_ALLOCTYPE(table)) |
615 | { | 612 | { |
616 | case ICBTAG_FLAG_AD_SHORT: | 613 | case ICBTAG_FLAG_AD_SHORT: |
@@ -619,7 +616,7 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
619 | sad->extLength = cpu_to_le32( | 616 | sad->extLength = cpu_to_le32( |
620 | EXT_NEXT_EXTENT_ALLOCDECS | | 617 | EXT_NEXT_EXTENT_ALLOCDECS | |
621 | sb->s_blocksize); | 618 | sb->s_blocksize); |
622 | sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum); | 619 | sad->extPosition = cpu_to_le32(epos.block.logicalBlockNum); |
623 | break; | 620 | break; |
624 | } | 621 | } |
625 | case ICBTAG_FLAG_AD_LONG: | 622 | case ICBTAG_FLAG_AD_LONG: |
@@ -628,14 +625,14 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
628 | lad->extLength = cpu_to_le32( | 625 | lad->extLength = cpu_to_le32( |
629 | EXT_NEXT_EXTENT_ALLOCDECS | | 626 | EXT_NEXT_EXTENT_ALLOCDECS | |
630 | sb->s_blocksize); | 627 | sb->s_blocksize); |
631 | lad->extLocation = cpu_to_lelb(nbloc); | 628 | lad->extLocation = cpu_to_lelb(epos.block); |
632 | break; | 629 | break; |
633 | } | 630 | } |
634 | } | 631 | } |
635 | if (obh) | 632 | if (oepos.bh) |
636 | { | 633 | { |
637 | udf_update_tag(obh->b_data, loffset); | 634 | udf_update_tag(oepos.bh->b_data, loffset); |
638 | mark_buffer_dirty(obh); | 635 | mark_buffer_dirty(oepos.bh); |
639 | } | 636 | } |
640 | else | 637 | else |
641 | mark_inode_dirty(table); | 638 | mark_inode_dirty(table); |
@@ -643,26 +640,26 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
643 | 640 | ||
644 | if (elen) /* It's possible that stealing the block emptied the extent */ | 641 | if (elen) /* It's possible that stealing the block emptied the extent */ |
645 | { | 642 | { |
646 | udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1); | 643 | udf_write_aext(table, &epos, eloc, elen, 1); |
647 | 644 | ||
648 | if (!nbh) | 645 | if (!epos.bh) |
649 | { | 646 | { |
650 | UDF_I_LENALLOC(table) += adsize; | 647 | UDF_I_LENALLOC(table) += adsize; |
651 | mark_inode_dirty(table); | 648 | mark_inode_dirty(table); |
652 | } | 649 | } |
653 | else | 650 | else |
654 | { | 651 | { |
655 | aed = (struct allocExtDesc *)nbh->b_data; | 652 | aed = (struct allocExtDesc *)epos.bh->b_data; |
656 | aed->lengthAllocDescs = | 653 | aed->lengthAllocDescs = |
657 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 654 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
658 | udf_update_tag(nbh->b_data, nextoffset); | 655 | udf_update_tag(epos.bh->b_data, epos.offset); |
659 | mark_buffer_dirty(nbh); | 656 | mark_buffer_dirty(epos.bh); |
660 | } | 657 | } |
661 | } | 658 | } |
662 | } | 659 | } |
663 | 660 | ||
664 | udf_release_data(nbh); | 661 | brelse(epos.bh); |
665 | udf_release_data(obh); | 662 | brelse(oepos.bh); |
666 | 663 | ||
667 | error_return: | 664 | error_return: |
668 | sb->s_dirt = 1; | 665 | sb->s_dirt = 1; |
@@ -677,9 +674,9 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
677 | { | 674 | { |
678 | struct udf_sb_info *sbi = UDF_SB(sb); | 675 | struct udf_sb_info *sbi = UDF_SB(sb); |
679 | int alloc_count = 0; | 676 | int alloc_count = 0; |
680 | uint32_t extoffset, elen, adsize; | 677 | uint32_t elen, adsize; |
681 | kernel_lb_addr bloc, eloc; | 678 | kernel_lb_addr eloc; |
682 | struct buffer_head *bh; | 679 | struct extent_position epos; |
683 | int8_t etype = -1; | 680 | int8_t etype = -1; |
684 | 681 | ||
685 | if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) | 682 | if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) |
@@ -693,14 +690,13 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
693 | return 0; | 690 | return 0; |
694 | 691 | ||
695 | mutex_lock(&sbi->s_alloc_mutex); | 692 | mutex_lock(&sbi->s_alloc_mutex); |
696 | extoffset = sizeof(struct unallocSpaceEntry); | 693 | epos.offset = sizeof(struct unallocSpaceEntry); |
697 | bloc = UDF_I_LOCATION(table); | 694 | epos.block = UDF_I_LOCATION(table); |
698 | 695 | epos.bh = NULL; | |
699 | bh = NULL; | ||
700 | eloc.logicalBlockNum = 0xFFFFFFFF; | 696 | eloc.logicalBlockNum = 0xFFFFFFFF; |
701 | 697 | ||
702 | while (first_block != eloc.logicalBlockNum && (etype = | 698 | while (first_block != eloc.logicalBlockNum && (etype = |
703 | udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 699 | udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
704 | { | 700 | { |
705 | udf_debug("eloc=%d, elen=%d, first_block=%d\n", | 701 | udf_debug("eloc=%d, elen=%d, first_block=%d\n", |
706 | eloc.logicalBlockNum, elen, first_block); | 702 | eloc.logicalBlockNum, elen, first_block); |
@@ -709,7 +705,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
709 | 705 | ||
710 | if (first_block == eloc.logicalBlockNum) | 706 | if (first_block == eloc.logicalBlockNum) |
711 | { | 707 | { |
712 | extoffset -= adsize; | 708 | epos.offset -= adsize; |
713 | 709 | ||
714 | alloc_count = (elen >> sb->s_blocksize_bits); | 710 | alloc_count = (elen >> sb->s_blocksize_bits); |
715 | if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) | 711 | if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) |
@@ -719,15 +715,15 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
719 | alloc_count = block_count; | 715 | alloc_count = block_count; |
720 | eloc.logicalBlockNum += alloc_count; | 716 | eloc.logicalBlockNum += alloc_count; |
721 | elen -= (alloc_count << sb->s_blocksize_bits); | 717 | elen -= (alloc_count << sb->s_blocksize_bits); |
722 | udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1); | 718 | udf_write_aext(table, &epos, eloc, (etype << 30) | elen, 1); |
723 | } | 719 | } |
724 | else | 720 | else |
725 | udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh); | 721 | udf_delete_aext(table, epos, eloc, (etype << 30) | elen); |
726 | } | 722 | } |
727 | else | 723 | else |
728 | alloc_count = 0; | 724 | alloc_count = 0; |
729 | 725 | ||
730 | udf_release_data(bh); | 726 | brelse(epos.bh); |
731 | 727 | ||
732 | if (alloc_count && UDF_SB_LVIDBH(sb)) | 728 | if (alloc_count && UDF_SB_LVIDBH(sb)) |
733 | { | 729 | { |
@@ -747,9 +743,9 @@ static int udf_table_new_block(struct super_block * sb, | |||
747 | struct udf_sb_info *sbi = UDF_SB(sb); | 743 | struct udf_sb_info *sbi = UDF_SB(sb); |
748 | uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; | 744 | uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; |
749 | uint32_t newblock = 0, adsize; | 745 | uint32_t newblock = 0, adsize; |
750 | uint32_t extoffset, goal_extoffset, elen, goal_elen = 0; | 746 | uint32_t elen, goal_elen = 0; |
751 | kernel_lb_addr bloc, goal_bloc, eloc, goal_eloc; | 747 | kernel_lb_addr eloc, goal_eloc; |
752 | struct buffer_head *bh, *goal_bh; | 748 | struct extent_position epos, goal_epos; |
753 | int8_t etype; | 749 | int8_t etype; |
754 | 750 | ||
755 | *err = -ENOSPC; | 751 | *err = -ENOSPC; |
@@ -770,14 +766,12 @@ static int udf_table_new_block(struct super_block * sb, | |||
770 | We store the buffer_head, bloc, and extoffset of the current closest | 766 | We store the buffer_head, bloc, and extoffset of the current closest |
771 | match and use that when we are done. | 767 | match and use that when we are done. |
772 | */ | 768 | */ |
773 | 769 | epos.offset = sizeof(struct unallocSpaceEntry); | |
774 | extoffset = sizeof(struct unallocSpaceEntry); | 770 | epos.block = UDF_I_LOCATION(table); |
775 | bloc = UDF_I_LOCATION(table); | 771 | epos.bh = goal_epos.bh = NULL; |
776 | |||
777 | goal_bh = bh = NULL; | ||
778 | 772 | ||
779 | while (spread && (etype = | 773 | while (spread && (etype = |
780 | udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 774 | udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
781 | { | 775 | { |
782 | if (goal >= eloc.logicalBlockNum) | 776 | if (goal >= eloc.logicalBlockNum) |
783 | { | 777 | { |
@@ -793,24 +787,24 @@ static int udf_table_new_block(struct super_block * sb, | |||
793 | if (nspread < spread) | 787 | if (nspread < spread) |
794 | { | 788 | { |
795 | spread = nspread; | 789 | spread = nspread; |
796 | if (goal_bh != bh) | 790 | if (goal_epos.bh != epos.bh) |
797 | { | 791 | { |
798 | udf_release_data(goal_bh); | 792 | brelse(goal_epos.bh); |
799 | goal_bh = bh; | 793 | goal_epos.bh = epos.bh; |
800 | atomic_inc(&goal_bh->b_count); | 794 | get_bh(goal_epos.bh); |
801 | } | 795 | } |
802 | goal_bloc = bloc; | 796 | goal_epos.block = epos.block; |
803 | goal_extoffset = extoffset - adsize; | 797 | goal_epos.offset = epos.offset - adsize; |
804 | goal_eloc = eloc; | 798 | goal_eloc = eloc; |
805 | goal_elen = (etype << 30) | elen; | 799 | goal_elen = (etype << 30) | elen; |
806 | } | 800 | } |
807 | } | 801 | } |
808 | 802 | ||
809 | udf_release_data(bh); | 803 | brelse(epos.bh); |
810 | 804 | ||
811 | if (spread == 0xFFFFFFFF) | 805 | if (spread == 0xFFFFFFFF) |
812 | { | 806 | { |
813 | udf_release_data(goal_bh); | 807 | brelse(goal_epos.bh); |
814 | mutex_unlock(&sbi->s_alloc_mutex); | 808 | mutex_unlock(&sbi->s_alloc_mutex); |
815 | return 0; | 809 | return 0; |
816 | } | 810 | } |
@@ -826,17 +820,17 @@ static int udf_table_new_block(struct super_block * sb, | |||
826 | 820 | ||
827 | if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) | 821 | if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) |
828 | { | 822 | { |
829 | udf_release_data(goal_bh); | 823 | brelse(goal_epos.bh); |
830 | mutex_unlock(&sbi->s_alloc_mutex); | 824 | mutex_unlock(&sbi->s_alloc_mutex); |
831 | *err = -EDQUOT; | 825 | *err = -EDQUOT; |
832 | return 0; | 826 | return 0; |
833 | } | 827 | } |
834 | 828 | ||
835 | if (goal_elen) | 829 | if (goal_elen) |
836 | udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1); | 830 | udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1); |
837 | else | 831 | else |
838 | udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh); | 832 | udf_delete_aext(table, goal_epos, goal_eloc, goal_elen); |
839 | udf_release_data(goal_bh); | 833 | brelse(goal_epos.bh); |
840 | 834 | ||
841 | if (UDF_SB_LVIDBH(sb)) | 835 | if (UDF_SB_LVIDBH(sb)) |
842 | { | 836 | { |
@@ -921,11 +915,14 @@ inline int udf_new_block(struct super_block * sb, | |||
921 | struct inode * inode, | 915 | struct inode * inode, |
922 | uint16_t partition, uint32_t goal, int *err) | 916 | uint16_t partition, uint32_t goal, int *err) |
923 | { | 917 | { |
918 | int ret; | ||
919 | |||
924 | if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) | 920 | if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) |
925 | { | 921 | { |
926 | return udf_bitmap_new_block(sb, inode, | 922 | ret = udf_bitmap_new_block(sb, inode, |
927 | UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap, | 923 | UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap, |
928 | partition, goal, err); | 924 | partition, goal, err); |
925 | return ret; | ||
929 | } | 926 | } |
930 | else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) | 927 | else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) |
931 | { | 928 | { |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 2391c9150c49..e45f86b5e7b0 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -111,11 +111,13 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
111 | uint16_t liu; | 111 | uint16_t liu; |
112 | uint8_t lfi; | 112 | uint8_t lfi; |
113 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 113 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; |
114 | struct buffer_head * bh = NULL, * tmp, * bha[16]; | 114 | struct buffer_head *tmp, *bha[16]; |
115 | kernel_lb_addr bloc, eloc; | 115 | kernel_lb_addr eloc; |
116 | uint32_t extoffset, elen, offset; | 116 | uint32_t elen; |
117 | sector_t offset; | ||
117 | int i, num; | 118 | int i, num; |
118 | unsigned int dt_type; | 119 | unsigned int dt_type; |
120 | struct extent_position epos = { NULL, 0, {0, 0}}; | ||
119 | 121 | ||
120 | if (nf_pos >= size) | 122 | if (nf_pos >= size) |
121 | return 0; | 123 | return 0; |
@@ -127,23 +129,22 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
127 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 129 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
128 | fibh.sbh = fibh.ebh = NULL; | 130 | fibh.sbh = fibh.ebh = NULL; |
129 | else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), | 131 | else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), |
130 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 132 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
131 | { | 133 | { |
132 | offset >>= dir->i_sb->s_blocksize_bits; | ||
133 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 134 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
134 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 135 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
135 | { | 136 | { |
136 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 137 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
137 | extoffset -= sizeof(short_ad); | 138 | epos.offset -= sizeof(short_ad); |
138 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 139 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
139 | extoffset -= sizeof(long_ad); | 140 | epos.offset -= sizeof(long_ad); |
140 | } | 141 | } |
141 | else | 142 | else |
142 | offset = 0; | 143 | offset = 0; |
143 | 144 | ||
144 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) | 145 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) |
145 | { | 146 | { |
146 | udf_release_data(bh); | 147 | brelse(epos.bh); |
147 | return -EIO; | 148 | return -EIO; |
148 | } | 149 | } |
149 | 150 | ||
@@ -171,7 +172,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
171 | } | 172 | } |
172 | else | 173 | else |
173 | { | 174 | { |
174 | udf_release_data(bh); | 175 | brelse(epos.bh); |
175 | return -ENOENT; | 176 | return -ENOENT; |
176 | } | 177 | } |
177 | 178 | ||
@@ -179,14 +180,14 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
179 | { | 180 | { |
180 | filp->f_pos = nf_pos + 1; | 181 | filp->f_pos = nf_pos + 1; |
181 | 182 | ||
182 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 183 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); |
183 | 184 | ||
184 | if (!fi) | 185 | if (!fi) |
185 | { | 186 | { |
186 | if (fibh.sbh != fibh.ebh) | 187 | if (fibh.sbh != fibh.ebh) |
187 | udf_release_data(fibh.ebh); | 188 | brelse(fibh.ebh); |
188 | udf_release_data(fibh.sbh); | 189 | brelse(fibh.sbh); |
189 | udf_release_data(bh); | 190 | brelse(epos.bh); |
190 | return 0; | 191 | return 0; |
191 | } | 192 | } |
192 | 193 | ||
@@ -244,9 +245,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
244 | if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) | 245 | if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) |
245 | { | 246 | { |
246 | if (fibh.sbh != fibh.ebh) | 247 | if (fibh.sbh != fibh.ebh) |
247 | udf_release_data(fibh.ebh); | 248 | brelse(fibh.ebh); |
248 | udf_release_data(fibh.sbh); | 249 | brelse(fibh.sbh); |
249 | udf_release_data(bh); | 250 | brelse(epos.bh); |
250 | return 0; | 251 | return 0; |
251 | } | 252 | } |
252 | } | 253 | } |
@@ -255,9 +256,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
255 | filp->f_pos = nf_pos + 1; | 256 | filp->f_pos = nf_pos + 1; |
256 | 257 | ||
257 | if (fibh.sbh != fibh.ebh) | 258 | if (fibh.sbh != fibh.ebh) |
258 | udf_release_data(fibh.ebh); | 259 | brelse(fibh.ebh); |
259 | udf_release_data(fibh.sbh); | 260 | brelse(fibh.sbh); |
260 | udf_release_data(bh); | 261 | brelse(epos.bh); |
261 | 262 | ||
262 | return 0; | 263 | return 0; |
263 | } | 264 | } |
diff --git a/fs/udf/directory.c b/fs/udf/directory.c index fe751a2a0e47..198caa33027a 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c | |||
@@ -36,14 +36,14 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, | |||
36 | 36 | ||
37 | if (!ad) | 37 | if (!ad) |
38 | { | 38 | { |
39 | udf_release_data(*bh); | 39 | brelse(*bh); |
40 | *error = 1; | 40 | *error = 1; |
41 | return NULL; | 41 | return NULL; |
42 | } | 42 | } |
43 | 43 | ||
44 | if (*offset == dir->i_sb->s_blocksize) | 44 | if (*offset == dir->i_sb->s_blocksize) |
45 | { | 45 | { |
46 | udf_release_data(*bh); | 46 | brelse(*bh); |
47 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); | 47 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); |
48 | if (!block) | 48 | if (!block) |
49 | return NULL; | 49 | return NULL; |
@@ -57,7 +57,7 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, | |||
57 | remainder = dir->i_sb->s_blocksize - loffset; | 57 | remainder = dir->i_sb->s_blocksize - loffset; |
58 | memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder); | 58 | memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder); |
59 | 59 | ||
60 | udf_release_data(*bh); | 60 | brelse(*bh); |
61 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); | 61 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); |
62 | if (!block) | 62 | if (!block) |
63 | return NULL; | 63 | return NULL; |
@@ -75,9 +75,9 @@ struct fileIdentDesc * | |||
75 | udf_fileident_read(struct inode *dir, loff_t *nf_pos, | 75 | udf_fileident_read(struct inode *dir, loff_t *nf_pos, |
76 | struct udf_fileident_bh *fibh, | 76 | struct udf_fileident_bh *fibh, |
77 | struct fileIdentDesc *cfi, | 77 | struct fileIdentDesc *cfi, |
78 | kernel_lb_addr *bloc, uint32_t *extoffset, | 78 | struct extent_position *epos, |
79 | kernel_lb_addr *eloc, uint32_t *elen, | 79 | kernel_lb_addr *eloc, uint32_t *elen, |
80 | uint32_t *offset, struct buffer_head **bh) | 80 | sector_t *offset) |
81 | { | 81 | { |
82 | struct fileIdentDesc *fi; | 82 | struct fileIdentDesc *fi; |
83 | int i, num, block; | 83 | int i, num, block; |
@@ -105,13 +105,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
105 | 105 | ||
106 | if (fibh->eoffset == dir->i_sb->s_blocksize) | 106 | if (fibh->eoffset == dir->i_sb->s_blocksize) |
107 | { | 107 | { |
108 | int lextoffset = *extoffset; | 108 | int lextoffset = epos->offset; |
109 | 109 | ||
110 | if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) != | 110 | if (udf_next_aext(dir, epos, eloc, elen, 1) != |
111 | (EXT_RECORDED_ALLOCATED >> 30)) | 111 | (EXT_RECORDED_ALLOCATED >> 30)) |
112 | { | ||
113 | return NULL; | 112 | return NULL; |
114 | } | ||
115 | 113 | ||
116 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); | 114 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); |
117 | 115 | ||
@@ -120,9 +118,9 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
120 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) | 118 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) |
121 | *offset = 0; | 119 | *offset = 0; |
122 | else | 120 | else |
123 | *extoffset = lextoffset; | 121 | epos->offset = lextoffset; |
124 | 122 | ||
125 | udf_release_data(fibh->sbh); | 123 | brelse(fibh->sbh); |
126 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) | 124 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) |
127 | return NULL; | 125 | return NULL; |
128 | fibh->soffset = fibh->eoffset = 0; | 126 | fibh->soffset = fibh->eoffset = 0; |
@@ -151,7 +149,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
151 | } | 149 | } |
152 | else if (fibh->sbh != fibh->ebh) | 150 | else if (fibh->sbh != fibh->ebh) |
153 | { | 151 | { |
154 | udf_release_data(fibh->sbh); | 152 | brelse(fibh->sbh); |
155 | fibh->sbh = fibh->ebh; | 153 | fibh->sbh = fibh->ebh; |
156 | } | 154 | } |
157 | 155 | ||
@@ -169,13 +167,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
169 | } | 167 | } |
170 | else if (fibh->eoffset > dir->i_sb->s_blocksize) | 168 | else if (fibh->eoffset > dir->i_sb->s_blocksize) |
171 | { | 169 | { |
172 | int lextoffset = *extoffset; | 170 | int lextoffset = epos->offset; |
173 | 171 | ||
174 | if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) != | 172 | if (udf_next_aext(dir, epos, eloc, elen, 1) != |
175 | (EXT_RECORDED_ALLOCATED >> 30)) | 173 | (EXT_RECORDED_ALLOCATED >> 30)) |
176 | { | ||
177 | return NULL; | 174 | return NULL; |
178 | } | ||
179 | 175 | ||
180 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); | 176 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); |
181 | 177 | ||
@@ -184,7 +180,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
184 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) | 180 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) |
185 | *offset = 0; | 181 | *offset = 0; |
186 | else | 182 | else |
187 | *extoffset = lextoffset; | 183 | epos->offset = lextoffset; |
188 | 184 | ||
189 | fibh->soffset -= dir->i_sb->s_blocksize; | 185 | fibh->soffset -= dir->i_sb->s_blocksize; |
190 | fibh->eoffset -= dir->i_sb->s_blocksize; | 186 | fibh->eoffset -= dir->i_sb->s_blocksize; |
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c index 5887d78cde43..6ded93e7c44f 100644 --- a/fs/udf/fsync.c +++ b/fs/udf/fsync.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "udfdecl.h" | 21 | #include "udfdecl.h" |
22 | 22 | ||
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/smp_lock.h> | ||
25 | 24 | ||
26 | static int udf_fsync_inode(struct inode *, int); | 25 | static int udf_fsync_inode(struct inode *, int); |
27 | 26 | ||
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index ae21a0e59e95..c8461551e108 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -49,10 +49,10 @@ MODULE_LICENSE("GPL"); | |||
49 | static mode_t udf_convert_permissions(struct fileEntry *); | 49 | static mode_t udf_convert_permissions(struct fileEntry *); |
50 | static int udf_update_inode(struct inode *, int); | 50 | static int udf_update_inode(struct inode *, int); |
51 | static void udf_fill_inode(struct inode *, struct buffer_head *); | 51 | static void udf_fill_inode(struct inode *, struct buffer_head *); |
52 | static struct buffer_head *inode_getblk(struct inode *, long, int *, | 52 | static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, |
53 | long *, int *); | 53 | long *, int *); |
54 | static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int, | 54 | static int8_t udf_insert_aext(struct inode *, struct extent_position, |
55 | kernel_lb_addr, uint32_t, struct buffer_head *); | 55 | kernel_lb_addr, uint32_t); |
56 | static void udf_split_extents(struct inode *, int *, int, int, | 56 | static void udf_split_extents(struct inode *, int *, int, int, |
57 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); | 57 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
58 | static void udf_prealloc_extents(struct inode *, int, int, | 58 | static void udf_prealloc_extents(struct inode *, int, int, |
@@ -61,7 +61,7 @@ static void udf_merge_extents(struct inode *, | |||
61 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); | 61 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
62 | static void udf_update_extents(struct inode *, | 62 | static void udf_update_extents(struct inode *, |
63 | kernel_long_ad [EXTENT_MERGE_SIZE], int, int, | 63 | kernel_long_ad [EXTENT_MERGE_SIZE], int, int, |
64 | kernel_lb_addr, uint32_t, struct buffer_head **); | 64 | struct extent_position *); |
65 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | 65 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
66 | 66 | ||
67 | /* | 67 | /* |
@@ -194,10 +194,11 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) | |||
194 | struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) | 194 | struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) |
195 | { | 195 | { |
196 | int newblock; | 196 | int newblock; |
197 | struct buffer_head *sbh = NULL, *dbh = NULL; | 197 | struct buffer_head *dbh = NULL; |
198 | kernel_lb_addr bloc, eloc; | 198 | kernel_lb_addr eloc; |
199 | uint32_t elen, extoffset; | 199 | uint32_t elen; |
200 | uint8_t alloctype; | 200 | uint8_t alloctype; |
201 | struct extent_position epos; | ||
201 | 202 | ||
202 | struct udf_fileident_bh sfibh, dfibh; | 203 | struct udf_fileident_bh sfibh, dfibh; |
203 | loff_t f_pos = udf_ext0_offset(inode) >> 2; | 204 | loff_t f_pos = udf_ext0_offset(inode) >> 2; |
@@ -237,16 +238,16 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int | |||
237 | mark_buffer_dirty_inode(dbh, inode); | 238 | mark_buffer_dirty_inode(dbh, inode); |
238 | 239 | ||
239 | sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; | 240 | sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; |
240 | sbh = sfibh.sbh = sfibh.ebh = NULL; | 241 | sfibh.sbh = sfibh.ebh = NULL; |
241 | dfibh.soffset = dfibh.eoffset = 0; | 242 | dfibh.soffset = dfibh.eoffset = 0; |
242 | dfibh.sbh = dfibh.ebh = dbh; | 243 | dfibh.sbh = dfibh.ebh = dbh; |
243 | while ( (f_pos < size) ) | 244 | while ( (f_pos < size) ) |
244 | { | 245 | { |
245 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; | 246 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
246 | sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL); | 247 | sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); |
247 | if (!sfi) | 248 | if (!sfi) |
248 | { | 249 | { |
249 | udf_release_data(dbh); | 250 | brelse(dbh); |
250 | return NULL; | 251 | return NULL; |
251 | } | 252 | } |
252 | UDF_I_ALLOCTYPE(inode) = alloctype; | 253 | UDF_I_ALLOCTYPE(inode) = alloctype; |
@@ -258,7 +259,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int | |||
258 | sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) | 259 | sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) |
259 | { | 260 | { |
260 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; | 261 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
261 | udf_release_data(dbh); | 262 | brelse(dbh); |
262 | return NULL; | 263 | return NULL; |
263 | } | 264 | } |
264 | } | 265 | } |
@@ -266,16 +267,17 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int | |||
266 | 267 | ||
267 | memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); | 268 | memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); |
268 | UDF_I_LENALLOC(inode) = 0; | 269 | UDF_I_LENALLOC(inode) = 0; |
269 | bloc = UDF_I_LOCATION(inode); | ||
270 | eloc.logicalBlockNum = *block; | 270 | eloc.logicalBlockNum = *block; |
271 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; | 271 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; |
272 | elen = inode->i_size; | 272 | elen = inode->i_size; |
273 | UDF_I_LENEXTENTS(inode) = elen; | 273 | UDF_I_LENEXTENTS(inode) = elen; |
274 | extoffset = udf_file_entry_alloc_offset(inode); | 274 | epos.bh = NULL; |
275 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0); | 275 | epos.block = UDF_I_LOCATION(inode); |
276 | epos.offset = udf_file_entry_alloc_offset(inode); | ||
277 | udf_add_aext(inode, &epos, eloc, elen, 0); | ||
276 | /* UniqueID stuff */ | 278 | /* UniqueID stuff */ |
277 | 279 | ||
278 | udf_release_data(sbh); | 280 | brelse(epos.bh); |
279 | mark_inode_dirty(inode); | 281 | mark_inode_dirty(inode); |
280 | return dbh; | 282 | return dbh; |
281 | } | 283 | } |
@@ -354,53 +356,153 @@ udf_getblk(struct inode *inode, long block, int create, int *err) | |||
354 | return NULL; | 356 | return NULL; |
355 | } | 357 | } |
356 | 358 | ||
357 | static struct buffer_head * inode_getblk(struct inode * inode, long block, | 359 | /* Extend the file by 'blocks' blocks, return the number of extents added */ |
360 | int udf_extend_file(struct inode *inode, struct extent_position *last_pos, | ||
361 | kernel_long_ad *last_ext, sector_t blocks) | ||
362 | { | ||
363 | sector_t add; | ||
364 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); | ||
365 | struct super_block *sb = inode->i_sb; | ||
366 | kernel_lb_addr prealloc_loc = {0, 0}; | ||
367 | int prealloc_len = 0; | ||
368 | |||
369 | /* The previous extent is fake and we should not extend by anything | ||
370 | * - there's nothing to do... */ | ||
371 | if (!blocks && fake) | ||
372 | return 0; | ||
373 | /* Round the last extent up to a multiple of block size */ | ||
374 | if (last_ext->extLength & (sb->s_blocksize - 1)) { | ||
375 | last_ext->extLength = | ||
376 | (last_ext->extLength & UDF_EXTENT_FLAG_MASK) | | ||
377 | (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) + | ||
378 | sb->s_blocksize - 1) & ~(sb->s_blocksize - 1)); | ||
379 | UDF_I_LENEXTENTS(inode) = | ||
380 | (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) & | ||
381 | ~(sb->s_blocksize - 1); | ||
382 | } | ||
383 | /* Last extent are just preallocated blocks? */ | ||
384 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) { | ||
385 | /* Save the extent so that we can reattach it to the end */ | ||
386 | prealloc_loc = last_ext->extLocation; | ||
387 | prealloc_len = last_ext->extLength; | ||
388 | /* Mark the extent as a hole */ | ||
389 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
390 | (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); | ||
391 | last_ext->extLocation.logicalBlockNum = 0; | ||
392 | last_ext->extLocation.partitionReferenceNum = 0; | ||
393 | } | ||
394 | /* Can we merge with the previous extent? */ | ||
395 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) { | ||
396 | add = ((1<<30) - sb->s_blocksize - (last_ext->extLength & | ||
397 | UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits; | ||
398 | if (add > blocks) | ||
399 | add = blocks; | ||
400 | blocks -= add; | ||
401 | last_ext->extLength += add << sb->s_blocksize_bits; | ||
402 | } | ||
403 | |||
404 | if (fake) { | ||
405 | udf_add_aext(inode, last_pos, last_ext->extLocation, | ||
406 | last_ext->extLength, 1); | ||
407 | count++; | ||
408 | } | ||
409 | else | ||
410 | udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1); | ||
411 | /* Managed to do everything necessary? */ | ||
412 | if (!blocks) | ||
413 | goto out; | ||
414 | |||
415 | /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ | ||
416 | last_ext->extLocation.logicalBlockNum = 0; | ||
417 | last_ext->extLocation.partitionReferenceNum = 0; | ||
418 | add = (1 << (30-sb->s_blocksize_bits)) - 1; | ||
419 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits); | ||
420 | /* Create enough extents to cover the whole hole */ | ||
421 | while (blocks > add) { | ||
422 | blocks -= add; | ||
423 | if (udf_add_aext(inode, last_pos, last_ext->extLocation, | ||
424 | last_ext->extLength, 1) == -1) | ||
425 | return -1; | ||
426 | count++; | ||
427 | } | ||
428 | if (blocks) { | ||
429 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
430 | (blocks << sb->s_blocksize_bits); | ||
431 | if (udf_add_aext(inode, last_pos, last_ext->extLocation, | ||
432 | last_ext->extLength, 1) == -1) | ||
433 | return -1; | ||
434 | count++; | ||
435 | } | ||
436 | out: | ||
437 | /* Do we have some preallocated blocks saved? */ | ||
438 | if (prealloc_len) { | ||
439 | if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1) | ||
440 | return -1; | ||
441 | last_ext->extLocation = prealloc_loc; | ||
442 | last_ext->extLength = prealloc_len; | ||
443 | count++; | ||
444 | } | ||
445 | /* last_pos should point to the last written extent... */ | ||
446 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | ||
447 | last_pos->offset -= sizeof(short_ad); | ||
448 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | ||
449 | last_pos->offset -= sizeof(long_ad); | ||
450 | else | ||
451 | return -1; | ||
452 | return count; | ||
453 | } | ||
454 | |||
455 | static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | ||
358 | int *err, long *phys, int *new) | 456 | int *err, long *phys, int *new) |
359 | { | 457 | { |
360 | struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL; | 458 | static sector_t last_block; |
459 | struct buffer_head *result = NULL; | ||
361 | kernel_long_ad laarr[EXTENT_MERGE_SIZE]; | 460 | kernel_long_ad laarr[EXTENT_MERGE_SIZE]; |
362 | uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0; | 461 | struct extent_position prev_epos, cur_epos, next_epos; |
363 | int count = 0, startnum = 0, endnum = 0; | 462 | int count = 0, startnum = 0, endnum = 0; |
364 | uint32_t elen = 0; | 463 | uint32_t elen = 0; |
365 | kernel_lb_addr eloc, pbloc, cbloc, nbloc; | 464 | kernel_lb_addr eloc; |
366 | int c = 1; | 465 | int c = 1; |
367 | uint64_t lbcount = 0, b_off = 0; | 466 | loff_t lbcount = 0, b_off = 0; |
368 | uint32_t newblocknum, newblock, offset = 0; | 467 | uint32_t newblocknum, newblock; |
468 | sector_t offset = 0; | ||
369 | int8_t etype; | 469 | int8_t etype; |
370 | int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; | 470 | int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; |
371 | char lastblock = 0; | 471 | int lastblock = 0; |
372 | 472 | ||
373 | pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode); | 473 | prev_epos.offset = udf_file_entry_alloc_offset(inode); |
374 | b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits; | 474 | prev_epos.block = UDF_I_LOCATION(inode); |
375 | pbloc = cbloc = nbloc = UDF_I_LOCATION(inode); | 475 | prev_epos.bh = NULL; |
476 | cur_epos = next_epos = prev_epos; | ||
477 | b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; | ||
376 | 478 | ||
377 | /* find the extent which contains the block we are looking for. | 479 | /* find the extent which contains the block we are looking for. |
378 | alternate between laarr[0] and laarr[1] for locations of the | 480 | alternate between laarr[0] and laarr[1] for locations of the |
379 | current extent, and the previous extent */ | 481 | current extent, and the previous extent */ |
380 | do | 482 | do |
381 | { | 483 | { |
382 | if (pbh != cbh) | 484 | if (prev_epos.bh != cur_epos.bh) |
383 | { | 485 | { |
384 | udf_release_data(pbh); | 486 | brelse(prev_epos.bh); |
385 | atomic_inc(&cbh->b_count); | 487 | get_bh(cur_epos.bh); |
386 | pbh = cbh; | 488 | prev_epos.bh = cur_epos.bh; |
387 | } | 489 | } |
388 | if (cbh != nbh) | 490 | if (cur_epos.bh != next_epos.bh) |
389 | { | 491 | { |
390 | udf_release_data(cbh); | 492 | brelse(cur_epos.bh); |
391 | atomic_inc(&nbh->b_count); | 493 | get_bh(next_epos.bh); |
392 | cbh = nbh; | 494 | cur_epos.bh = next_epos.bh; |
393 | } | 495 | } |
394 | 496 | ||
395 | lbcount += elen; | 497 | lbcount += elen; |
396 | 498 | ||
397 | pbloc = cbloc; | 499 | prev_epos.block = cur_epos.block; |
398 | cbloc = nbloc; | 500 | cur_epos.block = next_epos.block; |
399 | 501 | ||
400 | pextoffset = cextoffset; | 502 | prev_epos.offset = cur_epos.offset; |
401 | cextoffset = nextoffset; | 503 | cur_epos.offset = next_epos.offset; |
402 | 504 | ||
403 | if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1) | 505 | if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1) |
404 | break; | 506 | break; |
405 | 507 | ||
406 | c = !c; | 508 | c = !c; |
@@ -418,6 +520,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
418 | 520 | ||
419 | b_off -= lbcount; | 521 | b_off -= lbcount; |
420 | offset = b_off >> inode->i_sb->s_blocksize_bits; | 522 | offset = b_off >> inode->i_sb->s_blocksize_bits; |
523 | /* Move into indirect extent if we are at a pointer to it */ | ||
524 | udf_next_aext(inode, &prev_epos, &eloc, &elen, 0); | ||
421 | 525 | ||
422 | /* if the extent is allocated and recorded, return the block | 526 | /* if the extent is allocated and recorded, return the block |
423 | if the extent is not a multiple of the blocksize, round up */ | 527 | if the extent is not a multiple of the blocksize, round up */ |
@@ -429,54 +533,77 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
429 | elen = EXT_RECORDED_ALLOCATED | | 533 | elen = EXT_RECORDED_ALLOCATED | |
430 | ((elen + inode->i_sb->s_blocksize - 1) & | 534 | ((elen + inode->i_sb->s_blocksize - 1) & |
431 | ~(inode->i_sb->s_blocksize - 1)); | 535 | ~(inode->i_sb->s_blocksize - 1)); |
432 | etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1); | 536 | etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1); |
433 | } | 537 | } |
434 | udf_release_data(pbh); | 538 | brelse(prev_epos.bh); |
435 | udf_release_data(cbh); | 539 | brelse(cur_epos.bh); |
436 | udf_release_data(nbh); | 540 | brelse(next_epos.bh); |
437 | newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); | 541 | newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
438 | *phys = newblock; | 542 | *phys = newblock; |
439 | return NULL; | 543 | return NULL; |
440 | } | 544 | } |
441 | 545 | ||
546 | last_block = block; | ||
547 | /* Are we beyond EOF? */ | ||
442 | if (etype == -1) | 548 | if (etype == -1) |
443 | { | 549 | { |
444 | endnum = startnum = ((count > 1) ? 1 : count); | 550 | int ret; |
445 | if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1)) | 551 | |
446 | { | 552 | if (count) { |
447 | laarr[c].extLength = | 553 | if (c) |
448 | (laarr[c].extLength & UDF_EXTENT_FLAG_MASK) | | 554 | laarr[0] = laarr[1]; |
449 | (((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) + | 555 | startnum = 1; |
450 | inode->i_sb->s_blocksize - 1) & | 556 | } |
451 | ~(inode->i_sb->s_blocksize - 1)); | 557 | else { |
452 | UDF_I_LENEXTENTS(inode) = | 558 | /* Create a fake extent when there's not one */ |
453 | (UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) & | 559 | memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr)); |
454 | ~(inode->i_sb->s_blocksize - 1); | 560 | laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; |
561 | /* Will udf_extend_file() create real extent from a fake one? */ | ||
562 | startnum = (offset > 0); | ||
563 | } | ||
564 | /* Create extents for the hole between EOF and offset */ | ||
565 | ret = udf_extend_file(inode, &prev_epos, laarr, offset); | ||
566 | if (ret == -1) { | ||
567 | brelse(prev_epos.bh); | ||
568 | brelse(cur_epos.bh); | ||
569 | brelse(next_epos.bh); | ||
570 | /* We don't really know the error here so we just make | ||
571 | * something up */ | ||
572 | *err = -ENOSPC; | ||
573 | return NULL; | ||
455 | } | 574 | } |
456 | c = !c; | 575 | c = 0; |
457 | laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | 576 | offset = 0; |
458 | ((offset + 1) << inode->i_sb->s_blocksize_bits); | 577 | count += ret; |
459 | memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); | 578 | /* We are not covered by a preallocated extent? */ |
460 | count ++; | 579 | if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) { |
461 | endnum ++; | 580 | /* Is there any real extent? - otherwise we overwrite |
581 | * the fake one... */ | ||
582 | if (count) | ||
583 | c = !c; | ||
584 | laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
585 | inode->i_sb->s_blocksize; | ||
586 | memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); | ||
587 | count ++; | ||
588 | endnum ++; | ||
589 | } | ||
590 | endnum = c+1; | ||
462 | lastblock = 1; | 591 | lastblock = 1; |
463 | } | 592 | } |
464 | else | 593 | else { |
465 | endnum = startnum = ((count > 2) ? 2 : count); | 594 | endnum = startnum = ((count > 2) ? 2 : count); |
466 | 595 | ||
467 | /* if the current extent is in position 0, swap it with the previous */ | 596 | /* if the current extent is in position 0, swap it with the previous */ |
468 | if (!c && count != 1) | 597 | if (!c && count != 1) |
469 | { | 598 | { |
470 | laarr[2] = laarr[0]; | 599 | laarr[2] = laarr[0]; |
471 | laarr[0] = laarr[1]; | 600 | laarr[0] = laarr[1]; |
472 | laarr[1] = laarr[2]; | 601 | laarr[1] = laarr[2]; |
473 | c = 1; | 602 | c = 1; |
474 | } | 603 | } |
475 | 604 | ||
476 | /* if the current block is located in a extent, read the next extent */ | 605 | /* if the current block is located in an extent, read the next extent */ |
477 | if (etype != -1) | 606 | if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) |
478 | { | ||
479 | if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1) | ||
480 | { | 607 | { |
481 | laarr[c+1].extLength = (etype << 30) | elen; | 608 | laarr[c+1].extLength = (etype << 30) | elen; |
482 | laarr[c+1].extLocation = eloc; | 609 | laarr[c+1].extLocation = eloc; |
@@ -484,11 +611,10 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
484 | startnum ++; | 611 | startnum ++; |
485 | endnum ++; | 612 | endnum ++; |
486 | } | 613 | } |
487 | else | 614 | else { |
488 | lastblock = 1; | 615 | lastblock = 1; |
616 | } | ||
489 | } | 617 | } |
490 | udf_release_data(cbh); | ||
491 | udf_release_data(nbh); | ||
492 | 618 | ||
493 | /* if the current extent is not recorded but allocated, get the | 619 | /* if the current extent is not recorded but allocated, get the |
494 | block in the extent corresponding to the requested block */ | 620 | block in the extent corresponding to the requested block */ |
@@ -508,7 +634,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
508 | if (!(newblocknum = udf_new_block(inode->i_sb, inode, | 634 | if (!(newblocknum = udf_new_block(inode->i_sb, inode, |
509 | UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) | 635 | UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) |
510 | { | 636 | { |
511 | udf_release_data(pbh); | 637 | brelse(prev_epos.bh); |
512 | *err = -ENOSPC; | 638 | *err = -ENOSPC; |
513 | return NULL; | 639 | return NULL; |
514 | } | 640 | } |
@@ -529,11 +655,11 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
529 | udf_merge_extents(inode, laarr, &endnum); | 655 | udf_merge_extents(inode, laarr, &endnum); |
530 | 656 | ||
531 | /* write back the new extents, inserting new extents if the new number | 657 | /* write back the new extents, inserting new extents if the new number |
532 | of extents is greater than the old number, and deleting extents if | 658 | of extents is greater than the old number, and deleting extents if |
533 | the new number of extents is less than the old number */ | 659 | the new number of extents is less than the old number */ |
534 | udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh); | 660 | udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); |
535 | 661 | ||
536 | udf_release_data(pbh); | 662 | brelse(prev_epos.bh); |
537 | 663 | ||
538 | if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, | 664 | if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, |
539 | UDF_I_LOCATION(inode).partitionReferenceNum, 0))) | 665 | UDF_I_LOCATION(inode).partitionReferenceNum, 0))) |
@@ -795,7 +921,7 @@ static void udf_merge_extents(struct inode *inode, | |||
795 | 921 | ||
796 | static void udf_update_extents(struct inode *inode, | 922 | static void udf_update_extents(struct inode *inode, |
797 | kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, | 923 | kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, |
798 | kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh) | 924 | struct extent_position *epos) |
799 | { | 925 | { |
800 | int start = 0, i; | 926 | int start = 0, i; |
801 | kernel_lb_addr tmploc; | 927 | kernel_lb_addr tmploc; |
@@ -804,28 +930,26 @@ static void udf_update_extents(struct inode *inode, | |||
804 | if (startnum > endnum) | 930 | if (startnum > endnum) |
805 | { | 931 | { |
806 | for (i=0; i<(startnum-endnum); i++) | 932 | for (i=0; i<(startnum-endnum); i++) |
807 | { | 933 | udf_delete_aext(inode, *epos, laarr[i].extLocation, |
808 | udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation, | 934 | laarr[i].extLength); |
809 | laarr[i].extLength, *pbh); | ||
810 | } | ||
811 | } | 935 | } |
812 | else if (startnum < endnum) | 936 | else if (startnum < endnum) |
813 | { | 937 | { |
814 | for (i=0; i<(endnum-startnum); i++) | 938 | for (i=0; i<(endnum-startnum); i++) |
815 | { | 939 | { |
816 | udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation, | 940 | udf_insert_aext(inode, *epos, laarr[i].extLocation, |
817 | laarr[i].extLength, *pbh); | 941 | laarr[i].extLength); |
818 | udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation, | 942 | udf_next_aext(inode, epos, &laarr[i].extLocation, |
819 | &laarr[i].extLength, pbh, 1); | 943 | &laarr[i].extLength, 1); |
820 | start ++; | 944 | start ++; |
821 | } | 945 | } |
822 | } | 946 | } |
823 | 947 | ||
824 | for (i=start; i<endnum; i++) | 948 | for (i=start; i<endnum; i++) |
825 | { | 949 | { |
826 | udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0); | 950 | udf_next_aext(inode, epos, &tmploc, &tmplen, 0); |
827 | udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation, | 951 | udf_write_aext(inode, epos, laarr[i].extLocation, |
828 | laarr[i].extLength, *pbh, 1); | 952 | laarr[i].extLength, 1); |
829 | } | 953 | } |
830 | } | 954 | } |
831 | 955 | ||
@@ -931,7 +1055,7 @@ __udf_read_inode(struct inode *inode) | |||
931 | { | 1055 | { |
932 | printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", | 1056 | printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", |
933 | inode->i_ino, ident); | 1057 | inode->i_ino, ident); |
934 | udf_release_data(bh); | 1058 | brelse(bh); |
935 | make_bad_inode(inode); | 1059 | make_bad_inode(inode); |
936 | return; | 1060 | return; |
937 | } | 1061 | } |
@@ -960,35 +1084,36 @@ __udf_read_inode(struct inode *inode) | |||
960 | ident == TAG_IDENT_EFE) | 1084 | ident == TAG_IDENT_EFE) |
961 | { | 1085 | { |
962 | memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); | 1086 | memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); |
963 | udf_release_data(bh); | 1087 | brelse(bh); |
964 | udf_release_data(ibh); | 1088 | brelse(ibh); |
965 | udf_release_data(nbh); | 1089 | brelse(nbh); |
966 | __udf_read_inode(inode); | 1090 | __udf_read_inode(inode); |
967 | return; | 1091 | return; |
968 | } | 1092 | } |
969 | else | 1093 | else |
970 | { | 1094 | { |
971 | udf_release_data(nbh); | 1095 | brelse(nbh); |
972 | udf_release_data(ibh); | 1096 | brelse(ibh); |
973 | } | 1097 | } |
974 | } | 1098 | } |
975 | else | 1099 | else |
976 | udf_release_data(ibh); | 1100 | brelse(ibh); |
977 | } | 1101 | } |
978 | } | 1102 | } |
979 | else | 1103 | else |
980 | udf_release_data(ibh); | 1104 | brelse(ibh); |
981 | } | 1105 | } |
982 | else if (le16_to_cpu(fe->icbTag.strategyType) != 4) | 1106 | else if (le16_to_cpu(fe->icbTag.strategyType) != 4) |
983 | { | 1107 | { |
984 | printk(KERN_ERR "udf: unsupported strategy type: %d\n", | 1108 | printk(KERN_ERR "udf: unsupported strategy type: %d\n", |
985 | le16_to_cpu(fe->icbTag.strategyType)); | 1109 | le16_to_cpu(fe->icbTag.strategyType)); |
986 | udf_release_data(bh); | 1110 | brelse(bh); |
987 | make_bad_inode(inode); | 1111 | make_bad_inode(inode); |
988 | return; | 1112 | return; |
989 | } | 1113 | } |
990 | udf_fill_inode(inode, bh); | 1114 | udf_fill_inode(inode, bh); |
991 | udf_release_data(bh); | 1115 | |
1116 | brelse(bh); | ||
992 | } | 1117 | } |
993 | 1118 | ||
994 | static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | 1119 | static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) |
@@ -1331,7 +1456,7 @@ udf_update_inode(struct inode *inode, int do_sync) | |||
1331 | use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; | 1456 | use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; |
1332 | 1457 | ||
1333 | mark_buffer_dirty(bh); | 1458 | mark_buffer_dirty(bh); |
1334 | udf_release_data(bh); | 1459 | brelse(bh); |
1335 | return err; | 1460 | return err; |
1336 | } | 1461 | } |
1337 | 1462 | ||
@@ -1520,7 +1645,7 @@ udf_update_inode(struct inode *inode, int do_sync) | |||
1520 | err = -EIO; | 1645 | err = -EIO; |
1521 | } | 1646 | } |
1522 | } | 1647 | } |
1523 | udf_release_data(bh); | 1648 | brelse(bh); |
1524 | return err; | 1649 | return err; |
1525 | } | 1650 | } |
1526 | 1651 | ||
@@ -1556,8 +1681,8 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino) | |||
1556 | return NULL; | 1681 | return NULL; |
1557 | } | 1682 | } |
1558 | 1683 | ||
1559 | int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1684 | int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, |
1560 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) | 1685 | kernel_lb_addr eloc, uint32_t elen, int inc) |
1561 | { | 1686 | { |
1562 | int adsize; | 1687 | int adsize; |
1563 | short_ad *sad = NULL; | 1688 | short_ad *sad = NULL; |
@@ -1566,10 +1691,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1566 | int8_t etype; | 1691 | int8_t etype; |
1567 | uint8_t *ptr; | 1692 | uint8_t *ptr; |
1568 | 1693 | ||
1569 | if (!*bh) | 1694 | if (!epos->bh) |
1570 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1695 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1571 | else | 1696 | else |
1572 | ptr = (*bh)->b_data + *extoffset; | 1697 | ptr = epos->bh->b_data + epos->offset; |
1573 | 1698 | ||
1574 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 1699 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
1575 | adsize = sizeof(short_ad); | 1700 | adsize = sizeof(short_ad); |
@@ -1578,20 +1703,20 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1578 | else | 1703 | else |
1579 | return -1; | 1704 | return -1; |
1580 | 1705 | ||
1581 | if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize) | 1706 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) |
1582 | { | 1707 | { |
1583 | char *sptr, *dptr; | 1708 | char *sptr, *dptr; |
1584 | struct buffer_head *nbh; | 1709 | struct buffer_head *nbh; |
1585 | int err, loffset; | 1710 | int err, loffset; |
1586 | kernel_lb_addr obloc = *bloc; | 1711 | kernel_lb_addr obloc = epos->block; |
1587 | 1712 | ||
1588 | if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL, | 1713 | if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, |
1589 | obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) | 1714 | obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) |
1590 | { | 1715 | { |
1591 | return -1; | 1716 | return -1; |
1592 | } | 1717 | } |
1593 | if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, | 1718 | if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, |
1594 | *bloc, 0)))) | 1719 | epos->block, 0)))) |
1595 | { | 1720 | { |
1596 | return -1; | 1721 | return -1; |
1597 | } | 1722 | } |
@@ -1604,25 +1729,25 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1604 | aed = (struct allocExtDesc *)(nbh->b_data); | 1729 | aed = (struct allocExtDesc *)(nbh->b_data); |
1605 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) | 1730 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) |
1606 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); | 1731 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); |
1607 | if (*extoffset + adsize > inode->i_sb->s_blocksize) | 1732 | if (epos->offset + adsize > inode->i_sb->s_blocksize) |
1608 | { | 1733 | { |
1609 | loffset = *extoffset; | 1734 | loffset = epos->offset; |
1610 | aed->lengthAllocDescs = cpu_to_le32(adsize); | 1735 | aed->lengthAllocDescs = cpu_to_le32(adsize); |
1611 | sptr = ptr - adsize; | 1736 | sptr = ptr - adsize; |
1612 | dptr = nbh->b_data + sizeof(struct allocExtDesc); | 1737 | dptr = nbh->b_data + sizeof(struct allocExtDesc); |
1613 | memcpy(dptr, sptr, adsize); | 1738 | memcpy(dptr, sptr, adsize); |
1614 | *extoffset = sizeof(struct allocExtDesc) + adsize; | 1739 | epos->offset = sizeof(struct allocExtDesc) + adsize; |
1615 | } | 1740 | } |
1616 | else | 1741 | else |
1617 | { | 1742 | { |
1618 | loffset = *extoffset + adsize; | 1743 | loffset = epos->offset + adsize; |
1619 | aed->lengthAllocDescs = cpu_to_le32(0); | 1744 | aed->lengthAllocDescs = cpu_to_le32(0); |
1620 | sptr = ptr; | 1745 | sptr = ptr; |
1621 | *extoffset = sizeof(struct allocExtDesc); | 1746 | epos->offset = sizeof(struct allocExtDesc); |
1622 | 1747 | ||
1623 | if (*bh) | 1748 | if (epos->bh) |
1624 | { | 1749 | { |
1625 | aed = (struct allocExtDesc *)(*bh)->b_data; | 1750 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1626 | aed->lengthAllocDescs = | 1751 | aed->lengthAllocDescs = |
1627 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 1752 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1628 | } | 1753 | } |
@@ -1634,10 +1759,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1634 | } | 1759 | } |
1635 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) | 1760 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) |
1636 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, | 1761 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, |
1637 | bloc->logicalBlockNum, sizeof(tag)); | 1762 | epos->block.logicalBlockNum, sizeof(tag)); |
1638 | else | 1763 | else |
1639 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, | 1764 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, |
1640 | bloc->logicalBlockNum, sizeof(tag)); | 1765 | epos->block.logicalBlockNum, sizeof(tag)); |
1641 | switch (UDF_I_ALLOCTYPE(inode)) | 1766 | switch (UDF_I_ALLOCTYPE(inode)) |
1642 | { | 1767 | { |
1643 | case ICBTAG_FLAG_AD_SHORT: | 1768 | case ICBTAG_FLAG_AD_SHORT: |
@@ -1646,7 +1771,7 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1646 | sad->extLength = cpu_to_le32( | 1771 | sad->extLength = cpu_to_le32( |
1647 | EXT_NEXT_EXTENT_ALLOCDECS | | 1772 | EXT_NEXT_EXTENT_ALLOCDECS | |
1648 | inode->i_sb->s_blocksize); | 1773 | inode->i_sb->s_blocksize); |
1649 | sad->extPosition = cpu_to_le32(bloc->logicalBlockNum); | 1774 | sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum); |
1650 | break; | 1775 | break; |
1651 | } | 1776 | } |
1652 | case ICBTAG_FLAG_AD_LONG: | 1777 | case ICBTAG_FLAG_AD_LONG: |
@@ -1655,60 +1780,57 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1655 | lad->extLength = cpu_to_le32( | 1780 | lad->extLength = cpu_to_le32( |
1656 | EXT_NEXT_EXTENT_ALLOCDECS | | 1781 | EXT_NEXT_EXTENT_ALLOCDECS | |
1657 | inode->i_sb->s_blocksize); | 1782 | inode->i_sb->s_blocksize); |
1658 | lad->extLocation = cpu_to_lelb(*bloc); | 1783 | lad->extLocation = cpu_to_lelb(epos->block); |
1659 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); | 1784 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); |
1660 | break; | 1785 | break; |
1661 | } | 1786 | } |
1662 | } | 1787 | } |
1663 | if (*bh) | 1788 | if (epos->bh) |
1664 | { | 1789 | { |
1665 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1790 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1666 | udf_update_tag((*bh)->b_data, loffset); | 1791 | udf_update_tag(epos->bh->b_data, loffset); |
1667 | else | 1792 | else |
1668 | udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); | 1793 | udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
1669 | mark_buffer_dirty_inode(*bh, inode); | 1794 | mark_buffer_dirty_inode(epos->bh, inode); |
1670 | udf_release_data(*bh); | 1795 | brelse(epos->bh); |
1671 | } | 1796 | } |
1672 | else | 1797 | else |
1673 | mark_inode_dirty(inode); | 1798 | mark_inode_dirty(inode); |
1674 | *bh = nbh; | 1799 | epos->bh = nbh; |
1675 | } | 1800 | } |
1676 | 1801 | ||
1677 | etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc); | 1802 | etype = udf_write_aext(inode, epos, eloc, elen, inc); |
1678 | 1803 | ||
1679 | if (!*bh) | 1804 | if (!epos->bh) |
1680 | { | 1805 | { |
1681 | UDF_I_LENALLOC(inode) += adsize; | 1806 | UDF_I_LENALLOC(inode) += adsize; |
1682 | mark_inode_dirty(inode); | 1807 | mark_inode_dirty(inode); |
1683 | } | 1808 | } |
1684 | else | 1809 | else |
1685 | { | 1810 | { |
1686 | aed = (struct allocExtDesc *)(*bh)->b_data; | 1811 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1687 | aed->lengthAllocDescs = | 1812 | aed->lengthAllocDescs = |
1688 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 1813 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1689 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1814 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1690 | udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize)); | 1815 | udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize)); |
1691 | else | 1816 | else |
1692 | udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); | 1817 | udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
1693 | mark_buffer_dirty_inode(*bh, inode); | 1818 | mark_buffer_dirty_inode(epos->bh, inode); |
1694 | } | 1819 | } |
1695 | 1820 | ||
1696 | return etype; | 1821 | return etype; |
1697 | } | 1822 | } |
1698 | 1823 | ||
1699 | int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, | 1824 | int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, |
1700 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) | 1825 | kernel_lb_addr eloc, uint32_t elen, int inc) |
1701 | { | 1826 | { |
1702 | int adsize; | 1827 | int adsize; |
1703 | uint8_t *ptr; | 1828 | uint8_t *ptr; |
1704 | 1829 | ||
1705 | if (!bh) | 1830 | if (!epos->bh) |
1706 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1831 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1707 | else | 1832 | else |
1708 | { | 1833 | ptr = epos->bh->b_data + epos->offset; |
1709 | ptr = bh->b_data + *extoffset; | ||
1710 | atomic_inc(&bh->b_count); | ||
1711 | } | ||
1712 | 1834 | ||
1713 | switch (UDF_I_ALLOCTYPE(inode)) | 1835 | switch (UDF_I_ALLOCTYPE(inode)) |
1714 | { | 1836 | { |
@@ -1733,40 +1855,39 @@ int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, | |||
1733 | return -1; | 1855 | return -1; |
1734 | } | 1856 | } |
1735 | 1857 | ||
1736 | if (bh) | 1858 | if (epos->bh) |
1737 | { | 1859 | { |
1738 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1860 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1739 | { | 1861 | { |
1740 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data; | 1862 | struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data; |
1741 | udf_update_tag((bh)->b_data, | 1863 | udf_update_tag(epos->bh->b_data, |
1742 | le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); | 1864 | le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); |
1743 | } | 1865 | } |
1744 | mark_buffer_dirty_inode(bh, inode); | 1866 | mark_buffer_dirty_inode(epos->bh, inode); |
1745 | udf_release_data(bh); | ||
1746 | } | 1867 | } |
1747 | else | 1868 | else |
1748 | mark_inode_dirty(inode); | 1869 | mark_inode_dirty(inode); |
1749 | 1870 | ||
1750 | if (inc) | 1871 | if (inc) |
1751 | *extoffset += adsize; | 1872 | epos->offset += adsize; |
1752 | return (elen >> 30); | 1873 | return (elen >> 30); |
1753 | } | 1874 | } |
1754 | 1875 | ||
1755 | int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1876 | int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, |
1756 | kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) | 1877 | kernel_lb_addr *eloc, uint32_t *elen, int inc) |
1757 | { | 1878 | { |
1758 | int8_t etype; | 1879 | int8_t etype; |
1759 | 1880 | ||
1760 | while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) == | 1881 | while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == |
1761 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) | 1882 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
1762 | { | 1883 | { |
1763 | *bloc = *eloc; | 1884 | epos->block = *eloc; |
1764 | *extoffset = sizeof(struct allocExtDesc); | 1885 | epos->offset = sizeof(struct allocExtDesc); |
1765 | udf_release_data(*bh); | 1886 | brelse(epos->bh); |
1766 | if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) | 1887 | if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0)))) |
1767 | { | 1888 | { |
1768 | udf_debug("reading block %d failed!\n", | 1889 | udf_debug("reading block %d failed!\n", |
1769 | udf_get_lb_pblock(inode->i_sb, *bloc, 0)); | 1890 | udf_get_lb_pblock(inode->i_sb, epos->block, 0)); |
1770 | return -1; | 1891 | return -1; |
1771 | } | 1892 | } |
1772 | } | 1893 | } |
@@ -1774,26 +1895,26 @@ int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1774 | return etype; | 1895 | return etype; |
1775 | } | 1896 | } |
1776 | 1897 | ||
1777 | int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1898 | int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, |
1778 | kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) | 1899 | kernel_lb_addr *eloc, uint32_t *elen, int inc) |
1779 | { | 1900 | { |
1780 | int alen; | 1901 | int alen; |
1781 | int8_t etype; | 1902 | int8_t etype; |
1782 | uint8_t *ptr; | 1903 | uint8_t *ptr; |
1783 | 1904 | ||
1784 | if (!*bh) | 1905 | if (!epos->bh) |
1785 | { | 1906 | { |
1786 | if (!(*extoffset)) | 1907 | if (!epos->offset) |
1787 | *extoffset = udf_file_entry_alloc_offset(inode); | 1908 | epos->offset = udf_file_entry_alloc_offset(inode); |
1788 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1909 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1789 | alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); | 1910 | alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); |
1790 | } | 1911 | } |
1791 | else | 1912 | else |
1792 | { | 1913 | { |
1793 | if (!(*extoffset)) | 1914 | if (!epos->offset) |
1794 | *extoffset = sizeof(struct allocExtDesc); | 1915 | epos->offset = sizeof(struct allocExtDesc); |
1795 | ptr = (*bh)->b_data + *extoffset; | 1916 | ptr = epos->bh->b_data + epos->offset; |
1796 | alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); | 1917 | alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs); |
1797 | } | 1918 | } |
1798 | 1919 | ||
1799 | switch (UDF_I_ALLOCTYPE(inode)) | 1920 | switch (UDF_I_ALLOCTYPE(inode)) |
@@ -1802,7 +1923,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1802 | { | 1923 | { |
1803 | short_ad *sad; | 1924 | short_ad *sad; |
1804 | 1925 | ||
1805 | if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc))) | 1926 | if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc))) |
1806 | return -1; | 1927 | return -1; |
1807 | 1928 | ||
1808 | etype = le32_to_cpu(sad->extLength) >> 30; | 1929 | etype = le32_to_cpu(sad->extLength) >> 30; |
@@ -1815,7 +1936,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1815 | { | 1936 | { |
1816 | long_ad *lad; | 1937 | long_ad *lad; |
1817 | 1938 | ||
1818 | if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc))) | 1939 | if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc))) |
1819 | return -1; | 1940 | return -1; |
1820 | 1941 | ||
1821 | etype = le32_to_cpu(lad->extLength) >> 30; | 1942 | etype = le32_to_cpu(lad->extLength) >> 30; |
@@ -1834,41 +1955,40 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1834 | } | 1955 | } |
1835 | 1956 | ||
1836 | static int8_t | 1957 | static int8_t |
1837 | udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset, | 1958 | udf_insert_aext(struct inode *inode, struct extent_position epos, |
1838 | kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh) | 1959 | kernel_lb_addr neloc, uint32_t nelen) |
1839 | { | 1960 | { |
1840 | kernel_lb_addr oeloc; | 1961 | kernel_lb_addr oeloc; |
1841 | uint32_t oelen; | 1962 | uint32_t oelen; |
1842 | int8_t etype; | 1963 | int8_t etype; |
1843 | 1964 | ||
1844 | if (bh) | 1965 | if (epos.bh) |
1845 | atomic_inc(&bh->b_count); | 1966 | get_bh(epos.bh); |
1846 | 1967 | ||
1847 | while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1) | 1968 | while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) |
1848 | { | 1969 | { |
1849 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); | 1970 | udf_write_aext(inode, &epos, neloc, nelen, 1); |
1850 | 1971 | ||
1851 | neloc = oeloc; | 1972 | neloc = oeloc; |
1852 | nelen = (etype << 30) | oelen; | 1973 | nelen = (etype << 30) | oelen; |
1853 | } | 1974 | } |
1854 | udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1); | 1975 | udf_add_aext(inode, &epos, neloc, nelen, 1); |
1855 | udf_release_data(bh); | 1976 | brelse(epos.bh); |
1856 | return (nelen >> 30); | 1977 | return (nelen >> 30); |
1857 | } | 1978 | } |
1858 | 1979 | ||
1859 | int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset, | 1980 | int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, |
1860 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh) | 1981 | kernel_lb_addr eloc, uint32_t elen) |
1861 | { | 1982 | { |
1862 | struct buffer_head *obh; | 1983 | struct extent_position oepos; |
1863 | kernel_lb_addr obloc; | 1984 | int adsize; |
1864 | int oextoffset, adsize; | ||
1865 | int8_t etype; | 1985 | int8_t etype; |
1866 | struct allocExtDesc *aed; | 1986 | struct allocExtDesc *aed; |
1867 | 1987 | ||
1868 | if (nbh) | 1988 | if (epos.bh) |
1869 | { | 1989 | { |
1870 | atomic_inc(&nbh->b_count); | 1990 | get_bh(epos.bh); |
1871 | atomic_inc(&nbh->b_count); | 1991 | get_bh(epos.bh); |
1872 | } | 1992 | } |
1873 | 1993 | ||
1874 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 1994 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
@@ -1878,80 +1998,77 @@ int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset | |||
1878 | else | 1998 | else |
1879 | adsize = 0; | 1999 | adsize = 0; |
1880 | 2000 | ||
1881 | obh = nbh; | 2001 | oepos = epos; |
1882 | obloc = nbloc; | 2002 | if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) |
1883 | oextoffset = nextoffset; | ||
1884 | |||
1885 | if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1) | ||
1886 | return -1; | 2003 | return -1; |
1887 | 2004 | ||
1888 | while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) | 2005 | while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) |
1889 | { | 2006 | { |
1890 | udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1); | 2007 | udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1); |
1891 | if (obh != nbh) | 2008 | if (oepos.bh != epos.bh) |
1892 | { | 2009 | { |
1893 | obloc = nbloc; | 2010 | oepos.block = epos.block; |
1894 | udf_release_data(obh); | 2011 | brelse(oepos.bh); |
1895 | atomic_inc(&nbh->b_count); | 2012 | get_bh(epos.bh); |
1896 | obh = nbh; | 2013 | oepos.bh = epos.bh; |
1897 | oextoffset = nextoffset - adsize; | 2014 | oepos.offset = epos.offset - adsize; |
1898 | } | 2015 | } |
1899 | } | 2016 | } |
1900 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | 2017 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); |
1901 | elen = 0; | 2018 | elen = 0; |
1902 | 2019 | ||
1903 | if (nbh != obh) | 2020 | if (epos.bh != oepos.bh) |
1904 | { | 2021 | { |
1905 | udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1); | 2022 | udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1); |
1906 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 2023 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1907 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 2024 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1908 | if (!obh) | 2025 | if (!oepos.bh) |
1909 | { | 2026 | { |
1910 | UDF_I_LENALLOC(inode) -= (adsize * 2); | 2027 | UDF_I_LENALLOC(inode) -= (adsize * 2); |
1911 | mark_inode_dirty(inode); | 2028 | mark_inode_dirty(inode); |
1912 | } | 2029 | } |
1913 | else | 2030 | else |
1914 | { | 2031 | { |
1915 | aed = (struct allocExtDesc *)(obh)->b_data; | 2032 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
1916 | aed->lengthAllocDescs = | 2033 | aed->lengthAllocDescs = |
1917 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); | 2034 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); |
1918 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 2035 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1919 | udf_update_tag((obh)->b_data, oextoffset - (2*adsize)); | 2036 | udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize)); |
1920 | else | 2037 | else |
1921 | udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); | 2038 | udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
1922 | mark_buffer_dirty_inode(obh, inode); | 2039 | mark_buffer_dirty_inode(oepos.bh, inode); |
1923 | } | 2040 | } |
1924 | } | 2041 | } |
1925 | else | 2042 | else |
1926 | { | 2043 | { |
1927 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 2044 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1928 | if (!obh) | 2045 | if (!oepos.bh) |
1929 | { | 2046 | { |
1930 | UDF_I_LENALLOC(inode) -= adsize; | 2047 | UDF_I_LENALLOC(inode) -= adsize; |
1931 | mark_inode_dirty(inode); | 2048 | mark_inode_dirty(inode); |
1932 | } | 2049 | } |
1933 | else | 2050 | else |
1934 | { | 2051 | { |
1935 | aed = (struct allocExtDesc *)(obh)->b_data; | 2052 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
1936 | aed->lengthAllocDescs = | 2053 | aed->lengthAllocDescs = |
1937 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); | 2054 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); |
1938 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 2055 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1939 | udf_update_tag((obh)->b_data, oextoffset - adsize); | 2056 | udf_update_tag(oepos.bh->b_data, epos.offset - adsize); |
1940 | else | 2057 | else |
1941 | udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); | 2058 | udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
1942 | mark_buffer_dirty_inode(obh, inode); | 2059 | mark_buffer_dirty_inode(oepos.bh, inode); |
1943 | } | 2060 | } |
1944 | } | 2061 | } |
1945 | 2062 | ||
1946 | udf_release_data(nbh); | 2063 | brelse(epos.bh); |
1947 | udf_release_data(obh); | 2064 | brelse(oepos.bh); |
1948 | return (elen >> 30); | 2065 | return (elen >> 30); |
1949 | } | 2066 | } |
1950 | 2067 | ||
1951 | int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset, | 2068 | int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos, |
1952 | kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh) | 2069 | kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) |
1953 | { | 2070 | { |
1954 | uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits; | 2071 | loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits; |
1955 | int8_t etype; | 2072 | int8_t etype; |
1956 | 2073 | ||
1957 | if (block < 0) | 2074 | if (block < 0) |
@@ -1960,42 +2077,44 @@ int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t | |||
1960 | return -1; | 2077 | return -1; |
1961 | } | 2078 | } |
1962 | 2079 | ||
1963 | *extoffset = 0; | 2080 | pos->offset = 0; |
2081 | pos->block = UDF_I_LOCATION(inode); | ||
2082 | pos->bh = NULL; | ||
1964 | *elen = 0; | 2083 | *elen = 0; |
1965 | *bloc = UDF_I_LOCATION(inode); | ||
1966 | 2084 | ||
1967 | do | 2085 | do |
1968 | { | 2086 | { |
1969 | if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1) | 2087 | if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) |
1970 | { | 2088 | { |
1971 | *offset = bcount - lbcount; | 2089 | *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits; |
1972 | UDF_I_LENEXTENTS(inode) = lbcount; | 2090 | UDF_I_LENEXTENTS(inode) = lbcount; |
1973 | return -1; | 2091 | return -1; |
1974 | } | 2092 | } |
1975 | lbcount += *elen; | 2093 | lbcount += *elen; |
1976 | } while (lbcount <= bcount); | 2094 | } while (lbcount <= bcount); |
1977 | 2095 | ||
1978 | *offset = bcount + *elen - lbcount; | 2096 | *offset = (bcount + *elen - lbcount) >> inode->i_sb->s_blocksize_bits; |
1979 | 2097 | ||
1980 | return etype; | 2098 | return etype; |
1981 | } | 2099 | } |
1982 | 2100 | ||
1983 | long udf_block_map(struct inode *inode, long block) | 2101 | long udf_block_map(struct inode *inode, sector_t block) |
1984 | { | 2102 | { |
1985 | kernel_lb_addr eloc, bloc; | 2103 | kernel_lb_addr eloc; |
1986 | uint32_t offset, extoffset, elen; | 2104 | uint32_t elen; |
1987 | struct buffer_head *bh = NULL; | 2105 | sector_t offset; |
2106 | struct extent_position epos = { NULL, 0, { 0, 0}}; | ||
1988 | int ret; | 2107 | int ret; |
1989 | 2108 | ||
1990 | lock_kernel(); | 2109 | lock_kernel(); |
1991 | 2110 | ||
1992 | if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 2111 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
1993 | ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits); | 2112 | ret = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
1994 | else | 2113 | else |
1995 | ret = 0; | 2114 | ret = 0; |
1996 | 2115 | ||
1997 | unlock_kernel(); | 2116 | unlock_kernel(); |
1998 | udf_release_data(bh); | 2117 | brelse(epos.bh); |
1999 | 2118 | ||
2000 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 2119 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
2001 | return udf_fixed_to_variable(ret); | 2120 | return udf_fixed_to_variable(ret); |
diff --git a/fs/udf/misc.c b/fs/udf/misc.c index cc8ca3254db1..a2b2a98ce78a 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c | |||
@@ -274,12 +274,6 @@ udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, uint32_t offset, ui | |||
274 | loc.logicalBlockNum + offset, ident); | 274 | loc.logicalBlockNum + offset, ident); |
275 | } | 275 | } |
276 | 276 | ||
277 | void udf_release_data(struct buffer_head *bh) | ||
278 | { | ||
279 | if (bh) | ||
280 | brelse(bh); | ||
281 | } | ||
282 | |||
283 | void udf_update_tag(char *data, int length) | 277 | void udf_update_tag(char *data, int length) |
284 | { | 278 | { |
285 | tag *tptr = (tag *)data; | 279 | tag *tptr = (tag *)data; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index fe361cd19a98..91df4928651c 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -155,9 +155,10 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
155 | uint8_t lfi; | 155 | uint8_t lfi; |
156 | uint16_t liu; | 156 | uint16_t liu; |
157 | loff_t size; | 157 | loff_t size; |
158 | kernel_lb_addr bloc, eloc; | 158 | kernel_lb_addr eloc; |
159 | uint32_t extoffset, elen, offset; | 159 | uint32_t elen; |
160 | struct buffer_head *bh = NULL; | 160 | sector_t offset; |
161 | struct extent_position epos = { NULL, 0, { 0, 0}}; | ||
161 | 162 | ||
162 | size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 163 | size = (udf_ext0_offset(dir) + dir->i_size) >> 2; |
163 | f_pos = (udf_ext0_offset(dir) >> 2); | 164 | f_pos = (udf_ext0_offset(dir) >> 2); |
@@ -166,42 +167,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
166 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 167 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
167 | fibh->sbh = fibh->ebh = NULL; | 168 | fibh->sbh = fibh->ebh = NULL; |
168 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), | 169 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), |
169 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 170 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
170 | { | 171 | { |
171 | offset >>= dir->i_sb->s_blocksize_bits; | ||
172 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 172 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
173 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 173 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
174 | { | 174 | { |
175 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 175 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
176 | extoffset -= sizeof(short_ad); | 176 | epos.offset -= sizeof(short_ad); |
177 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 177 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
178 | extoffset -= sizeof(long_ad); | 178 | epos.offset -= sizeof(long_ad); |
179 | } | 179 | } |
180 | else | 180 | else |
181 | offset = 0; | 181 | offset = 0; |
182 | 182 | ||
183 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) | 183 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) |
184 | { | 184 | { |
185 | udf_release_data(bh); | 185 | brelse(epos.bh); |
186 | return NULL; | 186 | return NULL; |
187 | } | 187 | } |
188 | } | 188 | } |
189 | else | 189 | else |
190 | { | 190 | { |
191 | udf_release_data(bh); | 191 | brelse(epos.bh); |
192 | return NULL; | 192 | return NULL; |
193 | } | 193 | } |
194 | 194 | ||
195 | while ( (f_pos < size) ) | 195 | while ( (f_pos < size) ) |
196 | { | 196 | { |
197 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 197 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset); |
198 | 198 | ||
199 | if (!fi) | 199 | if (!fi) |
200 | { | 200 | { |
201 | if (fibh->sbh != fibh->ebh) | 201 | if (fibh->sbh != fibh->ebh) |
202 | udf_release_data(fibh->ebh); | 202 | brelse(fibh->ebh); |
203 | udf_release_data(fibh->sbh); | 203 | brelse(fibh->sbh); |
204 | udf_release_data(bh); | 204 | brelse(epos.bh); |
205 | return NULL; | 205 | return NULL; |
206 | } | 206 | } |
207 | 207 | ||
@@ -247,15 +247,15 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
247 | { | 247 | { |
248 | if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) | 248 | if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) |
249 | { | 249 | { |
250 | udf_release_data(bh); | 250 | brelse(epos.bh); |
251 | return fi; | 251 | return fi; |
252 | } | 252 | } |
253 | } | 253 | } |
254 | } | 254 | } |
255 | if (fibh->sbh != fibh->ebh) | 255 | if (fibh->sbh != fibh->ebh) |
256 | udf_release_data(fibh->ebh); | 256 | brelse(fibh->ebh); |
257 | udf_release_data(fibh->sbh); | 257 | brelse(fibh->sbh); |
258 | udf_release_data(bh); | 258 | brelse(epos.bh); |
259 | return NULL; | 259 | return NULL; |
260 | } | 260 | } |
261 | 261 | ||
@@ -321,8 +321,8 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
321 | if (udf_find_entry(dir, dentry, &fibh, &cfi)) | 321 | if (udf_find_entry(dir, dentry, &fibh, &cfi)) |
322 | { | 322 | { |
323 | if (fibh.sbh != fibh.ebh) | 323 | if (fibh.sbh != fibh.ebh) |
324 | udf_release_data(fibh.ebh); | 324 | brelse(fibh.ebh); |
325 | udf_release_data(fibh.sbh); | 325 | brelse(fibh.sbh); |
326 | 326 | ||
327 | inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); | 327 | inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); |
328 | if ( !inode ) | 328 | if ( !inode ) |
@@ -353,9 +353,10 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
353 | uint8_t lfi; | 353 | uint8_t lfi; |
354 | uint16_t liu; | 354 | uint16_t liu; |
355 | int block; | 355 | int block; |
356 | kernel_lb_addr bloc, eloc; | 356 | kernel_lb_addr eloc; |
357 | uint32_t extoffset, elen, offset; | 357 | uint32_t elen; |
358 | struct buffer_head *bh = NULL; | 358 | sector_t offset; |
359 | struct extent_position epos = { NULL, 0, { 0, 0 }}; | ||
359 | 360 | ||
360 | sb = dir->i_sb; | 361 | sb = dir->i_sb; |
361 | 362 | ||
@@ -384,23 +385,22 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
384 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 385 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
385 | fibh->sbh = fibh->ebh = NULL; | 386 | fibh->sbh = fibh->ebh = NULL; |
386 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), | 387 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), |
387 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 388 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
388 | { | 389 | { |
389 | offset >>= dir->i_sb->s_blocksize_bits; | ||
390 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 390 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
391 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 391 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
392 | { | 392 | { |
393 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 393 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
394 | extoffset -= sizeof(short_ad); | 394 | epos.offset -= sizeof(short_ad); |
395 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 395 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
396 | extoffset -= sizeof(long_ad); | 396 | epos.offset -= sizeof(long_ad); |
397 | } | 397 | } |
398 | else | 398 | else |
399 | offset = 0; | 399 | offset = 0; |
400 | 400 | ||
401 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) | 401 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) |
402 | { | 402 | { |
403 | udf_release_data(bh); | 403 | brelse(epos.bh); |
404 | *err = -EIO; | 404 | *err = -EIO; |
405 | return NULL; | 405 | return NULL; |
406 | } | 406 | } |
@@ -418,14 +418,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
418 | 418 | ||
419 | while ( (f_pos < size) ) | 419 | while ( (f_pos < size) ) |
420 | { | 420 | { |
421 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 421 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset); |
422 | 422 | ||
423 | if (!fi) | 423 | if (!fi) |
424 | { | 424 | { |
425 | if (fibh->sbh != fibh->ebh) | 425 | if (fibh->sbh != fibh->ebh) |
426 | udf_release_data(fibh->ebh); | 426 | brelse(fibh->ebh); |
427 | udf_release_data(fibh->sbh); | 427 | brelse(fibh->sbh); |
428 | udf_release_data(bh); | 428 | brelse(epos.bh); |
429 | *err = -EIO; | 429 | *err = -EIO; |
430 | return NULL; | 430 | return NULL; |
431 | } | 431 | } |
@@ -455,7 +455,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
455 | { | 455 | { |
456 | if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) | 456 | if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) |
457 | { | 457 | { |
458 | udf_release_data(bh); | 458 | brelse(epos.bh); |
459 | cfi->descTag.tagSerialNum = cpu_to_le16(1); | 459 | cfi->descTag.tagSerialNum = cpu_to_le16(1); |
460 | cfi->fileVersionNum = cpu_to_le16(1); | 460 | cfi->fileVersionNum = cpu_to_le16(1); |
461 | cfi->fileCharacteristics = 0; | 461 | cfi->fileCharacteristics = 0; |
@@ -478,9 +478,9 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
478 | udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) | 478 | udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) |
479 | { | 479 | { |
480 | if (fibh->sbh != fibh->ebh) | 480 | if (fibh->sbh != fibh->ebh) |
481 | udf_release_data(fibh->ebh); | 481 | brelse(fibh->ebh); |
482 | udf_release_data(fibh->sbh); | 482 | brelse(fibh->sbh); |
483 | udf_release_data(bh); | 483 | brelse(epos.bh); |
484 | *err = -EEXIST; | 484 | *err = -EEXIST; |
485 | return NULL; | 485 | return NULL; |
486 | } | 486 | } |
@@ -492,25 +492,25 @@ add: | |||
492 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB && | 492 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB && |
493 | sb->s_blocksize - fibh->eoffset < nfidlen) | 493 | sb->s_blocksize - fibh->eoffset < nfidlen) |
494 | { | 494 | { |
495 | udf_release_data(bh); | 495 | brelse(epos.bh); |
496 | bh = NULL; | 496 | epos.bh = NULL; |
497 | fibh->soffset -= udf_ext0_offset(dir); | 497 | fibh->soffset -= udf_ext0_offset(dir); |
498 | fibh->eoffset -= udf_ext0_offset(dir); | 498 | fibh->eoffset -= udf_ext0_offset(dir); |
499 | f_pos -= (udf_ext0_offset(dir) >> 2); | 499 | f_pos -= (udf_ext0_offset(dir) >> 2); |
500 | if (fibh->sbh != fibh->ebh) | 500 | if (fibh->sbh != fibh->ebh) |
501 | udf_release_data(fibh->ebh); | 501 | brelse(fibh->ebh); |
502 | udf_release_data(fibh->sbh); | 502 | brelse(fibh->sbh); |
503 | if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) | 503 | if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) |
504 | return NULL; | 504 | return NULL; |
505 | bloc = UDF_I_LOCATION(dir); | 505 | epos.block = UDF_I_LOCATION(dir); |
506 | eloc.logicalBlockNum = block; | 506 | eloc.logicalBlockNum = block; |
507 | eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; | 507 | eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; |
508 | elen = dir->i_sb->s_blocksize; | 508 | elen = dir->i_sb->s_blocksize; |
509 | extoffset = udf_file_entry_alloc_offset(dir); | 509 | epos.offset = udf_file_entry_alloc_offset(dir); |
510 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 510 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
511 | extoffset += sizeof(short_ad); | 511 | epos.offset += sizeof(short_ad); |
512 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 512 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
513 | extoffset += sizeof(long_ad); | 513 | epos.offset += sizeof(long_ad); |
514 | } | 514 | } |
515 | 515 | ||
516 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) | 516 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) |
@@ -519,7 +519,7 @@ add: | |||
519 | fibh->eoffset += nfidlen; | 519 | fibh->eoffset += nfidlen; |
520 | if (fibh->sbh != fibh->ebh) | 520 | if (fibh->sbh != fibh->ebh) |
521 | { | 521 | { |
522 | udf_release_data(fibh->sbh); | 522 | brelse(fibh->sbh); |
523 | fibh->sbh = fibh->ebh; | 523 | fibh->sbh = fibh->ebh; |
524 | } | 524 | } |
525 | 525 | ||
@@ -541,7 +541,7 @@ add: | |||
541 | fibh->eoffset += nfidlen - sb->s_blocksize; | 541 | fibh->eoffset += nfidlen - sb->s_blocksize; |
542 | if (fibh->sbh != fibh->ebh) | 542 | if (fibh->sbh != fibh->ebh) |
543 | { | 543 | { |
544 | udf_release_data(fibh->sbh); | 544 | brelse(fibh->sbh); |
545 | fibh->sbh = fibh->ebh; | 545 | fibh->sbh = fibh->ebh; |
546 | } | 546 | } |
547 | 547 | ||
@@ -550,14 +550,14 @@ add: | |||
550 | 550 | ||
551 | if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err))) | 551 | if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err))) |
552 | { | 552 | { |
553 | udf_release_data(bh); | 553 | brelse(epos.bh); |
554 | udf_release_data(fibh->sbh); | 554 | brelse(fibh->sbh); |
555 | return NULL; | 555 | return NULL; |
556 | } | 556 | } |
557 | 557 | ||
558 | if (!(fibh->soffset)) | 558 | if (!(fibh->soffset)) |
559 | { | 559 | { |
560 | if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) == | 560 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
561 | (EXT_RECORDED_ALLOCATED >> 30)) | 561 | (EXT_RECORDED_ALLOCATED >> 30)) |
562 | { | 562 | { |
563 | block = eloc.logicalBlockNum + ((elen - 1) >> | 563 | block = eloc.logicalBlockNum + ((elen - 1) >> |
@@ -566,7 +566,7 @@ add: | |||
566 | else | 566 | else |
567 | block ++; | 567 | block ++; |
568 | 568 | ||
569 | udf_release_data(fibh->sbh); | 569 | brelse(fibh->sbh); |
570 | fibh->sbh = fibh->ebh; | 570 | fibh->sbh = fibh->ebh; |
571 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); | 571 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); |
572 | } | 572 | } |
@@ -587,7 +587,7 @@ add: | |||
587 | cfi->lengthOfImpUse = cpu_to_le16(0); | 587 | cfi->lengthOfImpUse = cpu_to_le16(0); |
588 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) | 588 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) |
589 | { | 589 | { |
590 | udf_release_data(bh); | 590 | brelse(epos.bh); |
591 | dir->i_size += nfidlen; | 591 | dir->i_size += nfidlen; |
592 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 592 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
593 | UDF_I_LENALLOC(dir) += nfidlen; | 593 | UDF_I_LENALLOC(dir) += nfidlen; |
@@ -596,10 +596,10 @@ add: | |||
596 | } | 596 | } |
597 | else | 597 | else |
598 | { | 598 | { |
599 | udf_release_data(bh); | 599 | brelse(epos.bh); |
600 | if (fibh->sbh != fibh->ebh) | 600 | if (fibh->sbh != fibh->ebh) |
601 | udf_release_data(fibh->ebh); | 601 | brelse(fibh->ebh); |
602 | udf_release_data(fibh->sbh); | 602 | brelse(fibh->sbh); |
603 | *err = -EIO; | 603 | *err = -EIO; |
604 | return NULL; | 604 | return NULL; |
605 | } | 605 | } |
@@ -656,8 +656,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct | |||
656 | mark_inode_dirty(dir); | 656 | mark_inode_dirty(dir); |
657 | } | 657 | } |
658 | if (fibh.sbh != fibh.ebh) | 658 | if (fibh.sbh != fibh.ebh) |
659 | udf_release_data(fibh.ebh); | 659 | brelse(fibh.ebh); |
660 | udf_release_data(fibh.sbh); | 660 | brelse(fibh.sbh); |
661 | unlock_kernel(); | 661 | unlock_kernel(); |
662 | d_instantiate(dentry, inode); | 662 | d_instantiate(dentry, inode); |
663 | return 0; | 663 | return 0; |
@@ -701,8 +701,8 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t | |||
701 | mark_inode_dirty(inode); | 701 | mark_inode_dirty(inode); |
702 | 702 | ||
703 | if (fibh.sbh != fibh.ebh) | 703 | if (fibh.sbh != fibh.ebh) |
704 | udf_release_data(fibh.ebh); | 704 | brelse(fibh.ebh); |
705 | udf_release_data(fibh.sbh); | 705 | brelse(fibh.sbh); |
706 | d_instantiate(dentry, inode); | 706 | d_instantiate(dentry, inode); |
707 | err = 0; | 707 | err = 0; |
708 | out: | 708 | out: |
@@ -743,7 +743,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
743 | cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL); | 743 | cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL); |
744 | cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; | 744 | cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; |
745 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); | 745 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); |
746 | udf_release_data(fibh.sbh); | 746 | brelse(fibh.sbh); |
747 | inode->i_mode = S_IFDIR | mode; | 747 | inode->i_mode = S_IFDIR | mode; |
748 | if (dir->i_mode & S_ISGID) | 748 | if (dir->i_mode & S_ISGID) |
749 | inode->i_mode |= S_ISGID; | 749 | inode->i_mode |= S_ISGID; |
@@ -766,8 +766,8 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
766 | mark_inode_dirty(dir); | 766 | mark_inode_dirty(dir); |
767 | d_instantiate(dentry, inode); | 767 | d_instantiate(dentry, inode); |
768 | if (fibh.sbh != fibh.ebh) | 768 | if (fibh.sbh != fibh.ebh) |
769 | udf_release_data(fibh.ebh); | 769 | brelse(fibh.ebh); |
770 | udf_release_data(fibh.sbh); | 770 | brelse(fibh.sbh); |
771 | err = 0; | 771 | err = 0; |
772 | out: | 772 | out: |
773 | unlock_kernel(); | 773 | unlock_kernel(); |
@@ -781,9 +781,10 @@ static int empty_dir(struct inode *dir) | |||
781 | loff_t f_pos; | 781 | loff_t f_pos; |
782 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 782 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; |
783 | int block; | 783 | int block; |
784 | kernel_lb_addr bloc, eloc; | 784 | kernel_lb_addr eloc; |
785 | uint32_t extoffset, elen, offset; | 785 | uint32_t elen; |
786 | struct buffer_head *bh = NULL; | 786 | sector_t offset; |
787 | struct extent_position epos = { NULL, 0, { 0, 0}}; | ||
787 | 788 | ||
788 | f_pos = (udf_ext0_offset(dir) >> 2); | 789 | f_pos = (udf_ext0_offset(dir) >> 2); |
789 | 790 | ||
@@ -792,59 +793,58 @@ static int empty_dir(struct inode *dir) | |||
792 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 793 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
793 | fibh.sbh = fibh.ebh = NULL; | 794 | fibh.sbh = fibh.ebh = NULL; |
794 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), | 795 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), |
795 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 796 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
796 | { | 797 | { |
797 | offset >>= dir->i_sb->s_blocksize_bits; | ||
798 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 798 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
799 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 799 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
800 | { | 800 | { |
801 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 801 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
802 | extoffset -= sizeof(short_ad); | 802 | epos.offset -= sizeof(short_ad); |
803 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 803 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
804 | extoffset -= sizeof(long_ad); | 804 | epos.offset -= sizeof(long_ad); |
805 | } | 805 | } |
806 | else | 806 | else |
807 | offset = 0; | 807 | offset = 0; |
808 | 808 | ||
809 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) | 809 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) |
810 | { | 810 | { |
811 | udf_release_data(bh); | 811 | brelse(epos.bh); |
812 | return 0; | 812 | return 0; |
813 | } | 813 | } |
814 | } | 814 | } |
815 | else | 815 | else |
816 | { | 816 | { |
817 | udf_release_data(bh); | 817 | brelse(epos.bh); |
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | 821 | ||
822 | while ( (f_pos < size) ) | 822 | while ( (f_pos < size) ) |
823 | { | 823 | { |
824 | fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 824 | fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); |
825 | 825 | ||
826 | if (!fi) | 826 | if (!fi) |
827 | { | 827 | { |
828 | if (fibh.sbh != fibh.ebh) | 828 | if (fibh.sbh != fibh.ebh) |
829 | udf_release_data(fibh.ebh); | 829 | brelse(fibh.ebh); |
830 | udf_release_data(fibh.sbh); | 830 | brelse(fibh.sbh); |
831 | udf_release_data(bh); | 831 | brelse(epos.bh); |
832 | return 0; | 832 | return 0; |
833 | } | 833 | } |
834 | 834 | ||
835 | if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) | 835 | if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) |
836 | { | 836 | { |
837 | if (fibh.sbh != fibh.ebh) | 837 | if (fibh.sbh != fibh.ebh) |
838 | udf_release_data(fibh.ebh); | 838 | brelse(fibh.ebh); |
839 | udf_release_data(fibh.sbh); | 839 | brelse(fibh.sbh); |
840 | udf_release_data(bh); | 840 | brelse(epos.bh); |
841 | return 0; | 841 | return 0; |
842 | } | 842 | } |
843 | } | 843 | } |
844 | if (fibh.sbh != fibh.ebh) | 844 | if (fibh.sbh != fibh.ebh) |
845 | udf_release_data(fibh.ebh); | 845 | brelse(fibh.ebh); |
846 | udf_release_data(fibh.sbh); | 846 | brelse(fibh.sbh); |
847 | udf_release_data(bh); | 847 | brelse(epos.bh); |
848 | return 1; | 848 | return 1; |
849 | } | 849 | } |
850 | 850 | ||
@@ -878,14 +878,14 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) | |||
878 | inode->i_nlink); | 878 | inode->i_nlink); |
879 | clear_nlink(inode); | 879 | clear_nlink(inode); |
880 | inode->i_size = 0; | 880 | inode->i_size = 0; |
881 | inode_dec_link_count(inode); | 881 | inode_dec_link_count(dir); |
882 | inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); | 882 | inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); |
883 | mark_inode_dirty(dir); | 883 | mark_inode_dirty(dir); |
884 | 884 | ||
885 | end_rmdir: | 885 | end_rmdir: |
886 | if (fibh.sbh != fibh.ebh) | 886 | if (fibh.sbh != fibh.ebh) |
887 | udf_release_data(fibh.ebh); | 887 | brelse(fibh.ebh); |
888 | udf_release_data(fibh.sbh); | 888 | brelse(fibh.sbh); |
889 | out: | 889 | out: |
890 | unlock_kernel(); | 890 | unlock_kernel(); |
891 | return retval; | 891 | return retval; |
@@ -928,8 +928,8 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry) | |||
928 | 928 | ||
929 | end_unlink: | 929 | end_unlink: |
930 | if (fibh.sbh != fibh.ebh) | 930 | if (fibh.sbh != fibh.ebh) |
931 | udf_release_data(fibh.ebh); | 931 | brelse(fibh.ebh); |
932 | udf_release_data(fibh.sbh); | 932 | brelse(fibh.sbh); |
933 | out: | 933 | out: |
934 | unlock_kernel(); | 934 | unlock_kernel(); |
935 | return retval; | 935 | return retval; |
@@ -941,7 +941,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
941 | struct pathComponent *pc; | 941 | struct pathComponent *pc; |
942 | char *compstart; | 942 | char *compstart; |
943 | struct udf_fileident_bh fibh; | 943 | struct udf_fileident_bh fibh; |
944 | struct buffer_head *bh = NULL; | 944 | struct extent_position epos = { NULL, 0, {0, 0}}; |
945 | int eoffset, elen = 0; | 945 | int eoffset, elen = 0; |
946 | struct fileIdentDesc *fi; | 946 | struct fileIdentDesc *fi; |
947 | struct fileIdentDesc cfi; | 947 | struct fileIdentDesc cfi; |
@@ -961,33 +961,33 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
961 | 961 | ||
962 | if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) | 962 | if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) |
963 | { | 963 | { |
964 | struct buffer_head *bh = NULL; | 964 | kernel_lb_addr eloc; |
965 | kernel_lb_addr bloc, eloc; | 965 | uint32_t elen; |
966 | uint32_t elen, extoffset; | ||
967 | 966 | ||
968 | block = udf_new_block(inode->i_sb, inode, | 967 | block = udf_new_block(inode->i_sb, inode, |
969 | UDF_I_LOCATION(inode).partitionReferenceNum, | 968 | UDF_I_LOCATION(inode).partitionReferenceNum, |
970 | UDF_I_LOCATION(inode).logicalBlockNum, &err); | 969 | UDF_I_LOCATION(inode).logicalBlockNum, &err); |
971 | if (!block) | 970 | if (!block) |
972 | goto out_no_entry; | 971 | goto out_no_entry; |
973 | bloc = UDF_I_LOCATION(inode); | 972 | epos.block = UDF_I_LOCATION(inode); |
973 | epos.offset = udf_file_entry_alloc_offset(inode); | ||
974 | epos.bh = NULL; | ||
974 | eloc.logicalBlockNum = block; | 975 | eloc.logicalBlockNum = block; |
975 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; | 976 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; |
976 | elen = inode->i_sb->s_blocksize; | 977 | elen = inode->i_sb->s_blocksize; |
977 | UDF_I_LENEXTENTS(inode) = elen; | 978 | UDF_I_LENEXTENTS(inode) = elen; |
978 | extoffset = udf_file_entry_alloc_offset(inode); | 979 | udf_add_aext(inode, &epos, eloc, elen, 0); |
979 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0); | 980 | brelse(epos.bh); |
980 | udf_release_data(bh); | ||
981 | 981 | ||
982 | block = udf_get_pblock(inode->i_sb, block, | 982 | block = udf_get_pblock(inode->i_sb, block, |
983 | UDF_I_LOCATION(inode).partitionReferenceNum, 0); | 983 | UDF_I_LOCATION(inode).partitionReferenceNum, 0); |
984 | bh = udf_tread(inode->i_sb, block); | 984 | epos.bh = udf_tread(inode->i_sb, block); |
985 | lock_buffer(bh); | 985 | lock_buffer(epos.bh); |
986 | memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); | 986 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); |
987 | set_buffer_uptodate(bh); | 987 | set_buffer_uptodate(epos.bh); |
988 | unlock_buffer(bh); | 988 | unlock_buffer(epos.bh); |
989 | mark_buffer_dirty_inode(bh, inode); | 989 | mark_buffer_dirty_inode(epos.bh, inode); |
990 | ea = bh->b_data + udf_ext0_offset(inode); | 990 | ea = epos.bh->b_data + udf_ext0_offset(inode); |
991 | } | 991 | } |
992 | else | 992 | else |
993 | ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); | 993 | ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); |
@@ -1060,7 +1060,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
1060 | } | 1060 | } |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | udf_release_data(bh); | 1063 | brelse(epos.bh); |
1064 | inode->i_size = elen; | 1064 | inode->i_size = elen; |
1065 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) | 1065 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) |
1066 | UDF_I_LENALLOC(inode) = inode->i_size; | 1066 | UDF_I_LENALLOC(inode) = inode->i_size; |
@@ -1089,8 +1089,8 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
1089 | mark_inode_dirty(dir); | 1089 | mark_inode_dirty(dir); |
1090 | } | 1090 | } |
1091 | if (fibh.sbh != fibh.ebh) | 1091 | if (fibh.sbh != fibh.ebh) |
1092 | udf_release_data(fibh.ebh); | 1092 | brelse(fibh.ebh); |
1093 | udf_release_data(fibh.sbh); | 1093 | brelse(fibh.sbh); |
1094 | d_instantiate(dentry, inode); | 1094 | d_instantiate(dentry, inode); |
1095 | err = 0; | 1095 | err = 0; |
1096 | 1096 | ||
@@ -1145,8 +1145,8 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir, | |||
1145 | mark_inode_dirty(dir); | 1145 | mark_inode_dirty(dir); |
1146 | } | 1146 | } |
1147 | if (fibh.sbh != fibh.ebh) | 1147 | if (fibh.sbh != fibh.ebh) |
1148 | udf_release_data(fibh.ebh); | 1148 | brelse(fibh.ebh); |
1149 | udf_release_data(fibh.sbh); | 1149 | brelse(fibh.sbh); |
1150 | inc_nlink(inode); | 1150 | inc_nlink(inode); |
1151 | inode->i_ctime = current_fs_time(inode->i_sb); | 1151 | inode->i_ctime = current_fs_time(inode->i_sb); |
1152 | mark_inode_dirty(inode); | 1152 | mark_inode_dirty(inode); |
@@ -1174,8 +1174,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1174 | if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) | 1174 | if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) |
1175 | { | 1175 | { |
1176 | if (ofibh.sbh != ofibh.ebh) | 1176 | if (ofibh.sbh != ofibh.ebh) |
1177 | udf_release_data(ofibh.ebh); | 1177 | brelse(ofibh.ebh); |
1178 | udf_release_data(ofibh.sbh); | 1178 | brelse(ofibh.sbh); |
1179 | } | 1179 | } |
1180 | tloc = lelb_to_cpu(ocfi.icb.extLocation); | 1180 | tloc = lelb_to_cpu(ocfi.icb.extLocation); |
1181 | if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0) | 1181 | if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0) |
@@ -1188,8 +1188,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1188 | if (!new_inode) | 1188 | if (!new_inode) |
1189 | { | 1189 | { |
1190 | if (nfibh.sbh != nfibh.ebh) | 1190 | if (nfibh.sbh != nfibh.ebh) |
1191 | udf_release_data(nfibh.ebh); | 1191 | brelse(nfibh.ebh); |
1192 | udf_release_data(nfibh.sbh); | 1192 | brelse(nfibh.sbh); |
1193 | nfi = NULL; | 1193 | nfi = NULL; |
1194 | } | 1194 | } |
1195 | } | 1195 | } |
@@ -1290,19 +1290,19 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1290 | if (ofi) | 1290 | if (ofi) |
1291 | { | 1291 | { |
1292 | if (ofibh.sbh != ofibh.ebh) | 1292 | if (ofibh.sbh != ofibh.ebh) |
1293 | udf_release_data(ofibh.ebh); | 1293 | brelse(ofibh.ebh); |
1294 | udf_release_data(ofibh.sbh); | 1294 | brelse(ofibh.sbh); |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | retval = 0; | 1297 | retval = 0; |
1298 | 1298 | ||
1299 | end_rename: | 1299 | end_rename: |
1300 | udf_release_data(dir_bh); | 1300 | brelse(dir_bh); |
1301 | if (nfi) | 1301 | if (nfi) |
1302 | { | 1302 | { |
1303 | if (nfibh.sbh != nfibh.ebh) | 1303 | if (nfibh.sbh != nfibh.ebh) |
1304 | udf_release_data(nfibh.ebh); | 1304 | brelse(nfibh.ebh); |
1305 | udf_release_data(nfibh.sbh); | 1305 | brelse(nfibh.sbh); |
1306 | } | 1306 | } |
1307 | unlock_kernel(); | 1307 | unlock_kernel(); |
1308 | return retval; | 1308 | return retval; |
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index dabf2b841db8..467a26171cd9 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -81,7 +81,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t | |||
81 | 81 | ||
82 | loc = le32_to_cpu(((__le32 *)bh->b_data)[index]); | 82 | loc = le32_to_cpu(((__le32 *)bh->b_data)[index]); |
83 | 83 | ||
84 | udf_release_data(bh); | 84 | brelse(bh); |
85 | 85 | ||
86 | if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) | 86 | if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) |
87 | { | 87 | { |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 023b304fdd99..9b8644a06e53 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -563,7 +563,7 @@ udf_vrs(struct super_block *sb, int silent) | |||
563 | 563 | ||
564 | if (vsd->stdIdent[0] == 0) | 564 | if (vsd->stdIdent[0] == 0) |
565 | { | 565 | { |
566 | udf_release_data(bh); | 566 | brelse(bh); |
567 | break; | 567 | break; |
568 | } | 568 | } |
569 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) | 569 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) |
@@ -596,7 +596,7 @@ udf_vrs(struct super_block *sb, int silent) | |||
596 | } | 596 | } |
597 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) | 597 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) |
598 | { | 598 | { |
599 | udf_release_data(bh); | 599 | brelse(bh); |
600 | break; | 600 | break; |
601 | } | 601 | } |
602 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) | 602 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) |
@@ -607,7 +607,7 @@ udf_vrs(struct super_block *sb, int silent) | |||
607 | { | 607 | { |
608 | nsr03 = sector; | 608 | nsr03 = sector; |
609 | } | 609 | } |
610 | udf_release_data(bh); | 610 | brelse(bh); |
611 | } | 611 | } |
612 | 612 | ||
613 | if (nsr03) | 613 | if (nsr03) |
@@ -673,7 +673,7 @@ udf_find_anchor(struct super_block *sb) | |||
673 | { | 673 | { |
674 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 674 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
675 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 675 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
676 | udf_release_data(bh); | 676 | brelse(bh); |
677 | } | 677 | } |
678 | 678 | ||
679 | if (ident == TAG_IDENT_AVDP) | 679 | if (ident == TAG_IDENT_AVDP) |
@@ -708,7 +708,7 @@ udf_find_anchor(struct super_block *sb) | |||
708 | { | 708 | { |
709 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 709 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
710 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 710 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
711 | udf_release_data(bh); | 711 | brelse(bh); |
712 | } | 712 | } |
713 | 713 | ||
714 | if (ident == TAG_IDENT_AVDP && | 714 | if (ident == TAG_IDENT_AVDP && |
@@ -727,7 +727,7 @@ udf_find_anchor(struct super_block *sb) | |||
727 | { | 727 | { |
728 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 728 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
729 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 729 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
730 | udf_release_data(bh); | 730 | brelse(bh); |
731 | } | 731 | } |
732 | 732 | ||
733 | if (ident == TAG_IDENT_AVDP && | 733 | if (ident == TAG_IDENT_AVDP && |
@@ -749,7 +749,7 @@ udf_find_anchor(struct super_block *sb) | |||
749 | { | 749 | { |
750 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 750 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
751 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 751 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
752 | udf_release_data(bh); | 752 | brelse(bh); |
753 | 753 | ||
754 | if (ident == TAG_IDENT_AVDP && location == 256) | 754 | if (ident == TAG_IDENT_AVDP && location == 256) |
755 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | 755 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); |
@@ -766,7 +766,7 @@ udf_find_anchor(struct super_block *sb) | |||
766 | } | 766 | } |
767 | else | 767 | else |
768 | { | 768 | { |
769 | udf_release_data(bh); | 769 | brelse(bh); |
770 | if ((ident != TAG_IDENT_AVDP) && (i || | 770 | if ((ident != TAG_IDENT_AVDP) && (i || |
771 | (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE))) | 771 | (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE))) |
772 | { | 772 | { |
@@ -795,7 +795,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
795 | return 1; | 795 | return 1; |
796 | else if (ident != TAG_IDENT_FSD) | 796 | else if (ident != TAG_IDENT_FSD) |
797 | { | 797 | { |
798 | udf_release_data(bh); | 798 | brelse(bh); |
799 | return 1; | 799 | return 1; |
800 | } | 800 | } |
801 | 801 | ||
@@ -834,7 +834,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
834 | newfileset.logicalBlockNum += 1 + | 834 | newfileset.logicalBlockNum += 1 + |
835 | ((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1) | 835 | ((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1) |
836 | >> sb->s_blocksize_bits); | 836 | >> sb->s_blocksize_bits); |
837 | udf_release_data(bh); | 837 | brelse(bh); |
838 | break; | 838 | break; |
839 | } | 839 | } |
840 | case TAG_IDENT_FSD: | 840 | case TAG_IDENT_FSD: |
@@ -845,7 +845,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
845 | default: | 845 | default: |
846 | { | 846 | { |
847 | newfileset.logicalBlockNum ++; | 847 | newfileset.logicalBlockNum ++; |
848 | udf_release_data(bh); | 848 | brelse(bh); |
849 | bh = NULL; | 849 | bh = NULL; |
850 | break; | 850 | break; |
851 | } | 851 | } |
@@ -865,7 +865,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
865 | 865 | ||
866 | UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum; | 866 | UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum; |
867 | udf_load_fileset(sb, bh, root); | 867 | udf_load_fileset(sb, bh, root); |
868 | udf_release_data(bh); | 868 | brelse(bh); |
869 | return 0; | 869 | return 0; |
870 | } | 870 | } |
871 | return 1; | 871 | return 1; |
@@ -1083,7 +1083,7 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a | |||
1083 | if (ident != 0 || | 1083 | if (ident != 0 || |
1084 | strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) | 1084 | strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) |
1085 | { | 1085 | { |
1086 | udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]); | 1086 | brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]); |
1087 | UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL; | 1087 | UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL; |
1088 | } | 1088 | } |
1089 | } | 1089 | } |
@@ -1137,12 +1137,12 @@ udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) | |||
1137 | udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt)); | 1137 | udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt)); |
1138 | 1138 | ||
1139 | if (UDF_SB_LVIDBH(sb) != bh) | 1139 | if (UDF_SB_LVIDBH(sb) != bh) |
1140 | udf_release_data(bh); | 1140 | brelse(bh); |
1141 | loc.extLength -= sb->s_blocksize; | 1141 | loc.extLength -= sb->s_blocksize; |
1142 | loc.extLocation ++; | 1142 | loc.extLocation ++; |
1143 | } | 1143 | } |
1144 | if (UDF_SB_LVIDBH(sb) != bh) | 1144 | if (UDF_SB_LVIDBH(sb) != bh) |
1145 | udf_release_data(bh); | 1145 | brelse(bh); |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | /* | 1148 | /* |
@@ -1245,7 +1245,7 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_ | |||
1245 | done = 1; | 1245 | done = 1; |
1246 | break; | 1246 | break; |
1247 | } | 1247 | } |
1248 | udf_release_data(bh); | 1248 | brelse(bh); |
1249 | } | 1249 | } |
1250 | for (i=0; i<VDS_POS_LENGTH; i++) | 1250 | for (i=0; i<VDS_POS_LENGTH; i++) |
1251 | { | 1251 | { |
@@ -1267,10 +1267,10 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_ | |||
1267 | gd = (struct generic_desc *)bh2->b_data; | 1267 | gd = (struct generic_desc *)bh2->b_data; |
1268 | if (ident == TAG_IDENT_PD) | 1268 | if (ident == TAG_IDENT_PD) |
1269 | udf_load_partdesc(sb, bh2); | 1269 | udf_load_partdesc(sb, bh2); |
1270 | udf_release_data(bh2); | 1270 | brelse(bh2); |
1271 | } | 1271 | } |
1272 | } | 1272 | } |
1273 | udf_release_data(bh); | 1273 | brelse(bh); |
1274 | } | 1274 | } |
1275 | } | 1275 | } |
1276 | 1276 | ||
@@ -1333,7 +1333,7 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
1333 | reserve_e = reserve_e >> sb->s_blocksize_bits; | 1333 | reserve_e = reserve_e >> sb->s_blocksize_bits; |
1334 | reserve_e += reserve_s; | 1334 | reserve_e += reserve_s; |
1335 | 1335 | ||
1336 | udf_release_data(bh); | 1336 | brelse(bh); |
1337 | 1337 | ||
1338 | /* Process the main & reserve sequences */ | 1338 | /* Process the main & reserve sequences */ |
1339 | /* responsible for finding the PartitionDesc(s) */ | 1339 | /* responsible for finding the PartitionDesc(s) */ |
@@ -1403,12 +1403,14 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
1403 | 1403 | ||
1404 | pos = udf_block_map(UDF_SB_VAT(sb), 0); | 1404 | pos = udf_block_map(UDF_SB_VAT(sb), 0); |
1405 | bh = sb_bread(sb, pos); | 1405 | bh = sb_bread(sb, pos); |
1406 | if (!bh) | ||
1407 | return 1; | ||
1406 | UDF_SB_TYPEVIRT(sb,i).s_start_offset = | 1408 | UDF_SB_TYPEVIRT(sb,i).s_start_offset = |
1407 | le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) + | 1409 | le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) + |
1408 | udf_ext0_offset(UDF_SB_VAT(sb)); | 1410 | udf_ext0_offset(UDF_SB_VAT(sb)); |
1409 | UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - | 1411 | UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - |
1410 | UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2; | 1412 | UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2; |
1411 | udf_release_data(bh); | 1413 | brelse(bh); |
1412 | } | 1414 | } |
1413 | UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0); | 1415 | UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0); |
1414 | UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum); | 1416 | UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum); |
@@ -1661,7 +1663,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1661 | iput(inode); | 1663 | iput(inode); |
1662 | goto error_out; | 1664 | goto error_out; |
1663 | } | 1665 | } |
1664 | sb->s_maxbytes = 1<<30; | 1666 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
1665 | return 0; | 1667 | return 0; |
1666 | 1668 | ||
1667 | error_out: | 1669 | error_out: |
@@ -1680,7 +1682,7 @@ error_out: | |||
1680 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) | 1682 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) |
1681 | { | 1683 | { |
1682 | for (i=0; i<4; i++) | 1684 | for (i=0; i<4; i++) |
1683 | udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); | 1685 | brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); |
1684 | } | 1686 | } |
1685 | } | 1687 | } |
1686 | #ifdef CONFIG_UDF_NLS | 1688 | #ifdef CONFIG_UDF_NLS |
@@ -1689,7 +1691,7 @@ error_out: | |||
1689 | #endif | 1691 | #endif |
1690 | if (!(sb->s_flags & MS_RDONLY)) | 1692 | if (!(sb->s_flags & MS_RDONLY)) |
1691 | udf_close_lvid(sb); | 1693 | udf_close_lvid(sb); |
1692 | udf_release_data(UDF_SB_LVIDBH(sb)); | 1694 | brelse(UDF_SB_LVIDBH(sb)); |
1693 | UDF_SB_FREE(sb); | 1695 | UDF_SB_FREE(sb); |
1694 | kfree(sbi); | 1696 | kfree(sbi); |
1695 | sb->s_fs_info = NULL; | 1697 | sb->s_fs_info = NULL; |
@@ -1758,7 +1760,7 @@ udf_put_super(struct super_block *sb) | |||
1758 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) | 1760 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) |
1759 | { | 1761 | { |
1760 | for (i=0; i<4; i++) | 1762 | for (i=0; i<4; i++) |
1761 | udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); | 1763 | brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); |
1762 | } | 1764 | } |
1763 | } | 1765 | } |
1764 | #ifdef CONFIG_UDF_NLS | 1766 | #ifdef CONFIG_UDF_NLS |
@@ -1767,7 +1769,7 @@ udf_put_super(struct super_block *sb) | |||
1767 | #endif | 1769 | #endif |
1768 | if (!(sb->s_flags & MS_RDONLY)) | 1770 | if (!(sb->s_flags & MS_RDONLY)) |
1769 | udf_close_lvid(sb); | 1771 | udf_close_lvid(sb); |
1770 | udf_release_data(UDF_SB_LVIDBH(sb)); | 1772 | brelse(UDF_SB_LVIDBH(sb)); |
1771 | UDF_SB_FREE(sb); | 1773 | UDF_SB_FREE(sb); |
1772 | kfree(sb->s_fs_info); | 1774 | kfree(sb->s_fs_info); |
1773 | sb->s_fs_info = NULL; | 1775 | sb->s_fs_info = NULL; |
@@ -1837,7 +1839,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) | |||
1837 | } | 1839 | } |
1838 | else if (ident != TAG_IDENT_SBD) | 1840 | else if (ident != TAG_IDENT_SBD) |
1839 | { | 1841 | { |
1840 | udf_release_data(bh); | 1842 | brelse(bh); |
1841 | printk(KERN_ERR "udf: udf_count_free failed\n"); | 1843 | printk(KERN_ERR "udf: udf_count_free failed\n"); |
1842 | goto out; | 1844 | goto out; |
1843 | } | 1845 | } |
@@ -1859,7 +1861,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) | |||
1859 | } | 1861 | } |
1860 | if ( bytes ) | 1862 | if ( bytes ) |
1861 | { | 1863 | { |
1862 | udf_release_data(bh); | 1864 | brelse(bh); |
1863 | newblock = udf_get_lb_pblock(sb, loc, ++block); | 1865 | newblock = udf_get_lb_pblock(sb, loc, ++block); |
1864 | bh = udf_tread(sb, newblock); | 1866 | bh = udf_tread(sb, newblock); |
1865 | if (!bh) | 1867 | if (!bh) |
@@ -1871,7 +1873,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) | |||
1871 | ptr = (uint8_t *)bh->b_data; | 1873 | ptr = (uint8_t *)bh->b_data; |
1872 | } | 1874 | } |
1873 | } | 1875 | } |
1874 | udf_release_data(bh); | 1876 | brelse(bh); |
1875 | 1877 | ||
1876 | out: | 1878 | out: |
1877 | unlock_kernel(); | 1879 | unlock_kernel(); |
@@ -1883,21 +1885,20 @@ static unsigned int | |||
1883 | udf_count_free_table(struct super_block *sb, struct inode * table) | 1885 | udf_count_free_table(struct super_block *sb, struct inode * table) |
1884 | { | 1886 | { |
1885 | unsigned int accum = 0; | 1887 | unsigned int accum = 0; |
1886 | uint32_t extoffset, elen; | 1888 | uint32_t elen; |
1887 | kernel_lb_addr bloc, eloc; | 1889 | kernel_lb_addr eloc; |
1888 | int8_t etype; | 1890 | int8_t etype; |
1889 | struct buffer_head *bh = NULL; | 1891 | struct extent_position epos; |
1890 | 1892 | ||
1891 | lock_kernel(); | 1893 | lock_kernel(); |
1892 | 1894 | ||
1893 | bloc = UDF_I_LOCATION(table); | 1895 | epos.block = UDF_I_LOCATION(table); |
1894 | extoffset = sizeof(struct unallocSpaceEntry); | 1896 | epos.offset = sizeof(struct unallocSpaceEntry); |
1897 | epos.bh = NULL; | ||
1895 | 1898 | ||
1896 | while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 1899 | while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
1897 | { | ||
1898 | accum += (elen >> table->i_sb->s_blocksize_bits); | 1900 | accum += (elen >> table->i_sb->s_blocksize_bits); |
1899 | } | 1901 | brelse(epos.bh); |
1900 | udf_release_data(bh); | ||
1901 | 1902 | ||
1902 | unlock_kernel(); | 1903 | unlock_kernel(); |
1903 | 1904 | ||
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index ba068a786563..12613b680cc4 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -95,7 +95,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); | 97 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); |
98 | udf_release_data(bh); | 98 | brelse(bh); |
99 | 99 | ||
100 | unlock_kernel(); | 100 | unlock_kernel(); |
101 | SetPageUptodate(page); | 101 | SetPageUptodate(page); |
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 0abd66ce36ea..77975ae291a5 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -28,8 +28,8 @@ | |||
28 | #include "udf_i.h" | 28 | #include "udf_i.h" |
29 | #include "udf_sb.h" | 29 | #include "udf_sb.h" |
30 | 30 | ||
31 | static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffset, | 31 | static void extent_trunc(struct inode * inode, struct extent_position *epos, |
32 | kernel_lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen) | 32 | kernel_lb_addr eloc, int8_t etype, uint32_t elen, uint32_t nelen) |
33 | { | 33 | { |
34 | kernel_lb_addr neloc = { 0, 0 }; | 34 | kernel_lb_addr neloc = { 0, 0 }; |
35 | int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; | 35 | int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; |
@@ -49,7 +49,7 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse | |||
49 | 49 | ||
50 | if (elen != nelen) | 50 | if (elen != nelen) |
51 | { | 51 | { |
52 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0); | 52 | udf_write_aext(inode, epos, neloc, nelen, 0); |
53 | if (last_block - first_block > 0) | 53 | if (last_block - first_block > 0) |
54 | { | 54 | { |
55 | if (etype == (EXT_RECORDED_ALLOCATED >> 30)) | 55 | if (etype == (EXT_RECORDED_ALLOCATED >> 30)) |
@@ -63,18 +63,16 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse | |||
63 | 63 | ||
64 | void udf_discard_prealloc(struct inode * inode) | 64 | void udf_discard_prealloc(struct inode * inode) |
65 | { | 65 | { |
66 | kernel_lb_addr bloc, eloc; | 66 | struct extent_position epos = { NULL, 0, {0, 0}}; |
67 | uint32_t extoffset = 0, elen, nelen; | 67 | kernel_lb_addr eloc; |
68 | uint32_t elen, nelen; | ||
68 | uint64_t lbcount = 0; | 69 | uint64_t lbcount = 0; |
69 | int8_t etype = -1, netype; | 70 | int8_t etype = -1, netype; |
70 | struct buffer_head *bh = NULL; | ||
71 | int adsize; | 71 | int adsize; |
72 | 72 | ||
73 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || | 73 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || |
74 | inode->i_size == UDF_I_LENEXTENTS(inode)) | 74 | inode->i_size == UDF_I_LENEXTENTS(inode)) |
75 | { | ||
76 | return; | 75 | return; |
77 | } | ||
78 | 76 | ||
79 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 77 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
80 | adsize = sizeof(short_ad); | 78 | adsize = sizeof(short_ad); |
@@ -83,52 +81,58 @@ void udf_discard_prealloc(struct inode * inode) | |||
83 | else | 81 | else |
84 | adsize = 0; | 82 | adsize = 0; |
85 | 83 | ||
86 | bloc = UDF_I_LOCATION(inode); | 84 | epos.block = UDF_I_LOCATION(inode); |
87 | 85 | ||
88 | while ((netype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 86 | /* Find the last extent in the file */ |
87 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) | ||
89 | { | 88 | { |
90 | etype = netype; | 89 | etype = netype; |
91 | lbcount += elen; | 90 | lbcount += elen; |
92 | if (lbcount > inode->i_size && lbcount - inode->i_size < inode->i_sb->s_blocksize) | 91 | if (lbcount > inode->i_size && lbcount - elen < inode->i_size) |
93 | { | 92 | { |
93 | WARN_ON(lbcount - inode->i_size >= inode->i_sb->s_blocksize); | ||
94 | nelen = elen - (lbcount - inode->i_size); | 94 | nelen = elen - (lbcount - inode->i_size); |
95 | extent_trunc(inode, bloc, extoffset-adsize, eloc, etype, elen, bh, nelen); | 95 | epos.offset -= adsize; |
96 | extent_trunc(inode, &epos, eloc, etype, elen, nelen); | ||
97 | epos.offset += adsize; | ||
96 | lbcount = inode->i_size; | 98 | lbcount = inode->i_size; |
97 | } | 99 | } |
98 | } | 100 | } |
99 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | 101 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
100 | { | 102 | epos.offset -= adsize; |
101 | extoffset -= adsize; | ||
102 | lbcount -= elen; | 103 | lbcount -= elen; |
103 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); | 104 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
104 | if (!bh) | 105 | if (!epos.bh) |
105 | { | 106 | { |
106 | UDF_I_LENALLOC(inode) = extoffset - udf_file_entry_alloc_offset(inode); | 107 | UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode); |
107 | mark_inode_dirty(inode); | 108 | mark_inode_dirty(inode); |
108 | } | 109 | } |
109 | else | 110 | else |
110 | { | 111 | { |
111 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 112 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
112 | aed->lengthAllocDescs = cpu_to_le32(extoffset - sizeof(struct allocExtDesc)); | 113 | aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc)); |
113 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 114 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
114 | udf_update_tag(bh->b_data, extoffset); | 115 | udf_update_tag(epos.bh->b_data, epos.offset); |
115 | else | 116 | else |
116 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 117 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
117 | mark_buffer_dirty_inode(bh, inode); | 118 | mark_buffer_dirty_inode(epos.bh, inode); |
118 | } | 119 | } |
119 | } | 120 | } |
120 | UDF_I_LENEXTENTS(inode) = lbcount; | 121 | UDF_I_LENEXTENTS(inode) = lbcount; |
121 | 122 | ||
122 | udf_release_data(bh); | 123 | WARN_ON(lbcount != inode->i_size); |
124 | brelse(epos.bh); | ||
123 | } | 125 | } |
124 | 126 | ||
125 | void udf_truncate_extents(struct inode * inode) | 127 | void udf_truncate_extents(struct inode * inode) |
126 | { | 128 | { |
127 | kernel_lb_addr bloc, eloc, neloc = { 0, 0 }; | 129 | struct extent_position epos; |
128 | uint32_t extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc; | 130 | kernel_lb_addr eloc, neloc = { 0, 0 }; |
131 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; | ||
129 | int8_t etype; | 132 | int8_t etype; |
130 | int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits; | 133 | struct super_block *sb = inode->i_sb; |
131 | struct buffer_head *bh = NULL; | 134 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; |
135 | loff_t byte_offset; | ||
132 | int adsize; | 136 | int adsize; |
133 | 137 | ||
134 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 138 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
@@ -136,158 +140,130 @@ void udf_truncate_extents(struct inode * inode) | |||
136 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 140 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) |
137 | adsize = sizeof(long_ad); | 141 | adsize = sizeof(long_ad); |
138 | else | 142 | else |
139 | adsize = 0; | 143 | BUG(); |
140 | 144 | ||
141 | etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 145 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
142 | offset += (inode->i_size & (inode->i_sb->s_blocksize - 1)); | 146 | byte_offset = (offset << sb->s_blocksize_bits) + (inode->i_size & (sb->s_blocksize-1)); |
143 | if (etype != -1) | 147 | if (etype != -1) |
144 | { | 148 | { |
145 | extoffset -= adsize; | 149 | epos.offset -= adsize; |
146 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset); | 150 | extent_trunc(inode, &epos, eloc, etype, elen, byte_offset); |
147 | extoffset += adsize; | 151 | epos.offset += adsize; |
148 | 152 | if (byte_offset) | |
149 | if (offset) | 153 | lenalloc = epos.offset; |
150 | lenalloc = extoffset; | ||
151 | else | 154 | else |
152 | lenalloc = extoffset - adsize; | 155 | lenalloc = epos.offset - adsize; |
153 | 156 | ||
154 | if (!bh) | 157 | if (!epos.bh) |
155 | lenalloc -= udf_file_entry_alloc_offset(inode); | 158 | lenalloc -= udf_file_entry_alloc_offset(inode); |
156 | else | 159 | else |
157 | lenalloc -= sizeof(struct allocExtDesc); | 160 | lenalloc -= sizeof(struct allocExtDesc); |
158 | 161 | ||
159 | while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1) | 162 | while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) |
160 | { | 163 | { |
161 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) | 164 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
162 | { | 165 | { |
163 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0); | 166 | udf_write_aext(inode, &epos, neloc, nelen, 0); |
164 | extoffset = 0; | 167 | if (indirect_ext_len) |
165 | if (lelen) | ||
166 | { | 168 | { |
167 | if (!bh) | 169 | /* We managed to free all extents in the |
170 | * indirect extent - free it too */ | ||
171 | if (!epos.bh) | ||
168 | BUG(); | 172 | BUG(); |
169 | else | 173 | udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len); |
170 | memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); | ||
171 | udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); | ||
172 | } | 174 | } |
173 | else | 175 | else |
174 | { | 176 | { |
175 | if (!bh) | 177 | if (!epos.bh) |
176 | { | 178 | { |
177 | UDF_I_LENALLOC(inode) = lenalloc; | 179 | UDF_I_LENALLOC(inode) = lenalloc; |
178 | mark_inode_dirty(inode); | 180 | mark_inode_dirty(inode); |
179 | } | 181 | } |
180 | else | 182 | else |
181 | { | 183 | { |
182 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 184 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
183 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 185 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
184 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 186 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201) |
185 | udf_update_tag(bh->b_data, lenalloc + | 187 | udf_update_tag(epos.bh->b_data, lenalloc + |
186 | sizeof(struct allocExtDesc)); | 188 | sizeof(struct allocExtDesc)); |
187 | else | 189 | else |
188 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 190 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
189 | mark_buffer_dirty_inode(bh, inode); | 191 | mark_buffer_dirty_inode(epos.bh, inode); |
190 | } | 192 | } |
191 | } | 193 | } |
192 | 194 | brelse(epos.bh); | |
193 | udf_release_data(bh); | 195 | epos.offset = sizeof(struct allocExtDesc); |
194 | extoffset = sizeof(struct allocExtDesc); | 196 | epos.block = eloc; |
195 | bloc = eloc; | 197 | epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0)); |
196 | bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0)); | ||
197 | if (elen) | 198 | if (elen) |
198 | lelen = (elen + inode->i_sb->s_blocksize - 1) >> | 199 | indirect_ext_len = (elen + |
199 | inode->i_sb->s_blocksize_bits; | 200 | sb->s_blocksize - 1) >> |
201 | sb->s_blocksize_bits; | ||
200 | else | 202 | else |
201 | lelen = 1; | 203 | indirect_ext_len = 1; |
202 | } | 204 | } |
203 | else | 205 | else |
204 | { | 206 | { |
205 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); | 207 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
206 | extoffset += adsize; | 208 | epos.offset += adsize; |
207 | } | 209 | } |
208 | } | 210 | } |
209 | 211 | ||
210 | if (lelen) | 212 | if (indirect_ext_len) |
211 | { | 213 | { |
212 | if (!bh) | 214 | if (!epos.bh) |
213 | BUG(); | 215 | BUG(); |
214 | else | 216 | udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len); |
215 | memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); | ||
216 | udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); | ||
217 | } | 217 | } |
218 | else | 218 | else |
219 | { | 219 | { |
220 | if (!bh) | 220 | if (!epos.bh) |
221 | { | 221 | { |
222 | UDF_I_LENALLOC(inode) = lenalloc; | 222 | UDF_I_LENALLOC(inode) = lenalloc; |
223 | mark_inode_dirty(inode); | 223 | mark_inode_dirty(inode); |
224 | } | 224 | } |
225 | else | 225 | else |
226 | { | 226 | { |
227 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 227 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
228 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 228 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
229 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 229 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201) |
230 | udf_update_tag(bh->b_data, lenalloc + | 230 | udf_update_tag(epos.bh->b_data, lenalloc + |
231 | sizeof(struct allocExtDesc)); | 231 | sizeof(struct allocExtDesc)); |
232 | else | 232 | else |
233 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 233 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
234 | mark_buffer_dirty_inode(bh, inode); | 234 | mark_buffer_dirty_inode(epos.bh, inode); |
235 | } | 235 | } |
236 | } | 236 | } |
237 | } | 237 | } |
238 | else if (inode->i_size) | 238 | else if (inode->i_size) |
239 | { | 239 | { |
240 | if (offset) | 240 | if (byte_offset) |
241 | { | 241 | { |
242 | kernel_long_ad extent; | ||
243 | |||
242 | /* | 244 | /* |
243 | * OK, there is not extent covering inode->i_size and | 245 | * OK, there is not extent covering inode->i_size and |
244 | * no extent above inode->i_size => truncate is | 246 | * no extent above inode->i_size => truncate is |
245 | * extending the file by 'offset'. | 247 | * extending the file by 'offset' blocks. |
246 | */ | 248 | */ |
247 | if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) || | 249 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || |
248 | (bh && extoffset == sizeof(struct allocExtDesc))) { | 250 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { |
249 | /* File has no extents at all! */ | 251 | /* File has no extents at all or has empty last |
250 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | 252 | * indirect extent! Create a fake extent... */ |
251 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; | 253 | extent.extLocation.logicalBlockNum = 0; |
252 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); | 254 | extent.extLocation.partitionReferenceNum = 0; |
255 | extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; | ||
253 | } | 256 | } |
254 | else { | 257 | else { |
255 | extoffset -= adsize; | 258 | epos.offset -= adsize; |
256 | etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); | 259 | etype = udf_next_aext(inode, &epos, |
257 | if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) | 260 | &extent.extLocation, &extent.extLength, 0); |
258 | { | 261 | extent.extLength |= etype << 30; |
259 | extoffset -= adsize; | ||
260 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset); | ||
261 | udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); | ||
262 | } | ||
263 | else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | ||
264 | { | ||
265 | kernel_lb_addr neloc = { 0, 0 }; | ||
266 | extoffset -= adsize; | ||
267 | nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
268 | ((elen + offset + inode->i_sb->s_blocksize - 1) & | ||
269 | ~(inode->i_sb->s_blocksize - 1)); | ||
270 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); | ||
271 | udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); | ||
272 | } | ||
273 | else | ||
274 | { | ||
275 | if (elen & (inode->i_sb->s_blocksize - 1)) | ||
276 | { | ||
277 | extoffset -= adsize; | ||
278 | elen = EXT_RECORDED_ALLOCATED | | ||
279 | ((elen + inode->i_sb->s_blocksize - 1) & | ||
280 | ~(inode->i_sb->s_blocksize - 1)); | ||
281 | udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); | ||
282 | } | ||
283 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | ||
284 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; | ||
285 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); | ||
286 | } | ||
287 | } | 262 | } |
263 | udf_extend_file(inode, &epos, &extent, offset+((inode->i_size & (sb->s_blocksize-1)) != 0)); | ||
288 | } | 264 | } |
289 | } | 265 | } |
290 | UDF_I_LENEXTENTS(inode) = inode->i_size; | 266 | UDF_I_LENEXTENTS(inode) = inode->i_size; |
291 | 267 | ||
292 | udf_release_data(bh); | 268 | brelse(epos.bh); |
293 | } | 269 | } |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 110f8d62616f..3b2e6c8cb151 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -93,7 +93,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb) | |||
93 | for (i=0; i<nr_groups; i++)\ | 93 | for (i=0; i<nr_groups; i++)\ |
94 | {\ | 94 | {\ |
95 | if (UDF_SB_BITMAP(X,Y,Z,i))\ | 95 | if (UDF_SB_BITMAP(X,Y,Z,i))\ |
96 | udf_release_data(UDF_SB_BITMAP(X,Y,Z,i));\ | 96 | brelse(UDF_SB_BITMAP(X,Y,Z,i));\ |
97 | }\ | 97 | }\ |
98 | if (size <= PAGE_SIZE)\ | 98 | if (size <= PAGE_SIZE)\ |
99 | kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\ | 99 | kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\ |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index ee1dece1f6f5..67ded289497c 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -77,6 +77,13 @@ struct ustr | |||
77 | uint8_t u_len; | 77 | uint8_t u_len; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | struct extent_position { | ||
81 | struct buffer_head *bh; | ||
82 | uint32_t offset; | ||
83 | kernel_lb_addr block; | ||
84 | }; | ||
85 | |||
86 | |||
80 | /* super.c */ | 87 | /* super.c */ |
81 | extern void udf_error(struct super_block *, const char *, const char *, ...); | 88 | extern void udf_error(struct super_block *, const char *, const char *, ...); |
82 | extern void udf_warning(struct super_block *, const char *, const char *, ...); | 89 | extern void udf_warning(struct super_block *, const char *, const char *, ...); |
@@ -98,13 +105,14 @@ extern void udf_read_inode(struct inode *); | |||
98 | extern void udf_delete_inode(struct inode *); | 105 | extern void udf_delete_inode(struct inode *); |
99 | extern void udf_clear_inode(struct inode *); | 106 | extern void udf_clear_inode(struct inode *); |
100 | extern int udf_write_inode(struct inode *, int); | 107 | extern int udf_write_inode(struct inode *, int); |
101 | extern long udf_block_map(struct inode *, long); | 108 | extern long udf_block_map(struct inode *, sector_t); |
102 | extern int8_t inode_bmap(struct inode *, int, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **); | 109 | extern int udf_extend_file(struct inode *, struct extent_position *, kernel_long_ad *, sector_t); |
103 | extern int8_t udf_add_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr, uint32_t, struct buffer_head **, int); | 110 | extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *); |
104 | extern int8_t udf_write_aext(struct inode *, kernel_lb_addr, int *, kernel_lb_addr, uint32_t, struct buffer_head *, int); | 111 | extern int8_t udf_add_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int); |
105 | extern int8_t udf_delete_aext(struct inode *, kernel_lb_addr, int, kernel_lb_addr, uint32_t, struct buffer_head *); | 112 | extern int8_t udf_write_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int); |
106 | extern int8_t udf_next_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int); | 113 | extern int8_t udf_delete_aext(struct inode *, struct extent_position, kernel_lb_addr, uint32_t); |
107 | extern int8_t udf_current_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int); | 114 | extern int8_t udf_next_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); |
115 | extern int8_t udf_current_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); | ||
108 | 116 | ||
109 | /* misc.c */ | 117 | /* misc.c */ |
110 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); | 118 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); |
@@ -113,7 +121,6 @@ extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, uint | |||
113 | extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t); | 121 | extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t); |
114 | extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *); | 122 | extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *); |
115 | extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *); | 123 | extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *); |
116 | extern void udf_release_data(struct buffer_head *); | ||
117 | extern void udf_update_tag(char *, int); | 124 | extern void udf_update_tag(char *, int); |
118 | extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); | 125 | extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); |
119 | 126 | ||
@@ -151,7 +158,7 @@ extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_ | |||
151 | extern int udf_fsync_file(struct file *, struct dentry *, int); | 158 | extern int udf_fsync_file(struct file *, struct dentry *, int); |
152 | 159 | ||
153 | /* directory.c */ | 160 | /* directory.c */ |
154 | extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **); | 161 | extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *); |
155 | extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset); | 162 | extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset); |
156 | extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int); | 163 | extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int); |
157 | extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int); | 164 | extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int); |
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 4fb8b2e077ee..154452172f43 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/time.h> | 19 | #include <linux/time.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/ufs_fs.h> | 21 | #include <linux/ufs_fs.h> |
22 | #include <linux/smp_lock.h> | ||
23 | 22 | ||
24 | #include "swab.h" | 23 | #include "swab.h" |
25 | #include "util.h" | 24 | #include "util.h" |
diff --git a/fs/utimes.c b/fs/utimes.c index 99cf2cb11fec..480f7c8c29da 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -1,8 +1,10 @@ | |||
1 | #include <linux/compiler.h> | 1 | #include <linux/compiler.h> |
2 | #include <linux/file.h> | ||
2 | #include <linux/fs.h> | 3 | #include <linux/fs.h> |
3 | #include <linux/linkage.h> | 4 | #include <linux/linkage.h> |
4 | #include <linux/namei.h> | 5 | #include <linux/namei.h> |
5 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/stat.h> | ||
6 | #include <linux/utime.h> | 8 | #include <linux/utime.h> |
7 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
8 | #include <asm/unistd.h> | 10 | #include <asm/unistd.h> |
@@ -20,54 +22,18 @@ | |||
20 | * must be owner or have write permission. | 22 | * must be owner or have write permission. |
21 | * Else, update from *times, must be owner or super user. | 23 | * Else, update from *times, must be owner or super user. |
22 | */ | 24 | */ |
23 | asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) | 25 | asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) |
24 | { | 26 | { |
25 | int error; | 27 | struct timespec tv[2]; |
26 | struct nameidata nd; | ||
27 | struct inode * inode; | ||
28 | struct iattr newattrs; | ||
29 | 28 | ||
30 | error = user_path_walk(filename, &nd); | ||
31 | if (error) | ||
32 | goto out; | ||
33 | inode = nd.dentry->d_inode; | ||
34 | |||
35 | error = -EROFS; | ||
36 | if (IS_RDONLY(inode)) | ||
37 | goto dput_and_out; | ||
38 | |||
39 | /* Don't worry, the checks are done in inode_change_ok() */ | ||
40 | newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; | ||
41 | if (times) { | 29 | if (times) { |
42 | error = -EPERM; | 30 | if (get_user(tv[0].tv_sec, ×->actime) || |
43 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 31 | get_user(tv[1].tv_sec, ×->modtime)) |
44 | goto dput_and_out; | 32 | return -EFAULT; |
45 | 33 | tv[0].tv_nsec = 0; | |
46 | error = get_user(newattrs.ia_atime.tv_sec, ×->actime); | 34 | tv[1].tv_nsec = 0; |
47 | newattrs.ia_atime.tv_nsec = 0; | ||
48 | if (!error) | ||
49 | error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime); | ||
50 | newattrs.ia_mtime.tv_nsec = 0; | ||
51 | if (error) | ||
52 | goto dput_and_out; | ||
53 | |||
54 | newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; | ||
55 | } else { | ||
56 | error = -EACCES; | ||
57 | if (IS_IMMUTABLE(inode)) | ||
58 | goto dput_and_out; | ||
59 | |||
60 | if (current->fsuid != inode->i_uid && | ||
61 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | ||
62 | goto dput_and_out; | ||
63 | } | 35 | } |
64 | mutex_lock(&inode->i_mutex); | 36 | return do_utimes(AT_FDCWD, filename, times ? tv : NULL, 0); |
65 | error = notify_change(nd.dentry, &newattrs); | ||
66 | mutex_unlock(&inode->i_mutex); | ||
67 | dput_and_out: | ||
68 | path_release(&nd); | ||
69 | out: | ||
70 | return error; | ||
71 | } | 37 | } |
72 | 38 | ||
73 | #endif | 39 | #endif |
@@ -76,18 +42,38 @@ out: | |||
76 | * must be owner or have write permission. | 42 | * must be owner or have write permission. |
77 | * Else, update from *times, must be owner or super user. | 43 | * Else, update from *times, must be owner or super user. |
78 | */ | 44 | */ |
79 | long do_utimes(int dfd, char __user *filename, struct timeval *times) | 45 | long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags) |
80 | { | 46 | { |
81 | int error; | 47 | int error; |
82 | struct nameidata nd; | 48 | struct nameidata nd; |
83 | struct inode * inode; | 49 | struct dentry *dentry; |
50 | struct inode *inode; | ||
84 | struct iattr newattrs; | 51 | struct iattr newattrs; |
52 | struct file *f = NULL; | ||
85 | 53 | ||
86 | error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); | 54 | error = -EINVAL; |
87 | 55 | if (flags & ~AT_SYMLINK_NOFOLLOW) | |
88 | if (error) | ||
89 | goto out; | 56 | goto out; |
90 | inode = nd.dentry->d_inode; | 57 | |
58 | if (filename == NULL && dfd != AT_FDCWD) { | ||
59 | error = -EINVAL; | ||
60 | if (flags & AT_SYMLINK_NOFOLLOW) | ||
61 | goto out; | ||
62 | |||
63 | error = -EBADF; | ||
64 | f = fget(dfd); | ||
65 | if (!f) | ||
66 | goto out; | ||
67 | dentry = f->f_path.dentry; | ||
68 | } else { | ||
69 | error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); | ||
70 | if (error) | ||
71 | goto out; | ||
72 | |||
73 | dentry = nd.dentry; | ||
74 | } | ||
75 | |||
76 | inode = dentry->d_inode; | ||
91 | 77 | ||
92 | error = -EROFS; | 78 | error = -EROFS; |
93 | if (IS_RDONLY(inode)) | 79 | if (IS_RDONLY(inode)) |
@@ -100,11 +86,21 @@ long do_utimes(int dfd, char __user *filename, struct timeval *times) | |||
100 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 86 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
101 | goto dput_and_out; | 87 | goto dput_and_out; |
102 | 88 | ||
103 | newattrs.ia_atime.tv_sec = times[0].tv_sec; | 89 | if (times[0].tv_nsec == UTIME_OMIT) |
104 | newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000; | 90 | newattrs.ia_valid &= ~ATTR_ATIME; |
105 | newattrs.ia_mtime.tv_sec = times[1].tv_sec; | 91 | else if (times[0].tv_nsec != UTIME_NOW) { |
106 | newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000; | 92 | newattrs.ia_atime.tv_sec = times[0].tv_sec; |
107 | newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; | 93 | newattrs.ia_atime.tv_nsec = times[0].tv_nsec; |
94 | newattrs.ia_valid |= ATTR_ATIME_SET; | ||
95 | } | ||
96 | |||
97 | if (times[1].tv_nsec == UTIME_OMIT) | ||
98 | newattrs.ia_valid &= ~ATTR_MTIME; | ||
99 | else if (times[1].tv_nsec != UTIME_NOW) { | ||
100 | newattrs.ia_mtime.tv_sec = times[1].tv_sec; | ||
101 | newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; | ||
102 | newattrs.ia_valid |= ATTR_MTIME_SET; | ||
103 | } | ||
108 | } else { | 104 | } else { |
109 | error = -EACCES; | 105 | error = -EACCES; |
110 | if (IS_IMMUTABLE(inode)) | 106 | if (IS_IMMUTABLE(inode)) |
@@ -115,21 +111,67 @@ long do_utimes(int dfd, char __user *filename, struct timeval *times) | |||
115 | goto dput_and_out; | 111 | goto dput_and_out; |
116 | } | 112 | } |
117 | mutex_lock(&inode->i_mutex); | 113 | mutex_lock(&inode->i_mutex); |
118 | error = notify_change(nd.dentry, &newattrs); | 114 | error = notify_change(dentry, &newattrs); |
119 | mutex_unlock(&inode->i_mutex); | 115 | mutex_unlock(&inode->i_mutex); |
120 | dput_and_out: | 116 | dput_and_out: |
121 | path_release(&nd); | 117 | if (f) |
118 | fput(f); | ||
119 | else | ||
120 | path_release(&nd); | ||
122 | out: | 121 | out: |
123 | return error; | 122 | return error; |
124 | } | 123 | } |
125 | 124 | ||
125 | asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __user *utimes, int flags) | ||
126 | { | ||
127 | struct timespec tstimes[2]; | ||
128 | |||
129 | if (utimes) { | ||
130 | if (copy_from_user(&tstimes, utimes, sizeof(tstimes))) | ||
131 | return -EFAULT; | ||
132 | if ((tstimes[0].tv_nsec == UTIME_OMIT || | ||
133 | tstimes[0].tv_nsec == UTIME_NOW) && | ||
134 | tstimes[0].tv_sec != 0) | ||
135 | return -EINVAL; | ||
136 | if ((tstimes[1].tv_nsec == UTIME_OMIT || | ||
137 | tstimes[1].tv_nsec == UTIME_NOW) && | ||
138 | tstimes[1].tv_sec != 0) | ||
139 | return -EINVAL; | ||
140 | |||
141 | /* Nothing to do, we must not even check the path. */ | ||
142 | if (tstimes[0].tv_nsec == UTIME_OMIT && | ||
143 | tstimes[1].tv_nsec == UTIME_OMIT) | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | return do_utimes(dfd, filename, utimes ? tstimes : NULL, flags); | ||
148 | } | ||
149 | |||
126 | asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) | 150 | asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) |
127 | { | 151 | { |
128 | struct timeval times[2]; | 152 | struct timeval times[2]; |
153 | struct timespec tstimes[2]; | ||
154 | |||
155 | if (utimes) { | ||
156 | if (copy_from_user(×, utimes, sizeof(times))) | ||
157 | return -EFAULT; | ||
158 | |||
159 | /* This test is needed to catch all invalid values. If we | ||
160 | would test only in do_utimes we would miss those invalid | ||
161 | values truncated by the multiplication with 1000. Note | ||
162 | that we also catch UTIME_{NOW,OMIT} here which are only | ||
163 | valid for utimensat. */ | ||
164 | if (times[0].tv_usec >= 1000000 || times[0].tv_usec < 0 || | ||
165 | times[1].tv_usec >= 1000000 || times[1].tv_usec < 0) | ||
166 | return -EINVAL; | ||
167 | |||
168 | tstimes[0].tv_sec = times[0].tv_sec; | ||
169 | tstimes[0].tv_nsec = 1000 * times[0].tv_usec; | ||
170 | tstimes[1].tv_sec = times[1].tv_sec; | ||
171 | tstimes[1].tv_nsec = 1000 * times[1].tv_usec; | ||
172 | } | ||
129 | 173 | ||
130 | if (utimes && copy_from_user(×, utimes, sizeof(times))) | 174 | return do_utimes(dfd, filename, utimes ? tstimes : NULL, 0); |
131 | return -EFAULT; | ||
132 | return do_utimes(dfd, filename, utimes ? times : NULL); | ||
133 | } | 175 | } |
134 | 176 | ||
135 | asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) | 177 | asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) |
diff --git a/fs/xattr.c b/fs/xattr.c index 38646132ab0e..9f4568b55b0f 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/file.h> | 12 | #include <linux/file.h> |
14 | #include <linux/xattr.h> | 13 | #include <linux/xattr.h> |
15 | #include <linux/namei.h> | 14 | #include <linux/namei.h> |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index ff8d64eba9f8..558076dd0752 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -639,7 +639,6 @@ xfs_write( | |||
639 | xfs_fsize_t isize, new_size; | 639 | xfs_fsize_t isize, new_size; |
640 | xfs_iocore_t *io; | 640 | xfs_iocore_t *io; |
641 | bhv_vnode_t *vp; | 641 | bhv_vnode_t *vp; |
642 | unsigned long seg; | ||
643 | int iolock; | 642 | int iolock; |
644 | int eventsent = 0; | 643 | int eventsent = 0; |
645 | bhv_vrwlock_t locktype; | 644 | bhv_vrwlock_t locktype; |
@@ -652,24 +651,9 @@ xfs_write( | |||
652 | vp = BHV_TO_VNODE(bdp); | 651 | vp = BHV_TO_VNODE(bdp); |
653 | xip = XFS_BHVTOI(bdp); | 652 | xip = XFS_BHVTOI(bdp); |
654 | 653 | ||
655 | for (seg = 0; seg < segs; seg++) { | 654 | error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ); |
656 | const struct iovec *iv = &iovp[seg]; | 655 | if (error) |
657 | 656 | return error; | |
658 | /* | ||
659 | * If any segment has a negative length, or the cumulative | ||
660 | * length ever wraps negative then return -EINVAL. | ||
661 | */ | ||
662 | ocount += iv->iov_len; | ||
663 | if (unlikely((ssize_t)(ocount|iv->iov_len) < 0)) | ||
664 | return -EINVAL; | ||
665 | if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len)) | ||
666 | continue; | ||
667 | if (seg == 0) | ||
668 | return -EFAULT; | ||
669 | segs = seg; | ||
670 | ocount -= iv->iov_len; /* This segment is no good */ | ||
671 | break; | ||
672 | } | ||
673 | 657 | ||
674 | count = ocount; | 658 | count = ocount; |
675 | pos = *offset; | 659 | pos = *offset; |