diff --git a/config/kernel-current-time.m4 b/config/kernel-current-time.m4 new file mode 100644 index 0000000000..2ede9ff38c --- /dev/null +++ b/config/kernel-current-time.m4 @@ -0,0 +1,19 @@ +dnl # +dnl # 4.9, current_time() added +dnl # +AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME], + [AC_MSG_CHECKING([whether current_time() exists]) + ZFS_LINUX_TRY_COMPILE_SYMBOL([ + #include + ], [ + struct inode ip; + struct timespec now __attribute__ ((unused)); + + now = current_time(&ip); + ], [current_time], [fs/inode.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CURRENT_TIME, 1, [current_time() exists]) + ], [ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 493f01aeae..4a8eeab2ae 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -110,6 +110,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_GENERIC_IO_ACCT ZFS_AC_KERNEL_RENAME_WANTS_FLAGS ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR + ZFS_AC_KERNEL_CURRENT_TIME AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h index f62c6c8501..44634c3367 100644 --- a/include/linux/vfs_compat.h +++ b/include/linux/vfs_compat.h @@ -479,5 +479,16 @@ func(const struct path *path, struct kstat *stat, u32 request_mask, \ #error #endif +/* + * 4.9 API change + * Preferred interface to get the current FS time. + */ +#if !defined(HAVE_CURRENT_TIME) +static inline struct timespec +current_time(struct inode *ip) +{ + return (timespec_trunc(current_kernel_time(), ip->i_sb->s_time_gran)); +} +#endif #endif /* _ZFS_VFS_H */ diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c index 2767b235d5..ebf60408da 100644 --- a/module/zfs/zfs_ctldir.c +++ b/module/zfs/zfs_ctldir.c @@ -455,7 +455,7 @@ static struct inode * zfsctl_inode_alloc(zfs_sb_t *zsb, uint64_t id, const struct file_operations *fops, const struct inode_operations *ops) { - struct timespec now = current_fs_time(zsb->z_sb); + struct timespec now; struct inode *ip; znode_t *zp; @@ -463,6 +463,7 @@ zfsctl_inode_alloc(zfs_sb_t *zsb, uint64_t id, if (ip == NULL) return (NULL); + now = current_time(ip); zp = ITOZ(ip); ASSERT3P(zp->z_dirlocks, ==, NULL); ASSERT3P(zp->z_acl_cached, ==, NULL); diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c index d23edf3adf..50fb06bdef 100644 --- a/module/zfs/zpl_ctldir.c +++ b/module/zfs/zpl_ctldir.c @@ -103,8 +103,10 @@ static int zpl_root_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { - generic_fillattr(path->dentry->d_inode, stat); - stat->atime = CURRENT_TIME; + struct inode *ip = path->dentry->d_inode; + + generic_fillattr(ip, stat); + stat->atime = current_time(ip); return (0); } @@ -377,13 +379,14 @@ static int zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { + struct inode *ip = path->dentry->d_inode; zfs_sb_t *zsb = ITOZSB(path->dentry->d_inode); ZFS_ENTER(zsb); generic_fillattr(path->dentry->d_inode, stat); stat->nlink = stat->size = 2; stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zsb->z_os); - stat->atime = CURRENT_TIME; + stat->atime = current_time(ip); ZFS_EXIT(zsb); return (0); @@ -521,7 +524,7 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat, if (zsb->z_shares_dir == 0) { generic_fillattr(path->dentry->d_inode, stat); stat->nlink = stat->size = 2; - stat->atime = CURRENT_TIME; + stat->atime = current_time(ip); ZFS_EXIT(zsb); return (0); } diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index 1a2e2edffa..18401fe308 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -557,7 +557,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) return (-EMLINK); crhold(cr); - ip->i_ctime = CURRENT_TIME_SEC; + ip->i_ctime = current_time(ip); igrab(ip); /* Use ihold() if available */ cookie = spl_fstrans_mark(); diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c index 58962076d6..b74b53a0e1 100644 --- a/module/zfs/zpl_xattr.c +++ b/module/zfs/zpl_xattr.c @@ -938,7 +938,6 @@ xattr_handler_t zpl_xattr_security_handler = { int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type) { - struct super_block *sb = ITOZSB(ip)->z_sb; char *name, *value = NULL; int error = 0; size_t size = 0; @@ -964,7 +963,7 @@ zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type) */ if (ip->i_mode != mode) { ip->i_mode = mode; - ip->i_ctime = current_fs_time(sb); + ip->i_ctime = current_time(ip); zfs_mark_inode_dirty(ip); } @@ -1130,7 +1129,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir) if (!acl) { ip->i_mode &= ~current_umask(); - ip->i_ctime = current_fs_time(ITOZSB(ip)->z_sb); + ip->i_ctime = current_time(ip); zfs_mark_inode_dirty(ip); return (0); }