summaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-26 14:48:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-26 14:48:42 -0400
commitaba16dc5cf9318b4e0fe92f8261779cd9f1d2d77 (patch)
tree1f53d2cee40e82efe6a727208307af475327af9a /fs/super.c
parentc4726e774ed27680c418e138234dfd2b8e1e89ac (diff)
parent1df895190233fcc30d46beca4550bcafb7b959a6 (diff)
Merge branch 'ida-4.19' of git://git.infradead.org/users/willy/linux-dax
Pull IDA updates from Matthew Wilcox: "A better IDA API: id = ida_alloc(ida, GFP_xxx); ida_free(ida, id); rather than the cumbersome ida_simple_get(), ida_simple_remove(). The new IDA API is similar to ida_simple_get() but better named. The internal restructuring of the IDA code removes the bitmap preallocation nonsense. I hope the net -200 lines of code is convincing" * 'ida-4.19' of git://git.infradead.org/users/willy/linux-dax: (29 commits) ida: Change ida_get_new_above to return the id ida: Remove old API test_ida: check_ida_destroy and check_ida_alloc test_ida: Convert check_ida_conv to new API test_ida: Move ida_check_max test_ida: Move ida_check_leaf idr-test: Convert ida_check_nomem to new API ida: Start new test_ida module target/iscsi: Allocate session IDs from an IDA iscsi target: fix session creation failure handling drm/vmwgfx: Convert to new IDA API dmaengine: Convert to new IDA API ppc: Convert vas ID allocation to new IDA API media: Convert entity ID allocation to new IDA API ppc: Convert mmu context allocation to new IDA API Convert net_namespace to new IDA API cb710: Convert to new IDA API rsxx: Convert to new IDA API osd: Convert to new IDA API sd: Convert to new IDA API ...
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c67
1 files changed, 24 insertions, 43 deletions
diff --git a/fs/super.c b/fs/super.c
index 7429588d6b49..f3a8c008e164 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -981,58 +981,42 @@ void emergency_thaw_all(void)
981 } 981 }
982} 982}
983 983
984/*
985 * Unnamed block devices are dummy devices used by virtual
986 * filesystems which don't use real block-devices. -- jrs
987 */
988
989static DEFINE_IDA(unnamed_dev_ida); 984static DEFINE_IDA(unnamed_dev_ida);
990static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
991/* Many userspace utilities consider an FSID of 0 invalid.
992 * Always return at least 1 from get_anon_bdev.
993 */
994static int unnamed_dev_start = 1;
995 985
986/**
987 * get_anon_bdev - Allocate a block device for filesystems which don't have one.
988 * @p: Pointer to a dev_t.
989 *
990 * Filesystems which don't use real block devices can call this function
991 * to allocate a virtual block device.
992 *
993 * Context: Any context. Frequently called while holding sb_lock.
994 * Return: 0 on success, -EMFILE if there are no anonymous bdevs left
995 * or -ENOMEM if memory allocation failed.
996 */
996int get_anon_bdev(dev_t *p) 997int get_anon_bdev(dev_t *p)
997{ 998{
998 int dev; 999 int dev;
999 int error;
1000 1000
1001 retry: 1001 /*
1002 if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0) 1002 * Many userspace utilities consider an FSID of 0 invalid.
1003 return -ENOMEM; 1003 * Always return at least 1 from get_anon_bdev.
1004 spin_lock(&unnamed_dev_lock); 1004 */
1005 error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev); 1005 dev = ida_alloc_range(&unnamed_dev_ida, 1, (1 << MINORBITS) - 1,
1006 if (!error) 1006 GFP_ATOMIC);
1007 unnamed_dev_start = dev + 1; 1007 if (dev == -ENOSPC)
1008 spin_unlock(&unnamed_dev_lock); 1008 dev = -EMFILE;
1009 if (error == -EAGAIN) 1009 if (dev < 0)
1010 /* We raced and lost with another CPU. */ 1010 return dev;
1011 goto retry; 1011
1012 else if (error) 1012 *p = MKDEV(0, dev);
1013 return -EAGAIN;
1014
1015 if (dev >= (1 << MINORBITS)) {
1016 spin_lock(&unnamed_dev_lock);
1017 ida_remove(&unnamed_dev_ida, dev);
1018 if (unnamed_dev_start > dev)
1019 unnamed_dev_start = dev;
1020 spin_unlock(&unnamed_dev_lock);
1021 return -EMFILE;
1022 }
1023 *p = MKDEV(0, dev & MINORMASK);
1024 return 0; 1013 return 0;
1025} 1014}
1026EXPORT_SYMBOL(get_anon_bdev); 1015EXPORT_SYMBOL(get_anon_bdev);
1027 1016
1028void free_anon_bdev(dev_t dev) 1017void free_anon_bdev(dev_t dev)
1029{ 1018{
1030 int slot = MINOR(dev); 1019 ida_free(&unnamed_dev_ida, MINOR(dev));
1031 spin_lock(&unnamed_dev_lock);
1032 ida_remove(&unnamed_dev_ida, slot);
1033 if (slot < unnamed_dev_start)
1034 unnamed_dev_start = slot;
1035 spin_unlock(&unnamed_dev_lock);
1036} 1020}
1037EXPORT_SYMBOL(free_anon_bdev); 1021EXPORT_SYMBOL(free_anon_bdev);
1038 1022
@@ -1040,7 +1024,6 @@ int set_anon_super(struct super_block *s, void *data)
1040{ 1024{
1041 return get_anon_bdev(&s->s_dev); 1025 return get_anon_bdev(&s->s_dev);
1042} 1026}
1043
1044EXPORT_SYMBOL(set_anon_super); 1027EXPORT_SYMBOL(set_anon_super);
1045 1028
1046void kill_anon_super(struct super_block *sb) 1029void kill_anon_super(struct super_block *sb)
@@ -1049,7 +1032,6 @@ void kill_anon_super(struct super_block *sb)
1049 generic_shutdown_super(sb); 1032 generic_shutdown_super(sb);
1050 free_anon_bdev(dev); 1033 free_anon_bdev(dev);
1051} 1034}
1052
1053EXPORT_SYMBOL(kill_anon_super); 1035EXPORT_SYMBOL(kill_anon_super);
1054 1036
1055void kill_litter_super(struct super_block *sb) 1037void kill_litter_super(struct super_block *sb)
@@ -1058,7 +1040,6 @@ void kill_litter_super(struct super_block *sb)
1058 d_genocide(sb->s_root); 1040 d_genocide(sb->s_root);
1059 kill_anon_super(sb); 1041 kill_anon_super(sb);
1060} 1042}
1061
1062EXPORT_SYMBOL(kill_litter_super); 1043EXPORT_SYMBOL(kill_litter_super);
1063 1044
1064static int ns_test_super(struct super_block *sb, void *data) 1045static int ns_test_super(struct super_block *sb, void *data)