diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-26 14:48:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-26 14:48:42 -0400 |
commit | aba16dc5cf9318b4e0fe92f8261779cd9f1d2d77 (patch) | |
tree | 1f53d2cee40e82efe6a727208307af475327af9a /fs/super.c | |
parent | c4726e774ed27680c418e138234dfd2b8e1e89ac (diff) | |
parent | 1df895190233fcc30d46beca4550bcafb7b959a6 (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.c | 67 |
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 | |||
989 | static DEFINE_IDA(unnamed_dev_ida); | 984 | static DEFINE_IDA(unnamed_dev_ida); |
990 | static 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 | */ | ||
994 | static 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 | */ | ||
996 | int get_anon_bdev(dev_t *p) | 997 | int 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 | } |
1026 | EXPORT_SYMBOL(get_anon_bdev); | 1015 | EXPORT_SYMBOL(get_anon_bdev); |
1027 | 1016 | ||
1028 | void free_anon_bdev(dev_t dev) | 1017 | void 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 | } |
1037 | EXPORT_SYMBOL(free_anon_bdev); | 1021 | EXPORT_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 | |||
1044 | EXPORT_SYMBOL(set_anon_super); | 1027 | EXPORT_SYMBOL(set_anon_super); |
1045 | 1028 | ||
1046 | void kill_anon_super(struct super_block *sb) | 1029 | void 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 | |||
1053 | EXPORT_SYMBOL(kill_anon_super); | 1035 | EXPORT_SYMBOL(kill_anon_super); |
1054 | 1036 | ||
1055 | void kill_litter_super(struct super_block *sb) | 1037 | void 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 | |||
1062 | EXPORT_SYMBOL(kill_litter_super); | 1043 | EXPORT_SYMBOL(kill_litter_super); |
1063 | 1044 | ||
1064 | static int ns_test_super(struct super_block *sb, void *data) | 1045 | static int ns_test_super(struct super_block *sb, void *data) |