[PATCH v1 07/12] libfs: allow scan_positives() to be called without a cursor.

NeilBrown <[email protected]> Mon, 3 Aug 2026 11:21:16 +1000
Newsgroups org.kernel.vger.linux-nfs,org.kernel.vger.autofs,org.kernel.vger.ceph-devel,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: NeilBrown <[email protected]>

Rather than taking parent from cursor, pass it in explicitly.  And only
cond_sched() if a cursor is available.  This will allow scan_positives()
to be used in place of find_positive_dentry().

Signed-off-by: NeilBrown <[email protected]>
---
 fs/libfs.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/fs/libfs.c b/fs/libfs.c
index c2369ea9196f..260f56863742 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -104,11 +104,12 @@ EXPORT_SYMBOL(dcache_dir_close);
  * found, dentry is grabbed and returned to caller.
  * If no such element exists, NULL is returned.
  */
-static struct dentry *scan_positives(struct dentry *cursor,
+static struct dentry *scan_positives(struct dentry *dentry,
+				     struct dentry *cursor,
 				     struct dentry *last,
 				     loff_t count)
 {
-	struct dentry *dentry = cursor->d_parent, *found = NULL;
+	struct dentry *found = NULL;
 	struct dentry *d = last;
 
 	d_for_each_positive_child_continue(d, dentry) {
@@ -121,7 +122,7 @@ static struct dentry *scan_positives(struct dentry *cursor,
 				break;
 			count = 1;
 		}
-		if (need_resched()) {
+		if (cursor && need_resched()) {
 			if (!hlist_unhashed(&cursor->d_sib))
 				__hlist_del(&cursor->d_sib);
 			hlist_add_behind(&cursor->d_sib, &d->d_sib);
@@ -156,7 +157,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
 		inode_lock_shared(dentry->d_inode);
 
 		if (offset > 2)
-			to = scan_positives(cursor, NULL, offset - 2);
+			to = scan_positives(dentry, cursor, NULL, offset - 2);
 		spin_lock(&dentry->d_lock);
 		hlist_del_init(&cursor->d_sib);
 		if (to)
@@ -190,7 +191,7 @@ int dcache_readdir(struct file *file, struct dir_context *ctx)
 	if (ctx->pos > 2)
 		next = dget(cursor);
 
-	while ((next = scan_positives(cursor, next, 1)) != NULL) {
+	while ((next = scan_positives(dentry, cursor, next, 1)) != NULL) {
 		if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
 			      d_inode(next)->i_ino,
 			      fs_umode_to_dtype(d_inode(next)->i_mode)))
-- 
2.50.0.107.gf914562f5916.dirty