Fix readdir for .zfs/snapshot directory
dmu_snapshot_list_next stores the index of the next snapshot entry to the offp argument, which zpl_snapdir_iterate then uses for the dir_emit. This result in an off-by-one error. Therefore a temporary variable should be used. This was a regression introduced in commit zfsonlinux/zfs@0f37d0c. Signed-off-by: Andrey Vesnovaty <andrey.vesnovaty@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2930
This commit is contained in:
parent
3941503c0a
commit
5f15fa2216
|
@ -252,7 +252,7 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
|||
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
|
||||
char snapname[MAXNAMELEN];
|
||||
boolean_t case_conflict;
|
||||
uint64_t id;
|
||||
uint64_t id, cookie;
|
||||
int error = 0;
|
||||
|
||||
ZFS_ENTER(zsb);
|
||||
|
@ -260,10 +260,11 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
|||
if (!dir_emit_dots(filp, ctx))
|
||||
goto out;
|
||||
|
||||
cookie = ctx->pos;
|
||||
while (error == 0) {
|
||||
dsl_pool_config_enter(dmu_objset_pool(zsb->z_os), FTAG);
|
||||
error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
|
||||
snapname, &id, &ctx->pos, &case_conflict);
|
||||
snapname, &id, &cookie, &case_conflict);
|
||||
dsl_pool_config_exit(dmu_objset_pool(zsb->z_os), FTAG);
|
||||
if (error)
|
||||
goto out;
|
||||
|
@ -271,6 +272,8 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
|||
if (!dir_emit(ctx, snapname, strlen(snapname),
|
||||
ZFSCTL_INO_SHARES - id, DT_DIR))
|
||||
goto out;
|
||||
|
||||
ctx->pos = cookie;
|
||||
}
|
||||
out:
|
||||
ZFS_EXIT(zsb);
|
||||
|
|
Loading…
Reference in New Issue