@@ -580,6 +580,7 @@ static void __dentry_kill(struct dentry *dentry)
580
580
spin_unlock (& dentry -> d_lock );
581
581
if (likely (can_free ))
582
582
dentry_free (dentry );
583
+ cond_resched ();
583
584
}
584
585
585
586
static struct dentry * __lock_parent (struct dentry * dentry )
@@ -827,30 +828,24 @@ static inline bool fast_dput(struct dentry *dentry)
827
828
*/
828
829
void dput (struct dentry * dentry )
829
830
{
830
- if ( unlikely (! dentry ))
831
- return ;
831
+ while ( dentry ) {
832
+ might_sleep () ;
832
833
833
- repeat :
834
- might_sleep ();
834
+ rcu_read_lock ();
835
+ if (likely (fast_dput (dentry ))) {
836
+ rcu_read_unlock ();
837
+ return ;
838
+ }
835
839
836
- rcu_read_lock ();
837
- if (likely (fast_dput (dentry ))) {
840
+ /* Slow case: now with the dentry lock held */
838
841
rcu_read_unlock ();
839
- return ;
840
- }
841
842
842
- /* Slow case: now with the dentry lock held */
843
- rcu_read_unlock ();
844
-
845
- if (likely (retain_dentry (dentry ))) {
846
- spin_unlock (& dentry -> d_lock );
847
- return ;
848
- }
843
+ if (likely (retain_dentry (dentry ))) {
844
+ spin_unlock (& dentry -> d_lock );
845
+ return ;
846
+ }
849
847
850
- dentry = dentry_kill (dentry );
851
- if (dentry ) {
852
- cond_resched ();
853
- goto repeat ;
848
+ dentry = dentry_kill (dentry );
854
849
}
855
850
}
856
851
EXPORT_SYMBOL (dput );
@@ -1052,8 +1047,6 @@ static void shrink_dentry_list(struct list_head *list)
1052
1047
while (!list_empty (list )) {
1053
1048
struct dentry * dentry , * parent ;
1054
1049
1055
- cond_resched ();
1056
-
1057
1050
dentry = list_entry (list -> prev , struct dentry , d_lru );
1058
1051
spin_lock (& dentry -> d_lock );
1059
1052
rcu_read_lock ();
@@ -1230,13 +1223,11 @@ enum d_walk_ret {
1230
1223
* @parent: start of walk
1231
1224
* @data: data passed to @enter() and @finish()
1232
1225
* @enter: callback when first entering the dentry
1233
- * @finish: callback when successfully finished the walk
1234
1226
*
1235
- * The @enter() and @finish() callbacks are called with d_lock held.
1227
+ * The @enter() callbacks are called with d_lock held.
1236
1228
*/
1237
1229
static void d_walk (struct dentry * parent , void * data ,
1238
- enum d_walk_ret (* enter )(void * , struct dentry * ),
1239
- void (* finish )(void * ))
1230
+ enum d_walk_ret (* enter )(void * , struct dentry * ))
1240
1231
{
1241
1232
struct dentry * this_parent ;
1242
1233
struct list_head * next ;
@@ -1325,8 +1316,6 @@ static void d_walk(struct dentry *parent, void *data,
1325
1316
if (need_seqretry (& rename_lock , seq ))
1326
1317
goto rename_retry ;
1327
1318
rcu_read_unlock ();
1328
- if (finish )
1329
- finish (data );
1330
1319
1331
1320
out_unlock :
1332
1321
spin_unlock (& this_parent -> d_lock );
@@ -1375,7 +1364,7 @@ int path_has_submounts(const struct path *parent)
1375
1364
struct check_mount data = { .mnt = parent -> mnt , .mounted = 0 };
1376
1365
1377
1366
read_seqlock_excl (& mount_lock );
1378
- d_walk (parent -> dentry , & data , path_check_mount , NULL );
1367
+ d_walk (parent -> dentry , & data , path_check_mount );
1379
1368
read_sequnlock_excl (& mount_lock );
1380
1369
1381
1370
return data .mounted ;
@@ -1483,11 +1472,16 @@ void shrink_dcache_parent(struct dentry *parent)
1483
1472
data .start = parent ;
1484
1473
data .found = 0 ;
1485
1474
1486
- d_walk (parent , & data , select_collect , NULL );
1475
+ d_walk (parent , & data , select_collect );
1476
+
1477
+ if (!list_empty (& data .dispose )) {
1478
+ shrink_dentry_list (& data .dispose );
1479
+ continue ;
1480
+ }
1481
+
1482
+ cond_resched ();
1487
1483
if (!data .found )
1488
1484
break ;
1489
-
1490
- shrink_dentry_list (& data .dispose );
1491
1485
}
1492
1486
}
1493
1487
EXPORT_SYMBOL (shrink_dcache_parent );
@@ -1518,7 +1512,7 @@ static enum d_walk_ret umount_check(void *_data, struct dentry *dentry)
1518
1512
static void do_one_tree (struct dentry * dentry )
1519
1513
{
1520
1514
shrink_dcache_parent (dentry );
1521
- d_walk (dentry , dentry , umount_check , NULL );
1515
+ d_walk (dentry , dentry , umount_check );
1522
1516
d_drop (dentry );
1523
1517
dput (dentry );
1524
1518
}
@@ -1542,78 +1536,48 @@ void shrink_dcache_for_umount(struct super_block *sb)
1542
1536
}
1543
1537
}
1544
1538
1545
- struct detach_data {
1546
- struct select_data select ;
1547
- struct dentry * mountpoint ;
1548
- };
1549
- static enum d_walk_ret detach_and_collect (void * _data , struct dentry * dentry )
1539
+ static enum d_walk_ret find_submount (void * _data , struct dentry * dentry )
1550
1540
{
1551
- struct detach_data * data = _data ;
1552
-
1541
+ struct dentry * * victim = _data ;
1553
1542
if (d_mountpoint (dentry )) {
1554
1543
__dget_dlock (dentry );
1555
- data -> mountpoint = dentry ;
1544
+ * victim = dentry ;
1556
1545
return D_WALK_QUIT ;
1557
1546
}
1558
-
1559
- return select_collect (& data -> select , dentry );
1560
- }
1561
-
1562
- static void check_and_drop (void * _data )
1563
- {
1564
- struct detach_data * data = _data ;
1565
-
1566
- if (!data -> mountpoint && list_empty (& data -> select .dispose ))
1567
- __d_drop (data -> select .start );
1547
+ return D_WALK_CONTINUE ;
1568
1548
}
1569
1549
1570
1550
/**
1571
1551
* d_invalidate - detach submounts, prune dcache, and drop
1572
1552
* @dentry: dentry to invalidate (aka detach, prune and drop)
1573
- *
1574
- * no dcache lock.
1575
- *
1576
- * The final d_drop is done as an atomic operation relative to
1577
- * rename_lock ensuring there are no races with d_set_mounted. This
1578
- * ensures there are no unhashed dentries on the path to a mountpoint.
1579
1553
*/
1580
1554
void d_invalidate (struct dentry * dentry )
1581
1555
{
1582
- /*
1583
- * If it's already been dropped, return OK.
1584
- */
1556
+ bool had_submounts = false;
1585
1557
spin_lock (& dentry -> d_lock );
1586
1558
if (d_unhashed (dentry )) {
1587
1559
spin_unlock (& dentry -> d_lock );
1588
1560
return ;
1589
1561
}
1562
+ __d_drop (dentry );
1590
1563
spin_unlock (& dentry -> d_lock );
1591
1564
1592
1565
/* Negative dentries can be dropped without further checks */
1593
- if (!dentry -> d_inode ) {
1594
- d_drop (dentry );
1566
+ if (!dentry -> d_inode )
1595
1567
return ;
1596
- }
1597
1568
1569
+ shrink_dcache_parent (dentry );
1598
1570
for (;;) {
1599
- struct detach_data data ;
1600
-
1601
- data .mountpoint = NULL ;
1602
- INIT_LIST_HEAD (& data .select .dispose );
1603
- data .select .start = dentry ;
1604
- data .select .found = 0 ;
1605
-
1606
- d_walk (dentry , & data , detach_and_collect , check_and_drop );
1607
-
1608
- if (!list_empty (& data .select .dispose ))
1609
- shrink_dentry_list (& data .select .dispose );
1610
- else if (!data .mountpoint )
1571
+ struct dentry * victim = NULL ;
1572
+ d_walk (dentry , & victim , find_submount );
1573
+ if (!victim ) {
1574
+ if (had_submounts )
1575
+ shrink_dcache_parent (dentry );
1611
1576
return ;
1612
-
1613
- if (data .mountpoint ) {
1614
- detach_mounts (data .mountpoint );
1615
- dput (data .mountpoint );
1616
1577
}
1578
+ had_submounts = true;
1579
+ detach_mounts (victim );
1580
+ dput (victim );
1617
1581
}
1618
1582
}
1619
1583
EXPORT_SYMBOL (d_invalidate );
@@ -3134,7 +3098,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry)
3134
3098
3135
3099
void d_genocide (struct dentry * parent )
3136
3100
{
3137
- d_walk (parent , parent , d_genocide_kill , NULL );
3101
+ d_walk (parent , parent , d_genocide_kill );
3138
3102
}
3139
3103
3140
3104
EXPORT_SYMBOL (d_genocide );
0 commit comments