Skip to content

Commit

Permalink
Fix readdir for .zfs/snapshot directory
Browse files Browse the repository at this point in the history
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 openzfs/zfs@0f37d0c.

Signed-off-by: Andrey Vesnovaty <andrey.vesnovaty@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes openzfs#2930
  • Loading branch information
andrey-ve authored and DeHackEd committed Apr 4, 2015
1 parent 44674ee commit 9ce4c7f
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions module/zfs/zpl_ctldir.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,25 +252,28 @@ 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);

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;

if (!dir_emit(ctx, snapname, strlen(snapname),
ZFSCTL_INO_SHARES - id, DT_DIR))
goto out;

ctx->pos = cookie;
}
out:
ZFS_EXIT(zsb);
Expand Down

0 comments on commit 9ce4c7f

Please sign in to comment.