mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
RHEL 7.5 compat: FMODE_KABI_ITERATE
As of RHEL 7.5 the mainline fops.iterate() method was added to the file_operations structure and is correctly detected by the configure script. Normally this is what we want, but in order to maintain KABI compatibility the RHEL change additionally does the following: * Requires that callers intending to use this extended interface set the FMODE_KABI_ITERATE flag on the file structure when opening the directory. * Adds the fops.iterate() method to the end of the structure, without removing fops.readdir(). This change updates the configure check to ignore the RHEL 7.5+ variant of fops.iterate() when detected. Instead fallback to the fops.readdir() interface which will be available. Finally, add the 'zpl_' prefix to the directory context wrappers to avoid colliding with the kernel provided symbols when both the fops.iterate() and fops.readdir() are provided by the kernel. Reviewed-by: Olaf Faaland <faaland1@llnl.gov> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #7460 Closes #7463
This commit is contained in:
committed by
Tony Hutter
parent
245be00597
commit
0ee129199f
@@ -2223,7 +2223,7 @@ out:
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
|
||||
zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
|
||||
{
|
||||
znode_t *zp = ITOZ(ip);
|
||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||
@@ -2328,7 +2328,7 @@ zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
|
||||
type = ZFS_DIRENT_TYPE(zap.za_first_integer);
|
||||
}
|
||||
|
||||
done = !dir_emit(ctx, zap.za_name, strlen(zap.za_name),
|
||||
done = !zpl_dir_emit(ctx, zap.za_name, strlen(zap.za_name),
|
||||
objnum, type);
|
||||
if (done)
|
||||
break;
|
||||
|
||||
+20
-17
@@ -50,27 +50,27 @@ zpl_common_open(struct inode *ip, struct file *filp)
|
||||
* Get root directory contents.
|
||||
*/
|
||||
static int
|
||||
zpl_root_iterate(struct file *filp, struct dir_context *ctx)
|
||||
zpl_root_iterate(struct file *filp, zpl_dir_context_t *ctx)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
|
||||
int error = 0;
|
||||
|
||||
ZFS_ENTER(zfsvfs);
|
||||
|
||||
if (!dir_emit_dots(filp, ctx))
|
||||
if (!zpl_dir_emit_dots(filp, ctx))
|
||||
goto out;
|
||||
|
||||
if (ctx->pos == 2) {
|
||||
if (!dir_emit(ctx, ZFS_SNAPDIR_NAME, strlen(ZFS_SNAPDIR_NAME),
|
||||
ZFSCTL_INO_SNAPDIR, DT_DIR))
|
||||
if (!zpl_dir_emit(ctx, ZFS_SNAPDIR_NAME,
|
||||
strlen(ZFS_SNAPDIR_NAME), ZFSCTL_INO_SNAPDIR, DT_DIR))
|
||||
goto out;
|
||||
|
||||
ctx->pos++;
|
||||
}
|
||||
|
||||
if (ctx->pos == 3) {
|
||||
if (!dir_emit(ctx, ZFS_SHAREDIR_NAME, strlen(ZFS_SHAREDIR_NAME),
|
||||
ZFSCTL_INO_SHARES, DT_DIR))
|
||||
if (!zpl_dir_emit(ctx, ZFS_SHAREDIR_NAME,
|
||||
strlen(ZFS_SHAREDIR_NAME), ZFSCTL_INO_SHARES, DT_DIR))
|
||||
goto out;
|
||||
|
||||
ctx->pos++;
|
||||
@@ -85,7 +85,8 @@ out:
|
||||
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);
|
||||
zpl_dir_context_t ctx =
|
||||
ZPL_DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
|
||||
int error;
|
||||
|
||||
error = zpl_root_iterate(filp, &ctx);
|
||||
@@ -93,7 +94,7 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_VFS_ITERATE */
|
||||
#endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
|
||||
|
||||
/*
|
||||
* Get root directory attributes.
|
||||
@@ -248,7 +249,7 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
|
||||
}
|
||||
|
||||
static int
|
||||
zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
||||
zpl_snapdir_iterate(struct file *filp, zpl_dir_context_t *ctx)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
|
||||
fstrans_cookie_t cookie;
|
||||
@@ -260,7 +261,7 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
||||
ZFS_ENTER(zfsvfs);
|
||||
cookie = spl_fstrans_mark();
|
||||
|
||||
if (!dir_emit_dots(filp, ctx))
|
||||
if (!zpl_dir_emit_dots(filp, ctx))
|
||||
goto out;
|
||||
|
||||
pos = ctx->pos;
|
||||
@@ -272,7 +273,7 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
if (!dir_emit(ctx, snapname, strlen(snapname),
|
||||
if (!zpl_dir_emit(ctx, snapname, strlen(snapname),
|
||||
ZFSCTL_INO_SHARES - id, DT_DIR))
|
||||
goto out;
|
||||
|
||||
@@ -292,7 +293,8 @@ out:
|
||||
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);
|
||||
zpl_dir_context_t ctx =
|
||||
ZPL_DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
|
||||
int error;
|
||||
|
||||
error = zpl_snapdir_iterate(filp, &ctx);
|
||||
@@ -300,7 +302,7 @@ zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_VFS_ITERATE */
|
||||
#endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
|
||||
|
||||
static int
|
||||
zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
|
||||
@@ -463,7 +465,7 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
|
||||
}
|
||||
|
||||
static int
|
||||
zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
|
||||
zpl_shares_iterate(struct file *filp, zpl_dir_context_t *ctx)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
cred_t *cr = CRED();
|
||||
@@ -475,7 +477,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
|
||||
cookie = spl_fstrans_mark();
|
||||
|
||||
if (zfsvfs->z_shares_dir == 0) {
|
||||
dir_emit_dots(filp, ctx);
|
||||
zpl_dir_emit_dots(filp, ctx);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -500,7 +502,8 @@ out:
|
||||
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);
|
||||
zpl_dir_context_t ctx =
|
||||
ZPL_DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
|
||||
int error;
|
||||
|
||||
error = zpl_shares_iterate(filp, &ctx);
|
||||
@@ -508,7 +511,7 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_VFS_ITERATE */
|
||||
#endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
|
||||
@@ -76,7 +76,7 @@ zpl_release(struct inode *ip, struct file *filp)
|
||||
}
|
||||
|
||||
static int
|
||||
zpl_iterate(struct file *filp, struct dir_context *ctx)
|
||||
zpl_iterate(struct file *filp, zpl_dir_context_t *ctx)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
int error;
|
||||
@@ -96,7 +96,8 @@ zpl_iterate(struct file *filp, struct dir_context *ctx)
|
||||
static int
|
||||
zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
{
|
||||
struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
|
||||
zpl_dir_context_t ctx =
|
||||
ZPL_DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
|
||||
int error;
|
||||
|
||||
error = zpl_iterate(filp, &ctx);
|
||||
@@ -104,7 +105,7 @@ zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_VFS_ITERATE */
|
||||
#endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
|
||||
|
||||
#if defined(HAVE_FSYNC_WITH_DENTRY)
|
||||
/*
|
||||
@@ -885,7 +886,7 @@ 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_SHARED
|
||||
#if defined(HAVE_VFS_ITERATE_SHARED)
|
||||
.iterate_shared = zpl_iterate,
|
||||
#elif defined(HAVE_VFS_ITERATE)
|
||||
.iterate = zpl_iterate,
|
||||
|
||||
Reference in New Issue
Block a user