17
17
18
18
#include "kernfs-internal.h"
19
19
20
- DECLARE_RWSEM (kernfs_rwsem );
21
20
static DEFINE_SPINLOCK (kernfs_rename_lock ); /* kn->parent and ->name */
22
21
static char kernfs_pr_cont_buf [PATH_MAX ]; /* protected by rename_lock */
23
22
static DEFINE_SPINLOCK (kernfs_idr_lock ); /* root->ino_idr */
@@ -26,7 +25,7 @@ static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */
26
25
27
26
static bool kernfs_active (struct kernfs_node * kn )
28
27
{
29
- lockdep_assert_held (& kernfs_rwsem );
28
+ lockdep_assert_held (& kernfs_root ( kn ) -> kernfs_rwsem );
30
29
return atomic_read (& kn -> active ) >= 0 ;
31
30
}
32
31
@@ -457,14 +456,15 @@ void kernfs_put_active(struct kernfs_node *kn)
457
456
* return after draining is complete.
458
457
*/
459
458
static void kernfs_drain (struct kernfs_node * kn )
460
- __releases (& kernfs_rwsem ) __acquires (& kernfs_rwsem )
459
+ __releases (& kernfs_root (kn )- > kernfs_rwsem )
460
+ __acquires (& kernfs_root (kn )- > kernfs_rwsem )
461
461
{
462
462
struct kernfs_root * root = kernfs_root (kn );
463
463
464
- lockdep_assert_held_write (& kernfs_rwsem );
464
+ lockdep_assert_held_write (& root -> kernfs_rwsem );
465
465
WARN_ON_ONCE (kernfs_active (kn ));
466
466
467
- up_write (& kernfs_rwsem );
467
+ up_write (& root -> kernfs_rwsem );
468
468
469
469
if (kernfs_lockdep (kn )) {
470
470
rwsem_acquire (& kn -> dep_map , 0 , 0 , _RET_IP_ );
@@ -483,7 +483,7 @@ static void kernfs_drain(struct kernfs_node *kn)
483
483
484
484
kernfs_drain_open_files (kn );
485
485
486
- down_write (& kernfs_rwsem );
486
+ down_write (& root -> kernfs_rwsem );
487
487
}
488
488
489
489
/**
@@ -718,11 +718,12 @@ struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root,
718
718
int kernfs_add_one (struct kernfs_node * kn )
719
719
{
720
720
struct kernfs_node * parent = kn -> parent ;
721
+ struct kernfs_root * root = kernfs_root (parent );
721
722
struct kernfs_iattrs * ps_iattr ;
722
723
bool has_ns ;
723
724
int ret ;
724
725
725
- down_write (& kernfs_rwsem );
726
+ down_write (& root -> kernfs_rwsem );
726
727
727
728
ret = - EINVAL ;
728
729
has_ns = kernfs_ns_enabled (parent );
@@ -753,7 +754,7 @@ int kernfs_add_one(struct kernfs_node *kn)
753
754
ps_iattr -> ia_mtime = ps_iattr -> ia_ctime ;
754
755
}
755
756
756
- up_write (& kernfs_rwsem );
757
+ up_write (& root -> kernfs_rwsem );
757
758
758
759
/*
759
760
* Activate the new node unless CREATE_DEACTIVATED is requested.
@@ -767,7 +768,7 @@ int kernfs_add_one(struct kernfs_node *kn)
767
768
return 0 ;
768
769
769
770
out_unlock :
770
- up_write (& kernfs_rwsem );
771
+ up_write (& root -> kernfs_rwsem );
771
772
return ret ;
772
773
}
773
774
@@ -788,7 +789,7 @@ static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent,
788
789
bool has_ns = kernfs_ns_enabled (parent );
789
790
unsigned int hash ;
790
791
791
- lockdep_assert_held (& kernfs_rwsem );
792
+ lockdep_assert_held (& kernfs_root ( parent ) -> kernfs_rwsem );
792
793
793
794
if (has_ns != (bool )ns ) {
794
795
WARN (1 , KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n" ,
@@ -820,7 +821,7 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent,
820
821
size_t len ;
821
822
char * p , * name ;
822
823
823
- lockdep_assert_held_read (& kernfs_rwsem );
824
+ lockdep_assert_held_read (& kernfs_root ( parent ) -> kernfs_rwsem );
824
825
825
826
/* grab kernfs_rename_lock to piggy back on kernfs_pr_cont_buf */
826
827
spin_lock_irq (& kernfs_rename_lock );
@@ -859,11 +860,12 @@ struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
859
860
const char * name , const void * ns )
860
861
{
861
862
struct kernfs_node * kn ;
863
+ struct kernfs_root * root = kernfs_root (parent );
862
864
863
- down_read (& kernfs_rwsem );
865
+ down_read (& root -> kernfs_rwsem );
864
866
kn = kernfs_find_ns (parent , name , ns );
865
867
kernfs_get (kn );
866
- up_read (& kernfs_rwsem );
868
+ up_read (& root -> kernfs_rwsem );
867
869
868
870
return kn ;
869
871
}
@@ -883,11 +885,12 @@ struct kernfs_node *kernfs_walk_and_get_ns(struct kernfs_node *parent,
883
885
const char * path , const void * ns )
884
886
{
885
887
struct kernfs_node * kn ;
888
+ struct kernfs_root * root = kernfs_root (parent );
886
889
887
- down_read (& kernfs_rwsem );
890
+ down_read (& root -> kernfs_rwsem );
888
891
kn = kernfs_walk_ns (parent , path , ns );
889
892
kernfs_get (kn );
890
- up_read (& kernfs_rwsem );
893
+ up_read (& root -> kernfs_rwsem );
891
894
892
895
return kn ;
893
896
}
@@ -912,6 +915,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
912
915
return ERR_PTR (- ENOMEM );
913
916
914
917
idr_init (& root -> ino_idr );
918
+ init_rwsem (& root -> kernfs_rwsem );
915
919
INIT_LIST_HEAD (& root -> supers );
916
920
917
921
/*
@@ -1035,6 +1039,7 @@ struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
1035
1039
static int kernfs_dop_revalidate (struct dentry * dentry , unsigned int flags )
1036
1040
{
1037
1041
struct kernfs_node * kn ;
1042
+ struct kernfs_root * root ;
1038
1043
1039
1044
if (flags & LOOKUP_RCU )
1040
1045
return - ECHILD ;
@@ -1046,18 +1051,19 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
1046
1051
/* If the kernfs parent node has changed discard and
1047
1052
* proceed to ->lookup.
1048
1053
*/
1049
- down_read (& kernfs_rwsem );
1050
1054
spin_lock (& dentry -> d_lock );
1051
1055
parent = kernfs_dentry_node (dentry -> d_parent );
1052
1056
if (parent ) {
1057
+ spin_unlock (& dentry -> d_lock );
1058
+ root = kernfs_root (parent );
1059
+ down_read (& root -> kernfs_rwsem );
1053
1060
if (kernfs_dir_changed (parent , dentry )) {
1054
- spin_unlock (& dentry -> d_lock );
1055
- up_read (& kernfs_rwsem );
1061
+ up_read (& root -> kernfs_rwsem );
1056
1062
return 0 ;
1057
1063
}
1058
- }
1059
- spin_unlock ( & dentry -> d_lock );
1060
- up_read ( & kernfs_rwsem );
1064
+ up_read ( & root -> kernfs_rwsem );
1065
+ } else
1066
+ spin_unlock ( & dentry -> d_lock );
1061
1067
1062
1068
/* The kernfs parent node hasn't changed, leave the
1063
1069
* dentry negative and return success.
@@ -1066,7 +1072,8 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
1066
1072
}
1067
1073
1068
1074
kn = kernfs_dentry_node (dentry );
1069
- down_read (& kernfs_rwsem );
1075
+ root = kernfs_root (kn );
1076
+ down_read (& root -> kernfs_rwsem );
1070
1077
1071
1078
/* The kernfs node has been deactivated */
1072
1079
if (!kernfs_active (kn ))
@@ -1085,10 +1092,10 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
1085
1092
kernfs_info (dentry -> d_sb )-> ns != kn -> ns )
1086
1093
goto out_bad ;
1087
1094
1088
- up_read (& kernfs_rwsem );
1095
+ up_read (& root -> kernfs_rwsem );
1089
1096
return 1 ;
1090
1097
out_bad :
1091
- up_read (& kernfs_rwsem );
1098
+ up_read (& root -> kernfs_rwsem );
1092
1099
return 0 ;
1093
1100
}
1094
1101
@@ -1102,10 +1109,12 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
1102
1109
{
1103
1110
struct kernfs_node * parent = dir -> i_private ;
1104
1111
struct kernfs_node * kn ;
1112
+ struct kernfs_root * root ;
1105
1113
struct inode * inode = NULL ;
1106
1114
const void * ns = NULL ;
1107
1115
1108
- down_read (& kernfs_rwsem );
1116
+ root = kernfs_root (parent );
1117
+ down_read (& root -> kernfs_rwsem );
1109
1118
if (kernfs_ns_enabled (parent ))
1110
1119
ns = kernfs_info (dir -> i_sb )-> ns ;
1111
1120
@@ -1116,7 +1125,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
1116
1125
* create a negative.
1117
1126
*/
1118
1127
if (!kernfs_active (kn )) {
1119
- up_read (& kernfs_rwsem );
1128
+ up_read (& root -> kernfs_rwsem );
1120
1129
return NULL ;
1121
1130
}
1122
1131
inode = kernfs_get_inode (dir -> i_sb , kn );
@@ -1131,7 +1140,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
1131
1140
*/
1132
1141
if (!IS_ERR (inode ))
1133
1142
kernfs_set_rev (parent , dentry );
1134
- up_read (& kernfs_rwsem );
1143
+ up_read (& root -> kernfs_rwsem );
1135
1144
1136
1145
/* instantiate and hash (possibly negative) dentry */
1137
1146
return d_splice_alias (inode , dentry );
@@ -1254,7 +1263,7 @@ static struct kernfs_node *kernfs_next_descendant_post(struct kernfs_node *pos,
1254
1263
{
1255
1264
struct rb_node * rbn ;
1256
1265
1257
- lockdep_assert_held_write (& kernfs_rwsem );
1266
+ lockdep_assert_held_write (& kernfs_root ( root ) -> kernfs_rwsem );
1258
1267
1259
1268
/* if first iteration, visit leftmost descendant which may be root */
1260
1269
if (!pos )
@@ -1289,8 +1298,9 @@ static struct kernfs_node *kernfs_next_descendant_post(struct kernfs_node *pos,
1289
1298
void kernfs_activate (struct kernfs_node * kn )
1290
1299
{
1291
1300
struct kernfs_node * pos ;
1301
+ struct kernfs_root * root = kernfs_root (kn );
1292
1302
1293
- down_write (& kernfs_rwsem );
1303
+ down_write (& root -> kernfs_rwsem );
1294
1304
1295
1305
pos = NULL ;
1296
1306
while ((pos = kernfs_next_descendant_post (pos , kn ))) {
@@ -1304,14 +1314,14 @@ void kernfs_activate(struct kernfs_node *kn)
1304
1314
pos -> flags |= KERNFS_ACTIVATED ;
1305
1315
}
1306
1316
1307
- up_write (& kernfs_rwsem );
1317
+ up_write (& root -> kernfs_rwsem );
1308
1318
}
1309
1319
1310
1320
static void __kernfs_remove (struct kernfs_node * kn )
1311
1321
{
1312
1322
struct kernfs_node * pos ;
1313
1323
1314
- lockdep_assert_held_write (& kernfs_rwsem );
1324
+ lockdep_assert_held_write (& kernfs_root ( kn ) -> kernfs_rwsem );
1315
1325
1316
1326
/*
1317
1327
* Short-circuit if non-root @kn has already finished removal.
@@ -1381,9 +1391,11 @@ static void __kernfs_remove(struct kernfs_node *kn)
1381
1391
*/
1382
1392
void kernfs_remove (struct kernfs_node * kn )
1383
1393
{
1384
- down_write (& kernfs_rwsem );
1394
+ struct kernfs_root * root = kernfs_root (kn );
1395
+
1396
+ down_write (& root -> kernfs_rwsem );
1385
1397
__kernfs_remove (kn );
1386
- up_write (& kernfs_rwsem );
1398
+ up_write (& root -> kernfs_rwsem );
1387
1399
}
1388
1400
1389
1401
/**
@@ -1469,8 +1481,9 @@ void kernfs_unbreak_active_protection(struct kernfs_node *kn)
1469
1481
bool kernfs_remove_self (struct kernfs_node * kn )
1470
1482
{
1471
1483
bool ret ;
1484
+ struct kernfs_root * root = kernfs_root (kn );
1472
1485
1473
- down_write (& kernfs_rwsem );
1486
+ down_write (& root -> kernfs_rwsem );
1474
1487
kernfs_break_active_protection (kn );
1475
1488
1476
1489
/*
@@ -1498,9 +1511,9 @@ bool kernfs_remove_self(struct kernfs_node *kn)
1498
1511
atomic_read (& kn -> active ) == KN_DEACTIVATED_BIAS )
1499
1512
break ;
1500
1513
1501
- up_write (& kernfs_rwsem );
1514
+ up_write (& root -> kernfs_rwsem );
1502
1515
schedule ();
1503
- down_write (& kernfs_rwsem );
1516
+ down_write (& root -> kernfs_rwsem );
1504
1517
}
1505
1518
finish_wait (waitq , & wait );
1506
1519
WARN_ON_ONCE (!RB_EMPTY_NODE (& kn -> rb ));
@@ -1513,7 +1526,7 @@ bool kernfs_remove_self(struct kernfs_node *kn)
1513
1526
*/
1514
1527
kernfs_unbreak_active_protection (kn );
1515
1528
1516
- up_write (& kernfs_rwsem );
1529
+ up_write (& root -> kernfs_rwsem );
1517
1530
return ret ;
1518
1531
}
1519
1532
@@ -1530,20 +1543,22 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
1530
1543
const void * ns )
1531
1544
{
1532
1545
struct kernfs_node * kn ;
1546
+ struct kernfs_root * root ;
1533
1547
1534
1548
if (!parent ) {
1535
1549
WARN (1 , KERN_WARNING "kernfs: can not remove '%s', no directory\n" ,
1536
1550
name );
1537
1551
return - ENOENT ;
1538
1552
}
1539
1553
1540
- down_write (& kernfs_rwsem );
1554
+ root = kernfs_root (parent );
1555
+ down_write (& root -> kernfs_rwsem );
1541
1556
1542
1557
kn = kernfs_find_ns (parent , name , ns );
1543
1558
if (kn )
1544
1559
__kernfs_remove (kn );
1545
1560
1546
- up_write (& kernfs_rwsem );
1561
+ up_write (& root -> kernfs_rwsem );
1547
1562
1548
1563
if (kn )
1549
1564
return 0 ;
@@ -1562,14 +1577,16 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
1562
1577
const char * new_name , const void * new_ns )
1563
1578
{
1564
1579
struct kernfs_node * old_parent ;
1580
+ struct kernfs_root * root ;
1565
1581
const char * old_name = NULL ;
1566
1582
int error ;
1567
1583
1568
1584
/* can't move or rename root */
1569
1585
if (!kn -> parent )
1570
1586
return - EINVAL ;
1571
1587
1572
- down_write (& kernfs_rwsem );
1588
+ root = kernfs_root (kn );
1589
+ down_write (& root -> kernfs_rwsem );
1573
1590
1574
1591
error = - ENOENT ;
1575
1592
if (!kernfs_active (kn ) || !kernfs_active (new_parent ) ||
@@ -1623,7 +1640,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
1623
1640
1624
1641
error = 0 ;
1625
1642
out :
1626
- up_write (& kernfs_rwsem );
1643
+ up_write (& root -> kernfs_rwsem );
1627
1644
return error ;
1628
1645
}
1629
1646
@@ -1694,11 +1711,14 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx)
1694
1711
struct dentry * dentry = file -> f_path .dentry ;
1695
1712
struct kernfs_node * parent = kernfs_dentry_node (dentry );
1696
1713
struct kernfs_node * pos = file -> private_data ;
1714
+ struct kernfs_root * root ;
1697
1715
const void * ns = NULL ;
1698
1716
1699
1717
if (!dir_emit_dots (file , ctx ))
1700
1718
return 0 ;
1701
- down_read (& kernfs_rwsem );
1719
+
1720
+ root = kernfs_root (parent );
1721
+ down_read (& root -> kernfs_rwsem );
1702
1722
1703
1723
if (kernfs_ns_enabled (parent ))
1704
1724
ns = kernfs_info (dentry -> d_sb )-> ns ;
@@ -1715,12 +1735,12 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx)
1715
1735
file -> private_data = pos ;
1716
1736
kernfs_get (pos );
1717
1737
1718
- up_read (& kernfs_rwsem );
1738
+ up_read (& root -> kernfs_rwsem );
1719
1739
if (!dir_emit (ctx , name , len , ino , type ))
1720
1740
return 0 ;
1721
- down_read (& kernfs_rwsem );
1741
+ down_read (& root -> kernfs_rwsem );
1722
1742
}
1723
- up_read (& kernfs_rwsem );
1743
+ up_read (& root -> kernfs_rwsem );
1724
1744
file -> private_data = NULL ;
1725
1745
ctx -> pos = INT_MAX ;
1726
1746
return 0 ;
0 commit comments