Linux 3.11 compat: fops->iterate()

Commit torvalds/linux@2233f31aad
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 <ryao@cs.stonybrook.edu>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #1653
Issue #1591
This commit is contained in:
Richard Yao
2013-08-07 08:53:45 -04:00
committed by Brian Behlendorf
parent 34e143323e
commit 0f37d0c8be
8 changed files with 262 additions and 126 deletions
+6 -6
View File
@@ -1997,8 +1997,7 @@ EXPORT_SYMBOL(zfs_rmdir);
*/
/* ARGSUSED */
int
zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir,
loff_t *pos, cred_t *cr)
zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
{
znode_t *zp = ITOZ(ip);
zfs_sb_t *zsb = ITOZSB(ip);
@@ -2010,6 +2009,7 @@ zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir,
uint8_t prefetch;
int done = 0;
uint64_t parent;
loff_t *pos = &(ctx->pos);
ZFS_ENTER(zsb);
ZFS_VERIFY_ZP(zp);
@@ -2098,11 +2098,11 @@ zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir,
objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
}
done = filldir(dirent, zap.za_name, strlen(zap.za_name),
*pos, objnum, ZFS_DIRENT_TYPE(zap.za_first_integer));
if (done) {
done = !dir_emit(ctx, zap.za_name, strlen(zap.za_name),
objnum, ZFS_DIRENT_TYPE(zap.za_first_integer));
if (done)
break;
}
/* Prefetch znode */
if (prefetch) {