Skip to content

Commit da549bd

Browse files
author
Al Viro
committed
dentry: switch the lists of children to hlist
Saves a pointer per struct dentry and actually makes the things less clumsy. Cleaned the d_walk() and dcache_readdir() a bit by use of hlist_for_... iterators. A couple of new helpers - d_first_child() and d_next_sibling(), to make the expressions less awful. Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent b31559f commit da549bd

12 files changed

Lines changed: 108 additions & 101 deletions

File tree

Documentation/filesystems/porting.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,3 +1061,12 @@ export_operations ->encode_fh() no longer has a default implementation to
10611061
encode FILEID_INO32_GEN* file handles.
10621062
Filesystems that used the default implementation may use the generic helper
10631063
generic_encode_ino32_fh() explicitly.
1064+
1065+
---
1066+
1067+
**mandatory**
1068+
1069+
The list of children anchored in parent dentry got turned into hlist now.
1070+
Field names got changed (->d_children/->d_sib instead of ->d_subdirs/->d_child
1071+
for anchor/entries resp.), so any affected places will be immediately caught
1072+
by compiler.

arch/powerpc/platforms/cell/spufs/inode.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,11 @@ spufs_evict_inode(struct inode *inode)
145145

146146
static void spufs_prune_dir(struct dentry *dir)
147147
{
148-
struct dentry *dentry, *tmp;
148+
struct dentry *dentry;
149+
struct hlist_node *n;
149150

150151
inode_lock(d_inode(dir));
151-
list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
152+
hlist_for_each_entry_safe(dentry, n, &dir->d_children, d_sib) {
152153
spin_lock(&dentry->d_lock);
153154
if (simple_positive(dentry)) {
154155
dget_dlock(dentry);

fs/afs/dynroot.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ int afs_dynroot_populate(struct super_block *sb)
370370
void afs_dynroot_depopulate(struct super_block *sb)
371371
{
372372
struct afs_net *net = afs_sb2net(sb);
373-
struct dentry *root = sb->s_root, *subdir, *tmp;
373+
struct dentry *root = sb->s_root, *subdir;
374374

375375
/* Prevent more subdirs from being created */
376376
mutex_lock(&net->proc_cells_lock);
@@ -379,10 +379,11 @@ void afs_dynroot_depopulate(struct super_block *sb)
379379
mutex_unlock(&net->proc_cells_lock);
380380

381381
if (root) {
382+
struct hlist_node *n;
382383
inode_lock(root->d_inode);
383384

384385
/* Remove all the pins for dirs created for manually added cells */
385-
list_for_each_entry_safe(subdir, tmp, &root->d_subdirs, d_child) {
386+
hlist_for_each_entry_safe(subdir, n, &root->d_children, d_sib) {
386387
if (subdir->d_fsdata) {
387388
subdir->d_fsdata = NULL;
388389
dput(subdir);

fs/autofs/expire.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,9 @@ static int autofs_mount_busy(struct vfsmount *mnt,
7373
/* p->d_lock held */
7474
static struct dentry *positive_after(struct dentry *p, struct dentry *child)
7575
{
76-
if (child)
77-
child = list_next_entry(child, d_child);
78-
else
79-
child = list_first_entry(&p->d_subdirs, struct dentry, d_child);
76+
child = child ? d_next_sibling(child) : d_first_child(p);
8077

81-
list_for_each_entry_from(child, &p->d_subdirs, d_child) {
78+
hlist_for_each_entry_from(child, d_sib) {
8279
spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
8380
if (simple_positive(child)) {
8481
dget_dlock(child);

fs/ceph/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ __dcache_find_get_entry(struct dentry *parent, u64 idx,
174174
/*
175175
* When possible, we try to satisfy a readdir by peeking at the
176176
* dcache. We make this work by carefully ordering dentries on
177-
* d_child when we initially get results back from the MDS, and
177+
* d_children when we initially get results back from the MDS, and
178178
* falling back to a "normal" sync readdir if any dentries in the dir
179179
* are dropped.
180180
*

fs/ceph/mds_client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2128,7 +2128,7 @@ static bool drop_negative_children(struct dentry *dentry)
21282128
goto out;
21292129

21302130
spin_lock(&dentry->d_lock);
2131-
list_for_each_entry(child, &dentry->d_subdirs, d_child) {
2131+
hlist_for_each_entry(child, &dentry->d_children, d_sib) {
21322132
if (d_really_is_positive(child)) {
21332133
all_negative = false;
21342134
break;

fs/coda/cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static void coda_flag_children(struct dentry *parent, int flag)
9393
struct dentry *de;
9494

9595
spin_lock(&parent->d_lock);
96-
list_for_each_entry(de, &parent->d_subdirs, d_child) {
96+
hlist_for_each_entry(de, &parent->d_children, d_sib) {
9797
struct inode *inode = d_inode_rcu(de);
9898
/* don't know what to do with negative dentries */
9999
if (inode)

fs/dcache.c

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
* - d_lru
5252
* - d_count
5353
* - d_unhashed()
54-
* - d_parent and d_subdirs
55-
* - childrens' d_child and d_parent
54+
* - d_parent and d_chilren
55+
* - childrens' d_sib and d_parent
5656
* - d_u.d_alias, d_inode
5757
*
5858
* Ordering:
@@ -537,41 +537,41 @@ void d_drop(struct dentry *dentry)
537537
}
538538
EXPORT_SYMBOL(d_drop);
539539

540-
static inline void dentry_unlist(struct dentry *dentry, struct dentry *parent)
540+
static inline void dentry_unlist(struct dentry *dentry)
541541
{
542542
struct dentry *next;
543543
/*
544544
* Inform d_walk() and shrink_dentry_list() that we are no longer
545545
* attached to the dentry tree
546546
*/
547547
dentry->d_flags |= DCACHE_DENTRY_KILLED;
548-
if (unlikely(list_empty(&dentry->d_child)))
548+
if (unlikely(hlist_unhashed(&dentry->d_sib)))
549549
return;
550-
__list_del_entry(&dentry->d_child);
550+
__hlist_del(&dentry->d_sib);
551551
/*
552552
* Cursors can move around the list of children. While we'd been
553-
* a normal list member, it didn't matter - ->d_child.next would've
553+
* a normal list member, it didn't matter - ->d_sib.next would've
554554
* been updated. However, from now on it won't be and for the
555555
* things like d_walk() it might end up with a nasty surprise.
556556
* Normally d_walk() doesn't care about cursors moving around -
557557
* ->d_lock on parent prevents that and since a cursor has no children
558558
* of its own, we get through it without ever unlocking the parent.
559559
* There is one exception, though - if we ascend from a child that
560560
* gets killed as soon as we unlock it, the next sibling is found
561-
* using the value left in its ->d_child.next. And if _that_
561+
* using the value left in its ->d_sib.next. And if _that_
562562
* pointed to a cursor, and cursor got moved (e.g. by lseek())
563563
* before d_walk() regains parent->d_lock, we'll end up skipping
564564
* everything the cursor had been moved past.
565565
*
566-
* Solution: make sure that the pointer left behind in ->d_child.next
566+
* Solution: make sure that the pointer left behind in ->d_sib.next
567567
* points to something that won't be moving around. I.e. skip the
568568
* cursors.
569569
*/
570-
while (dentry->d_child.next != &parent->d_subdirs) {
571-
next = list_entry(dentry->d_child.next, struct dentry, d_child);
570+
while (dentry->d_sib.next) {
571+
next = hlist_entry(dentry->d_sib.next, struct dentry, d_sib);
572572
if (likely(!(next->d_flags & DCACHE_DENTRY_CURSOR)))
573573
break;
574-
dentry->d_child.next = next->d_child.next;
574+
dentry->d_sib.next = next->d_sib.next;
575575
}
576576
}
577577

@@ -600,7 +600,7 @@ static void __dentry_kill(struct dentry *dentry)
600600
}
601601
/* if it was on the hash then remove it */
602602
__d_drop(dentry);
603-
dentry_unlist(dentry, parent);
603+
dentry_unlist(dentry);
604604
if (parent)
605605
spin_unlock(&parent->d_lock);
606606
if (dentry->d_inode)
@@ -1348,8 +1348,7 @@ enum d_walk_ret {
13481348
static void d_walk(struct dentry *parent, void *data,
13491349
enum d_walk_ret (*enter)(void *, struct dentry *))
13501350
{
1351-
struct dentry *this_parent;
1352-
struct list_head *next;
1351+
struct dentry *this_parent, *dentry;
13531352
unsigned seq = 0;
13541353
enum d_walk_ret ret;
13551354
bool retry = true;
@@ -1371,13 +1370,9 @@ static void d_walk(struct dentry *parent, void *data,
13711370
break;
13721371
}
13731372
repeat:
1374-
next = this_parent->d_subdirs.next;
1373+
dentry = d_first_child(this_parent);
13751374
resume:
1376-
while (next != &this_parent->d_subdirs) {
1377-
struct list_head *tmp = next;
1378-
struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
1379-
next = tmp->next;
1380-
1375+
hlist_for_each_entry_from(dentry, d_sib) {
13811376
if (unlikely(dentry->d_flags & DCACHE_DENTRY_CURSOR))
13821377
continue;
13831378

@@ -1398,7 +1393,7 @@ static void d_walk(struct dentry *parent, void *data,
13981393
continue;
13991394
}
14001395

1401-
if (!list_empty(&dentry->d_subdirs)) {
1396+
if (!hlist_empty(&dentry->d_children)) {
14021397
spin_unlock(&this_parent->d_lock);
14031398
spin_release(&dentry->d_lock.dep_map, _RET_IP_);
14041399
this_parent = dentry;
@@ -1413,24 +1408,23 @@ static void d_walk(struct dentry *parent, void *data,
14131408
rcu_read_lock();
14141409
ascend:
14151410
if (this_parent != parent) {
1416-
struct dentry *child = this_parent;
1417-
this_parent = child->d_parent;
1411+
dentry = this_parent;
1412+
this_parent = dentry->d_parent;
14181413

1419-
spin_unlock(&child->d_lock);
1414+
spin_unlock(&dentry->d_lock);
14201415
spin_lock(&this_parent->d_lock);
14211416

14221417
/* might go back up the wrong parent if we have had a rename. */
14231418
if (need_seqretry(&rename_lock, seq))
14241419
goto rename_retry;
14251420
/* go into the first sibling still alive */
1426-
do {
1427-
next = child->d_child.next;
1428-
if (next == &this_parent->d_subdirs)
1429-
goto ascend;
1430-
child = list_entry(next, struct dentry, d_child);
1431-
} while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED));
1432-
rcu_read_unlock();
1433-
goto resume;
1421+
hlist_for_each_entry_continue(dentry, d_sib) {
1422+
if (likely(!(dentry->d_flags & DCACHE_DENTRY_KILLED))) {
1423+
rcu_read_unlock();
1424+
goto resume;
1425+
}
1426+
}
1427+
goto ascend;
14341428
}
14351429
if (need_seqretry(&rename_lock, seq))
14361430
goto rename_retry;
@@ -1530,7 +1524,7 @@ int d_set_mounted(struct dentry *dentry)
15301524
* Search the dentry child list of the specified parent,
15311525
* and move any unused dentries to the end of the unused
15321526
* list for prune_dcache(). We descend to the next level
1533-
* whenever the d_subdirs list is non-empty and continue
1527+
* whenever the d_children list is non-empty and continue
15341528
* searching.
15351529
*
15361530
* It returns zero iff there are no unused children,
@@ -1657,7 +1651,7 @@ EXPORT_SYMBOL(shrink_dcache_parent);
16571651
static enum d_walk_ret umount_check(void *_data, struct dentry *dentry)
16581652
{
16591653
/* it has busy descendents; complain about those instead */
1660-
if (!list_empty(&dentry->d_subdirs))
1654+
if (!hlist_empty(&dentry->d_children))
16611655
return D_WALK_CONTINUE;
16621656

16631657
/* root with refcount 1 is fine */
@@ -1814,9 +1808,9 @@ static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
18141808
dentry->d_fsdata = NULL;
18151809
INIT_HLIST_BL_NODE(&dentry->d_hash);
18161810
INIT_LIST_HEAD(&dentry->d_lru);
1817-
INIT_LIST_HEAD(&dentry->d_subdirs);
1811+
INIT_HLIST_HEAD(&dentry->d_children);
18181812
INIT_HLIST_NODE(&dentry->d_u.d_alias);
1819-
INIT_LIST_HEAD(&dentry->d_child);
1813+
INIT_HLIST_NODE(&dentry->d_sib);
18201814
d_set_d_op(dentry, dentry->d_sb->s_d_op);
18211815

18221816
if (dentry->d_op && dentry->d_op->d_init) {
@@ -1855,7 +1849,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
18551849
*/
18561850
__dget_dlock(parent);
18571851
dentry->d_parent = parent;
1858-
list_add(&dentry->d_child, &parent->d_subdirs);
1852+
hlist_add_head(&dentry->d_sib, &parent->d_children);
18591853
spin_unlock(&parent->d_lock);
18601854

18611855
return dentry;
@@ -2993,11 +2987,15 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
29932987
} else {
29942988
target->d_parent = old_parent;
29952989
swap_names(dentry, target);
2996-
list_move(&target->d_child, &target->d_parent->d_subdirs);
2990+
if (!hlist_unhashed(&target->d_sib))
2991+
__hlist_del(&target->d_sib);
2992+
hlist_add_head(&target->d_sib, &target->d_parent->d_children);
29972993
__d_rehash(target);
29982994
fsnotify_update_flags(target);
29992995
}
3000-
list_move(&dentry->d_child, &dentry->d_parent->d_subdirs);
2996+
if (!hlist_unhashed(&dentry->d_sib))
2997+
__hlist_del(&dentry->d_sib);
2998+
hlist_add_head(&dentry->d_sib, &dentry->d_parent->d_children);
30012999
__d_rehash(dentry);
30023000
fsnotify_update_flags(dentry);
30033001
fscrypt_handle_d_move(dentry);

0 commit comments

Comments
 (0)