diff options
Diffstat (limited to 'fs/ufs/super.c')
-rw-r--r-- | fs/ufs/super.c | 82 |
1 files changed, 52 insertions, 30 deletions
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index d510c1b91817..3915ade6f9a8 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 | ||
@@ -465,9 +483,9 @@ static int ufs_parse_options (char * options, unsigned * mount_options) | |||
465 | } | 483 | } |
466 | 484 | ||
467 | /* | 485 | /* |
468 | * Diffrent types of UFS hold fs_cstotal in different | 486 | * Different types of UFS hold fs_cstotal in different |
469 | * places, and use diffrent data structure for it. | 487 | * places, and use different data structure for it. |
470 | * To make things simplier we just copy fs_cstotal to ufs_sb_private_info | 488 | * To make things simpler we just copy fs_cstotal to ufs_sb_private_info |
471 | */ | 489 | */ |
472 | static void ufs_setup_cstotal(struct super_block *sb) | 490 | static void ufs_setup_cstotal(struct super_block *sb) |
473 | { | 491 | { |
@@ -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 | ||
@@ -716,6 +730,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
716 | goto failed; | 730 | goto failed; |
717 | } | 731 | } |
718 | #endif | 732 | #endif |
733 | mutex_init(&sbi->mutex); | ||
719 | /* | 734 | /* |
720 | * Set default mount options | 735 | * Set default mount options |
721 | * Parse mount options | 736 | * Parse mount options |
@@ -1188,8 +1203,8 @@ static int ufs_sync_fs(struct super_block *sb, int wait) | |||
1188 | struct ufs_super_block_third * usb3; | 1203 | struct ufs_super_block_third * usb3; |
1189 | unsigned flags; | 1204 | unsigned flags; |
1190 | 1205 | ||
1206 | lock_ufs(sb); | ||
1191 | lock_super(sb); | 1207 | lock_super(sb); |
1192 | lock_kernel(); | ||
1193 | 1208 | ||
1194 | UFSD("ENTER\n"); | 1209 | UFSD("ENTER\n"); |
1195 | 1210 | ||
@@ -1208,8 +1223,8 @@ static int ufs_sync_fs(struct super_block *sb, int wait) | |||
1208 | sb->s_dirt = 0; | 1223 | sb->s_dirt = 0; |
1209 | 1224 | ||
1210 | UFSD("EXIT\n"); | 1225 | UFSD("EXIT\n"); |
1211 | unlock_kernel(); | ||
1212 | unlock_super(sb); | 1226 | unlock_super(sb); |
1227 | unlock_ufs(sb); | ||
1213 | 1228 | ||
1214 | return 0; | 1229 | return 0; |
1215 | } | 1230 | } |
@@ -1251,7 +1266,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1251 | unsigned new_mount_opt, ufstype; | 1266 | unsigned new_mount_opt, ufstype; |
1252 | unsigned flags; | 1267 | unsigned flags; |
1253 | 1268 | ||
1254 | lock_kernel(); | 1269 | lock_ufs(sb); |
1255 | lock_super(sb); | 1270 | lock_super(sb); |
1256 | uspi = UFS_SB(sb)->s_uspi; | 1271 | uspi = UFS_SB(sb)->s_uspi; |
1257 | flags = UFS_SB(sb)->s_flags; | 1272 | flags = UFS_SB(sb)->s_flags; |
@@ -1267,7 +1282,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1267 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); | 1282 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); |
1268 | if (!ufs_parse_options (data, &new_mount_opt)) { | 1283 | if (!ufs_parse_options (data, &new_mount_opt)) { |
1269 | unlock_super(sb); | 1284 | unlock_super(sb); |
1270 | unlock_kernel(); | 1285 | unlock_ufs(sb); |
1271 | return -EINVAL; | 1286 | return -EINVAL; |
1272 | } | 1287 | } |
1273 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { | 1288 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { |
@@ -1275,14 +1290,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1275 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { | 1290 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { |
1276 | printk("ufstype can't be changed during remount\n"); | 1291 | printk("ufstype can't be changed during remount\n"); |
1277 | unlock_super(sb); | 1292 | unlock_super(sb); |
1278 | unlock_kernel(); | 1293 | unlock_ufs(sb); |
1279 | return -EINVAL; | 1294 | return -EINVAL; |
1280 | } | 1295 | } |
1281 | 1296 | ||
1282 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { | 1297 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { |
1283 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1298 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1284 | unlock_super(sb); | 1299 | unlock_super(sb); |
1285 | unlock_kernel(); | 1300 | unlock_ufs(sb); |
1286 | return 0; | 1301 | return 0; |
1287 | } | 1302 | } |
1288 | 1303 | ||
@@ -1308,7 +1323,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1308 | printk("ufs was compiled with read-only support, " | 1323 | printk("ufs was compiled with read-only support, " |
1309 | "can't be mounted as read-write\n"); | 1324 | "can't be mounted as read-write\n"); |
1310 | unlock_super(sb); | 1325 | unlock_super(sb); |
1311 | unlock_kernel(); | 1326 | unlock_ufs(sb); |
1312 | return -EINVAL; | 1327 | return -EINVAL; |
1313 | #else | 1328 | #else |
1314 | if (ufstype != UFS_MOUNT_UFSTYPE_SUN && | 1329 | if (ufstype != UFS_MOUNT_UFSTYPE_SUN && |
@@ -1318,13 +1333,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1318 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { | 1333 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { |
1319 | printk("this ufstype is read-only supported\n"); | 1334 | printk("this ufstype is read-only supported\n"); |
1320 | unlock_super(sb); | 1335 | unlock_super(sb); |
1321 | unlock_kernel(); | 1336 | unlock_ufs(sb); |
1322 | return -EINVAL; | 1337 | return -EINVAL; |
1323 | } | 1338 | } |
1324 | if (!ufs_read_cylinder_structures(sb)) { | 1339 | if (!ufs_read_cylinder_structures(sb)) { |
1325 | printk("failed during remounting\n"); | 1340 | printk("failed during remounting\n"); |
1326 | unlock_super(sb); | 1341 | unlock_super(sb); |
1327 | unlock_kernel(); | 1342 | unlock_ufs(sb); |
1328 | return -EPERM; | 1343 | return -EPERM; |
1329 | } | 1344 | } |
1330 | sb->s_flags &= ~MS_RDONLY; | 1345 | sb->s_flags &= ~MS_RDONLY; |
@@ -1332,7 +1347,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1332 | } | 1347 | } |
1333 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1348 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1334 | unlock_super(sb); | 1349 | unlock_super(sb); |
1335 | unlock_kernel(); | 1350 | unlock_ufs(sb); |
1336 | return 0; | 1351 | return 0; |
1337 | } | 1352 | } |
1338 | 1353 | ||
@@ -1366,7 +1381,7 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1366 | struct ufs_super_block_third *usb3; | 1381 | struct ufs_super_block_third *usb3; |
1367 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); | 1382 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); |
1368 | 1383 | ||
1369 | lock_kernel(); | 1384 | lock_ufs(sb); |
1370 | 1385 | ||
1371 | usb1 = ubh_get_usb_first(uspi); | 1386 | usb1 = ubh_get_usb_first(uspi); |
1372 | usb2 = ubh_get_usb_second(uspi); | 1387 | usb2 = ubh_get_usb_second(uspi); |
@@ -1390,7 +1405,7 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1390 | buf->f_fsid.val[0] = (u32)id; | 1405 | buf->f_fsid.val[0] = (u32)id; |
1391 | buf->f_fsid.val[1] = (u32)(id >> 32); | 1406 | buf->f_fsid.val[1] = (u32)(id >> 32); |
1392 | 1407 | ||
1393 | unlock_kernel(); | 1408 | unlock_ufs(sb); |
1394 | 1409 | ||
1395 | return 0; | 1410 | return 0; |
1396 | } | 1411 | } |
@@ -1400,18 +1415,25 @@ static struct kmem_cache * ufs_inode_cachep; | |||
1400 | static struct inode *ufs_alloc_inode(struct super_block *sb) | 1415 | static struct inode *ufs_alloc_inode(struct super_block *sb) |
1401 | { | 1416 | { |
1402 | struct ufs_inode_info *ei; | 1417 | struct ufs_inode_info *ei; |
1403 | 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); |
1404 | if (!ei) | 1419 | if (!ei) |
1405 | return NULL; | 1420 | return NULL; |
1406 | ei->vfs_inode.i_version = 1; | 1421 | ei->vfs_inode.i_version = 1; |
1407 | return &ei->vfs_inode; | 1422 | return &ei->vfs_inode; |
1408 | } | 1423 | } |
1409 | 1424 | ||
1410 | static void ufs_destroy_inode(struct inode *inode) | 1425 | static void ufs_i_callback(struct rcu_head *head) |
1411 | { | 1426 | { |
1427 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
1428 | INIT_LIST_HEAD(&inode->i_dentry); | ||
1412 | kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); | 1429 | kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); |
1413 | } | 1430 | } |
1414 | 1431 | ||
1432 | static void ufs_destroy_inode(struct inode *inode) | ||
1433 | { | ||
1434 | call_rcu(&inode->i_rcu, ufs_i_callback); | ||
1435 | } | ||
1436 | |||
1415 | static void init_once(void *foo) | 1437 | static void init_once(void *foo) |
1416 | { | 1438 | { |
1417 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; | 1439 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; |
@@ -1449,16 +1471,16 @@ static const struct super_operations ufs_super_ops = { | |||
1449 | .show_options = ufs_show_options, | 1471 | .show_options = ufs_show_options, |
1450 | }; | 1472 | }; |
1451 | 1473 | ||
1452 | static int ufs_get_sb(struct file_system_type *fs_type, | 1474 | static struct dentry *ufs_mount(struct file_system_type *fs_type, |
1453 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 1475 | int flags, const char *dev_name, void *data) |
1454 | { | 1476 | { |
1455 | return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super, mnt); | 1477 | return mount_bdev(fs_type, flags, dev_name, data, ufs_fill_super); |
1456 | } | 1478 | } |
1457 | 1479 | ||
1458 | static struct file_system_type ufs_fs_type = { | 1480 | static struct file_system_type ufs_fs_type = { |
1459 | .owner = THIS_MODULE, | 1481 | .owner = THIS_MODULE, |
1460 | .name = "ufs", | 1482 | .name = "ufs", |
1461 | .get_sb = ufs_get_sb, | 1483 | .mount = ufs_mount, |
1462 | .kill_sb = kill_block_super, | 1484 | .kill_sb = kill_block_super, |
1463 | .fs_flags = FS_REQUIRES_DEV, | 1485 | .fs_flags = FS_REQUIRES_DEV, |
1464 | }; | 1486 | }; |