diff options
-rw-r--r-- | fs/ufs/Kconfig | 1 | ||||
-rw-r--r-- | fs/ufs/inode.c | 78 | ||||
-rw-r--r-- | fs/ufs/namei.c | 35 | ||||
-rw-r--r-- | fs/ufs/super.c | 64 | ||||
-rw-r--r-- | fs/ufs/truncate.c | 5 | ||||
-rw-r--r-- | fs/ufs/ufs.h | 6 | ||||
-rw-r--r-- | fs/ufs/util.c | 2 |
7 files changed, 83 insertions, 108 deletions
diff --git a/fs/ufs/Kconfig b/fs/ufs/Kconfig index 30c8f223253d..e4f10a40768a 100644 --- a/fs/ufs/Kconfig +++ b/fs/ufs/Kconfig | |||
@@ -1,7 +1,6 @@ | |||
1 | config UFS_FS | 1 | config UFS_FS |
2 | tristate "UFS file system support (read only)" | 2 | tristate "UFS file system support (read only)" |
3 | depends on BLOCK | 3 | depends on BLOCK |
4 | depends on BKL # probably fixable | ||
5 | help | 4 | help |
6 | BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, | 5 | BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, |
7 | OpenBSD and NeXTstep) use a file system called UFS. Some System V | 6 | OpenBSD and NeXTstep) use a file system called UFS. Some System V |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 2b251f2093af..03c255f12df5 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/stat.h> | 34 | #include <linux/stat.h> |
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
39 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
40 | 39 | ||
@@ -43,7 +42,7 @@ | |||
43 | #include "swab.h" | 42 | #include "swab.h" |
44 | #include "util.h" | 43 | #include "util.h" |
45 | 44 | ||
46 | static u64 ufs_frag_map(struct inode *inode, sector_t frag); | 45 | static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock); |
47 | 46 | ||
48 | static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) | 47 | static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) |
49 | { | 48 | { |
@@ -82,7 +81,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off | |||
82 | * the begining of the filesystem. | 81 | * the begining of the filesystem. |
83 | */ | 82 | */ |
84 | 83 | ||
85 | static u64 ufs_frag_map(struct inode *inode, sector_t frag) | 84 | static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock) |
86 | { | 85 | { |
87 | struct ufs_inode_info *ufsi = UFS_I(inode); | 86 | struct ufs_inode_info *ufsi = UFS_I(inode); |
88 | struct super_block *sb = inode->i_sb; | 87 | struct super_block *sb = inode->i_sb; |
@@ -107,7 +106,8 @@ static u64 ufs_frag_map(struct inode *inode, sector_t frag) | |||
107 | 106 | ||
108 | p = offsets; | 107 | p = offsets; |
109 | 108 | ||
110 | lock_kernel(); | 109 | if (needs_lock) |
110 | lock_ufs(sb); | ||
111 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | 111 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) |
112 | goto ufs2; | 112 | goto ufs2; |
113 | 113 | ||
@@ -152,7 +152,8 @@ ufs2: | |||
152 | ret = temp + (u64) (frag & uspi->s_fpbmask); | 152 | ret = temp + (u64) (frag & uspi->s_fpbmask); |
153 | 153 | ||
154 | out: | 154 | out: |
155 | unlock_kernel(); | 155 | if (needs_lock) |
156 | unlock_ufs(sb); | ||
156 | return ret; | 157 | return ret; |
157 | } | 158 | } |
158 | 159 | ||
@@ -415,14 +416,16 @@ out: | |||
415 | int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) | 416 | int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) |
416 | { | 417 | { |
417 | struct super_block * sb = inode->i_sb; | 418 | struct super_block * sb = inode->i_sb; |
418 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; | 419 | struct ufs_sb_info * sbi = UFS_SB(sb); |
420 | struct ufs_sb_private_info * uspi = sbi->s_uspi; | ||
419 | struct buffer_head * bh; | 421 | struct buffer_head * bh; |
420 | int ret, err, new; | 422 | int ret, err, new; |
421 | unsigned long ptr,phys; | 423 | unsigned long ptr,phys; |
422 | u64 phys64 = 0; | 424 | u64 phys64 = 0; |
425 | bool needs_lock = (sbi->mutex_owner != current); | ||
423 | 426 | ||
424 | if (!create) { | 427 | if (!create) { |
425 | phys64 = ufs_frag_map(inode, fragment); | 428 | phys64 = ufs_frag_map(inode, fragment, needs_lock); |
426 | UFSD("phys64 = %llu\n", (unsigned long long)phys64); | 429 | UFSD("phys64 = %llu\n", (unsigned long long)phys64); |
427 | if (phys64) | 430 | if (phys64) |
428 | map_bh(bh_result, sb, phys64); | 431 | map_bh(bh_result, sb, phys64); |
@@ -436,7 +439,8 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head | |||
436 | ret = 0; | 439 | ret = 0; |
437 | bh = NULL; | 440 | bh = NULL; |
438 | 441 | ||
439 | lock_kernel(); | 442 | if (needs_lock) |
443 | lock_ufs(sb); | ||
440 | 444 | ||
441 | UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); | 445 | UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); |
442 | if (fragment > | 446 | if (fragment > |
@@ -498,7 +502,9 @@ out: | |||
498 | set_buffer_new(bh_result); | 502 | set_buffer_new(bh_result); |
499 | map_bh(bh_result, sb, phys); | 503 | map_bh(bh_result, sb, phys); |
500 | abort: | 504 | abort: |
501 | unlock_kernel(); | 505 | if (needs_lock) |
506 | unlock_ufs(sb); | ||
507 | |||
502 | return err; | 508 | return err; |
503 | 509 | ||
504 | abort_too_big: | 510 | abort_too_big: |
@@ -506,48 +512,6 @@ abort_too_big: | |||
506 | goto abort; | 512 | goto abort; |
507 | } | 513 | } |
508 | 514 | ||
509 | static struct buffer_head *ufs_getfrag(struct inode *inode, | ||
510 | unsigned int fragment, | ||
511 | int create, int *err) | ||
512 | { | ||
513 | struct buffer_head dummy; | ||
514 | int error; | ||
515 | |||
516 | dummy.b_state = 0; | ||
517 | dummy.b_blocknr = -1000; | ||
518 | error = ufs_getfrag_block(inode, fragment, &dummy, create); | ||
519 | *err = error; | ||
520 | if (!error && buffer_mapped(&dummy)) { | ||
521 | struct buffer_head *bh; | ||
522 | bh = sb_getblk(inode->i_sb, dummy.b_blocknr); | ||
523 | if (buffer_new(&dummy)) { | ||
524 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | ||
525 | set_buffer_uptodate(bh); | ||
526 | mark_buffer_dirty(bh); | ||
527 | } | ||
528 | return bh; | ||
529 | } | ||
530 | return NULL; | ||
531 | } | ||
532 | |||
533 | struct buffer_head * ufs_bread (struct inode * inode, unsigned fragment, | ||
534 | int create, int * err) | ||
535 | { | ||
536 | struct buffer_head * bh; | ||
537 | |||
538 | UFSD("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment); | ||
539 | bh = ufs_getfrag (inode, fragment, create, err); | ||
540 | if (!bh || buffer_uptodate(bh)) | ||
541 | return bh; | ||
542 | ll_rw_block (READ, 1, &bh); | ||
543 | wait_on_buffer (bh); | ||
544 | if (buffer_uptodate(bh)) | ||
545 | return bh; | ||
546 | brelse (bh); | ||
547 | *err = -EIO; | ||
548 | return NULL; | ||
549 | } | ||
550 | |||
551 | static int ufs_writepage(struct page *page, struct writeback_control *wbc) | 515 | static int ufs_writepage(struct page *page, struct writeback_control *wbc) |
552 | { | 516 | { |
553 | return block_write_full_page(page,ufs_getfrag_block,wbc); | 517 | return block_write_full_page(page,ufs_getfrag_block,wbc); |
@@ -900,9 +864,9 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
900 | int ufs_write_inode(struct inode *inode, struct writeback_control *wbc) | 864 | int ufs_write_inode(struct inode *inode, struct writeback_control *wbc) |
901 | { | 865 | { |
902 | int ret; | 866 | int ret; |
903 | lock_kernel(); | 867 | lock_ufs(inode->i_sb); |
904 | ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | 868 | ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
905 | unlock_kernel(); | 869 | unlock_ufs(inode->i_sb); |
906 | return ret; | 870 | return ret; |
907 | } | 871 | } |
908 | 872 | ||
@@ -922,22 +886,22 @@ void ufs_evict_inode(struct inode * inode) | |||
922 | if (want_delete) { | 886 | if (want_delete) { |
923 | loff_t old_i_size; | 887 | loff_t old_i_size; |
924 | /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/ | 888 | /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/ |
925 | lock_kernel(); | 889 | lock_ufs(inode->i_sb); |
926 | mark_inode_dirty(inode); | 890 | mark_inode_dirty(inode); |
927 | ufs_update_inode(inode, IS_SYNC(inode)); | 891 | ufs_update_inode(inode, IS_SYNC(inode)); |
928 | old_i_size = inode->i_size; | 892 | old_i_size = inode->i_size; |
929 | inode->i_size = 0; | 893 | inode->i_size = 0; |
930 | if (inode->i_blocks && ufs_truncate(inode, old_i_size)) | 894 | if (inode->i_blocks && ufs_truncate(inode, old_i_size)) |
931 | ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n"); | 895 | ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n"); |
932 | unlock_kernel(); | 896 | unlock_ufs(inode->i_sb); |
933 | } | 897 | } |
934 | 898 | ||
935 | invalidate_inode_buffers(inode); | 899 | invalidate_inode_buffers(inode); |
936 | end_writeback(inode); | 900 | end_writeback(inode); |
937 | 901 | ||
938 | if (want_delete) { | 902 | if (want_delete) { |
939 | lock_kernel(); | 903 | lock_ufs(inode->i_sb); |
940 | ufs_free_inode (inode); | 904 | ufs_free_inode (inode); |
941 | unlock_kernel(); | 905 | unlock_ufs(inode->i_sb); |
942 | } | 906 | } |
943 | } | 907 | } |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 12f39b9e4437..205030a707fe 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/time.h> | 30 | #include <linux/time.h> |
31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
32 | #include <linux/smp_lock.h> | ||
33 | 32 | ||
34 | #include "ufs_fs.h" | 33 | #include "ufs_fs.h" |
35 | #include "ufs.h" | 34 | #include "ufs.h" |
@@ -55,16 +54,16 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, stru | |||
55 | if (dentry->d_name.len > UFS_MAXNAMLEN) | 54 | if (dentry->d_name.len > UFS_MAXNAMLEN) |
56 | return ERR_PTR(-ENAMETOOLONG); | 55 | return ERR_PTR(-ENAMETOOLONG); |
57 | 56 | ||
58 | lock_kernel(); | 57 | lock_ufs(dir->i_sb); |
59 | ino = ufs_inode_by_name(dir, &dentry->d_name); | 58 | ino = ufs_inode_by_name(dir, &dentry->d_name); |
60 | if (ino) { | 59 | if (ino) { |
61 | inode = ufs_iget(dir->i_sb, ino); | 60 | inode = ufs_iget(dir->i_sb, ino); |
62 | if (IS_ERR(inode)) { | 61 | if (IS_ERR(inode)) { |
63 | unlock_kernel(); | 62 | unlock_ufs(dir->i_sb); |
64 | return ERR_CAST(inode); | 63 | return ERR_CAST(inode); |
65 | } | 64 | } |
66 | } | 65 | } |
67 | unlock_kernel(); | 66 | unlock_ufs(dir->i_sb); |
68 | d_add(dentry, inode); | 67 | d_add(dentry, inode); |
69 | return NULL; | 68 | return NULL; |
70 | } | 69 | } |
@@ -93,9 +92,9 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, | |||
93 | inode->i_fop = &ufs_file_operations; | 92 | inode->i_fop = &ufs_file_operations; |
94 | inode->i_mapping->a_ops = &ufs_aops; | 93 | inode->i_mapping->a_ops = &ufs_aops; |
95 | mark_inode_dirty(inode); | 94 | mark_inode_dirty(inode); |
96 | lock_kernel(); | 95 | lock_ufs(dir->i_sb); |
97 | err = ufs_add_nondir(dentry, inode); | 96 | err = ufs_add_nondir(dentry, inode); |
98 | unlock_kernel(); | 97 | unlock_ufs(dir->i_sb); |
99 | } | 98 | } |
100 | UFSD("END: err=%d\n", err); | 99 | UFSD("END: err=%d\n", err); |
101 | return err; | 100 | return err; |
@@ -115,9 +114,9 @@ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t | |||
115 | init_special_inode(inode, mode, rdev); | 114 | init_special_inode(inode, mode, rdev); |
116 | ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); | 115 | ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); |
117 | mark_inode_dirty(inode); | 116 | mark_inode_dirty(inode); |
118 | lock_kernel(); | 117 | lock_ufs(dir->i_sb); |
119 | err = ufs_add_nondir(dentry, inode); | 118 | err = ufs_add_nondir(dentry, inode); |
120 | unlock_kernel(); | 119 | unlock_ufs(dir->i_sb); |
121 | } | 120 | } |
122 | return err; | 121 | return err; |
123 | } | 122 | } |
@@ -133,7 +132,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
133 | if (l > sb->s_blocksize) | 132 | if (l > sb->s_blocksize) |
134 | goto out_notlocked; | 133 | goto out_notlocked; |
135 | 134 | ||
136 | lock_kernel(); | 135 | lock_ufs(dir->i_sb); |
137 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 136 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
138 | err = PTR_ERR(inode); | 137 | err = PTR_ERR(inode); |
139 | if (IS_ERR(inode)) | 138 | if (IS_ERR(inode)) |
@@ -156,7 +155,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
156 | 155 | ||
157 | err = ufs_add_nondir(dentry, inode); | 156 | err = ufs_add_nondir(dentry, inode); |
158 | out: | 157 | out: |
159 | unlock_kernel(); | 158 | unlock_ufs(dir->i_sb); |
160 | out_notlocked: | 159 | out_notlocked: |
161 | return err; | 160 | return err; |
162 | 161 | ||
@@ -172,9 +171,9 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, | |||
172 | struct inode *inode = old_dentry->d_inode; | 171 | struct inode *inode = old_dentry->d_inode; |
173 | int error; | 172 | int error; |
174 | 173 | ||
175 | lock_kernel(); | 174 | lock_ufs(dir->i_sb); |
176 | if (inode->i_nlink >= UFS_LINK_MAX) { | 175 | if (inode->i_nlink >= UFS_LINK_MAX) { |
177 | unlock_kernel(); | 176 | unlock_ufs(dir->i_sb); |
178 | return -EMLINK; | 177 | return -EMLINK; |
179 | } | 178 | } |
180 | 179 | ||
@@ -183,7 +182,7 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, | |||
183 | ihold(inode); | 182 | ihold(inode); |
184 | 183 | ||
185 | error = ufs_add_nondir(dentry, inode); | 184 | error = ufs_add_nondir(dentry, inode); |
186 | unlock_kernel(); | 185 | unlock_ufs(dir->i_sb); |
187 | return error; | 186 | return error; |
188 | } | 187 | } |
189 | 188 | ||
@@ -195,7 +194,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
195 | if (dir->i_nlink >= UFS_LINK_MAX) | 194 | if (dir->i_nlink >= UFS_LINK_MAX) |
196 | goto out; | 195 | goto out; |
197 | 196 | ||
198 | lock_kernel(); | 197 | lock_ufs(dir->i_sb); |
199 | inode_inc_link_count(dir); | 198 | inode_inc_link_count(dir); |
200 | 199 | ||
201 | inode = ufs_new_inode(dir, S_IFDIR|mode); | 200 | inode = ufs_new_inode(dir, S_IFDIR|mode); |
@@ -216,7 +215,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
216 | err = ufs_add_link(dentry, inode); | 215 | err = ufs_add_link(dentry, inode); |
217 | if (err) | 216 | if (err) |
218 | goto out_fail; | 217 | goto out_fail; |
219 | unlock_kernel(); | 218 | unlock_ufs(dir->i_sb); |
220 | 219 | ||
221 | d_instantiate(dentry, inode); | 220 | d_instantiate(dentry, inode); |
222 | out: | 221 | out: |
@@ -228,7 +227,7 @@ out_fail: | |||
228 | iput (inode); | 227 | iput (inode); |
229 | out_dir: | 228 | out_dir: |
230 | inode_dec_link_count(dir); | 229 | inode_dec_link_count(dir); |
231 | unlock_kernel(); | 230 | unlock_ufs(dir->i_sb); |
232 | goto out; | 231 | goto out; |
233 | } | 232 | } |
234 | 233 | ||
@@ -259,7 +258,7 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
259 | struct inode * inode = dentry->d_inode; | 258 | struct inode * inode = dentry->d_inode; |
260 | int err= -ENOTEMPTY; | 259 | int err= -ENOTEMPTY; |
261 | 260 | ||
262 | lock_kernel(); | 261 | lock_ufs(dir->i_sb); |
263 | if (ufs_empty_dir (inode)) { | 262 | if (ufs_empty_dir (inode)) { |
264 | err = ufs_unlink(dir, dentry); | 263 | err = ufs_unlink(dir, dentry); |
265 | if (!err) { | 264 | if (!err) { |
@@ -268,7 +267,7 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
268 | inode_dec_link_count(dir); | 267 | inode_dec_link_count(dir); |
269 | } | 268 | } |
270 | } | 269 | } |
271 | unlock_kernel(); | 270 | unlock_ufs(dir->i_sb); |
272 | return err; | 271 | return err; |
273 | } | 272 | } |
274 | 273 | ||
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 2c61ac5d4e48..7693d6293404 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -84,7 +84,6 @@ | |||
84 | #include <linux/blkdev.h> | 84 | #include <linux/blkdev.h> |
85 | #include <linux/init.h> | 85 | #include <linux/init.h> |
86 | #include <linux/parser.h> | 86 | #include <linux/parser.h> |
87 | #include <linux/smp_lock.h> | ||
88 | #include <linux/buffer_head.h> | 87 | #include <linux/buffer_head.h> |
89 | #include <linux/vfs.h> | 88 | #include <linux/vfs.h> |
90 | #include <linux/log2.h> | 89 | #include <linux/log2.h> |
@@ -96,6 +95,26 @@ | |||
96 | #include "swab.h" | 95 | #include "swab.h" |
97 | #include "util.h" | 96 | #include "util.h" |
98 | 97 | ||
98 | void lock_ufs(struct super_block *sb) | ||
99 | { | ||
100 | #if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT) | ||
101 | struct ufs_sb_info *sbi = UFS_SB(sb); | ||
102 | |||
103 | mutex_lock(&sbi->mutex); | ||
104 | sbi->mutex_owner = current; | ||
105 | #endif | ||
106 | } | ||
107 | |||
108 | void unlock_ufs(struct super_block *sb) | ||
109 | { | ||
110 | #if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT) | ||
111 | struct ufs_sb_info *sbi = UFS_SB(sb); | ||
112 | |||
113 | sbi->mutex_owner = NULL; | ||
114 | mutex_unlock(&sbi->mutex); | ||
115 | #endif | ||
116 | } | ||
117 | |||
99 | static struct inode *ufs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) | 118 | static struct inode *ufs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) |
100 | { | 119 | { |
101 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 120 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
@@ -313,7 +332,6 @@ void ufs_panic (struct super_block * sb, const char * function, | |||
313 | struct ufs_super_block_first * usb1; | 332 | struct ufs_super_block_first * usb1; |
314 | va_list args; | 333 | va_list args; |
315 | 334 | ||
316 | lock_kernel(); | ||
317 | uspi = UFS_SB(sb)->s_uspi; | 335 | uspi = UFS_SB(sb)->s_uspi; |
318 | usb1 = ubh_get_usb_first(uspi); | 336 | usb1 = ubh_get_usb_first(uspi); |
319 | 337 | ||
@@ -521,7 +539,7 @@ static int ufs_read_cylinder_structures(struct super_block *sb) | |||
521 | */ | 539 | */ |
522 | size = uspi->s_cssize; | 540 | size = uspi->s_cssize; |
523 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; | 541 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; |
524 | base = space = kmalloc(size, GFP_KERNEL); | 542 | base = space = kmalloc(size, GFP_NOFS); |
525 | if (!base) | 543 | if (!base) |
526 | goto failed; | 544 | goto failed; |
527 | sbi->s_csp = (struct ufs_csum *)space; | 545 | sbi->s_csp = (struct ufs_csum *)space; |
@@ -546,7 +564,7 @@ static int ufs_read_cylinder_structures(struct super_block *sb) | |||
546 | * Read cylinder group (we read only first fragment from block | 564 | * Read cylinder group (we read only first fragment from block |
547 | * at this time) and prepare internal data structures for cg caching. | 565 | * at this time) and prepare internal data structures for cg caching. |
548 | */ | 566 | */ |
549 | if (!(sbi->s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_KERNEL))) | 567 | if (!(sbi->s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_NOFS))) |
550 | goto failed; | 568 | goto failed; |
551 | for (i = 0; i < uspi->s_ncg; i++) | 569 | for (i = 0; i < uspi->s_ncg; i++) |
552 | sbi->s_ucg[i] = NULL; | 570 | sbi->s_ucg[i] = NULL; |
@@ -564,7 +582,7 @@ static int ufs_read_cylinder_structures(struct super_block *sb) | |||
564 | ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data); | 582 | ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data); |
565 | } | 583 | } |
566 | for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) { | 584 | for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) { |
567 | if (!(sbi->s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL))) | 585 | if (!(sbi->s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_NOFS))) |
568 | goto failed; | 586 | goto failed; |
569 | sbi->s_cgno[i] = UFS_CGNO_EMPTY; | 587 | sbi->s_cgno[i] = UFS_CGNO_EMPTY; |
570 | } | 588 | } |
@@ -646,8 +664,6 @@ static void ufs_put_super_internal(struct super_block *sb) | |||
646 | 664 | ||
647 | UFSD("ENTER\n"); | 665 | UFSD("ENTER\n"); |
648 | 666 | ||
649 | lock_kernel(); | ||
650 | |||
651 | ufs_put_cstotal(sb); | 667 | ufs_put_cstotal(sb); |
652 | size = uspi->s_cssize; | 668 | size = uspi->s_cssize; |
653 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; | 669 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; |
@@ -676,8 +692,6 @@ static void ufs_put_super_internal(struct super_block *sb) | |||
676 | kfree (sbi->s_ucg); | 692 | kfree (sbi->s_ucg); |
677 | kfree (base); | 693 | kfree (base); |
678 | 694 | ||
679 | unlock_kernel(); | ||
680 | |||
681 | UFSD("EXIT\n"); | 695 | UFSD("EXIT\n"); |
682 | } | 696 | } |
683 | 697 | ||
@@ -696,8 +710,6 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
696 | unsigned maxsymlen; | 710 | unsigned maxsymlen; |
697 | int ret = -EINVAL; | 711 | int ret = -EINVAL; |
698 | 712 | ||
699 | lock_kernel(); | ||
700 | |||
701 | uspi = NULL; | 713 | uspi = NULL; |
702 | ubh = NULL; | 714 | ubh = NULL; |
703 | flags = 0; | 715 | flags = 0; |
@@ -718,6 +730,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
718 | goto failed; | 730 | goto failed; |
719 | } | 731 | } |
720 | #endif | 732 | #endif |
733 | mutex_init(&sbi->mutex); | ||
721 | /* | 734 | /* |
722 | * Set default mount options | 735 | * Set default mount options |
723 | * Parse mount options | 736 | * Parse mount options |
@@ -1165,7 +1178,6 @@ magic_found: | |||
1165 | goto failed; | 1178 | goto failed; |
1166 | 1179 | ||
1167 | UFSD("EXIT\n"); | 1180 | UFSD("EXIT\n"); |
1168 | unlock_kernel(); | ||
1169 | return 0; | 1181 | return 0; |
1170 | 1182 | ||
1171 | dalloc_failed: | 1183 | dalloc_failed: |
@@ -1177,12 +1189,10 @@ failed: | |||
1177 | kfree(sbi); | 1189 | kfree(sbi); |
1178 | sb->s_fs_info = NULL; | 1190 | sb->s_fs_info = NULL; |
1179 | UFSD("EXIT (FAILED)\n"); | 1191 | UFSD("EXIT (FAILED)\n"); |
1180 | unlock_kernel(); | ||
1181 | return ret; | 1192 | return ret; |
1182 | 1193 | ||
1183 | failed_nomem: | 1194 | failed_nomem: |
1184 | UFSD("EXIT (NOMEM)\n"); | 1195 | UFSD("EXIT (NOMEM)\n"); |
1185 | unlock_kernel(); | ||
1186 | return -ENOMEM; | 1196 | return -ENOMEM; |
1187 | } | 1197 | } |
1188 | 1198 | ||
@@ -1193,8 +1203,8 @@ static int ufs_sync_fs(struct super_block *sb, int wait) | |||
1193 | struct ufs_super_block_third * usb3; | 1203 | struct ufs_super_block_third * usb3; |
1194 | unsigned flags; | 1204 | unsigned flags; |
1195 | 1205 | ||
1206 | lock_ufs(sb); | ||
1196 | lock_super(sb); | 1207 | lock_super(sb); |
1197 | lock_kernel(); | ||
1198 | 1208 | ||
1199 | UFSD("ENTER\n"); | 1209 | UFSD("ENTER\n"); |
1200 | 1210 | ||
@@ -1213,8 +1223,8 @@ static int ufs_sync_fs(struct super_block *sb, int wait) | |||
1213 | sb->s_dirt = 0; | 1223 | sb->s_dirt = 0; |
1214 | 1224 | ||
1215 | UFSD("EXIT\n"); | 1225 | UFSD("EXIT\n"); |
1216 | unlock_kernel(); | ||
1217 | unlock_super(sb); | 1226 | unlock_super(sb); |
1227 | unlock_ufs(sb); | ||
1218 | 1228 | ||
1219 | return 0; | 1229 | return 0; |
1220 | } | 1230 | } |
@@ -1256,7 +1266,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1256 | unsigned new_mount_opt, ufstype; | 1266 | unsigned new_mount_opt, ufstype; |
1257 | unsigned flags; | 1267 | unsigned flags; |
1258 | 1268 | ||
1259 | lock_kernel(); | 1269 | lock_ufs(sb); |
1260 | lock_super(sb); | 1270 | lock_super(sb); |
1261 | uspi = UFS_SB(sb)->s_uspi; | 1271 | uspi = UFS_SB(sb)->s_uspi; |
1262 | flags = UFS_SB(sb)->s_flags; | 1272 | flags = UFS_SB(sb)->s_flags; |
@@ -1272,7 +1282,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1272 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); | 1282 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); |
1273 | if (!ufs_parse_options (data, &new_mount_opt)) { | 1283 | if (!ufs_parse_options (data, &new_mount_opt)) { |
1274 | unlock_super(sb); | 1284 | unlock_super(sb); |
1275 | unlock_kernel(); | 1285 | unlock_ufs(sb); |
1276 | return -EINVAL; | 1286 | return -EINVAL; |
1277 | } | 1287 | } |
1278 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { | 1288 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { |
@@ -1280,14 +1290,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1280 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { | 1290 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { |
1281 | printk("ufstype can't be changed during remount\n"); | 1291 | printk("ufstype can't be changed during remount\n"); |
1282 | unlock_super(sb); | 1292 | unlock_super(sb); |
1283 | unlock_kernel(); | 1293 | unlock_ufs(sb); |
1284 | return -EINVAL; | 1294 | return -EINVAL; |
1285 | } | 1295 | } |
1286 | 1296 | ||
1287 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { | 1297 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { |
1288 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1298 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1289 | unlock_super(sb); | 1299 | unlock_super(sb); |
1290 | unlock_kernel(); | 1300 | unlock_ufs(sb); |
1291 | return 0; | 1301 | return 0; |
1292 | } | 1302 | } |
1293 | 1303 | ||
@@ -1313,7 +1323,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1313 | printk("ufs was compiled with read-only support, " | 1323 | printk("ufs was compiled with read-only support, " |
1314 | "can't be mounted as read-write\n"); | 1324 | "can't be mounted as read-write\n"); |
1315 | unlock_super(sb); | 1325 | unlock_super(sb); |
1316 | unlock_kernel(); | 1326 | unlock_ufs(sb); |
1317 | return -EINVAL; | 1327 | return -EINVAL; |
1318 | #else | 1328 | #else |
1319 | if (ufstype != UFS_MOUNT_UFSTYPE_SUN && | 1329 | if (ufstype != UFS_MOUNT_UFSTYPE_SUN && |
@@ -1323,13 +1333,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1323 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { | 1333 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { |
1324 | printk("this ufstype is read-only supported\n"); | 1334 | printk("this ufstype is read-only supported\n"); |
1325 | unlock_super(sb); | 1335 | unlock_super(sb); |
1326 | unlock_kernel(); | 1336 | unlock_ufs(sb); |
1327 | return -EINVAL; | 1337 | return -EINVAL; |
1328 | } | 1338 | } |
1329 | if (!ufs_read_cylinder_structures(sb)) { | 1339 | if (!ufs_read_cylinder_structures(sb)) { |
1330 | printk("failed during remounting\n"); | 1340 | printk("failed during remounting\n"); |
1331 | unlock_super(sb); | 1341 | unlock_super(sb); |
1332 | unlock_kernel(); | 1342 | unlock_ufs(sb); |
1333 | return -EPERM; | 1343 | return -EPERM; |
1334 | } | 1344 | } |
1335 | sb->s_flags &= ~MS_RDONLY; | 1345 | sb->s_flags &= ~MS_RDONLY; |
@@ -1337,7 +1347,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1337 | } | 1347 | } |
1338 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1348 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1339 | unlock_super(sb); | 1349 | unlock_super(sb); |
1340 | unlock_kernel(); | 1350 | unlock_ufs(sb); |
1341 | return 0; | 1351 | return 0; |
1342 | } | 1352 | } |
1343 | 1353 | ||
@@ -1371,7 +1381,7 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1371 | struct ufs_super_block_third *usb3; | 1381 | struct ufs_super_block_third *usb3; |
1372 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); | 1382 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); |
1373 | 1383 | ||
1374 | lock_kernel(); | 1384 | lock_ufs(sb); |
1375 | 1385 | ||
1376 | usb1 = ubh_get_usb_first(uspi); | 1386 | usb1 = ubh_get_usb_first(uspi); |
1377 | usb2 = ubh_get_usb_second(uspi); | 1387 | usb2 = ubh_get_usb_second(uspi); |
@@ -1395,7 +1405,7 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1395 | buf->f_fsid.val[0] = (u32)id; | 1405 | buf->f_fsid.val[0] = (u32)id; |
1396 | buf->f_fsid.val[1] = (u32)(id >> 32); | 1406 | buf->f_fsid.val[1] = (u32)(id >> 32); |
1397 | 1407 | ||
1398 | unlock_kernel(); | 1408 | unlock_ufs(sb); |
1399 | 1409 | ||
1400 | return 0; | 1410 | return 0; |
1401 | } | 1411 | } |
@@ -1405,7 +1415,7 @@ static struct kmem_cache * ufs_inode_cachep; | |||
1405 | static struct inode *ufs_alloc_inode(struct super_block *sb) | 1415 | static struct inode *ufs_alloc_inode(struct super_block *sb) |
1406 | { | 1416 | { |
1407 | struct ufs_inode_info *ei; | 1417 | struct ufs_inode_info *ei; |
1408 | ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_KERNEL); | 1418 | ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_NOFS); |
1409 | if (!ei) | 1419 | if (!ei) |
1410 | return NULL; | 1420 | return NULL; |
1411 | ei->vfs_inode.i_version = 1; | 1421 | ei->vfs_inode.i_version = 1; |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index a58f9155fc9a..e56a4f567212 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/time.h> | 40 | #include <linux/time.h> |
41 | #include <linux/stat.h> | 41 | #include <linux/stat.h> |
42 | #include <linux/string.h> | 42 | #include <linux/string.h> |
43 | #include <linux/smp_lock.h> | ||
44 | #include <linux/buffer_head.h> | 43 | #include <linux/buffer_head.h> |
45 | #include <linux/blkdev.h> | 44 | #include <linux/blkdev.h> |
46 | #include <linux/sched.h> | 45 | #include <linux/sched.h> |
@@ -467,7 +466,6 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) | |||
467 | 466 | ||
468 | block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); | 467 | block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); |
469 | 468 | ||
470 | lock_kernel(); | ||
471 | while (1) { | 469 | while (1) { |
472 | retry = ufs_trunc_direct(inode); | 470 | retry = ufs_trunc_direct(inode); |
473 | retry |= ufs_trunc_indirect(inode, UFS_IND_BLOCK, | 471 | retry |= ufs_trunc_indirect(inode, UFS_IND_BLOCK, |
@@ -487,7 +485,6 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) | |||
487 | 485 | ||
488 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 486 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
489 | ufsi->i_lastfrag = DIRECT_FRAGMENT; | 487 | ufsi->i_lastfrag = DIRECT_FRAGMENT; |
490 | unlock_kernel(); | ||
491 | mark_inode_dirty(inode); | 488 | mark_inode_dirty(inode); |
492 | out: | 489 | out: |
493 | UFSD("EXIT: err %d\n", err); | 490 | UFSD("EXIT: err %d\n", err); |
@@ -510,7 +507,9 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr) | |||
510 | /* XXX(truncate): truncate_setsize should be called last */ | 507 | /* XXX(truncate): truncate_setsize should be called last */ |
511 | truncate_setsize(inode, attr->ia_size); | 508 | truncate_setsize(inode, attr->ia_size); |
512 | 509 | ||
510 | lock_ufs(inode->i_sb); | ||
513 | error = ufs_truncate(inode, old_i_size); | 511 | error = ufs_truncate(inode, old_i_size); |
512 | unlock_ufs(inode->i_sb); | ||
514 | if (error) | 513 | if (error) |
515 | return error; | 514 | return error; |
516 | } | 515 | } |
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index c08782e1b48a..5be2755dd715 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h | |||
@@ -18,6 +18,8 @@ struct ufs_sb_info { | |||
18 | unsigned s_cgno[UFS_MAX_GROUP_LOADED]; | 18 | unsigned s_cgno[UFS_MAX_GROUP_LOADED]; |
19 | unsigned short s_cg_loaded; | 19 | unsigned short s_cg_loaded; |
20 | unsigned s_mount_opt; | 20 | unsigned s_mount_opt; |
21 | struct mutex mutex; | ||
22 | struct task_struct *mutex_owner; | ||
21 | }; | 23 | }; |
22 | 24 | ||
23 | struct ufs_inode_info { | 25 | struct ufs_inode_info { |
@@ -109,7 +111,6 @@ extern struct inode *ufs_iget(struct super_block *, unsigned long); | |||
109 | extern int ufs_write_inode (struct inode *, struct writeback_control *); | 111 | extern int ufs_write_inode (struct inode *, struct writeback_control *); |
110 | extern int ufs_sync_inode (struct inode *); | 112 | extern int ufs_sync_inode (struct inode *); |
111 | extern void ufs_evict_inode (struct inode *); | 113 | extern void ufs_evict_inode (struct inode *); |
112 | extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *); | ||
113 | extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create); | 114 | extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create); |
114 | 115 | ||
115 | /* namei.c */ | 116 | /* namei.c */ |
@@ -154,4 +155,7 @@ static inline u32 ufs_dtogd(struct ufs_sb_private_info * uspi, u64 b) | |||
154 | return do_div(b, uspi->s_fpg); | 155 | return do_div(b, uspi->s_fpg); |
155 | } | 156 | } |
156 | 157 | ||
158 | extern void lock_ufs(struct super_block *sb); | ||
159 | extern void unlock_ufs(struct super_block *sb); | ||
160 | |||
157 | #endif /* _UFS_UFS_H */ | 161 | #endif /* _UFS_UFS_H */ |
diff --git a/fs/ufs/util.c b/fs/ufs/util.c index d2c36d53fe66..95425b59ce0a 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c | |||
@@ -27,7 +27,7 @@ struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, | |||
27 | if (count > UFS_MAXFRAG) | 27 | if (count > UFS_MAXFRAG) |
28 | return NULL; | 28 | return NULL; |
29 | ubh = (struct ufs_buffer_head *) | 29 | ubh = (struct ufs_buffer_head *) |
30 | kmalloc (sizeof (struct ufs_buffer_head), GFP_KERNEL); | 30 | kmalloc (sizeof (struct ufs_buffer_head), GFP_NOFS); |
31 | if (!ubh) | 31 | if (!ubh) |
32 | return NULL; | 32 | return NULL; |
33 | ubh->fragment = fragment; | 33 | ubh->fragment = fragment; |