bcachefs: readdir fixes
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 29 Apr 2025 18:30:01 +0000 (14:30 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 30 Apr 2025 15:49:34 +0000 (11:49 -0400)
- Don't call bch2_trans_relock() after dir_emit(); taking a transaction
  restart here will cause us to emit the same dirent to userspace twice

- Fix incorrect checking of the return value on dir_emit(): "true" means
  success, keep going, but bch2_dir_emit() needs to return true when
  we're finished iterating.

https://github.com/koverstreet/bcachefs/issues/867

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/dirent.c

index 92ee59d9e00eced56f4ff53b57579c97c5c91873..8a680e52c1ed12c06f2692c4c220b1f21312cf18 100644 (file)
@@ -685,7 +685,7 @@ static int bch2_dir_emit(struct dir_context *ctx, struct bkey_s_c_dirent d, subv
                      vfs_d_type(d.v->d_type));
        if (ret)
                ctx->pos = d.k->p.offset + 1;
-       return ret;
+       return !ret;
 }
 
 int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
@@ -710,7 +710,7 @@ int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
                        if (ret2 > 0)
                                continue;
 
-                       ret2 ?: drop_locks_do(trans, bch2_dir_emit(ctx, dirent, target));
+                       ret2 ?: (bch2_trans_unlock(trans), bch2_dir_emit(ctx, dirent, target));
                })));
 
        bch2_bkey_buf_exit(&sk, c);