diff options
Diffstat (limited to 'fs')
50 files changed, 408 insertions, 380 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index ab5547ff29a1..38d695d66a0b 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/mount.h> | 37 | #include <linux/mount.h> |
38 | #include <linux/idr.h> | 38 | #include <linux/idr.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <net/9p/9p.h> | 40 | #include <net/9p/9p.h> |
42 | #include <net/9p/client.h> | 41 | #include <net/9p/client.h> |
43 | 42 | ||
@@ -231,10 +230,8 @@ v9fs_umount_begin(struct super_block *sb) | |||
231 | { | 230 | { |
232 | struct v9fs_session_info *v9ses; | 231 | struct v9fs_session_info *v9ses; |
233 | 232 | ||
234 | lock_kernel(); | ||
235 | v9ses = sb->s_fs_info; | 233 | v9ses = sb->s_fs_info; |
236 | v9fs_session_cancel(v9ses); | 234 | v9fs_session_cancel(v9ses); |
237 | unlock_kernel(); | ||
238 | } | 235 | } |
239 | 236 | ||
240 | static const struct super_operations v9fs_super_ops = { | 237 | static const struct super_operations v9fs_super_ops = { |
diff --git a/fs/Kconfig b/fs/Kconfig index 4044f163035f..d78e950402c1 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -134,7 +134,7 @@ config TMPFS_POSIX_ACL | |||
134 | config HUGETLBFS | 134 | config HUGETLBFS |
135 | bool "HugeTLB file system support" | 135 | bool "HugeTLB file system support" |
136 | depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \ | 136 | depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \ |
137 | (S390 && 64BIT) || BROKEN | 137 | (S390 && 64BIT) || SYS_SUPPORTS_HUGETLBFS || BROKEN |
138 | help | 138 | help |
139 | hugetlbfs is a filesystem backing for HugeTLB pages, based on | 139 | hugetlbfs is a filesystem backing for HugeTLB pages, based on |
140 | ramfs. For architectures that support it, say Y here and read | 140 | ramfs. For architectures that support it, say Y here and read |
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h index a6665f37f456..9cc18775b832 100644 --- a/fs/adfs/adfs.h +++ b/fs/adfs/adfs.h | |||
@@ -1,3 +1,6 @@ | |||
1 | #include <linux/fs.h> | ||
2 | #include <linux/adfs_fs.h> | ||
3 | |||
1 | /* Internal data structures for ADFS */ | 4 | /* Internal data structures for ADFS */ |
2 | 5 | ||
3 | #define ADFS_FREE_FRAG 0 | 6 | #define ADFS_FREE_FRAG 0 |
@@ -17,6 +20,58 @@ | |||
17 | struct buffer_head; | 20 | struct buffer_head; |
18 | 21 | ||
19 | /* | 22 | /* |
23 | * adfs file system inode data in memory | ||
24 | */ | ||
25 | struct adfs_inode_info { | ||
26 | loff_t mmu_private; | ||
27 | unsigned long parent_id; /* object id of parent */ | ||
28 | __u32 loadaddr; /* RISC OS load address */ | ||
29 | __u32 execaddr; /* RISC OS exec address */ | ||
30 | unsigned int filetype; /* RISC OS file type */ | ||
31 | unsigned int attr; /* RISC OS permissions */ | ||
32 | unsigned int stamped:1; /* RISC OS file has date/time */ | ||
33 | struct inode vfs_inode; | ||
34 | }; | ||
35 | |||
36 | /* | ||
37 | * Forward-declare this | ||
38 | */ | ||
39 | struct adfs_discmap; | ||
40 | struct adfs_dir_ops; | ||
41 | |||
42 | /* | ||
43 | * ADFS file system superblock data in memory | ||
44 | */ | ||
45 | struct adfs_sb_info { | ||
46 | struct adfs_discmap *s_map; /* bh list containing map */ | ||
47 | struct adfs_dir_ops *s_dir; /* directory operations */ | ||
48 | |||
49 | uid_t s_uid; /* owner uid */ | ||
50 | gid_t s_gid; /* owner gid */ | ||
51 | umode_t s_owner_mask; /* ADFS owner perm -> unix perm */ | ||
52 | umode_t s_other_mask; /* ADFS other perm -> unix perm */ | ||
53 | |||
54 | __u32 s_ids_per_zone; /* max. no ids in one zone */ | ||
55 | __u32 s_idlen; /* length of ID in map */ | ||
56 | __u32 s_map_size; /* sector size of a map */ | ||
57 | unsigned long s_size; /* total size (in blocks) of this fs */ | ||
58 | signed int s_map2blk; /* shift left by this for map->sector */ | ||
59 | unsigned int s_log2sharesize;/* log2 share size */ | ||
60 | __le32 s_version; /* disc format version */ | ||
61 | unsigned int s_namelen; /* maximum number of characters in name */ | ||
62 | }; | ||
63 | |||
64 | static inline struct adfs_sb_info *ADFS_SB(struct super_block *sb) | ||
65 | { | ||
66 | return sb->s_fs_info; | ||
67 | } | ||
68 | |||
69 | static inline struct adfs_inode_info *ADFS_I(struct inode *inode) | ||
70 | { | ||
71 | return container_of(inode, struct adfs_inode_info, vfs_inode); | ||
72 | } | ||
73 | |||
74 | /* | ||
20 | * Directory handling | 75 | * Directory handling |
21 | */ | 76 | */ |
22 | struct adfs_dir { | 77 | struct adfs_dir { |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index 4d4073447d1a..23aa52f548a0 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -9,15 +9,7 @@ | |||
9 | * | 9 | * |
10 | * Common directory handling for ADFS | 10 | * Common directory handling for ADFS |
11 | */ | 11 | */ |
12 | #include <linux/errno.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/adfs_fs.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/stat.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/smp_lock.h> | 12 | #include <linux/smp_lock.h> |
19 | #include <linux/buffer_head.h> /* for file_fsync() */ | ||
20 | |||
21 | #include "adfs.h" | 13 | #include "adfs.h" |
22 | 14 | ||
23 | /* | 15 | /* |
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c index 31df6adf0de6..bafc71222e25 100644 --- a/fs/adfs/dir_f.c +++ b/fs/adfs/dir_f.c | |||
@@ -9,15 +9,7 @@ | |||
9 | * | 9 | * |
10 | * E and F format directory handling | 10 | * E and F format directory handling |
11 | */ | 11 | */ |
12 | #include <linux/errno.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/adfs_fs.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/stat.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/buffer_head.h> | 12 | #include <linux/buffer_head.h> |
19 | #include <linux/string.h> | ||
20 | |||
21 | #include "adfs.h" | 13 | #include "adfs.h" |
22 | #include "dir_f.h" | 14 | #include "dir_f.h" |
23 | 15 | ||
diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c index 139e0f345f18..1796bb352d05 100644 --- a/fs/adfs/dir_fplus.c +++ b/fs/adfs/dir_fplus.c | |||
@@ -7,15 +7,7 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/errno.h> | ||
11 | #include <linux/fs.h> | ||
12 | #include <linux/adfs_fs.h> | ||
13 | #include <linux/time.h> | ||
14 | #include <linux/stat.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
17 | #include <linux/string.h> | ||
18 | |||
19 | #include "adfs.h" | 11 | #include "adfs.h" |
20 | #include "dir_fplus.h" | 12 | #include "dir_fplus.h" |
21 | 13 | ||
diff --git a/fs/adfs/file.c b/fs/adfs/file.c index 8224d54a2afb..005ea34d1758 100644 --- a/fs/adfs/file.c +++ b/fs/adfs/file.c | |||
@@ -19,10 +19,6 @@ | |||
19 | * | 19 | * |
20 | * adfs regular file handling primitives | 20 | * adfs regular file handling primitives |
21 | */ | 21 | */ |
22 | #include <linux/fs.h> | ||
23 | #include <linux/buffer_head.h> /* for file_fsync() */ | ||
24 | #include <linux/adfs_fs.h> | ||
25 | |||
26 | #include "adfs.h" | 22 | #include "adfs.h" |
27 | 23 | ||
28 | const struct file_operations adfs_file_operations = { | 24 | const struct file_operations adfs_file_operations = { |
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 05b3a677201d..798cb071d132 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c | |||
@@ -7,17 +7,8 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/errno.h> | ||
11 | #include <linux/fs.h> | ||
12 | #include <linux/adfs_fs.h> | ||
13 | #include <linux/time.h> | ||
14 | #include <linux/stat.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/mm.h> | ||
17 | #include <linux/smp_lock.h> | 10 | #include <linux/smp_lock.h> |
18 | #include <linux/module.h> | ||
19 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
20 | |||
21 | #include "adfs.h" | 12 | #include "adfs.h" |
22 | 13 | ||
23 | /* | 14 | /* |
@@ -395,4 +386,3 @@ int adfs_write_inode(struct inode *inode, int wait) | |||
395 | unlock_kernel(); | 386 | unlock_kernel(); |
396 | return ret; | 387 | return ret; |
397 | } | 388 | } |
398 | MODULE_LICENSE("GPL"); | ||
diff --git a/fs/adfs/map.c b/fs/adfs/map.c index 568081b93f73..d1a5932bb0f1 100644 --- a/fs/adfs/map.c +++ b/fs/adfs/map.c | |||
@@ -7,14 +7,8 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/errno.h> | ||
11 | #include <linux/fs.h> | ||
12 | #include <linux/adfs_fs.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
15 | |||
16 | #include <asm/unaligned.h> | 11 | #include <asm/unaligned.h> |
17 | |||
18 | #include "adfs.h" | 12 | #include "adfs.h" |
19 | 13 | ||
20 | /* | 14 | /* |
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 0ec5aaf47aa7..aad92f0a1048 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -8,26 +8,12 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/errno.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/adfs_fs.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/stat.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/init.h> | 11 | #include <linux/init.h> |
19 | #include <linux/buffer_head.h> | 12 | #include <linux/buffer_head.h> |
20 | #include <linux/vfs.h> | ||
21 | #include <linux/parser.h> | 13 | #include <linux/parser.h> |
22 | #include <linux/bitops.h> | ||
23 | #include <linux/mount.h> | 14 | #include <linux/mount.h> |
24 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
25 | 16 | #include <linux/statfs.h> | |
26 | #include <asm/uaccess.h> | ||
27 | #include <asm/system.h> | ||
28 | |||
29 | #include <stdarg.h> | ||
30 | |||
31 | #include "adfs.h" | 17 | #include "adfs.h" |
32 | #include "dir_f.h" | 18 | #include "dir_f.h" |
33 | #include "dir_fplus.h" | 19 | #include "dir_fplus.h" |
@@ -534,3 +520,4 @@ static void __exit exit_adfs_fs(void) | |||
534 | 520 | ||
535 | module_init(init_adfs_fs) | 521 | module_init(init_adfs_fs) |
536 | module_exit(exit_adfs_fs) | 522 | module_exit(exit_adfs_fs) |
523 | MODULE_LICENSE("GPL"); | ||
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 89cd2deeb4af..615d5496fe0f 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -735,8 +735,6 @@ parse_options(char *options, befs_mount_options * opts) | |||
735 | static void | 735 | static void |
736 | befs_put_super(struct super_block *sb) | 736 | befs_put_super(struct super_block *sb) |
737 | { | 737 | { |
738 | lock_kernel(); | ||
739 | |||
740 | kfree(BEFS_SB(sb)->mount_opts.iocharset); | 738 | kfree(BEFS_SB(sb)->mount_opts.iocharset); |
741 | BEFS_SB(sb)->mount_opts.iocharset = NULL; | 739 | BEFS_SB(sb)->mount_opts.iocharset = NULL; |
742 | 740 | ||
@@ -747,8 +745,6 @@ befs_put_super(struct super_block *sb) | |||
747 | 745 | ||
748 | kfree(sb->s_fs_info); | 746 | kfree(sb->s_fs_info); |
749 | sb->s_fs_info = NULL; | 747 | sb->s_fs_info = NULL; |
750 | |||
751 | unlock_kernel(); | ||
752 | } | 748 | } |
753 | 749 | ||
754 | /* Allocate private field of the superblock, fill it. | 750 | /* Allocate private field of the superblock, fill it. |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 40381df34869..9fa212b014a5 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1340,8 +1340,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1340 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; | 1340 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; |
1341 | prstatus->pr_sigpend = p->pending.signal.sig[0]; | 1341 | prstatus->pr_sigpend = p->pending.signal.sig[0]; |
1342 | prstatus->pr_sighold = p->blocked.sig[0]; | 1342 | prstatus->pr_sighold = p->blocked.sig[0]; |
1343 | rcu_read_lock(); | ||
1344 | prstatus->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | ||
1345 | rcu_read_unlock(); | ||
1343 | prstatus->pr_pid = task_pid_vnr(p); | 1346 | prstatus->pr_pid = task_pid_vnr(p); |
1344 | prstatus->pr_ppid = task_pid_vnr(p->real_parent); | ||
1345 | prstatus->pr_pgrp = task_pgrp_vnr(p); | 1347 | prstatus->pr_pgrp = task_pgrp_vnr(p); |
1346 | prstatus->pr_sid = task_session_vnr(p); | 1348 | prstatus->pr_sid = task_session_vnr(p); |
1347 | if (thread_group_leader(p)) { | 1349 | if (thread_group_leader(p)) { |
@@ -1382,8 +1384,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1382 | psinfo->pr_psargs[i] = ' '; | 1384 | psinfo->pr_psargs[i] = ' '; |
1383 | psinfo->pr_psargs[len] = 0; | 1385 | psinfo->pr_psargs[len] = 0; |
1384 | 1386 | ||
1387 | rcu_read_lock(); | ||
1388 | psinfo->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | ||
1389 | rcu_read_unlock(); | ||
1385 | psinfo->pr_pid = task_pid_vnr(p); | 1390 | psinfo->pr_pid = task_pid_vnr(p); |
1386 | psinfo->pr_ppid = task_pid_vnr(p->real_parent); | ||
1387 | psinfo->pr_pgrp = task_pgrp_vnr(p); | 1391 | psinfo->pr_pgrp = task_pgrp_vnr(p); |
1388 | psinfo->pr_sid = task_session_vnr(p); | 1392 | psinfo->pr_sid = task_session_vnr(p); |
1389 | 1393 | ||
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index fdb66faa24f1..20fbeced472b 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1387,8 +1387,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1387 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; | 1387 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; |
1388 | prstatus->pr_sigpend = p->pending.signal.sig[0]; | 1388 | prstatus->pr_sigpend = p->pending.signal.sig[0]; |
1389 | prstatus->pr_sighold = p->blocked.sig[0]; | 1389 | prstatus->pr_sighold = p->blocked.sig[0]; |
1390 | rcu_read_lock(); | ||
1391 | prstatus->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | ||
1392 | rcu_read_unlock(); | ||
1390 | prstatus->pr_pid = task_pid_vnr(p); | 1393 | prstatus->pr_pid = task_pid_vnr(p); |
1391 | prstatus->pr_ppid = task_pid_vnr(p->real_parent); | ||
1392 | prstatus->pr_pgrp = task_pgrp_vnr(p); | 1394 | prstatus->pr_pgrp = task_pgrp_vnr(p); |
1393 | prstatus->pr_sid = task_session_vnr(p); | 1395 | prstatus->pr_sid = task_session_vnr(p); |
1394 | if (thread_group_leader(p)) { | 1396 | if (thread_group_leader(p)) { |
@@ -1432,8 +1434,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1432 | psinfo->pr_psargs[i] = ' '; | 1434 | psinfo->pr_psargs[i] = ' '; |
1433 | psinfo->pr_psargs[len] = 0; | 1435 | psinfo->pr_psargs[len] = 0; |
1434 | 1436 | ||
1437 | rcu_read_lock(); | ||
1438 | psinfo->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | ||
1439 | rcu_read_unlock(); | ||
1435 | psinfo->pr_pid = task_pid_vnr(p); | 1440 | psinfo->pr_pid = task_pid_vnr(p); |
1436 | psinfo->pr_ppid = task_pid_vnr(p->real_parent); | ||
1437 | psinfo->pr_pgrp = task_pgrp_vnr(p); | 1441 | psinfo->pr_pgrp = task_pgrp_vnr(p); |
1438 | psinfo->pr_sid = task_session_vnr(p); | 1442 | psinfo->pr_sid = task_session_vnr(p); |
1439 | 1443 | ||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 0aac371bff0b..c5ded5ff72b5 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -788,12 +788,6 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
788 | if (put_user(compat_ptr(data), &sgio->usr_ptr)) | 788 | if (put_user(compat_ptr(data), &sgio->usr_ptr)) |
789 | return -EFAULT; | 789 | return -EFAULT; |
790 | 790 | ||
791 | if (copy_in_user(&sgio->status, &sgio32->status, | ||
792 | (4 * sizeof(unsigned char)) + | ||
793 | (2 * sizeof(unsigned short)) + | ||
794 | (3 * sizeof(int)))) | ||
795 | return -EFAULT; | ||
796 | |||
797 | err = sys_ioctl(fd, cmd, (unsigned long) sgio); | 791 | err = sys_ioctl(fd, cmd, (unsigned long) sgio); |
798 | 792 | ||
799 | if (err >= 0) { | 793 | if (err >= 0) { |
diff --git a/fs/efs/dir.c b/fs/efs/dir.c index 49308a29798a..7ee6f7e3a608 100644 --- a/fs/efs/dir.c +++ b/fs/efs/dir.c | |||
@@ -5,12 +5,12 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/buffer_head.h> | 7 | #include <linux/buffer_head.h> |
8 | #include <linux/smp_lock.h> | ||
9 | #include "efs.h" | 8 | #include "efs.h" |
10 | 9 | ||
11 | static int efs_readdir(struct file *, void *, filldir_t); | 10 | static int efs_readdir(struct file *, void *, filldir_t); |
12 | 11 | ||
13 | const struct file_operations efs_dir_operations = { | 12 | const struct file_operations efs_dir_operations = { |
13 | .llseek = generic_file_llseek, | ||
14 | .read = generic_read_dir, | 14 | .read = generic_read_dir, |
15 | .readdir = efs_readdir, | 15 | .readdir = efs_readdir, |
16 | }; | 16 | }; |
@@ -33,8 +33,6 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { | |||
33 | if (inode->i_size & (EFS_DIRBSIZE-1)) | 33 | if (inode->i_size & (EFS_DIRBSIZE-1)) |
34 | printk(KERN_WARNING "EFS: WARNING: readdir(): directory size not a multiple of EFS_DIRBSIZE\n"); | 34 | printk(KERN_WARNING "EFS: WARNING: readdir(): directory size not a multiple of EFS_DIRBSIZE\n"); |
35 | 35 | ||
36 | lock_kernel(); | ||
37 | |||
38 | /* work out where this entry can be found */ | 36 | /* work out where this entry can be found */ |
39 | block = filp->f_pos >> EFS_DIRBSIZE_BITS; | 37 | block = filp->f_pos >> EFS_DIRBSIZE_BITS; |
40 | 38 | ||
@@ -107,7 +105,6 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { | |||
107 | 105 | ||
108 | filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot; | 106 | filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot; |
109 | out: | 107 | out: |
110 | unlock_kernel(); | ||
111 | return 0; | 108 | return 0; |
112 | } | 109 | } |
113 | 110 | ||
diff --git a/fs/efs/namei.c b/fs/efs/namei.c index c3fb5f9c4a44..1511bf9e5f80 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/buffer_head.h> | 9 | #include <linux/buffer_head.h> |
10 | #include <linux/string.h> | 10 | #include <linux/string.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/exportfs.h> | 11 | #include <linux/exportfs.h> |
13 | #include "efs.h" | 12 | #include "efs.h" |
14 | 13 | ||
@@ -63,16 +62,12 @@ struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct namei | |||
63 | efs_ino_t inodenum; | 62 | efs_ino_t inodenum; |
64 | struct inode * inode = NULL; | 63 | struct inode * inode = NULL; |
65 | 64 | ||
66 | lock_kernel(); | ||
67 | inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); | 65 | inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); |
68 | if (inodenum) { | 66 | if (inodenum) { |
69 | inode = efs_iget(dir->i_sb, inodenum); | 67 | inode = efs_iget(dir->i_sb, inodenum); |
70 | if (IS_ERR(inode)) { | 68 | if (IS_ERR(inode)) |
71 | unlock_kernel(); | ||
72 | return ERR_CAST(inode); | 69 | return ERR_CAST(inode); |
73 | } | ||
74 | } | 70 | } |
75 | unlock_kernel(); | ||
76 | 71 | ||
77 | return d_splice_alias(inode, dentry); | 72 | return d_splice_alias(inode, dentry); |
78 | } | 73 | } |
@@ -115,11 +110,9 @@ struct dentry *efs_get_parent(struct dentry *child) | |||
115 | struct dentry *parent = ERR_PTR(-ENOENT); | 110 | struct dentry *parent = ERR_PTR(-ENOENT); |
116 | efs_ino_t ino; | 111 | efs_ino_t ino; |
117 | 112 | ||
118 | lock_kernel(); | ||
119 | ino = efs_find_entry(child->d_inode, "..", 2); | 113 | ino = efs_find_entry(child->d_inode, "..", 2); |
120 | if (ino) | 114 | if (ino) |
121 | parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino)); | 115 | parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino)); |
122 | unlock_kernel(); | ||
123 | 116 | ||
124 | return parent; | 117 | return parent; |
125 | } | 118 | } |
diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 41911ec83aaf..75117d0dac2b 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/pagemap.h> | 10 | #include <linux/pagemap.h> |
11 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include "efs.h" | 12 | #include "efs.h" |
14 | 13 | ||
15 | static int efs_symlink_readpage(struct file *file, struct page *page) | 14 | static int efs_symlink_readpage(struct file *file, struct page *page) |
@@ -22,9 +21,8 @@ static int efs_symlink_readpage(struct file *file, struct page *page) | |||
22 | 21 | ||
23 | err = -ENAMETOOLONG; | 22 | err = -ENAMETOOLONG; |
24 | if (size > 2 * EFS_BLOCKSIZE) | 23 | if (size > 2 * EFS_BLOCKSIZE) |
25 | goto fail_notlocked; | 24 | goto fail; |
26 | 25 | ||
27 | lock_kernel(); | ||
28 | /* read first 512 bytes of link target */ | 26 | /* read first 512 bytes of link target */ |
29 | err = -EIO; | 27 | err = -EIO; |
30 | bh = sb_bread(inode->i_sb, efs_bmap(inode, 0)); | 28 | bh = sb_bread(inode->i_sb, efs_bmap(inode, 0)); |
@@ -40,14 +38,11 @@ static int efs_symlink_readpage(struct file *file, struct page *page) | |||
40 | brelse(bh); | 38 | brelse(bh); |
41 | } | 39 | } |
42 | link[size] = '\0'; | 40 | link[size] = '\0'; |
43 | unlock_kernel(); | ||
44 | SetPageUptodate(page); | 41 | SetPageUptodate(page); |
45 | kunmap(page); | 42 | kunmap(page); |
46 | unlock_page(page); | 43 | unlock_page(page); |
47 | return 0; | 44 | return 0; |
48 | fail: | 45 | fail: |
49 | unlock_kernel(); | ||
50 | fail_notlocked: | ||
51 | SetPageError(page); | 46 | SetPageError(page); |
52 | kunmap(page); | 47 | kunmap(page); |
53 | unlock_page(page); | 48 | unlock_page(page); |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 5458e80fc558..085c5c063420 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -98,7 +98,7 @@ struct epoll_filefd { | |||
98 | struct nested_call_node { | 98 | struct nested_call_node { |
99 | struct list_head llink; | 99 | struct list_head llink; |
100 | void *cookie; | 100 | void *cookie; |
101 | int cpu; | 101 | void *ctx; |
102 | }; | 102 | }; |
103 | 103 | ||
104 | /* | 104 | /* |
@@ -317,17 +317,17 @@ static void ep_nested_calls_init(struct nested_calls *ncalls) | |||
317 | * @nproc: Nested call core function pointer. | 317 | * @nproc: Nested call core function pointer. |
318 | * @priv: Opaque data to be passed to the @nproc callback. | 318 | * @priv: Opaque data to be passed to the @nproc callback. |
319 | * @cookie: Cookie to be used to identify this nested call. | 319 | * @cookie: Cookie to be used to identify this nested call. |
320 | * @ctx: This instance context. | ||
320 | * | 321 | * |
321 | * Returns: Returns the code returned by the @nproc callback, or -1 if | 322 | * Returns: Returns the code returned by the @nproc callback, or -1 if |
322 | * the maximum recursion limit has been exceeded. | 323 | * the maximum recursion limit has been exceeded. |
323 | */ | 324 | */ |
324 | static int ep_call_nested(struct nested_calls *ncalls, int max_nests, | 325 | static int ep_call_nested(struct nested_calls *ncalls, int max_nests, |
325 | int (*nproc)(void *, void *, int), void *priv, | 326 | int (*nproc)(void *, void *, int), void *priv, |
326 | void *cookie) | 327 | void *cookie, void *ctx) |
327 | { | 328 | { |
328 | int error, call_nests = 0; | 329 | int error, call_nests = 0; |
329 | unsigned long flags; | 330 | unsigned long flags; |
330 | int this_cpu = get_cpu(); | ||
331 | struct list_head *lsthead = &ncalls->tasks_call_list; | 331 | struct list_head *lsthead = &ncalls->tasks_call_list; |
332 | struct nested_call_node *tncur; | 332 | struct nested_call_node *tncur; |
333 | struct nested_call_node tnode; | 333 | struct nested_call_node tnode; |
@@ -340,7 +340,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests, | |||
340 | * very much limited. | 340 | * very much limited. |
341 | */ | 341 | */ |
342 | list_for_each_entry(tncur, lsthead, llink) { | 342 | list_for_each_entry(tncur, lsthead, llink) { |
343 | if (tncur->cpu == this_cpu && | 343 | if (tncur->ctx == ctx && |
344 | (tncur->cookie == cookie || ++call_nests > max_nests)) { | 344 | (tncur->cookie == cookie || ++call_nests > max_nests)) { |
345 | /* | 345 | /* |
346 | * Ops ... loop detected or maximum nest level reached. | 346 | * Ops ... loop detected or maximum nest level reached. |
@@ -352,7 +352,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests, | |||
352 | } | 352 | } |
353 | 353 | ||
354 | /* Add the current task and cookie to the list */ | 354 | /* Add the current task and cookie to the list */ |
355 | tnode.cpu = this_cpu; | 355 | tnode.ctx = ctx; |
356 | tnode.cookie = cookie; | 356 | tnode.cookie = cookie; |
357 | list_add(&tnode.llink, lsthead); | 357 | list_add(&tnode.llink, lsthead); |
358 | 358 | ||
@@ -364,10 +364,9 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests, | |||
364 | /* Remove the current task from the list */ | 364 | /* Remove the current task from the list */ |
365 | spin_lock_irqsave(&ncalls->lock, flags); | 365 | spin_lock_irqsave(&ncalls->lock, flags); |
366 | list_del(&tnode.llink); | 366 | list_del(&tnode.llink); |
367 | out_unlock: | 367 | out_unlock: |
368 | spin_unlock_irqrestore(&ncalls->lock, flags); | 368 | spin_unlock_irqrestore(&ncalls->lock, flags); |
369 | 369 | ||
370 | put_cpu(); | ||
371 | return error; | 370 | return error; |
372 | } | 371 | } |
373 | 372 | ||
@@ -408,8 +407,12 @@ static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests) | |||
408 | */ | 407 | */ |
409 | static void ep_poll_safewake(wait_queue_head_t *wq) | 408 | static void ep_poll_safewake(wait_queue_head_t *wq) |
410 | { | 409 | { |
410 | int this_cpu = get_cpu(); | ||
411 | |||
411 | ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS, | 412 | ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS, |
412 | ep_poll_wakeup_proc, NULL, wq); | 413 | ep_poll_wakeup_proc, NULL, wq, (void *) (long) this_cpu); |
414 | |||
415 | put_cpu(); | ||
413 | } | 416 | } |
414 | 417 | ||
415 | /* | 418 | /* |
@@ -663,7 +666,7 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait) | |||
663 | * could re-enter here. | 666 | * could re-enter here. |
664 | */ | 667 | */ |
665 | pollflags = ep_call_nested(&poll_readywalk_ncalls, EP_MAX_NESTS, | 668 | pollflags = ep_call_nested(&poll_readywalk_ncalls, EP_MAX_NESTS, |
666 | ep_poll_readyevents_proc, ep, ep); | 669 | ep_poll_readyevents_proc, ep, ep, current); |
667 | 670 | ||
668 | return pollflags != -1 ? pollflags : 0; | 671 | return pollflags != -1 ? pollflags : 0; |
669 | } | 672 | } |
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 003500498c22..6cde970b0a1a 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -450,7 +450,7 @@ ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child) | |||
450 | 450 | ||
451 | /* Releases the page */ | 451 | /* Releases the page */ |
452 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | 452 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, |
453 | struct page *page, struct inode *inode) | 453 | struct page *page, struct inode *inode, int update_times) |
454 | { | 454 | { |
455 | loff_t pos = page_offset(page) + | 455 | loff_t pos = page_offset(page) + |
456 | (char *) de - (char *) page_address(page); | 456 | (char *) de - (char *) page_address(page); |
@@ -465,7 +465,8 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | |||
465 | ext2_set_de_type(de, inode); | 465 | ext2_set_de_type(de, inode); |
466 | err = ext2_commit_chunk(page, pos, len); | 466 | err = ext2_commit_chunk(page, pos, len); |
467 | ext2_put_page(page); | 467 | ext2_put_page(page); |
468 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 468 | if (update_times) |
469 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | ||
469 | EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; | 470 | EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; |
470 | mark_inode_dirty(dir); | 471 | mark_inode_dirty(dir); |
471 | } | 472 | } |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index f2e5811936d0..d988a718aedb 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -111,7 +111,7 @@ extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct qstr *, | |||
111 | extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *); | 111 | extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *); |
112 | extern int ext2_empty_dir (struct inode *); | 112 | extern int ext2_empty_dir (struct inode *); |
113 | extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **); | 113 | extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **); |
114 | extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *); | 114 | extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int); |
115 | 115 | ||
116 | /* ialloc.c */ | 116 | /* ialloc.c */ |
117 | extern struct inode * ext2_new_inode (struct inode *, int); | 117 | extern struct inode * ext2_new_inode (struct inode *, int); |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 90ea17998a73..6524ecaebb7a 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -320,7 +320,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
320 | if (!new_de) | 320 | if (!new_de) |
321 | goto out_dir; | 321 | goto out_dir; |
322 | inode_inc_link_count(old_inode); | 322 | inode_inc_link_count(old_inode); |
323 | ext2_set_link(new_dir, new_de, new_page, old_inode); | 323 | ext2_set_link(new_dir, new_de, new_page, old_inode, 1); |
324 | new_inode->i_ctime = CURRENT_TIME_SEC; | 324 | new_inode->i_ctime = CURRENT_TIME_SEC; |
325 | if (dir_de) | 325 | if (dir_de) |
326 | drop_nlink(new_inode); | 326 | drop_nlink(new_inode); |
@@ -352,7 +352,8 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
352 | inode_dec_link_count(old_inode); | 352 | inode_dec_link_count(old_inode); |
353 | 353 | ||
354 | if (dir_de) { | 354 | if (dir_de) { |
355 | ext2_set_link(old_inode, dir_de, dir_page, new_dir); | 355 | if (old_dir != new_dir) |
356 | ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0); | ||
356 | inode_dec_link_count(old_dir); | 357 | inode_dec_link_count(old_dir); |
357 | } | 358 | } |
358 | return 0; | 359 | return 0; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index b0248c6d5d4c..05dea8132fc0 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -820,7 +820,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
820 | while (count < maxblocks && count <= blocks_to_boundary) { | 820 | while (count < maxblocks && count <= blocks_to_boundary) { |
821 | ext3_fsblk_t blk; | 821 | ext3_fsblk_t blk; |
822 | 822 | ||
823 | if (!verify_chain(chain, partial)) { | 823 | if (!verify_chain(chain, chain + depth - 1)) { |
824 | /* | 824 | /* |
825 | * Indirect block might be removed by | 825 | * Indirect block might be removed by |
826 | * truncate while we were reading it. | 826 | * truncate while we were reading it. |
@@ -2374,7 +2374,7 @@ void ext3_truncate(struct inode *inode) | |||
2374 | struct page *page; | 2374 | struct page *page; |
2375 | 2375 | ||
2376 | if (!ext3_can_truncate(inode)) | 2376 | if (!ext3_can_truncate(inode)) |
2377 | return; | 2377 | goto out_notrans; |
2378 | 2378 | ||
2379 | if (inode->i_size == 0 && ext3_should_writeback_data(inode)) | 2379 | if (inode->i_size == 0 && ext3_should_writeback_data(inode)) |
2380 | ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE; | 2380 | ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE; |
@@ -2390,7 +2390,7 @@ void ext3_truncate(struct inode *inode) | |||
2390 | page = grab_cache_page(mapping, | 2390 | page = grab_cache_page(mapping, |
2391 | inode->i_size >> PAGE_CACHE_SHIFT); | 2391 | inode->i_size >> PAGE_CACHE_SHIFT); |
2392 | if (!page) | 2392 | if (!page) |
2393 | return; | 2393 | goto out_notrans; |
2394 | } | 2394 | } |
2395 | 2395 | ||
2396 | handle = start_transaction(inode); | 2396 | handle = start_transaction(inode); |
@@ -2401,7 +2401,7 @@ void ext3_truncate(struct inode *inode) | |||
2401 | unlock_page(page); | 2401 | unlock_page(page); |
2402 | page_cache_release(page); | 2402 | page_cache_release(page); |
2403 | } | 2403 | } |
2404 | return; /* AKPM: return what? */ | 2404 | goto out_notrans; |
2405 | } | 2405 | } |
2406 | 2406 | ||
2407 | last_block = (inode->i_size + blocksize-1) | 2407 | last_block = (inode->i_size + blocksize-1) |
@@ -2525,6 +2525,14 @@ out_stop: | |||
2525 | ext3_orphan_del(handle, inode); | 2525 | ext3_orphan_del(handle, inode); |
2526 | 2526 | ||
2527 | ext3_journal_stop(handle); | 2527 | ext3_journal_stop(handle); |
2528 | return; | ||
2529 | out_notrans: | ||
2530 | /* | ||
2531 | * Delete the inode from orphan list so that it doesn't stay there | ||
2532 | * forever and trigger assertion on umount. | ||
2533 | */ | ||
2534 | if (inode->i_nlink) | ||
2535 | ext3_orphan_del(NULL, inode); | ||
2528 | } | 2536 | } |
2529 | 2537 | ||
2530 | static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, | 2538 | static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, |
@@ -3122,12 +3130,6 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
3122 | 3130 | ||
3123 | rc = inode_setattr(inode, attr); | 3131 | rc = inode_setattr(inode, attr); |
3124 | 3132 | ||
3125 | /* If inode_setattr's call to ext3_truncate failed to get a | ||
3126 | * transaction handle at all, we need to clean up the in-core | ||
3127 | * orphan list manually. */ | ||
3128 | if (inode->i_nlink) | ||
3129 | ext3_orphan_del(NULL, inode); | ||
3130 | |||
3131 | if (!rc && (ia_valid & ATTR_MODE)) | 3133 | if (!rc && (ia_valid & ATTR_MODE)) |
3132 | rc = ext3_acl_chmod(inode); | 3134 | rc = ext3_acl_chmod(inode); |
3133 | 3135 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index f0df55a52929..d8673ccf90b7 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/random.h> | 19 | #include <linux/random.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/exportfs.h> | 21 | #include <linux/exportfs.h> |
22 | #include <linux/smp_lock.h> | ||
23 | 22 | ||
24 | MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | 23 | MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); |
25 | MODULE_DESCRIPTION("Filesystem in Userspace"); | 24 | MODULE_DESCRIPTION("Filesystem in Userspace"); |
@@ -260,9 +259,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, | |||
260 | 259 | ||
261 | static void fuse_umount_begin(struct super_block *sb) | 260 | static void fuse_umount_begin(struct super_block *sb) |
262 | { | 261 | { |
263 | lock_kernel(); | ||
264 | fuse_abort_conn(get_fuse_conn_super(sb)); | 262 | fuse_abort_conn(get_fuse_conn_super(sb)); |
265 | unlock_kernel(); | ||
266 | } | 263 | } |
267 | 264 | ||
268 | static void fuse_send_destroy(struct fuse_conn *fc) | 265 | static void fuse_send_destroy(struct fuse_conn *fc) |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 286f38dfc6c0..001f8d3118f2 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -70,9 +70,7 @@ static int ioctl_fibmap(struct file *filp, int __user *p) | |||
70 | res = get_user(block, p); | 70 | res = get_user(block, p); |
71 | if (res) | 71 | if (res) |
72 | return res; | 72 | return res; |
73 | lock_kernel(); | ||
74 | res = mapping->a_ops->bmap(mapping, block); | 73 | res = mapping->a_ops->bmap(mapping, block); |
75 | unlock_kernel(); | ||
76 | return put_user(res, p); | 74 | return put_user(res, p); |
77 | } | 75 | } |
78 | 76 | ||
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index 2f0dc5a14633..8ba5441063be 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c | |||
@@ -195,9 +195,8 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp, | |||
195 | * Do not report hidden files if so instructed, or associated | 195 | * Do not report hidden files if so instructed, or associated |
196 | * files unless instructed to do so | 196 | * files unless instructed to do so |
197 | */ | 197 | */ |
198 | if ((sbi->s_hide == 'y' && | 198 | if ((sbi->s_hide && (de->flags[-sbi->s_high_sierra] & 1)) || |
199 | (de->flags[-sbi->s_high_sierra] & 1)) || | 199 | (!sbi->s_showassoc && |
200 | (sbi->s_showassoc =='n' && | ||
201 | (de->flags[-sbi->s_high_sierra] & 4))) { | 200 | (de->flags[-sbi->s_high_sierra] & 4))) { |
202 | filp->f_pos += de_len; | 201 | filp->f_pos += de_len; |
203 | continue; | 202 | continue; |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 068b34b5a107..58a7963e168a 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -141,13 +141,17 @@ static const struct dentry_operations isofs_dentry_ops[] = { | |||
141 | }; | 141 | }; |
142 | 142 | ||
143 | struct iso9660_options{ | 143 | struct iso9660_options{ |
144 | char map; | 144 | unsigned int rock:1; |
145 | char rock; | 145 | unsigned int cruft:1; |
146 | unsigned int hide:1; | ||
147 | unsigned int showassoc:1; | ||
148 | unsigned int nocompress:1; | ||
149 | unsigned int overriderockperm:1; | ||
150 | unsigned int uid_set:1; | ||
151 | unsigned int gid_set:1; | ||
152 | unsigned int utf8:1; | ||
153 | unsigned char map; | ||
146 | char joliet; | 154 | char joliet; |
147 | char cruft; | ||
148 | char hide; | ||
149 | char showassoc; | ||
150 | char nocompress; | ||
151 | unsigned char check; | 155 | unsigned char check; |
152 | unsigned int blocksize; | 156 | unsigned int blocksize; |
153 | mode_t fmode; | 157 | mode_t fmode; |
@@ -155,7 +159,6 @@ struct iso9660_options{ | |||
155 | gid_t gid; | 159 | gid_t gid; |
156 | uid_t uid; | 160 | uid_t uid; |
157 | char *iocharset; | 161 | char *iocharset; |
158 | unsigned char utf8; | ||
159 | /* LVE */ | 162 | /* LVE */ |
160 | s32 session; | 163 | s32 session; |
161 | s32 sbsector; | 164 | s32 sbsector; |
@@ -312,7 +315,7 @@ enum { | |||
312 | Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore, | 315 | Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore, |
313 | Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet, | 316 | Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet, |
314 | Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, | 317 | Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, |
315 | Opt_nocompress, Opt_hide, Opt_showassoc, Opt_dmode, | 318 | Opt_nocompress, Opt_hide, Opt_showassoc, Opt_dmode, Opt_overriderockperm, |
316 | }; | 319 | }; |
317 | 320 | ||
318 | static const match_table_t tokens = { | 321 | static const match_table_t tokens = { |
@@ -340,6 +343,7 @@ static const match_table_t tokens = { | |||
340 | {Opt_gid, "gid=%u"}, | 343 | {Opt_gid, "gid=%u"}, |
341 | {Opt_mode, "mode=%u"}, | 344 | {Opt_mode, "mode=%u"}, |
342 | {Opt_dmode, "dmode=%u"}, | 345 | {Opt_dmode, "dmode=%u"}, |
346 | {Opt_overriderockperm, "overriderockperm"}, | ||
343 | {Opt_block, "block=%u"}, | 347 | {Opt_block, "block=%u"}, |
344 | {Opt_ignore, "conv=binary"}, | 348 | {Opt_ignore, "conv=binary"}, |
345 | {Opt_ignore, "conv=b"}, | 349 | {Opt_ignore, "conv=b"}, |
@@ -359,24 +363,22 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
359 | int option; | 363 | int option; |
360 | 364 | ||
361 | popt->map = 'n'; | 365 | popt->map = 'n'; |
362 | popt->rock = 'y'; | 366 | popt->rock = 1; |
363 | popt->joliet = 'y'; | 367 | popt->joliet = 1; |
364 | popt->cruft = 'n'; | 368 | popt->cruft = 0; |
365 | popt->hide = 'n'; | 369 | popt->hide = 0; |
366 | popt->showassoc = 'n'; | 370 | popt->showassoc = 0; |
367 | popt->check = 'u'; /* unset */ | 371 | popt->check = 'u'; /* unset */ |
368 | popt->nocompress = 0; | 372 | popt->nocompress = 0; |
369 | popt->blocksize = 1024; | 373 | popt->blocksize = 1024; |
370 | popt->fmode = popt->dmode = S_IRUGO | S_IXUGO; /* | 374 | popt->fmode = popt->dmode = ISOFS_INVALID_MODE; |
371 | * r-x for all. The disc could | 375 | popt->uid_set = 0; |
372 | * be shared with DOS machines so | 376 | popt->gid_set = 0; |
373 | * virtually anything could be | ||
374 | * a valid executable. | ||
375 | */ | ||
376 | popt->gid = 0; | 377 | popt->gid = 0; |
377 | popt->uid = 0; | 378 | popt->uid = 0; |
378 | popt->iocharset = NULL; | 379 | popt->iocharset = NULL; |
379 | popt->utf8 = 0; | 380 | popt->utf8 = 0; |
381 | popt->overriderockperm = 0; | ||
380 | popt->session=-1; | 382 | popt->session=-1; |
381 | popt->sbsector=-1; | 383 | popt->sbsector=-1; |
382 | if (!options) | 384 | if (!options) |
@@ -393,20 +395,20 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
393 | token = match_token(p, tokens, args); | 395 | token = match_token(p, tokens, args); |
394 | switch (token) { | 396 | switch (token) { |
395 | case Opt_norock: | 397 | case Opt_norock: |
396 | popt->rock = 'n'; | 398 | popt->rock = 0; |
397 | break; | 399 | break; |
398 | case Opt_nojoliet: | 400 | case Opt_nojoliet: |
399 | popt->joliet = 'n'; | 401 | popt->joliet = 0; |
400 | break; | 402 | break; |
401 | case Opt_hide: | 403 | case Opt_hide: |
402 | popt->hide = 'y'; | 404 | popt->hide = 1; |
403 | break; | 405 | break; |
404 | case Opt_unhide: | 406 | case Opt_unhide: |
405 | case Opt_showassoc: | 407 | case Opt_showassoc: |
406 | popt->showassoc = 'y'; | 408 | popt->showassoc = 1; |
407 | break; | 409 | break; |
408 | case Opt_cruft: | 410 | case Opt_cruft: |
409 | popt->cruft = 'y'; | 411 | popt->cruft = 1; |
410 | break; | 412 | break; |
411 | case Opt_utf8: | 413 | case Opt_utf8: |
412 | popt->utf8 = 1; | 414 | popt->utf8 = 1; |
@@ -450,11 +452,13 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
450 | if (match_int(&args[0], &option)) | 452 | if (match_int(&args[0], &option)) |
451 | return 0; | 453 | return 0; |
452 | popt->uid = option; | 454 | popt->uid = option; |
455 | popt->uid_set = 1; | ||
453 | break; | 456 | break; |
454 | case Opt_gid: | 457 | case Opt_gid: |
455 | if (match_int(&args[0], &option)) | 458 | if (match_int(&args[0], &option)) |
456 | return 0; | 459 | return 0; |
457 | popt->gid = option; | 460 | popt->gid = option; |
461 | popt->gid_set = 1; | ||
458 | break; | 462 | break; |
459 | case Opt_mode: | 463 | case Opt_mode: |
460 | if (match_int(&args[0], &option)) | 464 | if (match_int(&args[0], &option)) |
@@ -466,6 +470,9 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
466 | return 0; | 470 | return 0; |
467 | popt->dmode = option; | 471 | popt->dmode = option; |
468 | break; | 472 | break; |
473 | case Opt_overriderockperm: | ||
474 | popt->overriderockperm = 1; | ||
475 | break; | ||
469 | case Opt_block: | 476 | case Opt_block: |
470 | if (match_int(&args[0], &option)) | 477 | if (match_int(&args[0], &option)) |
471 | return 0; | 478 | return 0; |
@@ -650,7 +657,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
650 | goto out_freebh; | 657 | goto out_freebh; |
651 | 658 | ||
652 | sbi->s_high_sierra = 1; | 659 | sbi->s_high_sierra = 1; |
653 | opt.rock = 'n'; | 660 | opt.rock = 0; |
654 | h_pri = (struct hs_primary_descriptor *)vdp; | 661 | h_pri = (struct hs_primary_descriptor *)vdp; |
655 | goto root_found; | 662 | goto root_found; |
656 | } | 663 | } |
@@ -673,7 +680,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
673 | 680 | ||
674 | root_found: | 681 | root_found: |
675 | 682 | ||
676 | if (joliet_level && (pri == NULL || opt.rock == 'n')) { | 683 | if (joliet_level && (pri == NULL || !opt.rock)) { |
677 | /* This is the case of Joliet with the norock mount flag. | 684 | /* This is the case of Joliet with the norock mount flag. |
678 | * A disc with both Joliet and Rock Ridge is handled later | 685 | * A disc with both Joliet and Rock Ridge is handled later |
679 | */ | 686 | */ |
@@ -802,22 +809,31 @@ root_found: | |||
802 | s->s_op = &isofs_sops; | 809 | s->s_op = &isofs_sops; |
803 | s->s_export_op = &isofs_export_ops; | 810 | s->s_export_op = &isofs_export_ops; |
804 | sbi->s_mapping = opt.map; | 811 | sbi->s_mapping = opt.map; |
805 | sbi->s_rock = (opt.rock == 'y' ? 2 : 0); | 812 | sbi->s_rock = (opt.rock ? 2 : 0); |
806 | sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ | 813 | sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ |
807 | sbi->s_cruft = opt.cruft; | 814 | sbi->s_cruft = opt.cruft; |
808 | sbi->s_hide = opt.hide; | 815 | sbi->s_hide = opt.hide; |
809 | sbi->s_showassoc = opt.showassoc; | 816 | sbi->s_showassoc = opt.showassoc; |
810 | sbi->s_uid = opt.uid; | 817 | sbi->s_uid = opt.uid; |
811 | sbi->s_gid = opt.gid; | 818 | sbi->s_gid = opt.gid; |
819 | sbi->s_uid_set = opt.uid_set; | ||
820 | sbi->s_gid_set = opt.gid_set; | ||
812 | sbi->s_utf8 = opt.utf8; | 821 | sbi->s_utf8 = opt.utf8; |
813 | sbi->s_nocompress = opt.nocompress; | 822 | sbi->s_nocompress = opt.nocompress; |
823 | sbi->s_overriderockperm = opt.overriderockperm; | ||
814 | /* | 824 | /* |
815 | * It would be incredibly stupid to allow people to mark every file | 825 | * It would be incredibly stupid to allow people to mark every file |
816 | * on the disk as suid, so we merely allow them to set the default | 826 | * on the disk as suid, so we merely allow them to set the default |
817 | * permissions. | 827 | * permissions. |
818 | */ | 828 | */ |
819 | sbi->s_fmode = opt.fmode & 0777; | 829 | if (opt.fmode != ISOFS_INVALID_MODE) |
820 | sbi->s_dmode = opt.dmode & 0777; | 830 | sbi->s_fmode = opt.fmode & 0777; |
831 | else | ||
832 | sbi->s_fmode = ISOFS_INVALID_MODE; | ||
833 | if (opt.dmode != ISOFS_INVALID_MODE) | ||
834 | sbi->s_dmode = opt.dmode & 0777; | ||
835 | else | ||
836 | sbi->s_dmode = ISOFS_INVALID_MODE; | ||
821 | 837 | ||
822 | /* | 838 | /* |
823 | * Read the root inode, which _may_ result in changing | 839 | * Read the root inode, which _may_ result in changing |
@@ -1095,18 +1111,6 @@ static const struct address_space_operations isofs_aops = { | |||
1095 | .bmap = _isofs_bmap | 1111 | .bmap = _isofs_bmap |
1096 | }; | 1112 | }; |
1097 | 1113 | ||
1098 | static inline void test_and_set_uid(uid_t *p, uid_t value) | ||
1099 | { | ||
1100 | if (value) | ||
1101 | *p = value; | ||
1102 | } | ||
1103 | |||
1104 | static inline void test_and_set_gid(gid_t *p, gid_t value) | ||
1105 | { | ||
1106 | if (value) | ||
1107 | *p = value; | ||
1108 | } | ||
1109 | |||
1110 | static int isofs_read_level3_size(struct inode *inode) | 1114 | static int isofs_read_level3_size(struct inode *inode) |
1111 | { | 1115 | { |
1112 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); | 1116 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); |
@@ -1261,7 +1265,10 @@ static int isofs_read_inode(struct inode *inode) | |||
1261 | ei->i_file_format = isofs_file_normal; | 1265 | ei->i_file_format = isofs_file_normal; |
1262 | 1266 | ||
1263 | if (de->flags[-high_sierra] & 2) { | 1267 | if (de->flags[-high_sierra] & 2) { |
1264 | inode->i_mode = sbi->s_dmode | S_IFDIR; | 1268 | if (sbi->s_dmode != ISOFS_INVALID_MODE) |
1269 | inode->i_mode = S_IFDIR | sbi->s_dmode; | ||
1270 | else | ||
1271 | inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; | ||
1265 | inode->i_nlink = 1; /* | 1272 | inode->i_nlink = 1; /* |
1266 | * Set to 1. We know there are 2, but | 1273 | * Set to 1. We know there are 2, but |
1267 | * the find utility tries to optimize | 1274 | * the find utility tries to optimize |
@@ -1270,8 +1277,16 @@ static int isofs_read_inode(struct inode *inode) | |||
1270 | * do it the hard way. | 1277 | * do it the hard way. |
1271 | */ | 1278 | */ |
1272 | } else { | 1279 | } else { |
1273 | /* Everybody gets to read the file. */ | 1280 | if (sbi->s_fmode != ISOFS_INVALID_MODE) { |
1274 | inode->i_mode = sbi->s_fmode | S_IFREG; | 1281 | inode->i_mode = S_IFREG | sbi->s_fmode; |
1282 | } else { | ||
1283 | /* | ||
1284 | * Set default permissions: r-x for all. The disc | ||
1285 | * could be shared with DOS machines so virtually | ||
1286 | * anything could be a valid executable. | ||
1287 | */ | ||
1288 | inode->i_mode = S_IFREG | S_IRUGO | S_IXUGO; | ||
1289 | } | ||
1275 | inode->i_nlink = 1; | 1290 | inode->i_nlink = 1; |
1276 | } | 1291 | } |
1277 | inode->i_uid = sbi->s_uid; | 1292 | inode->i_uid = sbi->s_uid; |
@@ -1300,7 +1315,7 @@ static int isofs_read_inode(struct inode *inode) | |||
1300 | * this CDROM was mounted with the cruft option. | 1315 | * this CDROM was mounted with the cruft option. |
1301 | */ | 1316 | */ |
1302 | 1317 | ||
1303 | if (sbi->s_cruft == 'y') | 1318 | if (sbi->s_cruft) |
1304 | inode->i_size &= 0x00ffffff; | 1319 | inode->i_size &= 0x00ffffff; |
1305 | 1320 | ||
1306 | if (de->interleave[0]) { | 1321 | if (de->interleave[0]) { |
@@ -1346,9 +1361,18 @@ static int isofs_read_inode(struct inode *inode) | |||
1346 | if (!high_sierra) { | 1361 | if (!high_sierra) { |
1347 | parse_rock_ridge_inode(de, inode); | 1362 | parse_rock_ridge_inode(de, inode); |
1348 | /* if we want uid/gid set, override the rock ridge setting */ | 1363 | /* if we want uid/gid set, override the rock ridge setting */ |
1349 | test_and_set_uid(&inode->i_uid, sbi->s_uid); | 1364 | if (sbi->s_uid_set) |
1350 | test_and_set_gid(&inode->i_gid, sbi->s_gid); | 1365 | inode->i_uid = sbi->s_uid; |
1366 | if (sbi->s_gid_set) | ||
1367 | inode->i_gid = sbi->s_gid; | ||
1351 | } | 1368 | } |
1369 | /* Now set final access rights if overriding rock ridge setting */ | ||
1370 | if (S_ISDIR(inode->i_mode) && sbi->s_overriderockperm && | ||
1371 | sbi->s_dmode != ISOFS_INVALID_MODE) | ||
1372 | inode->i_mode = S_IFDIR | sbi->s_dmode; | ||
1373 | if (S_ISREG(inode->i_mode) && sbi->s_overriderockperm && | ||
1374 | sbi->s_fmode != ISOFS_INVALID_MODE) | ||
1375 | inode->i_mode = S_IFREG | sbi->s_fmode; | ||
1352 | 1376 | ||
1353 | /* Install the inode operations vector */ | 1377 | /* Install the inode operations vector */ |
1354 | if (S_ISREG(inode->i_mode)) { | 1378 | if (S_ISREG(inode->i_mode)) { |
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index ccbf72faf27a..7d33de84f52a 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h | |||
@@ -35,21 +35,20 @@ struct isofs_sb_info { | |||
35 | unsigned long s_log_zone_size; | 35 | unsigned long s_log_zone_size; |
36 | unsigned long s_max_size; | 36 | unsigned long s_max_size; |
37 | 37 | ||
38 | unsigned char s_high_sierra; /* A simple flag */ | ||
39 | unsigned char s_mapping; | ||
40 | int s_rock_offset; /* offset of SUSP fields within SU area */ | 38 | int s_rock_offset; /* offset of SUSP fields within SU area */ |
41 | unsigned char s_rock; | ||
42 | unsigned char s_joliet_level; | 39 | unsigned char s_joliet_level; |
43 | unsigned char s_utf8; | 40 | unsigned char s_mapping; |
44 | unsigned char s_cruft; /* Broken disks with high | 41 | unsigned int s_high_sierra:1; |
45 | byte of length containing | 42 | unsigned int s_rock:2; |
46 | junk */ | 43 | unsigned int s_utf8:1; |
47 | unsigned char s_unhide; | 44 | unsigned int s_cruft:1; /* Broken disks with high byte of length |
48 | unsigned char s_nosuid; | 45 | * containing junk */ |
49 | unsigned char s_nodev; | 46 | unsigned int s_nocompress:1; |
50 | unsigned char s_nocompress; | 47 | unsigned int s_hide:1; |
51 | unsigned char s_hide; | 48 | unsigned int s_showassoc:1; |
52 | unsigned char s_showassoc; | 49 | unsigned int s_overriderockperm:1; |
50 | unsigned int s_uid_set:1; | ||
51 | unsigned int s_gid_set:1; | ||
53 | 52 | ||
54 | mode_t s_fmode; | 53 | mode_t s_fmode; |
55 | mode_t s_dmode; | 54 | mode_t s_dmode; |
@@ -58,6 +57,8 @@ struct isofs_sb_info { | |||
58 | struct nls_table *s_nls_iocharset; /* Native language support table */ | 57 | struct nls_table *s_nls_iocharset; /* Native language support table */ |
59 | }; | 58 | }; |
60 | 59 | ||
60 | #define ISOFS_INVALID_MODE ((mode_t) -1) | ||
61 | |||
61 | static inline struct isofs_sb_info *ISOFS_SB(struct super_block *sb) | 62 | static inline struct isofs_sb_info *ISOFS_SB(struct super_block *sb) |
62 | { | 63 | { |
63 | return sb->s_fs_info; | 64 | return sb->s_fs_info; |
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 8299889a835e..eaa831311c9c 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c | |||
@@ -142,9 +142,9 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, | |||
142 | */ | 142 | */ |
143 | match = 0; | 143 | match = 0; |
144 | if (dlen > 0 && | 144 | if (dlen > 0 && |
145 | (sbi->s_hide =='n' || | 145 | (!sbi->s_hide || |
146 | (!(de->flags[-sbi->s_high_sierra] & 1))) && | 146 | (!(de->flags[-sbi->s_high_sierra] & 1))) && |
147 | (sbi->s_showassoc =='y' || | 147 | (sbi->s_showassoc || |
148 | (!(de->flags[-sbi->s_high_sierra] & 4)))) { | 148 | (!(de->flags[-sbi->s_high_sierra] & 4)))) { |
149 | match = (isofs_cmp(dentry, dpnt, dlen) == 0); | 149 | match = (isofs_cmp(dentry, dpnt, dlen) == 0); |
150 | } | 150 | } |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index ed886e6db399..73242ba7c7b1 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -1686,35 +1686,6 @@ out: | |||
1686 | return; | 1686 | return; |
1687 | } | 1687 | } |
1688 | 1688 | ||
1689 | /* | ||
1690 | * journal_try_to_free_buffers() could race with journal_commit_transaction() | ||
1691 | * The latter might still hold the a count on buffers when inspecting | ||
1692 | * them on t_syncdata_list or t_locked_list. | ||
1693 | * | ||
1694 | * journal_try_to_free_buffers() will call this function to | ||
1695 | * wait for the current transaction to finish syncing data buffers, before | ||
1696 | * tryinf to free that buffer. | ||
1697 | * | ||
1698 | * Called with journal->j_state_lock held. | ||
1699 | */ | ||
1700 | static void journal_wait_for_transaction_sync_data(journal_t *journal) | ||
1701 | { | ||
1702 | transaction_t *transaction = NULL; | ||
1703 | tid_t tid; | ||
1704 | |||
1705 | spin_lock(&journal->j_state_lock); | ||
1706 | transaction = journal->j_committing_transaction; | ||
1707 | |||
1708 | if (!transaction) { | ||
1709 | spin_unlock(&journal->j_state_lock); | ||
1710 | return; | ||
1711 | } | ||
1712 | |||
1713 | tid = transaction->t_tid; | ||
1714 | spin_unlock(&journal->j_state_lock); | ||
1715 | log_wait_commit(journal, tid); | ||
1716 | } | ||
1717 | |||
1718 | /** | 1689 | /** |
1719 | * int journal_try_to_free_buffers() - try to free page buffers. | 1690 | * int journal_try_to_free_buffers() - try to free page buffers. |
1720 | * @journal: journal for operation | 1691 | * @journal: journal for operation |
@@ -1786,25 +1757,6 @@ int journal_try_to_free_buffers(journal_t *journal, | |||
1786 | 1757 | ||
1787 | ret = try_to_free_buffers(page); | 1758 | ret = try_to_free_buffers(page); |
1788 | 1759 | ||
1789 | /* | ||
1790 | * There are a number of places where journal_try_to_free_buffers() | ||
1791 | * could race with journal_commit_transaction(), the later still | ||
1792 | * holds the reference to the buffers to free while processing them. | ||
1793 | * try_to_free_buffers() failed to free those buffers. Some of the | ||
1794 | * caller of releasepage() request page buffers to be dropped, otherwise | ||
1795 | * treat the fail-to-free as errors (such as generic_file_direct_IO()) | ||
1796 | * | ||
1797 | * So, if the caller of try_to_release_page() wants the synchronous | ||
1798 | * behaviour(i.e make sure buffers are dropped upon return), | ||
1799 | * let's wait for the current transaction to finish flush of | ||
1800 | * dirty data buffers, then try to free those buffers again, | ||
1801 | * with the journal locked. | ||
1802 | */ | ||
1803 | if (ret == 0 && (gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS)) { | ||
1804 | journal_wait_for_transaction_sync_data(journal); | ||
1805 | ret = try_to_free_buffers(page); | ||
1806 | } | ||
1807 | |||
1808 | busy: | 1760 | busy: |
1809 | return ret; | 1761 | return ret; |
1810 | } | 1762 | } |
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 3aebe322271a..6ac693faae49 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c | |||
@@ -12,13 +12,14 @@ | |||
12 | /* bitmap.c contains the code that handles the inode and block bitmaps */ | 12 | /* bitmap.c contains the code that handles the inode and block bitmaps */ |
13 | 13 | ||
14 | #include "minix.h" | 14 | #include "minix.h" |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/buffer_head.h> | 15 | #include <linux/buffer_head.h> |
17 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
18 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
19 | 18 | ||
20 | static const int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 }; | 19 | static const int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 }; |
21 | 20 | ||
21 | static DEFINE_SPINLOCK(bitmap_lock); | ||
22 | |||
22 | static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits) | 23 | static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits) |
23 | { | 24 | { |
24 | unsigned i, j, sum = 0; | 25 | unsigned i, j, sum = 0; |
@@ -69,11 +70,11 @@ void minix_free_block(struct inode *inode, unsigned long block) | |||
69 | return; | 70 | return; |
70 | } | 71 | } |
71 | bh = sbi->s_zmap[zone]; | 72 | bh = sbi->s_zmap[zone]; |
72 | lock_kernel(); | 73 | spin_lock(&bitmap_lock); |
73 | if (!minix_test_and_clear_bit(bit, bh->b_data)) | 74 | if (!minix_test_and_clear_bit(bit, bh->b_data)) |
74 | printk("minix_free_block (%s:%lu): bit already cleared\n", | 75 | printk("minix_free_block (%s:%lu): bit already cleared\n", |
75 | sb->s_id, block); | 76 | sb->s_id, block); |
76 | unlock_kernel(); | 77 | spin_unlock(&bitmap_lock); |
77 | mark_buffer_dirty(bh); | 78 | mark_buffer_dirty(bh); |
78 | return; | 79 | return; |
79 | } | 80 | } |
@@ -88,18 +89,18 @@ int minix_new_block(struct inode * inode) | |||
88 | struct buffer_head *bh = sbi->s_zmap[i]; | 89 | struct buffer_head *bh = sbi->s_zmap[i]; |
89 | int j; | 90 | int j; |
90 | 91 | ||
91 | lock_kernel(); | 92 | spin_lock(&bitmap_lock); |
92 | j = minix_find_first_zero_bit(bh->b_data, bits_per_zone); | 93 | j = minix_find_first_zero_bit(bh->b_data, bits_per_zone); |
93 | if (j < bits_per_zone) { | 94 | if (j < bits_per_zone) { |
94 | minix_set_bit(j, bh->b_data); | 95 | minix_set_bit(j, bh->b_data); |
95 | unlock_kernel(); | 96 | spin_unlock(&bitmap_lock); |
96 | mark_buffer_dirty(bh); | 97 | mark_buffer_dirty(bh); |
97 | j += i * bits_per_zone + sbi->s_firstdatazone-1; | 98 | j += i * bits_per_zone + sbi->s_firstdatazone-1; |
98 | if (j < sbi->s_firstdatazone || j >= sbi->s_nzones) | 99 | if (j < sbi->s_firstdatazone || j >= sbi->s_nzones) |
99 | break; | 100 | break; |
100 | return j; | 101 | return j; |
101 | } | 102 | } |
102 | unlock_kernel(); | 103 | spin_unlock(&bitmap_lock); |
103 | } | 104 | } |
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |
@@ -211,10 +212,10 @@ void minix_free_inode(struct inode * inode) | |||
211 | minix_clear_inode(inode); /* clear on-disk copy */ | 212 | minix_clear_inode(inode); /* clear on-disk copy */ |
212 | 213 | ||
213 | bh = sbi->s_imap[ino]; | 214 | bh = sbi->s_imap[ino]; |
214 | lock_kernel(); | 215 | spin_lock(&bitmap_lock); |
215 | if (!minix_test_and_clear_bit(bit, bh->b_data)) | 216 | if (!minix_test_and_clear_bit(bit, bh->b_data)) |
216 | printk("minix_free_inode: bit %lu already cleared\n", bit); | 217 | printk("minix_free_inode: bit %lu already cleared\n", bit); |
217 | unlock_kernel(); | 218 | spin_unlock(&bitmap_lock); |
218 | mark_buffer_dirty(bh); | 219 | mark_buffer_dirty(bh); |
219 | out: | 220 | out: |
220 | clear_inode(inode); /* clear in-memory copy */ | 221 | clear_inode(inode); /* clear in-memory copy */ |
@@ -237,7 +238,7 @@ struct inode * minix_new_inode(const struct inode * dir, int * error) | |||
237 | j = bits_per_zone; | 238 | j = bits_per_zone; |
238 | bh = NULL; | 239 | bh = NULL; |
239 | *error = -ENOSPC; | 240 | *error = -ENOSPC; |
240 | lock_kernel(); | 241 | spin_lock(&bitmap_lock); |
241 | for (i = 0; i < sbi->s_imap_blocks; i++) { | 242 | for (i = 0; i < sbi->s_imap_blocks; i++) { |
242 | bh = sbi->s_imap[i]; | 243 | bh = sbi->s_imap[i]; |
243 | j = minix_find_first_zero_bit(bh->b_data, bits_per_zone); | 244 | j = minix_find_first_zero_bit(bh->b_data, bits_per_zone); |
@@ -245,17 +246,17 @@ struct inode * minix_new_inode(const struct inode * dir, int * error) | |||
245 | break; | 246 | break; |
246 | } | 247 | } |
247 | if (!bh || j >= bits_per_zone) { | 248 | if (!bh || j >= bits_per_zone) { |
248 | unlock_kernel(); | 249 | spin_unlock(&bitmap_lock); |
249 | iput(inode); | 250 | iput(inode); |
250 | return NULL; | 251 | return NULL; |
251 | } | 252 | } |
252 | if (minix_test_and_set_bit(j, bh->b_data)) { /* shouldn't happen */ | 253 | if (minix_test_and_set_bit(j, bh->b_data)) { /* shouldn't happen */ |
253 | unlock_kernel(); | 254 | spin_unlock(&bitmap_lock); |
254 | printk("minix_new_inode: bit already set\n"); | 255 | printk("minix_new_inode: bit already set\n"); |
255 | iput(inode); | 256 | iput(inode); |
256 | return NULL; | 257 | return NULL; |
257 | } | 258 | } |
258 | unlock_kernel(); | 259 | spin_unlock(&bitmap_lock); |
259 | mark_buffer_dirty(bh); | 260 | mark_buffer_dirty(bh); |
260 | j += i * bits_per_zone; | 261 | j += i * bits_per_zone; |
261 | if (!j || j > sbi->s_ninodes) { | 262 | if (!j || j > sbi->s_ninodes) { |
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index e5f206467e40..d407e7a0b6fe 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include "minix.h" | 11 | #include "minix.h" |
12 | #include <linux/buffer_head.h> | 12 | #include <linux/buffer_head.h> |
13 | #include <linux/highmem.h> | 13 | #include <linux/highmem.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/swap.h> | 14 | #include <linux/swap.h> |
16 | 15 | ||
17 | typedef struct minix_dir_entry minix_dirent; | 16 | typedef struct minix_dir_entry minix_dirent; |
@@ -20,6 +19,7 @@ typedef struct minix3_dir_entry minix3_dirent; | |||
20 | static int minix_readdir(struct file *, void *, filldir_t); | 19 | static int minix_readdir(struct file *, void *, filldir_t); |
21 | 20 | ||
22 | const struct file_operations minix_dir_operations = { | 21 | const struct file_operations minix_dir_operations = { |
22 | .llseek = generic_file_llseek, | ||
23 | .read = generic_read_dir, | 23 | .read = generic_read_dir, |
24 | .readdir = minix_readdir, | 24 | .readdir = minix_readdir, |
25 | .fsync = simple_fsync, | 25 | .fsync = simple_fsync, |
@@ -102,8 +102,6 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
102 | char *name; | 102 | char *name; |
103 | __u32 inumber; | 103 | __u32 inumber; |
104 | 104 | ||
105 | lock_kernel(); | ||
106 | |||
107 | pos = (pos + chunk_size-1) & ~(chunk_size-1); | 105 | pos = (pos + chunk_size-1) & ~(chunk_size-1); |
108 | if (pos >= inode->i_size) | 106 | if (pos >= inode->i_size) |
109 | goto done; | 107 | goto done; |
@@ -146,7 +144,6 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
146 | 144 | ||
147 | done: | 145 | done: |
148 | filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; | 146 | filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; |
149 | unlock_kernel(); | ||
150 | return 0; | 147 | return 0; |
151 | } | 148 | } |
152 | 149 | ||
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index f91a23693597..74ea82d72164 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -35,8 +35,6 @@ static void minix_put_super(struct super_block *sb) | |||
35 | int i; | 35 | int i; |
36 | struct minix_sb_info *sbi = minix_sb(sb); | 36 | struct minix_sb_info *sbi = minix_sb(sb); |
37 | 37 | ||
38 | lock_kernel(); | ||
39 | |||
40 | if (!(sb->s_flags & MS_RDONLY)) { | 38 | if (!(sb->s_flags & MS_RDONLY)) { |
41 | if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ | 39 | if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ |
42 | sbi->s_ms->s_state = sbi->s_mount_state; | 40 | sbi->s_ms->s_state = sbi->s_mount_state; |
@@ -50,8 +48,6 @@ static void minix_put_super(struct super_block *sb) | |||
50 | kfree(sbi->s_imap); | 48 | kfree(sbi->s_imap); |
51 | sb->s_fs_info = NULL; | 49 | sb->s_fs_info = NULL; |
52 | kfree(sbi); | 50 | kfree(sbi); |
53 | |||
54 | unlock_kernel(); | ||
55 | } | 51 | } |
56 | 52 | ||
57 | static struct kmem_cache * minix_inode_cachep; | 53 | static struct kmem_cache * minix_inode_cachep; |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 63d965193b22..11a7b5c68153 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -18,6 +18,7 @@ proc-y += meminfo.o | |||
18 | proc-y += stat.o | 18 | proc-y += stat.o |
19 | proc-y += uptime.o | 19 | proc-y += uptime.o |
20 | proc-y += version.o | 20 | proc-y += version.o |
21 | proc-y += softirqs.o | ||
21 | proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o | 22 | proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o |
22 | proc-$(CONFIG_NET) += proc_net.o | 23 | proc-$(CONFIG_NET) += proc_net.o |
23 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 24 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index fc6c3025befd..7ba79a54948c 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c | |||
@@ -195,20 +195,20 @@ void proc_device_tree_add_node(struct device_node *np, | |||
195 | p = fixup_name(np, de, p); | 195 | p = fixup_name(np, de, p); |
196 | 196 | ||
197 | ent = proc_mkdir(p, de); | 197 | ent = proc_mkdir(p, de); |
198 | if (ent == 0) | 198 | if (ent == NULL) |
199 | break; | 199 | break; |
200 | proc_device_tree_add_node(child, ent); | 200 | proc_device_tree_add_node(child, ent); |
201 | } | 201 | } |
202 | of_node_put(child); | 202 | of_node_put(child); |
203 | 203 | ||
204 | for (pp = np->properties; pp != 0; pp = pp->next) { | 204 | for (pp = np->properties; pp != NULL; pp = pp->next) { |
205 | p = pp->name; | 205 | p = pp->name; |
206 | 206 | ||
207 | if (duplicate_name(de, p)) | 207 | if (duplicate_name(de, p)) |
208 | p = fixup_name(np, de, p); | 208 | p = fixup_name(np, de, p); |
209 | 209 | ||
210 | ent = __proc_device_tree_add_prop(de, pp, p); | 210 | ent = __proc_device_tree_add_prop(de, pp, p); |
211 | if (ent == 0) | 211 | if (ent == NULL) |
212 | break; | 212 | break; |
213 | } | 213 | } |
214 | } | 214 | } |
@@ -221,10 +221,10 @@ void __init proc_device_tree_init(void) | |||
221 | struct device_node *root; | 221 | struct device_node *root; |
222 | 222 | ||
223 | proc_device_tree = proc_mkdir("device-tree", NULL); | 223 | proc_device_tree = proc_mkdir("device-tree", NULL); |
224 | if (proc_device_tree == 0) | 224 | if (proc_device_tree == NULL) |
225 | return; | 225 | return; |
226 | root = of_find_node_by_path("/"); | 226 | root = of_find_node_by_path("/"); |
227 | if (root == 0) { | 227 | if (root == NULL) { |
228 | printk(KERN_ERR "/proc/device-tree: can't find root\n"); | 228 | printk(KERN_ERR "/proc/device-tree: can't find root\n"); |
229 | return; | 229 | return; |
230 | } | 230 | } |
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c new file mode 100644 index 000000000000..1807c2419f17 --- /dev/null +++ b/fs/proc/softirqs.c | |||
@@ -0,0 +1,44 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/kernel_stat.h> | ||
3 | #include <linux/proc_fs.h> | ||
4 | #include <linux/seq_file.h> | ||
5 | |||
6 | /* | ||
7 | * /proc/softirqs ... display the number of softirqs | ||
8 | */ | ||
9 | static int show_softirqs(struct seq_file *p, void *v) | ||
10 | { | ||
11 | int i, j; | ||
12 | |||
13 | seq_printf(p, " "); | ||
14 | for_each_possible_cpu(i) | ||
15 | seq_printf(p, "CPU%-8d", i); | ||
16 | seq_printf(p, "\n"); | ||
17 | |||
18 | for (i = 0; i < NR_SOFTIRQS; i++) { | ||
19 | seq_printf(p, "%8s:", softirq_to_name[i]); | ||
20 | for_each_possible_cpu(j) | ||
21 | seq_printf(p, " %10u", kstat_softirqs_cpu(i, j)); | ||
22 | seq_printf(p, "\n"); | ||
23 | } | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static int softirqs_open(struct inode *inode, struct file *file) | ||
28 | { | ||
29 | return single_open(file, show_softirqs, NULL); | ||
30 | } | ||
31 | |||
32 | static const struct file_operations proc_softirqs_operations = { | ||
33 | .open = softirqs_open, | ||
34 | .read = seq_read, | ||
35 | .llseek = seq_lseek, | ||
36 | .release = single_release, | ||
37 | }; | ||
38 | |||
39 | static int __init proc_softirqs_init(void) | ||
40 | { | ||
41 | proc_create("softirqs", 0, NULL, &proc_softirqs_operations); | ||
42 | return 0; | ||
43 | } | ||
44 | module_init(proc_softirqs_init); | ||
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 81e4eb60972e..7cc726c6d70a 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -29,6 +29,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
29 | cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; | 29 | cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; |
30 | cputime64_t guest; | 30 | cputime64_t guest; |
31 | u64 sum = 0; | 31 | u64 sum = 0; |
32 | u64 sum_softirq = 0; | ||
33 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; | ||
32 | struct timespec boottime; | 34 | struct timespec boottime; |
33 | unsigned int per_irq_sum; | 35 | unsigned int per_irq_sum; |
34 | 36 | ||
@@ -53,6 +55,13 @@ static int show_stat(struct seq_file *p, void *v) | |||
53 | sum += kstat_irqs_cpu(j, i); | 55 | sum += kstat_irqs_cpu(j, i); |
54 | } | 56 | } |
55 | sum += arch_irq_stat_cpu(i); | 57 | sum += arch_irq_stat_cpu(i); |
58 | |||
59 | for (j = 0; j < NR_SOFTIRQS; j++) { | ||
60 | unsigned int softirq_stat = kstat_softirqs_cpu(j, i); | ||
61 | |||
62 | per_softirq_sums[j] += softirq_stat; | ||
63 | sum_softirq += softirq_stat; | ||
64 | } | ||
56 | } | 65 | } |
57 | sum += arch_irq_stat(); | 66 | sum += arch_irq_stat(); |
58 | 67 | ||
@@ -115,6 +124,12 @@ static int show_stat(struct seq_file *p, void *v) | |||
115 | nr_running(), | 124 | nr_running(), |
116 | nr_iowait()); | 125 | nr_iowait()); |
117 | 126 | ||
127 | seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq); | ||
128 | |||
129 | for (i = 0; i < NR_SOFTIRQS; i++) | ||
130 | seq_printf(p, " %u", per_softirq_sums[i]); | ||
131 | seq_printf(p, "\n"); | ||
132 | |||
118 | return 0; | 133 | return 0; |
119 | } | 134 | } |
120 | 135 | ||
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 5edcc3f92ba7..0872afa58d39 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -166,12 +166,7 @@ static const struct file_operations proc_vmcore_operations = { | |||
166 | 166 | ||
167 | static struct vmcore* __init get_new_element(void) | 167 | static struct vmcore* __init get_new_element(void) |
168 | { | 168 | { |
169 | struct vmcore *p; | 169 | return kzalloc(sizeof(struct vmcore), GFP_KERNEL); |
170 | |||
171 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
172 | if (p) | ||
173 | memset(p, 0, sizeof(*p)); | ||
174 | return p; | ||
175 | } | 170 | } |
176 | 171 | ||
177 | static u64 __init get_vmcore_size_elf64(char *elfptr) | 172 | static u64 __init get_vmcore_size_elf64(char *elfptr) |
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 4beb964a2a3e..128d3f7c8aa5 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
@@ -1270,9 +1270,8 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1270 | 1270 | ||
1271 | RFALSE(ih, "PAP-12210: ih must be 0"); | 1271 | RFALSE(ih, "PAP-12210: ih must be 0"); |
1272 | 1272 | ||
1273 | if (is_direntry_le_ih | 1273 | aux_ih = B_N_PITEM_HEAD(tbS0, item_pos); |
1274 | (aux_ih = | 1274 | if (is_direntry_le_ih(aux_ih)) { |
1275 | B_N_PITEM_HEAD(tbS0, item_pos))) { | ||
1276 | /* we append to directory item */ | 1275 | /* we append to directory item */ |
1277 | 1276 | ||
1278 | int entry_count; | 1277 | int entry_count; |
diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c index 381750a155f6..03d85cbf90bf 100644 --- a/fs/reiserfs/lbalance.c +++ b/fs/reiserfs/lbalance.c | |||
@@ -390,7 +390,8 @@ static void leaf_item_bottle(struct buffer_info *dest_bi, | |||
390 | 390 | ||
391 | if (last_first == FIRST_TO_LAST) { | 391 | if (last_first == FIRST_TO_LAST) { |
392 | /* if ( if item in position item_num in buffer SOURCE is directory item ) */ | 392 | /* if ( if item in position item_num in buffer SOURCE is directory item ) */ |
393 | if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num))) | 393 | ih = B_N_PITEM_HEAD(src, item_num); |
394 | if (is_direntry_le_ih(ih)) | ||
394 | leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, | 395 | leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, |
395 | item_num, 0, cpy_bytes); | 396 | item_num, 0, cpy_bytes); |
396 | else { | 397 | else { |
@@ -418,7 +419,8 @@ static void leaf_item_bottle(struct buffer_info *dest_bi, | |||
418 | } | 419 | } |
419 | } else { | 420 | } else { |
420 | /* if ( if item in position item_num in buffer SOURCE is directory item ) */ | 421 | /* if ( if item in position item_num in buffer SOURCE is directory item ) */ |
421 | if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num))) | 422 | ih = B_N_PITEM_HEAD(src, item_num); |
423 | if (is_direntry_le_ih(ih)) | ||
422 | leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST, | 424 | leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST, |
423 | item_num, | 425 | item_num, |
424 | I_ENTRY_COUNT(ih) - cpy_bytes, | 426 | I_ENTRY_COUNT(ih) - cpy_bytes, |
@@ -774,8 +776,8 @@ void leaf_delete_items(struct buffer_info *cur_bi, int last_first, | |||
774 | leaf_delete_items_entirely(cur_bi, first + 1, | 776 | leaf_delete_items_entirely(cur_bi, first + 1, |
775 | del_num - 1); | 777 | del_num - 1); |
776 | 778 | ||
777 | if (is_direntry_le_ih | 779 | ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh) - 1); |
778 | (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh) - 1))) | 780 | if (is_direntry_le_ih(ih)) |
779 | /* the last item is directory */ | 781 | /* the last item is directory */ |
780 | /* len = numbers of directory entries in this item */ | 782 | /* len = numbers of directory entries in this item */ |
781 | len = ih_entry_count(ih); | 783 | len = ih_entry_count(ih); |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 7f40f30c55c5..6c959275f2d0 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -640,6 +640,26 @@ int seq_puts(struct seq_file *m, const char *s) | |||
640 | } | 640 | } |
641 | EXPORT_SYMBOL(seq_puts); | 641 | EXPORT_SYMBOL(seq_puts); |
642 | 642 | ||
643 | /** | ||
644 | * seq_write - write arbitrary data to buffer | ||
645 | * @seq: seq_file identifying the buffer to which data should be written | ||
646 | * @data: data address | ||
647 | * @len: number of bytes | ||
648 | * | ||
649 | * Return 0 on success, non-zero otherwise. | ||
650 | */ | ||
651 | int seq_write(struct seq_file *seq, const void *data, size_t len) | ||
652 | { | ||
653 | if (seq->count + len < seq->size) { | ||
654 | memcpy(seq->buf + seq->count, data, len); | ||
655 | seq->count += len; | ||
656 | return 0; | ||
657 | } | ||
658 | seq->count = seq->size; | ||
659 | return -1; | ||
660 | } | ||
661 | EXPORT_SYMBOL(seq_write); | ||
662 | |||
643 | struct list_head *seq_list_start(struct list_head *head, loff_t pos) | 663 | struct list_head *seq_list_start(struct list_head *head, loff_t pos) |
644 | { | 664 | { |
645 | struct list_head *lh; | 665 | struct list_head *lh; |
diff --git a/fs/super.c b/fs/super.c index 83b47416d006..d40d53a22fb5 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -545,24 +545,18 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
545 | if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) { | 545 | if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) { |
546 | if (force) | 546 | if (force) |
547 | mark_files_ro(sb); | 547 | mark_files_ro(sb); |
548 | else if (!fs_may_remount_ro(sb)) { | 548 | else if (!fs_may_remount_ro(sb)) |
549 | unlock_kernel(); | ||
550 | return -EBUSY; | 549 | return -EBUSY; |
551 | } | ||
552 | retval = vfs_dq_off(sb, 1); | 550 | retval = vfs_dq_off(sb, 1); |
553 | if (retval < 0 && retval != -ENOSYS) { | 551 | if (retval < 0 && retval != -ENOSYS) |
554 | unlock_kernel(); | ||
555 | return -EBUSY; | 552 | return -EBUSY; |
556 | } | ||
557 | } | 553 | } |
558 | remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); | 554 | remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); |
559 | 555 | ||
560 | if (sb->s_op->remount_fs) { | 556 | if (sb->s_op->remount_fs) { |
561 | retval = sb->s_op->remount_fs(sb, &flags, data); | 557 | retval = sb->s_op->remount_fs(sb, &flags, data); |
562 | if (retval) { | 558 | if (retval) |
563 | unlock_kernel(); | ||
564 | return retval; | 559 | return retval; |
565 | } | ||
566 | } | 560 | } |
567 | sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); | 561 | sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); |
568 | if (remount_rw) | 562 | if (remount_rw) |
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index c7798079e644..4e50286a4cc3 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c | |||
@@ -15,13 +15,13 @@ | |||
15 | 15 | ||
16 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/swap.h> | 18 | #include <linux/swap.h> |
20 | #include "sysv.h" | 19 | #include "sysv.h" |
21 | 20 | ||
22 | static int sysv_readdir(struct file *, void *, filldir_t); | 21 | static int sysv_readdir(struct file *, void *, filldir_t); |
23 | 22 | ||
24 | const struct file_operations sysv_dir_operations = { | 23 | const struct file_operations sysv_dir_operations = { |
24 | .llseek = generic_file_llseek, | ||
25 | .read = generic_read_dir, | 25 | .read = generic_read_dir, |
26 | .readdir = sysv_readdir, | 26 | .readdir = sysv_readdir, |
27 | .fsync = simple_fsync, | 27 | .fsync = simple_fsync, |
@@ -74,8 +74,6 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
74 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 74 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
75 | unsigned long npages = dir_pages(inode); | 75 | unsigned long npages = dir_pages(inode); |
76 | 76 | ||
77 | lock_kernel(); | ||
78 | |||
79 | pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1); | 77 | pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1); |
80 | if (pos >= inode->i_size) | 78 | if (pos >= inode->i_size) |
81 | goto done; | 79 | goto done; |
@@ -113,7 +111,6 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
113 | 111 | ||
114 | done: | 112 | done: |
115 | filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset; | 113 | filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset; |
116 | unlock_kernel(); | ||
117 | return 0; | 114 | return 0; |
118 | } | 115 | } |
119 | 116 | ||
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 479923456a54..9824743832a7 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -21,7 +21,6 @@ | |||
21 | * the superblock. | 21 | * the superblock. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/highuid.h> | 24 | #include <linux/highuid.h> |
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -37,7 +36,6 @@ static int sysv_sync_fs(struct super_block *sb, int wait) | |||
37 | unsigned long time = get_seconds(), old_time; | 36 | unsigned long time = get_seconds(), old_time; |
38 | 37 | ||
39 | lock_super(sb); | 38 | lock_super(sb); |
40 | lock_kernel(); | ||
41 | 39 | ||
42 | /* | 40 | /* |
43 | * If we are going to write out the super block, | 41 | * If we are going to write out the super block, |
@@ -52,7 +50,6 @@ static int sysv_sync_fs(struct super_block *sb, int wait) | |||
52 | mark_buffer_dirty(sbi->s_bh2); | 50 | mark_buffer_dirty(sbi->s_bh2); |
53 | } | 51 | } |
54 | 52 | ||
55 | unlock_kernel(); | ||
56 | unlock_super(sb); | 53 | unlock_super(sb); |
57 | 54 | ||
58 | return 0; | 55 | return 0; |
@@ -82,8 +79,6 @@ static void sysv_put_super(struct super_block *sb) | |||
82 | { | 79 | { |
83 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 80 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
84 | 81 | ||
85 | lock_kernel(); | ||
86 | |||
87 | if (sb->s_dirt) | 82 | if (sb->s_dirt) |
88 | sysv_write_super(sb); | 83 | sysv_write_super(sb); |
89 | 84 | ||
@@ -99,8 +94,6 @@ static void sysv_put_super(struct super_block *sb) | |||
99 | brelse(sbi->s_bh2); | 94 | brelse(sbi->s_bh2); |
100 | 95 | ||
101 | kfree(sbi); | 96 | kfree(sbi); |
102 | |||
103 | unlock_kernel(); | ||
104 | } | 97 | } |
105 | 98 | ||
106 | static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) | 99 | static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) |
@@ -275,7 +268,6 @@ int sysv_write_inode(struct inode *inode, int wait) | |||
275 | return -EIO; | 268 | return -EIO; |
276 | } | 269 | } |
277 | 270 | ||
278 | lock_kernel(); | ||
279 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); | 271 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); |
280 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); | 272 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); |
281 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); | 273 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); |
@@ -291,7 +283,6 @@ int sysv_write_inode(struct inode *inode, int wait) | |||
291 | for (block = 0; block < 10+1+1+1; block++) | 283 | for (block = 0; block < 10+1+1+1; block++) |
292 | write3byte(sbi, (u8 *)&si->i_data[block], | 284 | write3byte(sbi, (u8 *)&si->i_data[block], |
293 | &raw_inode->i_data[3*block]); | 285 | &raw_inode->i_data[3*block]); |
294 | unlock_kernel(); | ||
295 | mark_buffer_dirty(bh); | 286 | mark_buffer_dirty(bh); |
296 | if (wait) { | 287 | if (wait) { |
297 | sync_dirty_buffer(bh); | 288 | sync_dirty_buffer(bh); |
@@ -315,9 +306,7 @@ static void sysv_delete_inode(struct inode *inode) | |||
315 | truncate_inode_pages(&inode->i_data, 0); | 306 | truncate_inode_pages(&inode->i_data, 0); |
316 | inode->i_size = 0; | 307 | inode->i_size = 0; |
317 | sysv_truncate(inode); | 308 | sysv_truncate(inode); |
318 | lock_kernel(); | ||
319 | sysv_free_inode(inode); | 309 | sysv_free_inode(inode); |
320 | unlock_kernel(); | ||
321 | } | 310 | } |
322 | 311 | ||
323 | static struct kmem_cache *sysv_inode_cachep; | 312 | static struct kmem_cache *sysv_inode_cachep; |
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index af1914462f02..eaf6d891d46f 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -91,7 +91,6 @@ static int shrink_liability(struct ubifs_info *c, int nr_to_write) | |||
91 | return nr_written; | 91 | return nr_written; |
92 | } | 92 | } |
93 | 93 | ||
94 | |||
95 | /** | 94 | /** |
96 | * run_gc - run garbage collector. | 95 | * run_gc - run garbage collector. |
97 | * @c: UBIFS file-system description object | 96 | * @c: UBIFS file-system description object |
@@ -628,7 +627,7 @@ void ubifs_convert_page_budget(struct ubifs_info *c) | |||
628 | * | 627 | * |
629 | * This function releases budget corresponding to a dirty inode. It is usually | 628 | * This function releases budget corresponding to a dirty inode. It is usually |
630 | * called when after the inode has been written to the media and marked as | 629 | * called when after the inode has been written to the media and marked as |
631 | * clean. | 630 | * clean. It also causes the "no space" flags to be cleared. |
632 | */ | 631 | */ |
633 | void ubifs_release_dirty_inode_budget(struct ubifs_info *c, | 632 | void ubifs_release_dirty_inode_budget(struct ubifs_info *c, |
634 | struct ubifs_inode *ui) | 633 | struct ubifs_inode *ui) |
@@ -636,6 +635,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c, | |||
636 | struct ubifs_budget_req req; | 635 | struct ubifs_budget_req req; |
637 | 636 | ||
638 | memset(&req, 0, sizeof(struct ubifs_budget_req)); | 637 | memset(&req, 0, sizeof(struct ubifs_budget_req)); |
638 | /* The "no space" flags will be cleared because dd_growth is > 0 */ | ||
639 | req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8); | 639 | req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8); |
640 | ubifs_release_budget(c, &req); | 640 | ubifs_release_budget(c, &req); |
641 | } | 641 | } |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index f55d523c52bb..552fb0111fff 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -528,6 +528,25 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, | |||
528 | inode->i_nlink, dir->i_ino); | 528 | inode->i_nlink, dir->i_ino); |
529 | ubifs_assert(mutex_is_locked(&dir->i_mutex)); | 529 | ubifs_assert(mutex_is_locked(&dir->i_mutex)); |
530 | ubifs_assert(mutex_is_locked(&inode->i_mutex)); | 530 | ubifs_assert(mutex_is_locked(&inode->i_mutex)); |
531 | |||
532 | /* | ||
533 | * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing | ||
534 | * otherwise has the potential to corrupt the orphan inode list. | ||
535 | * | ||
536 | * Indeed, consider a scenario when 'vfs_link(dirA/fileA)' and | ||
537 | * 'vfs_unlink(dirA/fileA, dirB/fileB)' race. 'vfs_link()' does not | ||
538 | * lock 'dirA->i_mutex', so this is possible. Both of the functions | ||
539 | * lock 'fileA->i_mutex' though. Suppose 'vfs_unlink()' wins, and takes | ||
540 | * 'fileA->i_mutex' mutex first. Suppose 'fileA->i_nlink' is 1. In this | ||
541 | * case 'ubifs_unlink()' will drop the last reference, and put 'inodeA' | ||
542 | * to the list of orphans. After this, 'vfs_link()' will link | ||
543 | * 'dirB/fileB' to 'inodeA'. This is a problem because, for example, | ||
544 | * the subsequent 'vfs_unlink(dirB/fileB)' will add the same inode | ||
545 | * to the list of orphans. | ||
546 | */ | ||
547 | if (inode->i_nlink == 0) | ||
548 | return -ENOENT; | ||
549 | |||
531 | err = dbg_check_synced_i_size(inode); | 550 | err = dbg_check_synced_i_size(inode); |
532 | if (err) | 551 | if (err) |
533 | return err; | 552 | return err; |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index e8e632a1dcdf..bc5857199ec2 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -293,13 +293,14 @@ void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last) | |||
293 | * | 293 | * |
294 | * This function is called when the write-buffer timer expires. | 294 | * This function is called when the write-buffer timer expires. |
295 | */ | 295 | */ |
296 | static void wbuf_timer_callback_nolock(unsigned long data) | 296 | static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer) |
297 | { | 297 | { |
298 | struct ubifs_wbuf *wbuf = (struct ubifs_wbuf *)data; | 298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); |
299 | 299 | ||
300 | wbuf->need_sync = 1; | 300 | wbuf->need_sync = 1; |
301 | wbuf->c->need_wbuf_sync = 1; | 301 | wbuf->c->need_wbuf_sync = 1; |
302 | ubifs_wake_up_bgt(wbuf->c); | 302 | ubifs_wake_up_bgt(wbuf->c); |
303 | return HRTIMER_NORESTART; | ||
303 | } | 304 | } |
304 | 305 | ||
305 | /** | 306 | /** |
@@ -308,13 +309,12 @@ static void wbuf_timer_callback_nolock(unsigned long data) | |||
308 | */ | 309 | */ |
309 | static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | 310 | static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) |
310 | { | 311 | { |
311 | ubifs_assert(!timer_pending(&wbuf->timer)); | 312 | ubifs_assert(!hrtimer_active(&wbuf->timer)); |
312 | 313 | ||
313 | if (!wbuf->timeout) | 314 | if (!ktime_to_ns(wbuf->softlimit)) |
314 | return; | 315 | return; |
315 | 316 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, | |
316 | wbuf->timer.expires = jiffies + wbuf->timeout; | 317 | HRTIMER_MODE_REL); |
317 | add_timer(&wbuf->timer); | ||
318 | } | 318 | } |
319 | 319 | ||
320 | /** | 320 | /** |
@@ -329,7 +329,7 @@ static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
329 | * should be canceled. | 329 | * should be canceled. |
330 | */ | 330 | */ |
331 | wbuf->need_sync = 0; | 331 | wbuf->need_sync = 0; |
332 | del_timer(&wbuf->timer); | 332 | hrtimer_cancel(&wbuf->timer); |
333 | } | 333 | } |
334 | 334 | ||
335 | /** | 335 | /** |
@@ -825,6 +825,7 @@ out: | |||
825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | 825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) |
826 | { | 826 | { |
827 | size_t size; | 827 | size_t size; |
828 | ktime_t hardlimit; | ||
828 | 829 | ||
829 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); | 830 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); |
830 | if (!wbuf->buf) | 831 | if (!wbuf->buf) |
@@ -845,14 +846,21 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
845 | wbuf->sync_callback = NULL; | 846 | wbuf->sync_callback = NULL; |
846 | mutex_init(&wbuf->io_mutex); | 847 | mutex_init(&wbuf->io_mutex); |
847 | spin_lock_init(&wbuf->lock); | 848 | spin_lock_init(&wbuf->lock); |
848 | |||
849 | wbuf->c = c; | 849 | wbuf->c = c; |
850 | init_timer(&wbuf->timer); | ||
851 | wbuf->timer.function = wbuf_timer_callback_nolock; | ||
852 | wbuf->timer.data = (unsigned long)wbuf; | ||
853 | wbuf->timeout = DEFAULT_WBUF_TIMEOUT; | ||
854 | wbuf->next_ino = 0; | 850 | wbuf->next_ino = 0; |
855 | 851 | ||
852 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
853 | wbuf->timer.function = wbuf_timer_callback_nolock; | ||
854 | /* | ||
855 | * Make write-buffer soft limit to be 20% of the hard limit. The | ||
856 | * write-buffer timer is allowed to expire any time between the soft | ||
857 | * and hard limits. | ||
858 | */ | ||
859 | hardlimit = ktime_set(DEFAULT_WBUF_TIMEOUT_SECS, 0); | ||
860 | wbuf->delta = (DEFAULT_WBUF_TIMEOUT_SECS * NSEC_PER_SEC) * 2 / 10; | ||
861 | wbuf->softlimit = ktime_sub_ns(hardlimit, wbuf->delta); | ||
862 | hrtimer_set_expires_range_ns(&wbuf->timer, wbuf->softlimit, | ||
863 | wbuf->delta); | ||
856 | return 0; | 864 | return 0; |
857 | } | 865 | } |
858 | 866 | ||
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 10662975d2ef..805605250f12 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -343,33 +343,15 @@ int ubifs_write_rcvrd_mst_node(struct ubifs_info *c) | |||
343 | * | 343 | * |
344 | * This function returns %1 if @offs was in the last write to the LEB whose data | 344 | * This function returns %1 if @offs was in the last write to the LEB whose data |
345 | * is in @buf, otherwise %0 is returned. The determination is made by checking | 345 | * is in @buf, otherwise %0 is returned. The determination is made by checking |
346 | * for subsequent empty space starting from the next min_io_size boundary (or a | 346 | * for subsequent empty space starting from the next @c->min_io_size boundary. |
347 | * bit less than the common header size if min_io_size is one). | ||
348 | */ | 347 | */ |
349 | static int is_last_write(const struct ubifs_info *c, void *buf, int offs) | 348 | static int is_last_write(const struct ubifs_info *c, void *buf, int offs) |
350 | { | 349 | { |
351 | int empty_offs; | 350 | int empty_offs, check_len; |
352 | int check_len; | ||
353 | uint8_t *p; | 351 | uint8_t *p; |
354 | 352 | ||
355 | if (c->min_io_size == 1) { | ||
356 | check_len = c->leb_size - offs; | ||
357 | p = buf + check_len; | ||
358 | for (; check_len > 0; check_len--) | ||
359 | if (*--p != 0xff) | ||
360 | break; | ||
361 | /* | ||
362 | * 'check_len' is the size of the corruption which cannot be | ||
363 | * more than the size of 1 node if it was caused by an unclean | ||
364 | * unmount. | ||
365 | */ | ||
366 | if (check_len > UBIFS_MAX_NODE_SZ) | ||
367 | return 0; | ||
368 | return 1; | ||
369 | } | ||
370 | |||
371 | /* | 353 | /* |
372 | * Round up to the next c->min_io_size boundary i.e. 'offs' is in the | 354 | * Round up to the next @c->min_io_size boundary i.e. @offs is in the |
373 | * last wbuf written. After that should be empty space. | 355 | * last wbuf written. After that should be empty space. |
374 | */ | 356 | */ |
375 | empty_offs = ALIGN(offs + 1, c->min_io_size); | 357 | empty_offs = ALIGN(offs + 1, c->min_io_size); |
@@ -392,7 +374,7 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs) | |||
392 | * | 374 | * |
393 | * This function pads up to the next min_io_size boundary (if there is one) and | 375 | * This function pads up to the next min_io_size boundary (if there is one) and |
394 | * sets empty space to all 0xff. @buf, @offs and @len are updated to the next | 376 | * sets empty space to all 0xff. @buf, @offs and @len are updated to the next |
395 | * min_io_size boundary (if there is one). | 377 | * @c->min_io_size boundary. |
396 | */ | 378 | */ |
397 | static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, | 379 | static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, |
398 | int *offs, int *len) | 380 | int *offs, int *len) |
@@ -402,11 +384,6 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, | |||
402 | lnum = lnum; | 384 | lnum = lnum; |
403 | dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); | 385 | dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); |
404 | 386 | ||
405 | if (c->min_io_size == 1) { | ||
406 | memset(*buf, 0xff, c->leb_size - *offs); | ||
407 | return; | ||
408 | } | ||
409 | |||
410 | ubifs_assert(!(*offs & 7)); | 387 | ubifs_assert(!(*offs & 7)); |
411 | empty_offs = ALIGN(*offs, c->min_io_size); | 388 | empty_offs = ALIGN(*offs, c->min_io_size); |
412 | pad_len = empty_offs - *offs; | 389 | pad_len = empty_offs - *offs; |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 3260b73abe29..79fad43f3c57 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -361,6 +361,11 @@ static void ubifs_delete_inode(struct inode *inode) | |||
361 | out: | 361 | out: |
362 | if (ui->dirty) | 362 | if (ui->dirty) |
363 | ubifs_release_dirty_inode_budget(c, ui); | 363 | ubifs_release_dirty_inode_budget(c, ui); |
364 | else { | ||
365 | /* We've deleted something - clean the "no space" flags */ | ||
366 | c->nospace = c->nospace_rp = 0; | ||
367 | smp_wmb(); | ||
368 | } | ||
364 | clear_inode(inode); | 369 | clear_inode(inode); |
365 | } | 370 | } |
366 | 371 | ||
@@ -792,7 +797,7 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
792 | * does not need to be synchronized by timer. | 797 | * does not need to be synchronized by timer. |
793 | */ | 798 | */ |
794 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; | 799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; |
795 | c->jheads[GCHD].wbuf.timeout = 0; | 800 | c->jheads[GCHD].wbuf.softlimit = ktime_set(0, 0); |
796 | 801 | ||
797 | return 0; | 802 | return 0; |
798 | } | 803 | } |
@@ -933,6 +938,27 @@ static const match_table_t tokens = { | |||
933 | }; | 938 | }; |
934 | 939 | ||
935 | /** | 940 | /** |
941 | * parse_standard_option - parse a standard mount option. | ||
942 | * @option: the option to parse | ||
943 | * | ||
944 | * Normally, standard mount options like "sync" are passed to file-systems as | ||
945 | * flags. However, when a "rootflags=" kernel boot parameter is used, they may | ||
946 | * be present in the options string. This function tries to deal with this | ||
947 | * situation and parse standard options. Returns 0 if the option was not | ||
948 | * recognized, and the corresponding integer flag if it was. | ||
949 | * | ||
950 | * UBIFS is only interested in the "sync" option, so do not check for anything | ||
951 | * else. | ||
952 | */ | ||
953 | static int parse_standard_option(const char *option) | ||
954 | { | ||
955 | ubifs_msg("parse %s", option); | ||
956 | if (!strcmp(option, "sync")) | ||
957 | return MS_SYNCHRONOUS; | ||
958 | return 0; | ||
959 | } | ||
960 | |||
961 | /** | ||
936 | * ubifs_parse_options - parse mount parameters. | 962 | * ubifs_parse_options - parse mount parameters. |
937 | * @c: UBIFS file-system description object | 963 | * @c: UBIFS file-system description object |
938 | * @options: parameters to parse | 964 | * @options: parameters to parse |
@@ -1008,9 +1034,19 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
1008 | break; | 1034 | break; |
1009 | } | 1035 | } |
1010 | default: | 1036 | default: |
1011 | ubifs_err("unrecognized mount option \"%s\" " | 1037 | { |
1012 | "or missing value", p); | 1038 | unsigned long flag; |
1013 | return -EINVAL; | 1039 | struct super_block *sb = c->vfs_sb; |
1040 | |||
1041 | flag = parse_standard_option(p); | ||
1042 | if (!flag) { | ||
1043 | ubifs_err("unrecognized mount option \"%s\" " | ||
1044 | "or missing value", p); | ||
1045 | return -EINVAL; | ||
1046 | } | ||
1047 | sb->s_flags |= flag; | ||
1048 | break; | ||
1049 | } | ||
1014 | } | 1050 | } |
1015 | } | 1051 | } |
1016 | 1052 | ||
@@ -1180,6 +1216,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1180 | if (!ubifs_compr_present(c->default_compr)) { | 1216 | if (!ubifs_compr_present(c->default_compr)) { |
1181 | ubifs_err("'compressor \"%s\" is not compiled in", | 1217 | ubifs_err("'compressor \"%s\" is not compiled in", |
1182 | ubifs_compr_name(c->default_compr)); | 1218 | ubifs_compr_name(c->default_compr)); |
1219 | err = -ENOTSUPP; | ||
1183 | goto out_free; | 1220 | goto out_free; |
1184 | } | 1221 | } |
1185 | 1222 | ||
@@ -1656,7 +1693,7 @@ static void ubifs_remount_ro(struct ubifs_info *c) | |||
1656 | 1693 | ||
1657 | for (i = 0; i < c->jhead_cnt; i++) { | 1694 | for (i = 0; i < c->jhead_cnt; i++) { |
1658 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1695 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
1659 | del_timer_sync(&c->jheads[i].wbuf.timer); | 1696 | hrtimer_cancel(&c->jheads[i].wbuf.timer); |
1660 | } | 1697 | } |
1661 | 1698 | ||
1662 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); | 1699 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); |
@@ -1719,7 +1756,7 @@ static void ubifs_put_super(struct super_block *sb) | |||
1719 | if (c->jheads) | 1756 | if (c->jheads) |
1720 | for (i = 0; i < c->jhead_cnt; i++) { | 1757 | for (i = 0; i < c->jhead_cnt; i++) { |
1721 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1758 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
1722 | del_timer_sync(&c->jheads[i].wbuf.timer); | 1759 | hrtimer_cancel(&c->jheads[i].wbuf.timer); |
1723 | } | 1760 | } |
1724 | 1761 | ||
1725 | /* | 1762 | /* |
@@ -1911,6 +1948,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
1911 | INIT_LIST_HEAD(&c->orph_list); | 1948 | INIT_LIST_HEAD(&c->orph_list); |
1912 | INIT_LIST_HEAD(&c->orph_new); | 1949 | INIT_LIST_HEAD(&c->orph_new); |
1913 | 1950 | ||
1951 | c->vfs_sb = sb; | ||
1914 | c->highest_inum = UBIFS_FIRST_INO; | 1952 | c->highest_inum = UBIFS_FIRST_INO; |
1915 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; | 1953 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; |
1916 | 1954 | ||
@@ -1945,13 +1983,10 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
1945 | if (err) | 1983 | if (err) |
1946 | goto out_bdi; | 1984 | goto out_bdi; |
1947 | 1985 | ||
1948 | c->vfs_sb = sb; | ||
1949 | |||
1950 | sb->s_fs_info = c; | 1986 | sb->s_fs_info = c; |
1951 | sb->s_magic = UBIFS_SUPER_MAGIC; | 1987 | sb->s_magic = UBIFS_SUPER_MAGIC; |
1952 | sb->s_blocksize = UBIFS_BLOCK_SIZE; | 1988 | sb->s_blocksize = UBIFS_BLOCK_SIZE; |
1953 | sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT; | 1989 | sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT; |
1954 | sb->s_dev = c->vi.cdev; | ||
1955 | sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c); | 1990 | sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c); |
1956 | if (c->max_inode_sz > MAX_LFS_FILESIZE) | 1991 | if (c->max_inode_sz > MAX_LFS_FILESIZE) |
1957 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; | 1992 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; |
@@ -1996,16 +2031,9 @@ out_free: | |||
1996 | static int sb_test(struct super_block *sb, void *data) | 2031 | static int sb_test(struct super_block *sb, void *data) |
1997 | { | 2032 | { |
1998 | dev_t *dev = data; | 2033 | dev_t *dev = data; |
2034 | struct ubifs_info *c = sb->s_fs_info; | ||
1999 | 2035 | ||
2000 | return sb->s_dev == *dev; | 2036 | return c->vi.cdev == *dev; |
2001 | } | ||
2002 | |||
2003 | static int sb_set(struct super_block *sb, void *data) | ||
2004 | { | ||
2005 | dev_t *dev = data; | ||
2006 | |||
2007 | sb->s_dev = *dev; | ||
2008 | return 0; | ||
2009 | } | 2037 | } |
2010 | 2038 | ||
2011 | static int ubifs_get_sb(struct file_system_type *fs_type, int flags, | 2039 | static int ubifs_get_sb(struct file_system_type *fs_type, int flags, |
@@ -2033,7 +2061,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags, | |||
2033 | 2061 | ||
2034 | dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id); | 2062 | dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id); |
2035 | 2063 | ||
2036 | sb = sget(fs_type, &sb_test, &sb_set, &vi.cdev); | 2064 | sb = sget(fs_type, &sb_test, &set_anon_super, &vi.cdev); |
2037 | if (IS_ERR(sb)) { | 2065 | if (IS_ERR(sb)) { |
2038 | err = PTR_ERR(sb); | 2066 | err = PTR_ERR(sb); |
2039 | goto out_close; | 2067 | goto out_close; |
@@ -2073,16 +2101,11 @@ out_close: | |||
2073 | return err; | 2101 | return err; |
2074 | } | 2102 | } |
2075 | 2103 | ||
2076 | static void ubifs_kill_sb(struct super_block *sb) | ||
2077 | { | ||
2078 | generic_shutdown_super(sb); | ||
2079 | } | ||
2080 | |||
2081 | static struct file_system_type ubifs_fs_type = { | 2104 | static struct file_system_type ubifs_fs_type = { |
2082 | .name = "ubifs", | 2105 | .name = "ubifs", |
2083 | .owner = THIS_MODULE, | 2106 | .owner = THIS_MODULE, |
2084 | .get_sb = ubifs_get_sb, | 2107 | .get_sb = ubifs_get_sb, |
2085 | .kill_sb = ubifs_kill_sb | 2108 | .kill_sb = kill_anon_super, |
2086 | }; | 2109 | }; |
2087 | 2110 | ||
2088 | /* | 2111 | /* |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 0a8341e14088..1bf01d820066 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -95,8 +95,8 @@ | |||
95 | */ | 95 | */ |
96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" | 96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" |
97 | 97 | ||
98 | /* Default write-buffer synchronization timeout (5 secs) */ | 98 | /* Default write-buffer synchronization timeout in seconds */ |
99 | #define DEFAULT_WBUF_TIMEOUT (5 * HZ) | 99 | #define DEFAULT_WBUF_TIMEOUT_SECS 5 |
100 | 100 | ||
101 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ | 101 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ |
102 | #define MAX_INUM 0xFFFFFFFF | 102 | #define MAX_INUM 0xFFFFFFFF |
@@ -650,8 +650,10 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, | |||
650 | * @io_mutex: serializes write-buffer I/O | 650 | * @io_mutex: serializes write-buffer I/O |
651 | * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes | 651 | * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes |
652 | * fields | 652 | * fields |
653 | * @softlimit: soft write-buffer timeout interval | ||
654 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit | ||
655 | * and @softlimit + @delta) | ||
653 | * @timer: write-buffer timer | 656 | * @timer: write-buffer timer |
654 | * @timeout: timer expire interval in jiffies | ||
655 | * @need_sync: it is set if its timer expired and needs sync | 657 | * @need_sync: it is set if its timer expired and needs sync |
656 | * @next_ino: points to the next position of the following inode number | 658 | * @next_ino: points to the next position of the following inode number |
657 | * @inodes: stores the inode numbers of the nodes which are in wbuf | 659 | * @inodes: stores the inode numbers of the nodes which are in wbuf |
@@ -678,8 +680,9 @@ struct ubifs_wbuf { | |||
678 | int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad); | 680 | int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad); |
679 | struct mutex io_mutex; | 681 | struct mutex io_mutex; |
680 | spinlock_t lock; | 682 | spinlock_t lock; |
681 | struct timer_list timer; | 683 | ktime_t softlimit; |
682 | int timeout; | 684 | unsigned long long delta; |
685 | struct hrtimer timer; | ||
683 | int need_sync; | 686 | int need_sync; |
684 | int next_ino; | 687 | int next_ino; |
685 | ino_t *inodes; | 688 | ino_t *inodes; |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 3d2512c21f05..7cf33379fd46 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off | |||
56 | 56 | ||
57 | 57 | ||
58 | UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks); | 58 | UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks); |
59 | if (i_block < 0) { | 59 | if (i_block < direct_blocks) { |
60 | ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0"); | ||
61 | } else if (i_block < direct_blocks) { | ||
62 | offsets[n++] = i_block; | 60 | offsets[n++] = i_block; |
63 | } else if ((i_block -= direct_blocks) < indirect_blocks) { | 61 | } else if ((i_block -= direct_blocks) < indirect_blocks) { |
64 | offsets[n++] = UFS_IND_BLOCK; | 62 | offsets[n++] = UFS_IND_BLOCK; |
@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head | |||
440 | lock_kernel(); | 438 | lock_kernel(); |
441 | 439 | ||
442 | UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); | 440 | UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); |
443 | if (fragment < 0) | ||
444 | goto abort_negative; | ||
445 | if (fragment > | 441 | if (fragment > |
446 | ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) | 442 | ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) |
447 | << uspi->s_fpbshift)) | 443 | << uspi->s_fpbshift)) |
@@ -504,10 +500,6 @@ abort: | |||
504 | unlock_kernel(); | 500 | unlock_kernel(); |
505 | return err; | 501 | return err; |
506 | 502 | ||
507 | abort_negative: | ||
508 | ufs_warning(sb, "ufs_get_block", "block < 0"); | ||
509 | goto abort; | ||
510 | |||
511 | abort_too_big: | 503 | abort_too_big: |
512 | ufs_warning(sb, "ufs_get_block", "block > big"); | 504 | ufs_warning(sb, "ufs_get_block", "block > big"); |
513 | goto abort; | 505 | goto abort; |