]> granicus.if.org Git - zfs/commitdiff
Use file_dentry and file_inode wrappers
authorChen Haiquan <oc@yunify.com>
Thu, 4 Aug 2016 15:57:35 +0000 (23:57 +0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 11 Aug 2016 19:06:37 +0000 (12:06 -0700)
Fix bugs due to kernel change in torvalds/linux@4bacc9c9234c ("overlayfs:
Make f_path always point to the overlay and f_inode to the underlay").

This problem crashes system when use zfs as a layer of overlayfs.

Signed-off-by: Chen Haiquan <oc@yunify.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4914
Closes #4935

config/kernel-file-dentry.m4 [new file with mode: 0644]
config/kernel.m4
include/linux/vfs_compat.h
include/sys/zpl.h
module/zfs/zpl_ctldir.c
module/zfs/zpl_file.c

diff --git a/config/kernel-file-dentry.m4 b/config/kernel-file-dentry.m4
new file mode 100644 (file)
index 0000000..daf742e
--- /dev/null
@@ -0,0 +1,20 @@
+dnl #
+dnl # 4.1 API change
+dnl # struct access file->f_path.dentry was replaced by accessor function
+dnl # since fix torvalds/linux@4bacc9c9234c ("overlayfs: Make f_path always
+dnl # point to the overlay and f_inode to the underlay").
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FILE_DENTRY], [
+       AC_MSG_CHECKING([whether file_dentry() is available])
+       ZFS_LINUX_TRY_COMPILE([
+               #include <linux/fs.h>
+       ],[
+               struct file *f = NULL;
+               file_dentry(f);
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_FILE_DENTRY, 1, [file_dentry() is available])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+])
index 6cdad2d1adca9a4b6b85b75efcdb16d151abe7cb..d8964a7e1050488211034a20af71fb5b06f6f1bc 100644 (file)
@@ -56,6 +56,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
        ZFS_AC_KERNE_GET_ACL_HANDLE_CACHE
        ZFS_AC_KERNEL_SHOW_OPTIONS
        ZFS_AC_KERNEL_FILE_INODE
+       ZFS_AC_KERNEL_FILE_DENTRY
        ZFS_AC_KERNEL_FSYNC
        ZFS_AC_KERNEL_EVICT_INODE
        ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS
index 820647d395954c373a0383bacbd084ae2c584243..8a64cabef1eb143721ffb5c734eba30ce2e8391c 100644 (file)
@@ -352,6 +352,18 @@ static inline struct inode *file_inode(const struct file *f)
 }
 #endif /* HAVE_FILE_INODE */
 
+/*
+ * 4.1 API change
+ * struct access file->f_path.dentry was replaced by accessor function
+ * file_dentry(f)
+ */
+#ifndef HAVE_FILE_DENTRY
+static inline struct dentry *file_dentry(const struct file *f)
+{
+       return (f->f_path.dentry);
+}
+#endif /* HAVE_FILE_DENTRY */
+
 #ifdef HAVE_KUID_HELPERS
 static inline uid_t zfs_uid_read_impl(struct inode *ip)
 {
index c6085481bb32c62a953f023944b92d3f22a9d37b..386cf6d09af31c4ec6019b0c574e267911d22bde 100644 (file)
@@ -156,14 +156,14 @@ static inline bool
 dir_emit_dot(struct file *file, struct dir_context *ctx)
 {
        return (ctx->actor(ctx->dirent, ".", 1, ctx->pos,
-           file->f_path.dentry->d_inode->i_ino, DT_DIR) == 0);
+           file_inode(file)->i_ino, DT_DIR) == 0);
 }
 
 static inline bool
 dir_emit_dotdot(struct file *file, struct dir_context *ctx)
 {
        return (ctx->actor(ctx->dirent, "..", 2, ctx->pos,
-           parent_ino(file->f_path.dentry), DT_DIR) == 0);
+           parent_ino(file_dentry(file)), DT_DIR) == 0);
 }
 
 static inline bool
index 069834eae662eca2e3976ea961f75b82ebe2ceee..7c4fcea3e43c4efa485babde8720ebdf03ef03dc 100644 (file)
@@ -52,7 +52,7 @@ zpl_common_open(struct inode *ip, struct file *filp)
 static int
 zpl_root_iterate(struct file *filp, struct dir_context *ctx)
 {
-       zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
+       zfs_sb_t *zsb = ITOZSB(file_inode(filp));
        int error = 0;
 
        ZFS_ENTER(zsb);
@@ -249,7 +249,7 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
 static int
 zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
 {
-       zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
+       zfs_sb_t *zsb = ITOZSB(file_inode(filp));
        fstrans_cookie_t cookie;
        char snapname[MAXNAMELEN];
        boolean_t case_conflict;
@@ -447,7 +447,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
 {
        fstrans_cookie_t cookie;
        cred_t *cr = CRED();
-       zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
+       zfs_sb_t *zsb = ITOZSB(file_inode(filp));
        znode_t *dzp;
        int error = 0;
 
index 4481237bca5027be5326df95da24b45dc0790ee2..c8ac7f8a32f3151d02cfcb48d53413ea3a6d1395 100644 (file)
@@ -78,14 +78,13 @@ zpl_release(struct inode *ip, struct file *filp)
 static int
 zpl_iterate(struct file *filp, struct dir_context *ctx)
 {
-       struct dentry *dentry = filp->f_path.dentry;
        cred_t *cr = CRED();
        int error;
        fstrans_cookie_t cookie;
 
        crhold(cr);
        cookie = spl_fstrans_mark();
-       error = -zfs_readdir(dentry->d_inode, ctx, cr);
+       error = -zfs_readdir(file_inode(filp), ctx, cr);
        spl_fstrans_unmark(cookie);
        crfree(cr);
        ASSERT3S(error, <=, 0);
@@ -135,7 +134,7 @@ static int
 zpl_aio_fsync(struct kiocb *kiocb, int datasync)
 {
        struct file *filp = kiocb->ki_filp;
-       return (zpl_fsync(filp, filp->f_path.dentry, datasync));
+       return (zpl_fsync(filp, file_dentry(filp), datasync));
 }
 #elif defined(HAVE_FSYNC_WITHOUT_DENTRY)
 /*
@@ -688,7 +687,7 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
 static long
 zpl_fallocate(struct file *filp, int mode, loff_t offset, loff_t len)
 {
-       return zpl_fallocate_common(filp->f_path.dentry->d_inode,
+       return zpl_fallocate_common(file_inode(filp),
            mode, offset, len);
 }
 #endif /* HAVE_FILE_FALLOCATE */