X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzpl_ctldir.c;h=1bb646fdf728ac1a0e3d041dbf1d97372c143c89;hb=0f37d0c8bed442dd0d2c1b1dddd68653fa6eec66;hp=08970170760c7f895e835e4009ed0fb721b6c9f7;hpb=34e143323e359b42bc9d06dd19cc4b1f13091283;p=zfs.git diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c index 0897017..1bb646f 100644 --- a/module/zfs/zpl_ctldir.c +++ b/module/zfs/zpl_ctldir.c @@ -46,79 +46,34 @@ zpl_common_open(struct inode *ip, struct file *filp) return generic_file_open(ip, filp); } -static int -zpl_common_readdir(struct file *filp, void *dirent, filldir_t filldir) -{ - struct dentry *dentry = filp->f_path.dentry; - struct inode *ip = dentry->d_inode; - int error = 0; - - switch (filp->f_pos) { - case 0: - error = filldir(dirent, ".", 1, 0, ip->i_ino, DT_DIR); - if (error) - break; - - filp->f_pos++; - /* fall-thru */ - case 1: - error = filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR); - if (error) - break; - - filp->f_pos++; - /* fall-thru */ - default: - break; - } - - return (error); -} - /* * Get root directory contents. */ static int -zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir) +zpl_root_iterate(struct file *filp, struct dir_context *ctx) { - struct dentry *dentry = filp->f_path.dentry; - struct inode *ip = dentry->d_inode; - zfs_sb_t *zsb = ITOZSB(ip); + zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode); int error = 0; ZFS_ENTER(zsb); - switch (filp->f_pos) { - case 0: - error = filldir(dirent, ".", 1, 0, ip->i_ino, DT_DIR); - if (error) - goto out; + if (!dir_emit_dots(filp, ctx)) + goto out; - filp->f_pos++; - /* fall-thru */ - case 1: - error = filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR); - if (error) + if (ctx->pos == 2) { + if (!dir_emit(ctx, ZFS_SNAPDIR_NAME, strlen(ZFS_SNAPDIR_NAME), + ZFSCTL_INO_SNAPDIR, DT_DIR)) goto out; - filp->f_pos++; - /* fall-thru */ - case 2: - error = filldir(dirent, ZFS_SNAPDIR_NAME, - strlen(ZFS_SNAPDIR_NAME), 2, ZFSCTL_INO_SNAPDIR, DT_DIR); - if (error) - goto out; + ctx->pos++; + } - filp->f_pos++; - /* fall-thru */ - case 3: - error = filldir(dirent, ZFS_SHAREDIR_NAME, - strlen(ZFS_SHAREDIR_NAME), 3, ZFSCTL_INO_SHARES, DT_DIR); - if (error) + if (ctx->pos == 3) { + if (!dir_emit(ctx, ZFS_SHAREDIR_NAME, strlen(ZFS_SHAREDIR_NAME), + ZFSCTL_INO_SHARES, DT_DIR)) goto out; - filp->f_pos++; - /* fall-thru */ + ctx->pos++; } out: ZFS_EXIT(zsb); @@ -126,6 +81,20 @@ out: return (error); } +#if !defined(HAVE_VFS_ITERATE) +static int +zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos); + int error; + + error = zpl_root_iterate(filp, &ctx); + filp->f_pos = ctx.pos; + + return (error); +} +#endif /* HAVE_VFS_ITERATE */ + /* * Get root directory attributes. */ @@ -175,7 +144,11 @@ const struct file_operations zpl_fops_root = { .open = zpl_common_open, .llseek = generic_file_llseek, .read = generic_read_dir, +#ifdef HAVE_VFS_ITERATE + .iterate = zpl_root_iterate, +#else .readdir = zpl_root_readdir, +#endif }; const struct inode_operations zpl_ops_root = { @@ -273,50 +246,29 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry, return d_splice_alias(ip, dentry); } -/* ARGSUSED */ static int -zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir) +zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx) { - struct dentry *dentry = filp->f_path.dentry; - struct inode *dip = dentry->d_inode; - zfs_sb_t *zsb = ITOZSB(dip); + zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode); char snapname[MAXNAMELEN]; - uint64_t id, cookie; boolean_t case_conflict; + uint64_t id; int error = 0; ZFS_ENTER(zsb); - cookie = filp->f_pos; - switch (filp->f_pos) { - case 0: - error = filldir(dirent, ".", 1, 0, dip->i_ino, DT_DIR); - if (error) - goto out; + if (!dir_emit_dots(filp, ctx)) + goto out; - filp->f_pos++; - /* fall-thru */ - case 1: - error = filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR); + while (error == 0) { + error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN, + snapname, &id, &(ctx->pos), &case_conflict); if (error) goto out; - filp->f_pos++; - /* fall-thru */ - default: - while (error == 0) { - error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN, - snapname, &id, &cookie, &case_conflict); - if (error) - goto out; - - error = filldir(dirent, snapname, strlen(snapname), - filp->f_pos, ZFSCTL_INO_SHARES - id, DT_DIR); - if (error) - goto out; - - filp->f_pos = cookie; - } + if (!dir_emit(ctx, snapname, strlen(snapname), + ZFSCTL_INO_SHARES - id, DT_DIR)) + goto out; } out: ZFS_EXIT(zsb); @@ -327,6 +279,20 @@ out: return (error); } +#if !defined(HAVE_VFS_ITERATE) +static int +zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos); + int error; + + error = zpl_snapdir_iterate(filp, &ctx); + filp->f_pos = ctx.pos; + + return (error); +} +#endif /* HAVE_VFS_ITERATE */ + int zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry) @@ -413,7 +379,12 @@ const struct file_operations zpl_fops_snapdir = { .open = zpl_common_open, .llseek = generic_file_llseek, .read = generic_read_dir, +#ifdef HAVE_VFS_ITERATE + .iterate = zpl_snapdir_iterate, +#else .readdir = zpl_snapdir_readdir, +#endif + }; /* @@ -458,42 +429,51 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry, return d_splice_alias(ip, dentry); } -/* ARGSUSED */ static int -zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir) +zpl_shares_iterate(struct file *filp, struct dir_context *ctx) { cred_t *cr = CRED(); - struct dentry *dentry = filp->f_path.dentry; - struct inode *ip = dentry->d_inode; - zfs_sb_t *zsb = ITOZSB(ip); + zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode); znode_t *dzp; - int error; + int error = 0; ZFS_ENTER(zsb); if (zsb->z_shares_dir == 0) { - error = zpl_common_readdir(filp, dirent, filldir); - ZFS_EXIT(zsb); - return (error); + dir_emit_dots(filp, ctx); + goto out; } error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp); - if (error) { - ZFS_EXIT(zsb); - return (error); - } + if (error) + goto out; crhold(cr); - error = -zfs_readdir(ZTOI(dzp), dirent, filldir, &filp->f_pos, cr); + error = -zfs_readdir(ZTOI(dzp), ctx, cr); crfree(cr); iput(ZTOI(dzp)); +out: ZFS_EXIT(zsb); ASSERT3S(error, <=, 0); return (error); } +#if !defined(HAVE_VFS_ITERATE) +static int +zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos); + int error; + + error = zpl_shares_iterate(filp, &ctx); + filp->f_pos = ctx.pos; + + return (error); +} +#endif /* HAVE_VFS_ITERATE */ + /* ARGSUSED */ static int zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry, @@ -532,7 +512,12 @@ const struct file_operations zpl_fops_shares = { .open = zpl_common_open, .llseek = generic_file_llseek, .read = generic_read_dir, +#ifdef HAVE_VFS_ITERATE + .iterate = zpl_shares_iterate, +#else .readdir = zpl_shares_readdir, +#endif + }; /*