@@ -24,45 +24,46 @@ static const struct inode_operations kernfs_iops = {
2424 .listxattr = kernfs_iop_listxattr ,
2525};
2626
27- static struct kernfs_iattrs * __kernfs_iattrs (struct kernfs_node * kn , int alloc )
27+ static struct kernfs_iattrs * __kernfs_iattrs (struct kernfs_node * kn , bool alloc )
2828{
29- static DEFINE_MUTEX ( iattr_mutex ) ;
30- struct kernfs_iattrs * ret ;
29+ struct kernfs_iattrs * ret __free ( kfree ) = NULL ;
30+ struct kernfs_iattrs * attr ;
3131
32- mutex_lock (& iattr_mutex );
32+ attr = READ_ONCE (kn -> iattr );
33+ if (attr || !alloc )
34+ return attr ;
3335
34- if (kn -> iattr || !alloc )
35- goto out_unlock ;
36-
37- kn -> iattr = kmem_cache_zalloc (kernfs_iattrs_cache , GFP_KERNEL );
38- if (!kn -> iattr )
39- goto out_unlock ;
36+ ret = kmem_cache_zalloc (kernfs_iattrs_cache , GFP_KERNEL );
37+ if (!ret )
38+ return NULL ;
4039
4140 /* assign default attributes */
42- kn -> iattr -> ia_uid = GLOBAL_ROOT_UID ;
43- kn -> iattr -> ia_gid = GLOBAL_ROOT_GID ;
44-
45- ktime_get_real_ts64 (& kn -> iattr -> ia_atime );
46- kn -> iattr -> ia_mtime = kn -> iattr -> ia_atime ;
47- kn -> iattr -> ia_ctime = kn -> iattr -> ia_atime ;
48-
49- simple_xattrs_init (& kn -> iattr -> xattrs );
50- atomic_set (& kn -> iattr -> nr_user_xattrs , 0 );
51- atomic_set (& kn -> iattr -> user_xattr_size , 0 );
52- out_unlock :
53- ret = kn -> iattr ;
54- mutex_unlock (& iattr_mutex );
55- return ret ;
41+ ret -> ia_uid = GLOBAL_ROOT_UID ;
42+ ret -> ia_gid = GLOBAL_ROOT_GID ;
43+
44+ ktime_get_real_ts64 (& ret -> ia_atime );
45+ ret -> ia_mtime = ret -> ia_atime ;
46+ ret -> ia_ctime = ret -> ia_atime ;
47+
48+ simple_xattrs_init (& ret -> xattrs );
49+ atomic_set (& ret -> nr_user_xattrs , 0 );
50+ atomic_set (& ret -> user_xattr_size , 0 );
51+
52+ /* If someone raced us, recognize it. */
53+ if (!try_cmpxchg (& kn -> iattr , & attr , ret ))
54+ return READ_ONCE (kn -> iattr );
55+
56+ return no_free_ptr (ret );
5657}
5758
5859static struct kernfs_iattrs * kernfs_iattrs (struct kernfs_node * kn )
5960{
60- return __kernfs_iattrs (kn , 1 );
61+ return __kernfs_iattrs (kn , true );
6162}
6263
6364static struct kernfs_iattrs * kernfs_iattrs_noalloc (struct kernfs_node * kn )
6465{
65- return __kernfs_iattrs (kn , 0 );
66+ return __kernfs_iattrs (kn , false );
6667}
6768
6869int __kernfs_setattr (struct kernfs_node * kn , const struct iattr * iattr )
@@ -141,9 +142,9 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
141142 struct kernfs_node * kn = kernfs_dentry_node (dentry );
142143 struct kernfs_iattrs * attrs ;
143144
144- attrs = kernfs_iattrs (kn );
145+ attrs = kernfs_iattrs_noalloc (kn );
145146 if (!attrs )
146- return - ENOMEM ;
147+ return - ENODATA ;
147148
148149 return simple_xattr_list (d_inode (dentry ), & attrs -> xattrs , buf , size );
149150}
@@ -166,9 +167,10 @@ static inline void set_inode_attr(struct inode *inode,
166167
167168static void kernfs_refresh_inode (struct kernfs_node * kn , struct inode * inode )
168169{
169- struct kernfs_iattrs * attrs = kn -> iattr ;
170+ struct kernfs_iattrs * attrs ;
170171
171172 inode -> i_mode = kn -> mode ;
173+ attrs = kernfs_iattrs_noalloc (kn );
172174 if (attrs )
173175 /*
174176 * kernfs_node has non-default attributes get them from
@@ -306,7 +308,9 @@ int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
306308 const void * value , size_t size , int flags )
307309{
308310 struct simple_xattr * old_xattr ;
309- struct kernfs_iattrs * attrs = kernfs_iattrs (kn );
311+ struct kernfs_iattrs * attrs ;
312+
313+ attrs = kernfs_iattrs (kn );
310314 if (!attrs )
311315 return - ENOMEM ;
312316
@@ -345,8 +349,9 @@ static int kernfs_vfs_user_xattr_add(struct kernfs_node *kn,
345349 struct simple_xattrs * xattrs ,
346350 const void * value , size_t size , int flags )
347351{
348- atomic_t * sz = & kn -> iattr -> user_xattr_size ;
349- atomic_t * nr = & kn -> iattr -> nr_user_xattrs ;
352+ struct kernfs_iattrs * attr = kernfs_iattrs_noalloc (kn );
353+ atomic_t * sz = & attr -> user_xattr_size ;
354+ atomic_t * nr = & attr -> nr_user_xattrs ;
350355 struct simple_xattr * old_xattr ;
351356 int ret ;
352357
@@ -384,8 +389,9 @@ static int kernfs_vfs_user_xattr_rm(struct kernfs_node *kn,
384389 struct simple_xattrs * xattrs ,
385390 const void * value , size_t size , int flags )
386391{
387- atomic_t * sz = & kn -> iattr -> user_xattr_size ;
388- atomic_t * nr = & kn -> iattr -> nr_user_xattrs ;
392+ struct kernfs_iattrs * attr = kernfs_iattrs_noalloc (kn );
393+ atomic_t * sz = & attr -> user_xattr_size ;
394+ atomic_t * nr = & attr -> nr_user_xattrs ;
389395 struct simple_xattr * old_xattr ;
390396
391397 old_xattr = simple_xattr_set (xattrs , full_name , value , size , flags );
0 commit comments