Commit 788257d6101d986ac8f2741aaa35974af47f574c

Authored by Arnd Bergmann
1 parent 9a311b96c3

ufs: remove the BKL

This introduces a new per-superblock mutex in UFS to replace
the big kernel lock. I have been careful to avoid nested
calls to lock_ufs and to get the lock order right with
respect to other mutexes, in particular lock_super.

I did not make any attempt to prove that the big kernel
lock is not needed in a particular place in the code,
which is very possible.

The mutex has a significant performance impact, so it is only
used on SMP or PREEMPT configurations.

As Nick Piggin noticed, any allocation inside of the lock
may end up deadlocking when we get to ufs_getfrag_block
in the reclaim task, so we now use GFP_NOFS.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Nick Bowler <nbowler@elliptictech.com>
Cc: Evgeniy Dushistov <dushistov@mail.ru>
Cc: Nick Piggin <npiggin@gmail.com>

Showing 7 changed files with 83 additions and 108 deletions Side-by-side Diff

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