aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c81
1 files changed, 60 insertions, 21 deletions
diff --git a/fs/super.c b/fs/super.c
index c183835566c1..1709ed029a2c 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -244,7 +244,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
244 mutex_init(&s->s_vfs_rename_mutex); 244 mutex_init(&s->s_vfs_rename_mutex);
245 lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); 245 lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
246 mutex_init(&s->s_dquot.dqio_mutex); 246 mutex_init(&s->s_dquot.dqio_mutex);
247 mutex_init(&s->s_dquot.dqonoff_mutex);
248 s->s_maxbytes = MAX_NON_LFS; 247 s->s_maxbytes = MAX_NON_LFS;
249 s->s_op = &default_op; 248 s->s_op = &default_op;
250 s->s_time_gran = 1000000000; 249 s->s_time_gran = 1000000000;
@@ -558,6 +557,13 @@ void drop_super(struct super_block *sb)
558 557
559EXPORT_SYMBOL(drop_super); 558EXPORT_SYMBOL(drop_super);
560 559
560void drop_super_exclusive(struct super_block *sb)
561{
562 up_write(&sb->s_umount);
563 put_super(sb);
564}
565EXPORT_SYMBOL(drop_super_exclusive);
566
561/** 567/**
562 * iterate_supers - call function for all active superblocks 568 * iterate_supers - call function for all active superblocks
563 * @f: function to call 569 * @f: function to call
@@ -628,15 +634,7 @@ void iterate_supers_type(struct file_system_type *type,
628 634
629EXPORT_SYMBOL(iterate_supers_type); 635EXPORT_SYMBOL(iterate_supers_type);
630 636
631/** 637static struct super_block *__get_super(struct block_device *bdev, bool excl)
632 * get_super - get the superblock of a device
633 * @bdev: device to get the superblock for
634 *
635 * Scans the superblock list and finds the superblock of the file system
636 * mounted on the device given. %NULL is returned if no match is found.
637 */
638
639struct super_block *get_super(struct block_device *bdev)
640{ 638{
641 struct super_block *sb; 639 struct super_block *sb;
642 640
@@ -651,11 +649,17 @@ rescan:
651 if (sb->s_bdev == bdev) { 649 if (sb->s_bdev == bdev) {
652 sb->s_count++; 650 sb->s_count++;
653 spin_unlock(&sb_lock); 651 spin_unlock(&sb_lock);
654 down_read(&sb->s_umount); 652 if (!excl)
653 down_read(&sb->s_umount);
654 else
655 down_write(&sb->s_umount);
655 /* still alive? */ 656 /* still alive? */
656 if (sb->s_root && (sb->s_flags & MS_BORN)) 657 if (sb->s_root && (sb->s_flags & MS_BORN))
657 return sb; 658 return sb;
658 up_read(&sb->s_umount); 659 if (!excl)
660 up_read(&sb->s_umount);
661 else
662 up_write(&sb->s_umount);
659 /* nope, got unmounted */ 663 /* nope, got unmounted */
660 spin_lock(&sb_lock); 664 spin_lock(&sb_lock);
661 __put_super(sb); 665 __put_super(sb);
@@ -666,32 +670,67 @@ rescan:
666 return NULL; 670 return NULL;
667} 671}
668 672
669EXPORT_SYMBOL(get_super);
670
671/** 673/**
672 * get_super_thawed - get thawed superblock of a device 674 * get_super - get the superblock of a device
673 * @bdev: device to get the superblock for 675 * @bdev: device to get the superblock for
674 * 676 *
675 * Scans the superblock list and finds the superblock of the file system 677 * Scans the superblock list and finds the superblock of the file system
676 * mounted on the device. The superblock is returned once it is thawed 678 * mounted on the device given. %NULL is returned if no match is found.
677 * (or immediately if it was not frozen). %NULL is returned if no match
678 * is found.
679 */ 679 */
680struct super_block *get_super_thawed(struct block_device *bdev) 680struct super_block *get_super(struct block_device *bdev)
681{
682 return __get_super(bdev, false);
683}
684EXPORT_SYMBOL(get_super);
685
686static struct super_block *__get_super_thawed(struct block_device *bdev,
687 bool excl)
681{ 688{
682 while (1) { 689 while (1) {
683 struct super_block *s = get_super(bdev); 690 struct super_block *s = __get_super(bdev, excl);
684 if (!s || s->s_writers.frozen == SB_UNFROZEN) 691 if (!s || s->s_writers.frozen == SB_UNFROZEN)
685 return s; 692 return s;
686 up_read(&s->s_umount); 693 if (!excl)
694 up_read(&s->s_umount);
695 else
696 up_write(&s->s_umount);
687 wait_event(s->s_writers.wait_unfrozen, 697 wait_event(s->s_writers.wait_unfrozen,
688 s->s_writers.frozen == SB_UNFROZEN); 698 s->s_writers.frozen == SB_UNFROZEN);
689 put_super(s); 699 put_super(s);
690 } 700 }
691} 701}
702
703/**
704 * get_super_thawed - get thawed superblock of a device
705 * @bdev: device to get the superblock for
706 *
707 * Scans the superblock list and finds the superblock of the file system
708 * mounted on the device. The superblock is returned once it is thawed
709 * (or immediately if it was not frozen). %NULL is returned if no match
710 * is found.
711 */
712struct super_block *get_super_thawed(struct block_device *bdev)
713{
714 return __get_super_thawed(bdev, false);
715}
692EXPORT_SYMBOL(get_super_thawed); 716EXPORT_SYMBOL(get_super_thawed);
693 717
694/** 718/**
719 * get_super_exclusive_thawed - get thawed superblock of a device
720 * @bdev: device to get the superblock for
721 *
722 * Scans the superblock list and finds the superblock of the file system
723 * mounted on the device. The superblock is returned once it is thawed
724 * (or immediately if it was not frozen) and s_umount semaphore is held
725 * in exclusive mode. %NULL is returned if no match is found.
726 */
727struct super_block *get_super_exclusive_thawed(struct block_device *bdev)
728{
729 return __get_super_thawed(bdev, true);
730}
731EXPORT_SYMBOL(get_super_exclusive_thawed);
732
733/**
695 * get_active_super - get an active reference to the superblock of a device 734 * get_active_super - get an active reference to the superblock of a device
696 * @bdev: device to get the superblock for 735 * @bdev: device to get the superblock for
697 * 736 *