10
10
#include <linux/mount.h>
11
11
#include <linux/xattr.h>
12
12
#include <linux/posix_acl_xattr.h>
13
+ #include <linux/radix-tree.h>
13
14
#include <linux/vmalloc.h>
14
15
#include <linux/string.h>
15
16
#include <linux/compat.h>
@@ -127,7 +128,7 @@ struct send_ctx {
127
128
struct list_head new_refs ;
128
129
struct list_head deleted_refs ;
129
130
130
- struct xarray name_cache ;
131
+ struct radix_tree_root name_cache ;
131
132
struct list_head name_cache_list ;
132
133
int name_cache_size ;
133
134
@@ -268,13 +269,14 @@ struct orphan_dir_info {
268
269
struct name_cache_entry {
269
270
struct list_head list ;
270
271
/*
271
- * On 32bit kernels, xarray has only 32bit indices, but we need to
272
- * handle 64bit inums. We use the lower 32bit of the 64bit inum to store
273
- * it in the tree. If more than one inum would fall into the same entry,
274
- * we use inum_aliases to store the additional entries. inum_aliases is
275
- * also used to store entries with the same inum but different generations.
272
+ * radix_tree has only 32bit entries but we need to handle 64bit inums.
273
+ * We use the lower 32bit of the 64bit inum to store it in the tree. If
274
+ * more then one inum would fall into the same entry, we use radix_list
275
+ * to store the additional entries. radix_list is also used to store
276
+ * entries where two entries have the same inum but different
277
+ * generations.
276
278
*/
277
- struct list_head inum_aliases ;
279
+ struct list_head radix_list ;
278
280
u64 ino ;
279
281
u64 gen ;
280
282
u64 parent_ino ;
@@ -2024,9 +2026,9 @@ static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen)
2024
2026
}
2025
2027
2026
2028
/*
2027
- * Insert a name cache entry. On 32bit kernels the xarray index is 32bit,
2029
+ * Insert a name cache entry. On 32bit kernels the radix tree index is 32bit,
2028
2030
* so we need to do some special handling in case we have clashes. This function
2029
- * takes care of this with the help of name_cache_entry::inum_aliases .
2031
+ * takes care of this with the help of name_cache_entry::radix_list .
2030
2032
* In case of error, nce is kfreed.
2031
2033
*/
2032
2034
static int name_cache_insert (struct send_ctx * sctx ,
@@ -2035,7 +2037,8 @@ static int name_cache_insert(struct send_ctx *sctx,
2035
2037
int ret = 0 ;
2036
2038
struct list_head * nce_head ;
2037
2039
2038
- nce_head = xa_load (& sctx -> name_cache , (unsigned long )nce -> ino );
2040
+ nce_head = radix_tree_lookup (& sctx -> name_cache ,
2041
+ (unsigned long )nce -> ino );
2039
2042
if (!nce_head ) {
2040
2043
nce_head = kmalloc (sizeof (* nce_head ), GFP_KERNEL );
2041
2044
if (!nce_head ) {
@@ -2044,14 +2047,14 @@ static int name_cache_insert(struct send_ctx *sctx,
2044
2047
}
2045
2048
INIT_LIST_HEAD (nce_head );
2046
2049
2047
- ret = xa_insert (& sctx -> name_cache , nce -> ino , nce_head , GFP_KERNEL );
2050
+ ret = radix_tree_insert (& sctx -> name_cache , nce -> ino , nce_head );
2048
2051
if (ret < 0 ) {
2049
2052
kfree (nce_head );
2050
2053
kfree (nce );
2051
2054
return ret ;
2052
2055
}
2053
2056
}
2054
- list_add_tail (& nce -> inum_aliases , nce_head );
2057
+ list_add_tail (& nce -> radix_list , nce_head );
2055
2058
list_add_tail (& nce -> list , & sctx -> name_cache_list );
2056
2059
sctx -> name_cache_size ++ ;
2057
2060
@@ -2063,22 +2066,23 @@ static void name_cache_delete(struct send_ctx *sctx,
2063
2066
{
2064
2067
struct list_head * nce_head ;
2065
2068
2066
- nce_head = xa_load (& sctx -> name_cache , (unsigned long )nce -> ino );
2069
+ nce_head = radix_tree_lookup (& sctx -> name_cache ,
2070
+ (unsigned long )nce -> ino );
2067
2071
if (!nce_head ) {
2068
2072
btrfs_err (sctx -> send_root -> fs_info ,
2069
2073
"name_cache_delete lookup failed ino %llu cache size %d, leaking memory" ,
2070
2074
nce -> ino , sctx -> name_cache_size );
2071
2075
}
2072
2076
2073
- list_del (& nce -> inum_aliases );
2077
+ list_del (& nce -> radix_list );
2074
2078
list_del (& nce -> list );
2075
2079
sctx -> name_cache_size -- ;
2076
2080
2077
2081
/*
2078
2082
* We may not get to the final release of nce_head if the lookup fails
2079
2083
*/
2080
2084
if (nce_head && list_empty (nce_head )) {
2081
- xa_erase (& sctx -> name_cache , (unsigned long )nce -> ino );
2085
+ radix_tree_delete (& sctx -> name_cache , (unsigned long )nce -> ino );
2082
2086
kfree (nce_head );
2083
2087
}
2084
2088
}
@@ -2089,11 +2093,11 @@ static struct name_cache_entry *name_cache_search(struct send_ctx *sctx,
2089
2093
struct list_head * nce_head ;
2090
2094
struct name_cache_entry * cur ;
2091
2095
2092
- nce_head = xa_load (& sctx -> name_cache , (unsigned long )ino );
2096
+ nce_head = radix_tree_lookup (& sctx -> name_cache , (unsigned long )ino );
2093
2097
if (!nce_head )
2094
2098
return NULL ;
2095
2099
2096
- list_for_each_entry (cur , nce_head , inum_aliases ) {
2100
+ list_for_each_entry (cur , nce_head , radix_list ) {
2097
2101
if (cur -> ino == ino && cur -> gen == gen )
2098
2102
return cur ;
2099
2103
}
@@ -7518,7 +7522,7 @@ long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg)
7518
7522
7519
7523
INIT_LIST_HEAD (& sctx -> new_refs );
7520
7524
INIT_LIST_HEAD (& sctx -> deleted_refs );
7521
- xa_init_flags (& sctx -> name_cache , GFP_KERNEL );
7525
+ INIT_RADIX_TREE (& sctx -> name_cache , GFP_KERNEL );
7522
7526
INIT_LIST_HEAD (& sctx -> name_cache_list );
7523
7527
7524
7528
sctx -> flags = arg -> flags ;
0 commit comments