summaryrefslogtreecommitdiffstats
path: root/module/zfs/zpl_file.c
diff options
context:
space:
mode:
authorRichard Yao <[email protected]>2013-08-07 08:53:45 -0400
committerBrian Behlendorf <[email protected]>2013-08-15 16:19:07 -0700
commit0f37d0c8bed442dd0d2c1b1dddd68653fa6eec66 (patch)
treebbd56b426b2b72bed0e3f81afaab2ddf5e613e3e /module/zfs/zpl_file.c
parent34e143323e359b42bc9d06dd19cc4b1f13091283 (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.c23
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