diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-07-05 13:13:03 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-07-05 13:13:03 -0400 |
commit | 5e66dd6d66ffe758b39b6dcadf2330753ee1159b (patch) | |
tree | a72cdcff4448e4af9425cc213ddf56ab23e697fe /fs | |
parent | 026477c1141b67e98e3bd8bdedb7d4b88a3ecd09 (diff) | |
parent | ca78f6baca863afe2e6a244a0fe94b3a70211d46 (diff) |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_elf.c | 15 | ||||
-rw-r--r-- | fs/block_dev.c | 102 | ||||
-rw-r--r-- | fs/dcache.c | 6 | ||||
-rw-r--r-- | fs/direct-io.c | 6 | ||||
-rw-r--r-- | fs/eventpoll.c | 4 | ||||
-rw-r--r-- | fs/ext2/super.c | 2 | ||||
-rw-r--r-- | fs/ext3/super.c | 2 | ||||
-rw-r--r-- | fs/jffs2/acl.c | 4 | ||||
-rw-r--r-- | fs/jffs2/acl.h | 4 | ||||
-rw-r--r-- | fs/jffs2/malloc.c | 2 | ||||
-rw-r--r-- | fs/jffs2/nodelist.h | 2 | ||||
-rw-r--r-- | fs/jffs2/readinode.c | 1 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 4 | ||||
-rw-r--r-- | fs/jffs2/xattr.c | 45 | ||||
-rw-r--r-- | fs/namei.c | 20 | ||||
-rw-r--r-- | fs/ntfs/inode.c | 33 | ||||
-rw-r--r-- | fs/ntfs/super.c | 31 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 2 | ||||
-rw-r--r-- | fs/super.c | 11 | ||||
-rw-r--r-- | fs/ufs/super.c | 2 |
21 files changed, 220 insertions, 80 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index d0434406eaeb..f42e64210ee5 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -84,7 +84,7 @@ static struct linux_binfmt elf_format = { | |||
84 | .min_coredump = ELF_EXEC_PAGESIZE | 84 | .min_coredump = ELF_EXEC_PAGESIZE |
85 | }; | 85 | }; |
86 | 86 | ||
87 | #define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) | 87 | #define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) |
88 | 88 | ||
89 | static int set_brk(unsigned long start, unsigned long end) | 89 | static int set_brk(unsigned long start, unsigned long end) |
90 | { | 90 | { |
@@ -394,7 +394,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | |||
394 | * <= p_memsize so it's only necessary to check p_memsz. | 394 | * <= p_memsize so it's only necessary to check p_memsz. |
395 | */ | 395 | */ |
396 | k = load_addr + eppnt->p_vaddr; | 396 | k = load_addr + eppnt->p_vaddr; |
397 | if (k > TASK_SIZE || | 397 | if (BAD_ADDR(k) || |
398 | eppnt->p_filesz > eppnt->p_memsz || | 398 | eppnt->p_filesz > eppnt->p_memsz || |
399 | eppnt->p_memsz > TASK_SIZE || | 399 | eppnt->p_memsz > TASK_SIZE || |
400 | TASK_SIZE - eppnt->p_memsz < k) { | 400 | TASK_SIZE - eppnt->p_memsz < k) { |
@@ -887,7 +887,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
887 | * allowed task size. Note that p_filesz must always be | 887 | * allowed task size. Note that p_filesz must always be |
888 | * <= p_memsz so it is only necessary to check p_memsz. | 888 | * <= p_memsz so it is only necessary to check p_memsz. |
889 | */ | 889 | */ |
890 | if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || | 890 | if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || |
891 | elf_ppnt->p_memsz > TASK_SIZE || | 891 | elf_ppnt->p_memsz > TASK_SIZE || |
892 | TASK_SIZE - elf_ppnt->p_memsz < k) { | 892 | TASK_SIZE - elf_ppnt->p_memsz < k) { |
893 | /* set_brk can never work. Avoid overflows. */ | 893 | /* set_brk can never work. Avoid overflows. */ |
@@ -941,10 +941,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
941 | interpreter, | 941 | interpreter, |
942 | &interp_load_addr); | 942 | &interp_load_addr); |
943 | if (BAD_ADDR(elf_entry)) { | 943 | if (BAD_ADDR(elf_entry)) { |
944 | printk(KERN_ERR "Unable to load interpreter %.128s\n", | ||
945 | elf_interpreter); | ||
946 | force_sig(SIGSEGV, current); | 944 | force_sig(SIGSEGV, current); |
947 | retval = -ENOEXEC; /* Nobody gets to see this, but.. */ | 945 | retval = IS_ERR((void *)elf_entry) ? |
946 | (int)elf_entry : -EINVAL; | ||
948 | goto out_free_dentry; | 947 | goto out_free_dentry; |
949 | } | 948 | } |
950 | reloc_func_desc = interp_load_addr; | 949 | reloc_func_desc = interp_load_addr; |
@@ -955,8 +954,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
955 | } else { | 954 | } else { |
956 | elf_entry = loc->elf_ex.e_entry; | 955 | elf_entry = loc->elf_ex.e_entry; |
957 | if (BAD_ADDR(elf_entry)) { | 956 | if (BAD_ADDR(elf_entry)) { |
958 | send_sig(SIGSEGV, current, 0); | 957 | force_sig(SIGSEGV, current); |
959 | retval = -ENOEXEC; /* Nobody gets to see this, but.. */ | 958 | retval = -EINVAL; |
960 | goto out_free_dentry; | 959 | goto out_free_dentry; |
961 | } | 960 | } |
962 | } | 961 | } |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 9633a490dab0..37534573960b 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -739,7 +739,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, | |||
739 | if (!bo) | 739 | if (!bo) |
740 | return -ENOMEM; | 740 | return -ENOMEM; |
741 | 741 | ||
742 | mutex_lock(&bdev->bd_mutex); | 742 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); |
743 | res = bd_claim(bdev, holder); | 743 | res = bd_claim(bdev, holder); |
744 | if (res || !add_bd_holder(bdev, bo)) | 744 | if (res || !add_bd_holder(bdev, bo)) |
745 | free_bd_holder(bo); | 745 | free_bd_holder(bo); |
@@ -764,7 +764,7 @@ static void bd_release_from_kobject(struct block_device *bdev, | |||
764 | if (!kobj) | 764 | if (!kobj) |
765 | return; | 765 | return; |
766 | 766 | ||
767 | mutex_lock(&bdev->bd_mutex); | 767 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); |
768 | bd_release(bdev); | 768 | bd_release(bdev); |
769 | if ((bo = del_bd_holder(bdev, kobj))) | 769 | if ((bo = del_bd_holder(bdev, kobj))) |
770 | free_bd_holder(bo); | 770 | free_bd_holder(bo); |
@@ -822,6 +822,22 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode) | |||
822 | 822 | ||
823 | EXPORT_SYMBOL(open_by_devnum); | 823 | EXPORT_SYMBOL(open_by_devnum); |
824 | 824 | ||
825 | static int | ||
826 | blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags); | ||
827 | |||
828 | struct block_device *open_partition_by_devnum(dev_t dev, unsigned mode) | ||
829 | { | ||
830 | struct block_device *bdev = bdget(dev); | ||
831 | int err = -ENOMEM; | ||
832 | int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY; | ||
833 | if (bdev) | ||
834 | err = blkdev_get_partition(bdev, mode, flags); | ||
835 | return err ? ERR_PTR(err) : bdev; | ||
836 | } | ||
837 | |||
838 | EXPORT_SYMBOL(open_partition_by_devnum); | ||
839 | |||
840 | |||
825 | /* | 841 | /* |
826 | * This routine checks whether a removable media has been changed, | 842 | * This routine checks whether a removable media has been changed, |
827 | * and invalidates all buffer-cache-entries in that case. This | 843 | * and invalidates all buffer-cache-entries in that case. This |
@@ -868,7 +884,11 @@ void bd_set_size(struct block_device *bdev, loff_t size) | |||
868 | } | 884 | } |
869 | EXPORT_SYMBOL(bd_set_size); | 885 | EXPORT_SYMBOL(bd_set_size); |
870 | 886 | ||
871 | static int do_open(struct block_device *bdev, struct file *file) | 887 | static int |
888 | blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags); | ||
889 | |||
890 | static int | ||
891 | do_open(struct block_device *bdev, struct file *file, unsigned int subclass) | ||
872 | { | 892 | { |
873 | struct module *owner = NULL; | 893 | struct module *owner = NULL; |
874 | struct gendisk *disk; | 894 | struct gendisk *disk; |
@@ -885,7 +905,8 @@ static int do_open(struct block_device *bdev, struct file *file) | |||
885 | } | 905 | } |
886 | owner = disk->fops->owner; | 906 | owner = disk->fops->owner; |
887 | 907 | ||
888 | mutex_lock(&bdev->bd_mutex); | 908 | mutex_lock_nested(&bdev->bd_mutex, subclass); |
909 | |||
889 | if (!bdev->bd_openers) { | 910 | if (!bdev->bd_openers) { |
890 | bdev->bd_disk = disk; | 911 | bdev->bd_disk = disk; |
891 | bdev->bd_contains = bdev; | 912 | bdev->bd_contains = bdev; |
@@ -912,11 +933,11 @@ static int do_open(struct block_device *bdev, struct file *file) | |||
912 | ret = -ENOMEM; | 933 | ret = -ENOMEM; |
913 | if (!whole) | 934 | if (!whole) |
914 | goto out_first; | 935 | goto out_first; |
915 | ret = blkdev_get(whole, file->f_mode, file->f_flags); | 936 | ret = blkdev_get_whole(whole, file->f_mode, file->f_flags); |
916 | if (ret) | 937 | if (ret) |
917 | goto out_first; | 938 | goto out_first; |
918 | bdev->bd_contains = whole; | 939 | bdev->bd_contains = whole; |
919 | mutex_lock(&whole->bd_mutex); | 940 | mutex_lock_nested(&whole->bd_mutex, BD_MUTEX_WHOLE); |
920 | whole->bd_part_count++; | 941 | whole->bd_part_count++; |
921 | p = disk->part[part - 1]; | 942 | p = disk->part[part - 1]; |
922 | bdev->bd_inode->i_data.backing_dev_info = | 943 | bdev->bd_inode->i_data.backing_dev_info = |
@@ -944,7 +965,8 @@ static int do_open(struct block_device *bdev, struct file *file) | |||
944 | if (bdev->bd_invalidated) | 965 | if (bdev->bd_invalidated) |
945 | rescan_partitions(bdev->bd_disk, bdev); | 966 | rescan_partitions(bdev->bd_disk, bdev); |
946 | } else { | 967 | } else { |
947 | mutex_lock(&bdev->bd_contains->bd_mutex); | 968 | mutex_lock_nested(&bdev->bd_contains->bd_mutex, |
969 | BD_MUTEX_PARTITION); | ||
948 | bdev->bd_contains->bd_part_count++; | 970 | bdev->bd_contains->bd_part_count++; |
949 | mutex_unlock(&bdev->bd_contains->bd_mutex); | 971 | mutex_unlock(&bdev->bd_contains->bd_mutex); |
950 | } | 972 | } |
@@ -985,11 +1007,49 @@ int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) | |||
985 | fake_file.f_dentry = &fake_dentry; | 1007 | fake_file.f_dentry = &fake_dentry; |
986 | fake_dentry.d_inode = bdev->bd_inode; | 1008 | fake_dentry.d_inode = bdev->bd_inode; |
987 | 1009 | ||
988 | return do_open(bdev, &fake_file); | 1010 | return do_open(bdev, &fake_file, BD_MUTEX_NORMAL); |
989 | } | 1011 | } |
990 | 1012 | ||
991 | EXPORT_SYMBOL(blkdev_get); | 1013 | EXPORT_SYMBOL(blkdev_get); |
992 | 1014 | ||
1015 | static int | ||
1016 | blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags) | ||
1017 | { | ||
1018 | /* | ||
1019 | * This crockload is due to bad choice of ->open() type. | ||
1020 | * It will go away. | ||
1021 | * For now, block device ->open() routine must _not_ | ||
1022 | * examine anything in 'inode' argument except ->i_rdev. | ||
1023 | */ | ||
1024 | struct file fake_file = {}; | ||
1025 | struct dentry fake_dentry = {}; | ||
1026 | fake_file.f_mode = mode; | ||
1027 | fake_file.f_flags = flags; | ||
1028 | fake_file.f_dentry = &fake_dentry; | ||
1029 | fake_dentry.d_inode = bdev->bd_inode; | ||
1030 | |||
1031 | return do_open(bdev, &fake_file, BD_MUTEX_WHOLE); | ||
1032 | } | ||
1033 | |||
1034 | static int | ||
1035 | blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags) | ||
1036 | { | ||
1037 | /* | ||
1038 | * This crockload is due to bad choice of ->open() type. | ||
1039 | * It will go away. | ||
1040 | * For now, block device ->open() routine must _not_ | ||
1041 | * examine anything in 'inode' argument except ->i_rdev. | ||
1042 | */ | ||
1043 | struct file fake_file = {}; | ||
1044 | struct dentry fake_dentry = {}; | ||
1045 | fake_file.f_mode = mode; | ||
1046 | fake_file.f_flags = flags; | ||
1047 | fake_file.f_dentry = &fake_dentry; | ||
1048 | fake_dentry.d_inode = bdev->bd_inode; | ||
1049 | |||
1050 | return do_open(bdev, &fake_file, BD_MUTEX_PARTITION); | ||
1051 | } | ||
1052 | |||
993 | static int blkdev_open(struct inode * inode, struct file * filp) | 1053 | static int blkdev_open(struct inode * inode, struct file * filp) |
994 | { | 1054 | { |
995 | struct block_device *bdev; | 1055 | struct block_device *bdev; |
@@ -1005,7 +1065,7 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1005 | 1065 | ||
1006 | bdev = bd_acquire(inode); | 1066 | bdev = bd_acquire(inode); |
1007 | 1067 | ||
1008 | res = do_open(bdev, filp); | 1068 | res = do_open(bdev, filp, BD_MUTEX_NORMAL); |
1009 | if (res) | 1069 | if (res) |
1010 | return res; | 1070 | return res; |
1011 | 1071 | ||
@@ -1019,13 +1079,13 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1019 | return res; | 1079 | return res; |
1020 | } | 1080 | } |
1021 | 1081 | ||
1022 | int blkdev_put(struct block_device *bdev) | 1082 | static int __blkdev_put(struct block_device *bdev, unsigned int subclass) |
1023 | { | 1083 | { |
1024 | int ret = 0; | 1084 | int ret = 0; |
1025 | struct inode *bd_inode = bdev->bd_inode; | 1085 | struct inode *bd_inode = bdev->bd_inode; |
1026 | struct gendisk *disk = bdev->bd_disk; | 1086 | struct gendisk *disk = bdev->bd_disk; |
1027 | 1087 | ||
1028 | mutex_lock(&bdev->bd_mutex); | 1088 | mutex_lock_nested(&bdev->bd_mutex, subclass); |
1029 | lock_kernel(); | 1089 | lock_kernel(); |
1030 | if (!--bdev->bd_openers) { | 1090 | if (!--bdev->bd_openers) { |
1031 | sync_blockdev(bdev); | 1091 | sync_blockdev(bdev); |
@@ -1035,7 +1095,8 @@ int blkdev_put(struct block_device *bdev) | |||
1035 | if (disk->fops->release) | 1095 | if (disk->fops->release) |
1036 | ret = disk->fops->release(bd_inode, NULL); | 1096 | ret = disk->fops->release(bd_inode, NULL); |
1037 | } else { | 1097 | } else { |
1038 | mutex_lock(&bdev->bd_contains->bd_mutex); | 1098 | mutex_lock_nested(&bdev->bd_contains->bd_mutex, |
1099 | subclass + 1); | ||
1039 | bdev->bd_contains->bd_part_count--; | 1100 | bdev->bd_contains->bd_part_count--; |
1040 | mutex_unlock(&bdev->bd_contains->bd_mutex); | 1101 | mutex_unlock(&bdev->bd_contains->bd_mutex); |
1041 | } | 1102 | } |
@@ -1051,9 +1112,8 @@ int blkdev_put(struct block_device *bdev) | |||
1051 | } | 1112 | } |
1052 | bdev->bd_disk = NULL; | 1113 | bdev->bd_disk = NULL; |
1053 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; | 1114 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; |
1054 | if (bdev != bdev->bd_contains) { | 1115 | if (bdev != bdev->bd_contains) |
1055 | blkdev_put(bdev->bd_contains); | 1116 | __blkdev_put(bdev->bd_contains, subclass + 1); |
1056 | } | ||
1057 | bdev->bd_contains = NULL; | 1117 | bdev->bd_contains = NULL; |
1058 | } | 1118 | } |
1059 | unlock_kernel(); | 1119 | unlock_kernel(); |
@@ -1062,8 +1122,20 @@ int blkdev_put(struct block_device *bdev) | |||
1062 | return ret; | 1122 | return ret; |
1063 | } | 1123 | } |
1064 | 1124 | ||
1125 | int blkdev_put(struct block_device *bdev) | ||
1126 | { | ||
1127 | return __blkdev_put(bdev, BD_MUTEX_NORMAL); | ||
1128 | } | ||
1129 | |||
1065 | EXPORT_SYMBOL(blkdev_put); | 1130 | EXPORT_SYMBOL(blkdev_put); |
1066 | 1131 | ||
1132 | int blkdev_put_partition(struct block_device *bdev) | ||
1133 | { | ||
1134 | return __blkdev_put(bdev, BD_MUTEX_PARTITION); | ||
1135 | } | ||
1136 | |||
1137 | EXPORT_SYMBOL(blkdev_put_partition); | ||
1138 | |||
1067 | static int blkdev_close(struct inode * inode, struct file * filp) | 1139 | static int blkdev_close(struct inode * inode, struct file * filp) |
1068 | { | 1140 | { |
1069 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); | 1141 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); |
diff --git a/fs/dcache.c b/fs/dcache.c index c6e3535be192..1b4a3a34ec57 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -38,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100; | |||
38 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); | 38 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); |
39 | 39 | ||
40 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); | 40 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); |
41 | static seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; | 41 | static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); |
42 | 42 | ||
43 | EXPORT_SYMBOL(dcache_lock); | 43 | EXPORT_SYMBOL(dcache_lock); |
44 | 44 | ||
@@ -1339,10 +1339,10 @@ void d_move(struct dentry * dentry, struct dentry * target) | |||
1339 | */ | 1339 | */ |
1340 | if (target < dentry) { | 1340 | if (target < dentry) { |
1341 | spin_lock(&target->d_lock); | 1341 | spin_lock(&target->d_lock); |
1342 | spin_lock(&dentry->d_lock); | 1342 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
1343 | } else { | 1343 | } else { |
1344 | spin_lock(&dentry->d_lock); | 1344 | spin_lock(&dentry->d_lock); |
1345 | spin_lock(&target->d_lock); | 1345 | spin_lock_nested(&target->d_lock, DENTRY_D_LOCK_NESTED); |
1346 | } | 1346 | } |
1347 | 1347 | ||
1348 | /* Move the dentry to the target hash queue, if on different bucket */ | 1348 | /* Move the dentry to the target hash queue, if on different bucket */ |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 538fb0418fba..5981e17f46f0 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -220,7 +220,8 @@ static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes) | |||
220 | if (dio->end_io && dio->result) | 220 | if (dio->end_io && dio->result) |
221 | dio->end_io(dio->iocb, offset, bytes, dio->map_bh.b_private); | 221 | dio->end_io(dio->iocb, offset, bytes, dio->map_bh.b_private); |
222 | if (dio->lock_type == DIO_LOCKING) | 222 | if (dio->lock_type == DIO_LOCKING) |
223 | up_read(&dio->inode->i_alloc_sem); | 223 | /* lockdep: non-owner release */ |
224 | up_read_non_owner(&dio->inode->i_alloc_sem); | ||
224 | } | 225 | } |
225 | 226 | ||
226 | /* | 227 | /* |
@@ -1261,7 +1262,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1261 | } | 1262 | } |
1262 | 1263 | ||
1263 | if (dio_lock_type == DIO_LOCKING) | 1264 | if (dio_lock_type == DIO_LOCKING) |
1264 | down_read(&inode->i_alloc_sem); | 1265 | /* lockdep: not the owner will release it */ |
1266 | down_read_non_owner(&inode->i_alloc_sem); | ||
1265 | } | 1267 | } |
1266 | 1268 | ||
1267 | /* | 1269 | /* |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 9c677bbd0b08..19ffb043abbc 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -120,7 +120,7 @@ struct epoll_filefd { | |||
120 | */ | 120 | */ |
121 | struct wake_task_node { | 121 | struct wake_task_node { |
122 | struct list_head llink; | 122 | struct list_head llink; |
123 | task_t *task; | 123 | struct task_struct *task; |
124 | wait_queue_head_t *wq; | 124 | wait_queue_head_t *wq; |
125 | }; | 125 | }; |
126 | 126 | ||
@@ -413,7 +413,7 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq) | |||
413 | { | 413 | { |
414 | int wake_nests = 0; | 414 | int wake_nests = 0; |
415 | unsigned long flags; | 415 | unsigned long flags; |
416 | task_t *this_task = current; | 416 | struct task_struct *this_task = current; |
417 | struct list_head *lsthead = &psw->wake_task_list, *lnk; | 417 | struct list_head *lsthead = &psw->wake_task_list, *lnk; |
418 | struct wake_task_node *tncur; | 418 | struct wake_task_node *tncur; |
419 | struct wake_task_node tnode; | 419 | struct wake_task_node tnode; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 9f43879d6d68..f2702cda9779 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -1157,7 +1157,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, | |||
1157 | struct buffer_head tmp_bh; | 1157 | struct buffer_head tmp_bh; |
1158 | struct buffer_head *bh; | 1158 | struct buffer_head *bh; |
1159 | 1159 | ||
1160 | mutex_lock(&inode->i_mutex); | 1160 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
1161 | while (towrite > 0) { | 1161 | while (towrite > 0) { |
1162 | tocopy = sb->s_blocksize - offset < towrite ? | 1162 | tocopy = sb->s_blocksize - offset < towrite ? |
1163 | sb->s_blocksize - offset : towrite; | 1163 | sb->s_blocksize - offset : towrite; |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index f2dd71336612..813d589cc6c0 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2614,7 +2614,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
2614 | struct buffer_head *bh; | 2614 | struct buffer_head *bh; |
2615 | handle_t *handle = journal_current_handle(); | 2615 | handle_t *handle = journal_current_handle(); |
2616 | 2616 | ||
2617 | mutex_lock(&inode->i_mutex); | 2617 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
2618 | while (towrite > 0) { | 2618 | while (towrite > 0) { |
2619 | tocopy = sb->s_blocksize - offset < towrite ? | 2619 | tocopy = sb->s_blocksize - offset < towrite ? |
2620 | sb->s_blocksize - offset : towrite; | 2620 | sb->s_blocksize - offset : towrite; |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 9c2077e7e081..0ae3cd10702c 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -345,10 +345,8 @@ int jffs2_init_acl(struct inode *inode, struct inode *dir) | |||
345 | return rc; | 345 | return rc; |
346 | } | 346 | } |
347 | 347 | ||
348 | void jffs2_clear_acl(struct inode *inode) | 348 | void jffs2_clear_acl(struct jffs2_inode_info *f) |
349 | { | 349 | { |
350 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); | ||
351 | |||
352 | if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) { | 350 | if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) { |
353 | posix_acl_release(f->i_acl_access); | 351 | posix_acl_release(f->i_acl_access); |
354 | f->i_acl_access = JFFS2_ACL_NOT_CACHED; | 352 | f->i_acl_access = JFFS2_ACL_NOT_CACHED; |
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index 8893bd1a6ba7..fa327dbd3171 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h | |||
@@ -30,7 +30,7 @@ struct jffs2_acl_header { | |||
30 | extern int jffs2_permission(struct inode *, int, struct nameidata *); | 30 | extern int jffs2_permission(struct inode *, int, struct nameidata *); |
31 | extern int jffs2_acl_chmod(struct inode *); | 31 | extern int jffs2_acl_chmod(struct inode *); |
32 | extern int jffs2_init_acl(struct inode *, struct inode *); | 32 | extern int jffs2_init_acl(struct inode *, struct inode *); |
33 | extern void jffs2_clear_acl(struct inode *); | 33 | extern void jffs2_clear_acl(struct jffs2_inode_info *); |
34 | 34 | ||
35 | extern struct xattr_handler jffs2_acl_access_xattr_handler; | 35 | extern struct xattr_handler jffs2_acl_access_xattr_handler; |
36 | extern struct xattr_handler jffs2_acl_default_xattr_handler; | 36 | extern struct xattr_handler jffs2_acl_default_xattr_handler; |
@@ -40,6 +40,6 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler; | |||
40 | #define jffs2_permission NULL | 40 | #define jffs2_permission NULL |
41 | #define jffs2_acl_chmod(inode) (0) | 41 | #define jffs2_acl_chmod(inode) (0) |
42 | #define jffs2_init_acl(inode,dir) (0) | 42 | #define jffs2_init_acl(inode,dir) (0) |
43 | #define jffs2_clear_acl(inode) | 43 | #define jffs2_clear_acl(f) |
44 | 44 | ||
45 | #endif /* CONFIG_JFFS2_FS_POSIX_ACL */ | 45 | #endif /* CONFIG_JFFS2_FS_POSIX_ACL */ |
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c index 8310c95478e9..33f291005012 100644 --- a/fs/jffs2/malloc.c +++ b/fs/jffs2/malloc.c | |||
@@ -190,7 +190,7 @@ void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x) | |||
190 | kmem_cache_free(tmp_dnode_info_slab, x); | 190 | kmem_cache_free(tmp_dnode_info_slab, x); |
191 | } | 191 | } |
192 | 192 | ||
193 | struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) | 193 | static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) |
194 | { | 194 | { |
195 | struct jffs2_raw_node_ref *ret; | 195 | struct jffs2_raw_node_ref *ret; |
196 | 196 | ||
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index f752baa8d399..cae92c14116d 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h | |||
@@ -426,8 +426,6 @@ char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f); | |||
426 | /* scan.c */ | 426 | /* scan.c */ |
427 | int jffs2_scan_medium(struct jffs2_sb_info *c); | 427 | int jffs2_scan_medium(struct jffs2_sb_info *c); |
428 | void jffs2_rotate_lists(struct jffs2_sb_info *c); | 428 | void jffs2_rotate_lists(struct jffs2_sb_info *c); |
429 | int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf, | ||
430 | uint32_t ofs, uint32_t len); | ||
431 | struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino); | 429 | struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino); |
432 | int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); | 430 | int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); |
433 | int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size); | 431 | int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size); |
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index cc1899268c43..266423b2709d 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -968,6 +968,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) | |||
968 | struct jffs2_full_dirent *fd, *fds; | 968 | struct jffs2_full_dirent *fd, *fds; |
969 | int deleted; | 969 | int deleted; |
970 | 970 | ||
971 | jffs2_clear_acl(f); | ||
971 | jffs2_xattr_delete_inode(c, f->inocache); | 972 | jffs2_xattr_delete_inode(c, f->inocache); |
972 | down(&f->sem); | 973 | down(&f->sem); |
973 | deleted = f->inocache && !f->inocache->nlink; | 974 | deleted = f->inocache && !f->inocache->nlink; |
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 2bfdc33752d3..e2413466ddd5 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -274,8 +274,8 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
274 | return ret; | 274 | return ret; |
275 | } | 275 | } |
276 | 276 | ||
277 | int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf, | 277 | static int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf, |
278 | uint32_t ofs, uint32_t len) | 278 | uint32_t ofs, uint32_t len) |
279 | { | 279 | { |
280 | int ret; | 280 | int ret; |
281 | size_t retlen; | 281 | size_t retlen; |
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 18e66dbf23b4..25bc1ae08648 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
@@ -50,9 +50,10 @@ | |||
50 | * is used to write xdatum to medium. xd->version will be incremented. | 50 | * is used to write xdatum to medium. xd->version will be incremented. |
51 | * create_xattr_datum(c, xprefix, xname, xvalue, xsize) | 51 | * create_xattr_datum(c, xprefix, xname, xvalue, xsize) |
52 | * is used to create new xdatum and write to medium. | 52 | * is used to create new xdatum and write to medium. |
53 | * delete_xattr_datum(c, xd) | 53 | * unrefer_xattr_datum(c, xd) |
54 | * is used to delete a xdatum. It marks xd JFFS2_XFLAGS_DEAD, and allows | 54 | * is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD |
55 | * GC to reclaim those physical nodes. | 55 | * is set on xd->flags and chained xattr_dead_list or release it immediately. |
56 | * In the first case, the garbage collector release it later. | ||
56 | * -------------------------------------------------- */ | 57 | * -------------------------------------------------- */ |
57 | static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) | 58 | static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) |
58 | { | 59 | { |
@@ -394,22 +395,24 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, | |||
394 | return xd; | 395 | return xd; |
395 | } | 396 | } |
396 | 397 | ||
397 | static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) | 398 | static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) |
398 | { | 399 | { |
399 | /* must be called under down_write(xattr_sem) */ | 400 | /* must be called under down_write(xattr_sem) */ |
400 | BUG_ON(atomic_read(&xd->refcnt)); | 401 | if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) { |
402 | uint32_t xid = xd->xid, version = xd->version; | ||
401 | 403 | ||
402 | unload_xattr_datum(c, xd); | 404 | unload_xattr_datum(c, xd); |
403 | xd->flags |= JFFS2_XFLAGS_DEAD; | 405 | xd->flags |= JFFS2_XFLAGS_DEAD; |
404 | spin_lock(&c->erase_completion_lock); | 406 | if (xd->node == (void *)xd) { |
405 | if (xd->node == (void *)xd) { | 407 | BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID)); |
406 | BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID)); | 408 | jffs2_free_xattr_datum(xd); |
407 | jffs2_free_xattr_datum(xd); | 409 | } else { |
408 | } else { | 410 | list_add(&xd->xindex, &c->xattr_dead_list); |
409 | list_add(&xd->xindex, &c->xattr_dead_list); | 411 | } |
412 | spin_unlock(&c->erase_completion_lock); | ||
413 | |||
414 | dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xid, version); | ||
410 | } | 415 | } |
411 | spin_unlock(&c->erase_completion_lock); | ||
412 | dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xd->xid, xd->version); | ||
413 | } | 416 | } |
414 | 417 | ||
415 | /* -------- xref related functions ------------------ | 418 | /* -------- xref related functions ------------------ |
@@ -580,8 +583,7 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re | |||
580 | dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n", | 583 | dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n", |
581 | ref->ino, ref->xid, ref->xseqno); | 584 | ref->ino, ref->xid, ref->xseqno); |
582 | 585 | ||
583 | if (atomic_dec_and_test(&xd->refcnt)) | 586 | unrefer_xattr_datum(c, xd); |
584 | delete_xattr_datum(c, xd); | ||
585 | } | 587 | } |
586 | 588 | ||
587 | void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) | 589 | void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) |
@@ -1119,8 +1121,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | |||
1119 | ref->next = c->xref_dead_list; | 1121 | ref->next = c->xref_dead_list; |
1120 | c->xref_dead_list = ref; | 1122 | c->xref_dead_list = ref; |
1121 | spin_unlock(&c->erase_completion_lock); | 1123 | spin_unlock(&c->erase_completion_lock); |
1122 | if (atomic_dec_and_test(&xd->refcnt)) | 1124 | unrefer_xattr_datum(c, xd); |
1123 | delete_xattr_datum(c, xd); | ||
1124 | } else { | 1125 | } else { |
1125 | ref->ic = ic; | 1126 | ref->ic = ic; |
1126 | ref->xd = xd; | 1127 | ref->xd = xd; |
@@ -1156,8 +1157,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | |||
1156 | down_write(&c->xattr_sem); | 1157 | down_write(&c->xattr_sem); |
1157 | if (rc) { | 1158 | if (rc) { |
1158 | JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); | 1159 | JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); |
1159 | if (atomic_dec_and_test(&xd->refcnt)) | 1160 | unrefer_xattr_datum(c, xd); |
1160 | delete_xattr_datum(c, xd); | ||
1161 | up_write(&c->xattr_sem); | 1161 | up_write(&c->xattr_sem); |
1162 | return rc; | 1162 | return rc; |
1163 | } | 1163 | } |
@@ -1170,8 +1170,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | |||
1170 | ic->xref = ref; | 1170 | ic->xref = ref; |
1171 | } | 1171 | } |
1172 | rc = PTR_ERR(newref); | 1172 | rc = PTR_ERR(newref); |
1173 | if (atomic_dec_and_test(&xd->refcnt)) | 1173 | unrefer_xattr_datum(c, xd); |
1174 | delete_xattr_datum(c, xd); | ||
1175 | } else if (ref) { | 1174 | } else if (ref) { |
1176 | delete_xattr_ref(c, ref); | 1175 | delete_xattr_ref(c, ref); |
1177 | } | 1176 | } |
diff --git a/fs/namei.c b/fs/namei.c index c784e8bb57a3..c9750d755aff 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1423,7 +1423,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
1423 | struct dentry *p; | 1423 | struct dentry *p; |
1424 | 1424 | ||
1425 | if (p1 == p2) { | 1425 | if (p1 == p2) { |
1426 | mutex_lock(&p1->d_inode->i_mutex); | 1426 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT); |
1427 | return NULL; | 1427 | return NULL; |
1428 | } | 1428 | } |
1429 | 1429 | ||
@@ -1431,22 +1431,22 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
1431 | 1431 | ||
1432 | for (p = p1; p->d_parent != p; p = p->d_parent) { | 1432 | for (p = p1; p->d_parent != p; p = p->d_parent) { |
1433 | if (p->d_parent == p2) { | 1433 | if (p->d_parent == p2) { |
1434 | mutex_lock(&p2->d_inode->i_mutex); | 1434 | mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT); |
1435 | mutex_lock(&p1->d_inode->i_mutex); | 1435 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD); |
1436 | return p; | 1436 | return p; |
1437 | } | 1437 | } |
1438 | } | 1438 | } |
1439 | 1439 | ||
1440 | for (p = p2; p->d_parent != p; p = p->d_parent) { | 1440 | for (p = p2; p->d_parent != p; p = p->d_parent) { |
1441 | if (p->d_parent == p1) { | 1441 | if (p->d_parent == p1) { |
1442 | mutex_lock(&p1->d_inode->i_mutex); | 1442 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT); |
1443 | mutex_lock(&p2->d_inode->i_mutex); | 1443 | mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD); |
1444 | return p; | 1444 | return p; |
1445 | } | 1445 | } |
1446 | } | 1446 | } |
1447 | 1447 | ||
1448 | mutex_lock(&p1->d_inode->i_mutex); | 1448 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT); |
1449 | mutex_lock(&p2->d_inode->i_mutex); | 1449 | mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD); |
1450 | return NULL; | 1450 | return NULL; |
1451 | } | 1451 | } |
1452 | 1452 | ||
@@ -1751,7 +1751,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir) | |||
1751 | { | 1751 | { |
1752 | struct dentry *dentry = ERR_PTR(-EEXIST); | 1752 | struct dentry *dentry = ERR_PTR(-EEXIST); |
1753 | 1753 | ||
1754 | mutex_lock(&nd->dentry->d_inode->i_mutex); | 1754 | mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
1755 | /* | 1755 | /* |
1756 | * Yucky last component or no last component at all? | 1756 | * Yucky last component or no last component at all? |
1757 | * (foo/., foo/.., /////) | 1757 | * (foo/., foo/.., /////) |
@@ -2008,7 +2008,7 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2008 | error = -EBUSY; | 2008 | error = -EBUSY; |
2009 | goto exit1; | 2009 | goto exit1; |
2010 | } | 2010 | } |
2011 | mutex_lock(&nd.dentry->d_inode->i_mutex); | 2011 | mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
2012 | dentry = lookup_hash(&nd); | 2012 | dentry = lookup_hash(&nd); |
2013 | error = PTR_ERR(dentry); | 2013 | error = PTR_ERR(dentry); |
2014 | if (!IS_ERR(dentry)) { | 2014 | if (!IS_ERR(dentry)) { |
@@ -2082,7 +2082,7 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2082 | error = -EISDIR; | 2082 | error = -EISDIR; |
2083 | if (nd.last_type != LAST_NORM) | 2083 | if (nd.last_type != LAST_NORM) |
2084 | goto exit1; | 2084 | goto exit1; |
2085 | mutex_lock(&nd.dentry->d_inode->i_mutex); | 2085 | mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
2086 | dentry = lookup_hash(&nd); | 2086 | dentry = lookup_hash(&nd); |
2087 | error = PTR_ERR(dentry); | 2087 | error = PTR_ERR(dentry); |
2088 | if (!IS_ERR(dentry)) { | 2088 | if (!IS_ERR(dentry)) { |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 4c86b7e1d1eb..d313f356e66a 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -367,6 +367,12 @@ static void ntfs_destroy_extent_inode(ntfs_inode *ni) | |||
367 | kmem_cache_free(ntfs_inode_cache, ni); | 367 | kmem_cache_free(ntfs_inode_cache, ni); |
368 | } | 368 | } |
369 | 369 | ||
370 | /* | ||
371 | * The attribute runlist lock has separate locking rules from the | ||
372 | * normal runlist lock, so split the two lock-classes: | ||
373 | */ | ||
374 | static struct lock_class_key attr_list_rl_lock_class; | ||
375 | |||
370 | /** | 376 | /** |
371 | * __ntfs_init_inode - initialize ntfs specific part of an inode | 377 | * __ntfs_init_inode - initialize ntfs specific part of an inode |
372 | * @sb: super block of mounted volume | 378 | * @sb: super block of mounted volume |
@@ -394,6 +400,8 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) | |||
394 | ni->attr_list_size = 0; | 400 | ni->attr_list_size = 0; |
395 | ni->attr_list = NULL; | 401 | ni->attr_list = NULL; |
396 | ntfs_init_runlist(&ni->attr_list_rl); | 402 | ntfs_init_runlist(&ni->attr_list_rl); |
403 | lockdep_set_class(&ni->attr_list_rl.lock, | ||
404 | &attr_list_rl_lock_class); | ||
397 | ni->itype.index.bmp_ino = NULL; | 405 | ni->itype.index.bmp_ino = NULL; |
398 | ni->itype.index.block_size = 0; | 406 | ni->itype.index.block_size = 0; |
399 | ni->itype.index.vcn_size = 0; | 407 | ni->itype.index.vcn_size = 0; |
@@ -405,6 +413,13 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) | |||
405 | ni->ext.base_ntfs_ino = NULL; | 413 | ni->ext.base_ntfs_ino = NULL; |
406 | } | 414 | } |
407 | 415 | ||
416 | /* | ||
417 | * Extent inodes get MFT-mapped in a nested way, while the base inode | ||
418 | * is still mapped. Teach this nesting to the lock validator by creating | ||
419 | * a separate class for nested inode's mrec_lock's: | ||
420 | */ | ||
421 | static struct lock_class_key extent_inode_mrec_lock_key; | ||
422 | |||
408 | inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, | 423 | inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, |
409 | unsigned long mft_no) | 424 | unsigned long mft_no) |
410 | { | 425 | { |
@@ -413,6 +428,7 @@ inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, | |||
413 | ntfs_debug("Entering."); | 428 | ntfs_debug("Entering."); |
414 | if (likely(ni != NULL)) { | 429 | if (likely(ni != NULL)) { |
415 | __ntfs_init_inode(sb, ni); | 430 | __ntfs_init_inode(sb, ni); |
431 | lockdep_set_class(&ni->mrec_lock, &extent_inode_mrec_lock_key); | ||
416 | ni->mft_no = mft_no; | 432 | ni->mft_no = mft_no; |
417 | ni->type = AT_UNUSED; | 433 | ni->type = AT_UNUSED; |
418 | ni->name = NULL; | 434 | ni->name = NULL; |
@@ -1722,6 +1738,15 @@ err_out: | |||
1722 | return err; | 1738 | return err; |
1723 | } | 1739 | } |
1724 | 1740 | ||
1741 | /* | ||
1742 | * The MFT inode has special locking, so teach the lock validator | ||
1743 | * about this by splitting off the locking rules of the MFT from | ||
1744 | * the locking rules of other inodes. The MFT inode can never be | ||
1745 | * accessed from the VFS side (or even internally), only by the | ||
1746 | * map_mft functions. | ||
1747 | */ | ||
1748 | static struct lock_class_key mft_ni_runlist_lock_key, mft_ni_mrec_lock_key; | ||
1749 | |||
1725 | /** | 1750 | /** |
1726 | * ntfs_read_inode_mount - special read_inode for mount time use only | 1751 | * ntfs_read_inode_mount - special read_inode for mount time use only |
1727 | * @vi: inode to read | 1752 | * @vi: inode to read |
@@ -2148,6 +2173,14 @@ int ntfs_read_inode_mount(struct inode *vi) | |||
2148 | ntfs_attr_put_search_ctx(ctx); | 2173 | ntfs_attr_put_search_ctx(ctx); |
2149 | ntfs_debug("Done."); | 2174 | ntfs_debug("Done."); |
2150 | ntfs_free(m); | 2175 | ntfs_free(m); |
2176 | |||
2177 | /* | ||
2178 | * Split the locking rules of the MFT inode from the | ||
2179 | * locking rules of other inodes: | ||
2180 | */ | ||
2181 | lockdep_set_class(&ni->runlist.lock, &mft_ni_runlist_lock_key); | ||
2182 | lockdep_set_class(&ni->mrec_lock, &mft_ni_mrec_lock_key); | ||
2183 | |||
2151 | return 0; | 2184 | return 0; |
2152 | 2185 | ||
2153 | em_put_err_out: | 2186 | em_put_err_out: |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 0e14acea3f8b..74e0ee8fce72 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -1724,6 +1724,14 @@ upcase_failed: | |||
1724 | return FALSE; | 1724 | return FALSE; |
1725 | } | 1725 | } |
1726 | 1726 | ||
1727 | /* | ||
1728 | * The lcn and mft bitmap inodes are NTFS-internal inodes with | ||
1729 | * their own special locking rules: | ||
1730 | */ | ||
1731 | static struct lock_class_key | ||
1732 | lcnbmp_runlist_lock_key, lcnbmp_mrec_lock_key, | ||
1733 | mftbmp_runlist_lock_key, mftbmp_mrec_lock_key; | ||
1734 | |||
1727 | /** | 1735 | /** |
1728 | * load_system_files - open the system files using normal functions | 1736 | * load_system_files - open the system files using normal functions |
1729 | * @vol: ntfs super block describing device whose system files to load | 1737 | * @vol: ntfs super block describing device whose system files to load |
@@ -1780,6 +1788,10 @@ static BOOL load_system_files(ntfs_volume *vol) | |||
1780 | ntfs_error(sb, "Failed to load $MFT/$BITMAP attribute."); | 1788 | ntfs_error(sb, "Failed to load $MFT/$BITMAP attribute."); |
1781 | goto iput_mirr_err_out; | 1789 | goto iput_mirr_err_out; |
1782 | } | 1790 | } |
1791 | lockdep_set_class(&NTFS_I(vol->mftbmp_ino)->runlist.lock, | ||
1792 | &mftbmp_runlist_lock_key); | ||
1793 | lockdep_set_class(&NTFS_I(vol->mftbmp_ino)->mrec_lock, | ||
1794 | &mftbmp_mrec_lock_key); | ||
1783 | /* Read upcase table and setup @vol->upcase and @vol->upcase_len. */ | 1795 | /* Read upcase table and setup @vol->upcase and @vol->upcase_len. */ |
1784 | if (!load_and_init_upcase(vol)) | 1796 | if (!load_and_init_upcase(vol)) |
1785 | goto iput_mftbmp_err_out; | 1797 | goto iput_mftbmp_err_out; |
@@ -1802,6 +1814,11 @@ static BOOL load_system_files(ntfs_volume *vol) | |||
1802 | iput(vol->lcnbmp_ino); | 1814 | iput(vol->lcnbmp_ino); |
1803 | goto bitmap_failed; | 1815 | goto bitmap_failed; |
1804 | } | 1816 | } |
1817 | lockdep_set_class(&NTFS_I(vol->lcnbmp_ino)->runlist.lock, | ||
1818 | &lcnbmp_runlist_lock_key); | ||
1819 | lockdep_set_class(&NTFS_I(vol->lcnbmp_ino)->mrec_lock, | ||
1820 | &lcnbmp_mrec_lock_key); | ||
1821 | |||
1805 | NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino)); | 1822 | NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino)); |
1806 | if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) { | 1823 | if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) { |
1807 | iput(vol->lcnbmp_ino); | 1824 | iput(vol->lcnbmp_ino); |
@@ -2743,6 +2760,17 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2743 | struct inode *tmp_ino; | 2760 | struct inode *tmp_ino; |
2744 | int blocksize, result; | 2761 | int blocksize, result; |
2745 | 2762 | ||
2763 | /* | ||
2764 | * We do a pretty difficult piece of bootstrap by reading the | ||
2765 | * MFT (and other metadata) from disk into memory. We'll only | ||
2766 | * release this metadata during umount, so the locking patterns | ||
2767 | * observed during bootstrap do not count. So turn off the | ||
2768 | * observation of locking patterns (strictly for this context | ||
2769 | * only) while mounting NTFS. [The validator is still active | ||
2770 | * otherwise, even for this context: it will for example record | ||
2771 | * lock class registrations.] | ||
2772 | */ | ||
2773 | lockdep_off(); | ||
2746 | ntfs_debug("Entering."); | 2774 | ntfs_debug("Entering."); |
2747 | #ifndef NTFS_RW | 2775 | #ifndef NTFS_RW |
2748 | sb->s_flags |= MS_RDONLY; | 2776 | sb->s_flags |= MS_RDONLY; |
@@ -2754,6 +2782,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2754 | if (!silent) | 2782 | if (!silent) |
2755 | ntfs_error(sb, "Allocation of NTFS volume structure " | 2783 | ntfs_error(sb, "Allocation of NTFS volume structure " |
2756 | "failed. Aborting mount..."); | 2784 | "failed. Aborting mount..."); |
2785 | lockdep_on(); | ||
2757 | return -ENOMEM; | 2786 | return -ENOMEM; |
2758 | } | 2787 | } |
2759 | /* Initialize ntfs_volume structure. */ | 2788 | /* Initialize ntfs_volume structure. */ |
@@ -2940,6 +2969,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2940 | mutex_unlock(&ntfs_lock); | 2969 | mutex_unlock(&ntfs_lock); |
2941 | sb->s_export_op = &ntfs_export_ops; | 2970 | sb->s_export_op = &ntfs_export_ops; |
2942 | lock_kernel(); | 2971 | lock_kernel(); |
2972 | lockdep_on(); | ||
2943 | return 0; | 2973 | return 0; |
2944 | } | 2974 | } |
2945 | ntfs_error(sb, "Failed to allocate root directory."); | 2975 | ntfs_error(sb, "Failed to allocate root directory."); |
@@ -3059,6 +3089,7 @@ err_out_now: | |||
3059 | sb->s_fs_info = NULL; | 3089 | sb->s_fs_info = NULL; |
3060 | kfree(vol); | 3090 | kfree(vol); |
3061 | ntfs_debug("Failed, returning -EINVAL."); | 3091 | ntfs_debug("Failed, returning -EINVAL."); |
3092 | lockdep_on(); | ||
3062 | return -EINVAL; | 3093 | return -EINVAL; |
3063 | } | 3094 | } |
3064 | 3095 | ||
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index af69f28277b6..4616ed50ffcd 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -107,7 +107,7 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount * | |||
107 | { | 107 | { |
108 | struct vm_list_struct *vml; | 108 | struct vm_list_struct *vml; |
109 | struct vm_area_struct *vma; | 109 | struct vm_area_struct *vma; |
110 | struct task_struct *task = proc_task(inode); | 110 | struct task_struct *task = get_proc_task(inode); |
111 | struct mm_struct *mm = get_task_mm(task); | 111 | struct mm_struct *mm = get_task_mm(task); |
112 | int result = -ENOENT; | 112 | int result = -ENOENT; |
113 | 113 | ||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 28eb3c886034..5567328f1041 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -2203,7 +2203,7 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, | |||
2203 | size_t towrite = len; | 2203 | size_t towrite = len; |
2204 | struct buffer_head tmp_bh, *bh; | 2204 | struct buffer_head tmp_bh, *bh; |
2205 | 2205 | ||
2206 | mutex_lock(&inode->i_mutex); | 2206 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
2207 | while (towrite > 0) { | 2207 | while (towrite > 0) { |
2208 | tocopy = sb->s_blocksize - offset < towrite ? | 2208 | tocopy = sb->s_blocksize - offset < towrite ? |
2209 | sb->s_blocksize - offset : towrite; | 2209 | sb->s_blocksize - offset : towrite; |
diff --git a/fs/super.c b/fs/super.c index 9b780c42d845..6d4e8174b6db 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -53,7 +53,7 @@ DEFINE_SPINLOCK(sb_lock); | |||
53 | * Allocates and initializes a new &struct super_block. alloc_super() | 53 | * Allocates and initializes a new &struct super_block. alloc_super() |
54 | * returns a pointer new superblock or %NULL if allocation had failed. | 54 | * returns a pointer new superblock or %NULL if allocation had failed. |
55 | */ | 55 | */ |
56 | static struct super_block *alloc_super(void) | 56 | static struct super_block *alloc_super(struct file_system_type *type) |
57 | { | 57 | { |
58 | struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER); | 58 | struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER); |
59 | static struct super_operations default_op; | 59 | static struct super_operations default_op; |
@@ -72,6 +72,13 @@ static struct super_block *alloc_super(void) | |||
72 | INIT_LIST_HEAD(&s->s_inodes); | 72 | INIT_LIST_HEAD(&s->s_inodes); |
73 | init_rwsem(&s->s_umount); | 73 | init_rwsem(&s->s_umount); |
74 | mutex_init(&s->s_lock); | 74 | mutex_init(&s->s_lock); |
75 | lockdep_set_class(&s->s_umount, &type->s_umount_key); | ||
76 | /* | ||
77 | * The locking rules for s_lock are up to the | ||
78 | * filesystem. For example ext3fs has different | ||
79 | * lock ordering than usbfs: | ||
80 | */ | ||
81 | lockdep_set_class(&s->s_lock, &type->s_lock_key); | ||
75 | down_write(&s->s_umount); | 82 | down_write(&s->s_umount); |
76 | s->s_count = S_BIAS; | 83 | s->s_count = S_BIAS; |
77 | atomic_set(&s->s_active, 1); | 84 | atomic_set(&s->s_active, 1); |
@@ -295,7 +302,7 @@ retry: | |||
295 | } | 302 | } |
296 | if (!s) { | 303 | if (!s) { |
297 | spin_unlock(&sb_lock); | 304 | spin_unlock(&sb_lock); |
298 | s = alloc_super(); | 305 | s = alloc_super(type); |
299 | if (!s) | 306 | if (!s) |
300 | return ERR_PTR(-ENOMEM); | 307 | return ERR_PTR(-ENOMEM); |
301 | goto retry; | 308 | goto retry; |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 19a99726e58d..992ee0b87cc3 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -1326,7 +1326,7 @@ static ssize_t ufs_quota_write(struct super_block *sb, int type, | |||
1326 | size_t towrite = len; | 1326 | size_t towrite = len; |
1327 | struct buffer_head *bh; | 1327 | struct buffer_head *bh; |
1328 | 1328 | ||
1329 | mutex_lock(&inode->i_mutex); | 1329 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
1330 | while (towrite > 0) { | 1330 | while (towrite > 0) { |
1331 | tocopy = sb->s_blocksize - offset < towrite ? | 1331 | tocopy = sb->s_blocksize - offset < towrite ? |
1332 | sb->s_blocksize - offset : towrite; | 1332 | sb->s_blocksize - offset : towrite; |