@@ -151,11 +151,38 @@ configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd)
151
151
152
152
#endif /* CONFIG_LOCKDEP */
153
153
154
+ static struct configfs_fragment * new_fragment (void )
155
+ {
156
+ struct configfs_fragment * p ;
157
+
158
+ p = kmalloc (sizeof (struct configfs_fragment ), GFP_KERNEL );
159
+ if (p ) {
160
+ atomic_set (& p -> frag_count , 1 );
161
+ init_rwsem (& p -> frag_sem );
162
+ p -> frag_dead = false;
163
+ }
164
+ return p ;
165
+ }
166
+
167
+ void put_fragment (struct configfs_fragment * frag )
168
+ {
169
+ if (frag && atomic_dec_and_test (& frag -> frag_count ))
170
+ kfree (frag );
171
+ }
172
+
173
+ struct configfs_fragment * get_fragment (struct configfs_fragment * frag )
174
+ {
175
+ if (likely (frag ))
176
+ atomic_inc (& frag -> frag_count );
177
+ return frag ;
178
+ }
179
+
154
180
/*
155
181
* Allocates a new configfs_dirent and links it to the parent configfs_dirent
156
182
*/
157
183
static struct configfs_dirent * configfs_new_dirent (struct configfs_dirent * parent_sd ,
158
- void * element , int type )
184
+ void * element , int type ,
185
+ struct configfs_fragment * frag )
159
186
{
160
187
struct configfs_dirent * sd ;
161
188
@@ -175,6 +202,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *paren
175
202
kmem_cache_free (configfs_dir_cachep , sd );
176
203
return ERR_PTR (- ENOENT );
177
204
}
205
+ sd -> s_frag = get_fragment (frag );
178
206
list_add (& sd -> s_sibling , & parent_sd -> s_children );
179
207
spin_unlock (& configfs_dirent_lock );
180
208
@@ -209,11 +237,11 @@ static int configfs_dirent_exists(struct configfs_dirent *parent_sd,
209
237
210
238
int configfs_make_dirent (struct configfs_dirent * parent_sd ,
211
239
struct dentry * dentry , void * element ,
212
- umode_t mode , int type )
240
+ umode_t mode , int type , struct configfs_fragment * frag )
213
241
{
214
242
struct configfs_dirent * sd ;
215
243
216
- sd = configfs_new_dirent (parent_sd , element , type );
244
+ sd = configfs_new_dirent (parent_sd , element , type , frag );
217
245
if (IS_ERR (sd ))
218
246
return PTR_ERR (sd );
219
247
@@ -260,7 +288,8 @@ static void init_symlink(struct inode * inode)
260
288
* until it is validated by configfs_dir_set_ready()
261
289
*/
262
290
263
- static int configfs_create_dir (struct config_item * item , struct dentry * dentry )
291
+ static int configfs_create_dir (struct config_item * item , struct dentry * dentry ,
292
+ struct configfs_fragment * frag )
264
293
{
265
294
int error ;
266
295
umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO ;
@@ -273,7 +302,8 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry)
273
302
return error ;
274
303
275
304
error = configfs_make_dirent (p -> d_fsdata , dentry , item , mode ,
276
- CONFIGFS_DIR | CONFIGFS_USET_CREATING );
305
+ CONFIGFS_DIR | CONFIGFS_USET_CREATING ,
306
+ frag );
277
307
if (unlikely (error ))
278
308
return error ;
279
309
@@ -338,9 +368,10 @@ int configfs_create_link(struct configfs_symlink *sl,
338
368
{
339
369
int err = 0 ;
340
370
umode_t mode = S_IFLNK | S_IRWXUGO ;
371
+ struct configfs_dirent * p = parent -> d_fsdata ;
341
372
342
- err = configfs_make_dirent (parent -> d_fsdata , dentry , sl , mode ,
343
- CONFIGFS_ITEM_LINK );
373
+ err = configfs_make_dirent (p , dentry , sl , mode ,
374
+ CONFIGFS_ITEM_LINK , p -> s_frag );
344
375
if (!err ) {
345
376
err = configfs_create (dentry , mode , init_symlink );
346
377
if (err ) {
@@ -599,7 +630,8 @@ static int populate_attrs(struct config_item *item)
599
630
600
631
static int configfs_attach_group (struct config_item * parent_item ,
601
632
struct config_item * item ,
602
- struct dentry * dentry );
633
+ struct dentry * dentry ,
634
+ struct configfs_fragment * frag );
603
635
static void configfs_detach_group (struct config_item * item );
604
636
605
637
static void detach_groups (struct config_group * group )
@@ -647,7 +679,8 @@ static void detach_groups(struct config_group *group)
647
679
* try using vfs_mkdir. Just a thought.
648
680
*/
649
681
static int create_default_group (struct config_group * parent_group ,
650
- struct config_group * group )
682
+ struct config_group * group ,
683
+ struct configfs_fragment * frag )
651
684
{
652
685
int ret ;
653
686
struct configfs_dirent * sd ;
@@ -663,7 +696,7 @@ static int create_default_group(struct config_group *parent_group,
663
696
d_add (child , NULL );
664
697
665
698
ret = configfs_attach_group (& parent_group -> cg_item ,
666
- & group -> cg_item , child );
699
+ & group -> cg_item , child , frag );
667
700
if (!ret ) {
668
701
sd = child -> d_fsdata ;
669
702
sd -> s_type |= CONFIGFS_USET_DEFAULT ;
@@ -677,13 +710,14 @@ static int create_default_group(struct config_group *parent_group,
677
710
return ret ;
678
711
}
679
712
680
- static int populate_groups (struct config_group * group )
713
+ static int populate_groups (struct config_group * group ,
714
+ struct configfs_fragment * frag )
681
715
{
682
716
struct config_group * new_group ;
683
717
int ret = 0 ;
684
718
685
719
list_for_each_entry (new_group , & group -> default_groups , group_entry ) {
686
- ret = create_default_group (group , new_group );
720
+ ret = create_default_group (group , new_group , frag );
687
721
if (ret ) {
688
722
detach_groups (group );
689
723
break ;
@@ -797,11 +831,12 @@ static void link_group(struct config_group *parent_group, struct config_group *g
797
831
*/
798
832
static int configfs_attach_item (struct config_item * parent_item ,
799
833
struct config_item * item ,
800
- struct dentry * dentry )
834
+ struct dentry * dentry ,
835
+ struct configfs_fragment * frag )
801
836
{
802
837
int ret ;
803
838
804
- ret = configfs_create_dir (item , dentry );
839
+ ret = configfs_create_dir (item , dentry , frag );
805
840
if (!ret ) {
806
841
ret = populate_attrs (item );
807
842
if (ret ) {
@@ -831,12 +866,13 @@ static void configfs_detach_item(struct config_item *item)
831
866
832
867
static int configfs_attach_group (struct config_item * parent_item ,
833
868
struct config_item * item ,
834
- struct dentry * dentry )
869
+ struct dentry * dentry ,
870
+ struct configfs_fragment * frag )
835
871
{
836
872
int ret ;
837
873
struct configfs_dirent * sd ;
838
874
839
- ret = configfs_attach_item (parent_item , item , dentry );
875
+ ret = configfs_attach_item (parent_item , item , dentry , frag );
840
876
if (!ret ) {
841
877
sd = dentry -> d_fsdata ;
842
878
sd -> s_type |= CONFIGFS_USET_DIR ;
@@ -852,7 +888,7 @@ static int configfs_attach_group(struct config_item *parent_item,
852
888
*/
853
889
inode_lock_nested (d_inode (dentry ), I_MUTEX_CHILD );
854
890
configfs_adjust_dir_dirent_depth_before_populate (sd );
855
- ret = populate_groups (to_config_group (item ));
891
+ ret = populate_groups (to_config_group (item ), frag );
856
892
if (ret ) {
857
893
configfs_detach_item (item );
858
894
d_inode (dentry )-> i_flags |= S_DEAD ;
@@ -1247,6 +1283,7 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
1247
1283
struct configfs_dirent * sd ;
1248
1284
const struct config_item_type * type ;
1249
1285
struct module * subsys_owner = NULL , * new_item_owner = NULL ;
1286
+ struct configfs_fragment * frag ;
1250
1287
char * name ;
1251
1288
1252
1289
sd = dentry -> d_parent -> d_fsdata ;
@@ -1265,6 +1302,12 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
1265
1302
goto out ;
1266
1303
}
1267
1304
1305
+ frag = new_fragment ();
1306
+ if (!frag ) {
1307
+ ret = - ENOMEM ;
1308
+ goto out ;
1309
+ }
1310
+
1268
1311
/* Get a working ref for the duration of this function */
1269
1312
parent_item = configfs_get_config_item (dentry -> d_parent );
1270
1313
type = parent_item -> ci_type ;
@@ -1367,9 +1410,9 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
1367
1410
spin_unlock (& configfs_dirent_lock );
1368
1411
1369
1412
if (group )
1370
- ret = configfs_attach_group (parent_item , item , dentry );
1413
+ ret = configfs_attach_group (parent_item , item , dentry , frag );
1371
1414
else
1372
- ret = configfs_attach_item (parent_item , item , dentry );
1415
+ ret = configfs_attach_item (parent_item , item , dentry , frag );
1373
1416
1374
1417
spin_lock (& configfs_dirent_lock );
1375
1418
sd -> s_type &= ~CONFIGFS_USET_IN_MKDIR ;
@@ -1406,6 +1449,7 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
1406
1449
* reference.
1407
1450
*/
1408
1451
config_item_put (parent_item );
1452
+ put_fragment (frag );
1409
1453
1410
1454
out :
1411
1455
return ret ;
@@ -1574,7 +1618,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file)
1574
1618
*/
1575
1619
err = - ENOENT ;
1576
1620
if (configfs_dirent_is_ready (parent_sd )) {
1577
- file -> private_data = configfs_new_dirent (parent_sd , NULL , 0 );
1621
+ file -> private_data = configfs_new_dirent (parent_sd , NULL , 0 , NULL );
1578
1622
if (IS_ERR (file -> private_data ))
1579
1623
err = PTR_ERR (file -> private_data );
1580
1624
else
@@ -1732,29 +1776,36 @@ int configfs_register_group(struct config_group *parent_group,
1732
1776
{
1733
1777
struct configfs_subsystem * subsys = parent_group -> cg_subsys ;
1734
1778
struct dentry * parent ;
1779
+ struct configfs_fragment * frag ;
1735
1780
int ret ;
1736
1781
1782
+ frag = new_fragment ();
1783
+ if (!frag )
1784
+ return - ENOMEM ;
1785
+
1737
1786
mutex_lock (& subsys -> su_mutex );
1738
1787
link_group (parent_group , group );
1739
1788
mutex_unlock (& subsys -> su_mutex );
1740
1789
1741
1790
parent = parent_group -> cg_item .ci_dentry ;
1742
1791
1743
1792
inode_lock_nested (d_inode (parent ), I_MUTEX_PARENT );
1744
- ret = create_default_group (parent_group , group );
1793
+ ret = create_default_group (parent_group , group , frag );
1745
1794
if (ret )
1746
1795
goto err_out ;
1747
1796
1748
1797
spin_lock (& configfs_dirent_lock );
1749
1798
configfs_dir_set_ready (group -> cg_item .ci_dentry -> d_fsdata );
1750
1799
spin_unlock (& configfs_dirent_lock );
1751
1800
inode_unlock (d_inode (parent ));
1801
+ put_fragment (frag );
1752
1802
return 0 ;
1753
1803
err_out :
1754
1804
inode_unlock (d_inode (parent ));
1755
1805
mutex_lock (& subsys -> su_mutex );
1756
1806
unlink_group (group );
1757
1807
mutex_unlock (& subsys -> su_mutex );
1808
+ put_fragment (frag );
1758
1809
return ret ;
1759
1810
}
1760
1811
EXPORT_SYMBOL (configfs_register_group );
@@ -1842,10 +1893,17 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
1842
1893
struct dentry * dentry ;
1843
1894
struct dentry * root ;
1844
1895
struct configfs_dirent * sd ;
1896
+ struct configfs_fragment * frag ;
1897
+
1898
+ frag = new_fragment ();
1899
+ if (!frag )
1900
+ return - ENOMEM ;
1845
1901
1846
1902
root = configfs_pin_fs ();
1847
- if (IS_ERR (root ))
1903
+ if (IS_ERR (root )) {
1904
+ put_fragment (frag );
1848
1905
return PTR_ERR (root );
1906
+ }
1849
1907
1850
1908
if (!group -> cg_item .ci_name )
1851
1909
group -> cg_item .ci_name = group -> cg_item .ci_namebuf ;
@@ -1861,7 +1919,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
1861
1919
d_add (dentry , NULL );
1862
1920
1863
1921
err = configfs_attach_group (sd -> s_element , & group -> cg_item ,
1864
- dentry );
1922
+ dentry , frag );
1865
1923
if (err ) {
1866
1924
BUG_ON (d_inode (dentry ));
1867
1925
d_drop (dentry );
@@ -1879,6 +1937,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
1879
1937
unlink_group (group );
1880
1938
configfs_release_fs ();
1881
1939
}
1940
+ put_fragment (frag );
1882
1941
1883
1942
return err ;
1884
1943
}
0 commit comments