diff options
author | Richard Yao <[email protected]> | 2013-08-07 08:53:45 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2013-08-15 16:19:07 -0700 |
commit | 0f37d0c8bed442dd0d2c1b1dddd68653fa6eec66 (patch) | |
tree | bbd56b426b2b72bed0e3f81afaab2ddf5e613e3e /module/zfs/zpl_file.c | |
parent | 34e143323e359b42bc9d06dd19cc4b1f13091283 (diff) |
Linux 3.11 compat: fops->iterate()
Commit torvalds/linux@2233f31aade393641f0eaed43a71110e629bb900
replaced ->readdir() with ->iterate() in struct file_operations.
All filesystems must now use the new ->iterate method.
To handle this the code was reworked to use the new ->iterate
interface. Care was taken to keep the majority of changes
confined to the ZPL layer which is already Linux specific.
However, minor changes were required to the common zfs_readdir()
function.
Compatibility with older kernels was accomplished by adding
versions of the trivial dir_emit* helper functions. Also the
various *_readdir() functions were reworked in to wrappers
which create a dir_context structure to pass to the new
*_iterate() functions.
Unfortunately, the new dir_emit* functions prevent us from
passing a private pointer to the filldir function. The xattr
directory code leveraged this ability through zfs_readdir()
to generate the list of xattr names. Since we can no longer
use zfs_readdir() a simplified zpl_xattr_readdir() function
was added to perform the same task.
Signed-off-by: Richard Yao <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #1653
Issue #1591
Diffstat (limited to 'module/zfs/zpl_file.c')
-rw-r--r-- | module/zfs/zpl_file.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index 299589193..6598c1779 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -64,21 +64,34 @@ zpl_release(struct inode *ip, struct file *filp) } static int -zpl_readdir(struct file *filp, void *dirent, filldir_t filldir) +zpl_iterate(struct file *filp, struct dir_context *ctx) { struct dentry *dentry = filp->f_path.dentry; cred_t *cr = CRED(); int error; crhold(cr); - error = -zfs_readdir(dentry->d_inode, dirent, filldir, - &filp->f_pos, cr); + error = -zfs_readdir(dentry->d_inode, ctx, cr); crfree(cr); ASSERT3S(error, <=, 0); return (error); } +#if !defined(HAVE_VFS_ITERATE) +static int +zpl_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_iterate(filp, &ctx); + filp->f_pos = ctx.pos; + + return (error); +} +#endif /* HAVE_VFS_ITERATE */ + #if defined(HAVE_FSYNC_WITH_DENTRY) /* * Linux 2.6.x - 2.6.34 API, @@ -506,7 +519,11 @@ const struct file_operations zpl_file_operations = { const struct file_operations zpl_dir_file_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, +#ifdef HAVE_VFS_ITERATE + .iterate = zpl_iterate, +#else .readdir = zpl_readdir, +#endif .fsync = zpl_fsync, .unlocked_ioctl = zpl_ioctl, #ifdef CONFIG_COMPAT |