diff options
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/fs/super.c b/fs/super.c index 0e7207b9815c..19eb70b374bc 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -465,6 +465,48 @@ rescan: | |||
465 | } | 465 | } |
466 | 466 | ||
467 | EXPORT_SYMBOL(get_super); | 467 | EXPORT_SYMBOL(get_super); |
468 | |||
469 | /** | ||
470 | * get_active_super - get an active reference to the superblock of a device | ||
471 | * @bdev: device to get the superblock for | ||
472 | * | ||
473 | * Scans the superblock list and finds the superblock of the file system | ||
474 | * mounted on the device given. Returns the superblock with an active | ||
475 | * reference and s_umount held exclusively or %NULL if none was found. | ||
476 | */ | ||
477 | struct super_block *get_active_super(struct block_device *bdev) | ||
478 | { | ||
479 | struct super_block *sb; | ||
480 | |||
481 | if (!bdev) | ||
482 | return NULL; | ||
483 | |||
484 | spin_lock(&sb_lock); | ||
485 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
486 | if (sb->s_bdev != bdev) | ||
487 | continue; | ||
488 | |||
489 | sb->s_count++; | ||
490 | spin_unlock(&sb_lock); | ||
491 | down_write(&sb->s_umount); | ||
492 | if (sb->s_root) { | ||
493 | spin_lock(&sb_lock); | ||
494 | if (sb->s_count > S_BIAS) { | ||
495 | atomic_inc(&sb->s_active); | ||
496 | sb->s_count--; | ||
497 | spin_unlock(&sb_lock); | ||
498 | return sb; | ||
499 | } | ||
500 | spin_unlock(&sb_lock); | ||
501 | } | ||
502 | up_write(&sb->s_umount); | ||
503 | put_super(sb); | ||
504 | yield(); | ||
505 | spin_lock(&sb_lock); | ||
506 | } | ||
507 | spin_unlock(&sb_lock); | ||
508 | return NULL; | ||
509 | } | ||
468 | 510 | ||
469 | struct super_block * user_get_super(dev_t dev) | 511 | struct super_block * user_get_super(dev_t dev) |
470 | { | 512 | { |
@@ -527,11 +569,15 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
527 | { | 569 | { |
528 | int retval; | 570 | int retval; |
529 | int remount_rw; | 571 | int remount_rw; |
530 | 572 | ||
573 | if (sb->s_frozen != SB_UNFROZEN) | ||
574 | return -EBUSY; | ||
575 | |||
531 | #ifdef CONFIG_BLOCK | 576 | #ifdef CONFIG_BLOCK |
532 | if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) | 577 | if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) |
533 | return -EACCES; | 578 | return -EACCES; |
534 | #endif | 579 | #endif |
580 | |||
535 | if (flags & MS_RDONLY) | 581 | if (flags & MS_RDONLY) |
536 | acct_auto_close(sb); | 582 | acct_auto_close(sb); |
537 | shrink_dcache_sb(sb); | 583 | shrink_dcache_sb(sb); |
@@ -743,9 +789,14 @@ int get_sb_bdev(struct file_system_type *fs_type, | |||
743 | * will protect the lockfs code from trying to start a snapshot | 789 | * will protect the lockfs code from trying to start a snapshot |
744 | * while we are mounting | 790 | * while we are mounting |
745 | */ | 791 | */ |
746 | down(&bdev->bd_mount_sem); | 792 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
793 | if (bdev->bd_fsfreeze_count > 0) { | ||
794 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
795 | error = -EBUSY; | ||
796 | goto error_bdev; | ||
797 | } | ||
747 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); | 798 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); |
748 | up(&bdev->bd_mount_sem); | 799 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
749 | if (IS_ERR(s)) | 800 | if (IS_ERR(s)) |
750 | goto error_s; | 801 | goto error_s; |
751 | 802 | ||
@@ -892,6 +943,16 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
892 | if (error) | 943 | if (error) |
893 | goto out_sb; | 944 | goto out_sb; |
894 | 945 | ||
946 | /* | ||
947 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE | ||
948 | * but s_maxbytes was an unsigned long long for many releases. Throw | ||
949 | * this warning for a little while to try and catch filesystems that | ||
950 | * violate this rule. This warning should be either removed or | ||
951 | * converted to a BUG() in 2.6.34. | ||
952 | */ | ||
953 | WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " | ||
954 | "negative value (%lld)\n", type->name, mnt->mnt_sb->s_maxbytes); | ||
955 | |||
895 | mnt->mnt_mountpoint = mnt->mnt_root; | 956 | mnt->mnt_mountpoint = mnt->mnt_root; |
896 | mnt->mnt_parent = mnt; | 957 | mnt->mnt_parent = mnt; |
897 | up_write(&mnt->mnt_sb->s_umount); | 958 | up_write(&mnt->mnt_sb->s_umount); |