]> git.proxmox.com Git - mirror_zfs.git/commit
Fix `zfs set atime|relatime=off|on` behavior on inherited datasets
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Tue, 7 May 2019 17:06:30 +0000 (02:06 +0900)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 7 May 2019 17:06:30 +0000 (10:06 -0700)
commit9c53e51616c99592973ebf94b4fd54a5f8c8756d
tree7e1b9d39cebc8fdb7a4b4fc9f3853b79b122c196
parent75346937de39f059722eedd29468ac9b86bea67c
Fix `zfs set atime|relatime=off|on` behavior on inherited datasets

`zfs set atime|relatime=off|on` doesn't disable or enable the property
on read for datasets whose property was inherited from parent, until
a dataset is once unmounted and mounted again.

(The properties start to work properly if a dataset is once unmounted
and mounted again. The difference comes from regular mount process,
e.g. via zpool import, uses mount options based on properties read
from ondisk layout for each dataset, whereas
`zfs set atime|relatime=off|on` just remounts a specified dataset.)

--
 # zpool create p1 <device>
 # zfs create p1/f1
 # zfs set atime=off p1
 # echo test > /p1/f1/test
 # sync
 # zfs list
 NAME    USED  AVAIL     REFER  MOUNTPOINT
 p1      176K  18.9G     25.5K  /p1
 p1/f1    26K  18.9G       26K  /p1/f1
 # zfs get atime
 NAME   PROPERTY  VALUE  SOURCE
 p1     atime     off    local
 p1/f1  atime     off    inherited from p1
 # stat /p1/f1/test | grep Access | tail -1
 Access: 2019-04-26 23:32:33.741205192 +0900
 # cat /p1/f1/test
 test
 # stat /p1/f1/test | grep Access | tail -1
 Access: 2019-04-26 23:32:50.173231861 +0900
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ changed by read(2)
--

The problem is that zfsvfs::z_atime which was probably intended to keep
incore atime state just gets updated by a callback function of "atime"
property change, atime_changed_cb(), and never used for anything else.

Since now that all file read and atime update use a common function
zpl_iter_read_common() -> file_accessed(), and whether to update atime
via ->dirty_inode() is determined by atime_needs_update(),
atime_needs_update() needs to return false once atime is turned off.
It currently continues to return true on `zfs set atime=off`.

Fix atime_changed_cb() by setting or dropping SB_NOATIME in VFS super
block depending on a new atime value, so that atime_needs_update() works
as expected after property change.

The same problem applies to "relatime" except that a self contained
relatime test is needed. This is because relatime_need_update() is based
on a mount option flag MNT_RELATIME, which doesn't exist in datasets
with inherited "relatime" property via `zfs set relatime=...`, hence it
needs its own relatime test zfs_relatime_need_update().

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
Closes #8674
Closes #8675
14 files changed:
include/linux/vfs_compat.h
include/sys/zfs_vfsops.h
include/sys/zfs_znode.h
module/zfs/zfs_vfsops.c
module/zfs/zfs_znode.c
module/zfs/zpl_file.c
tests/runfiles/linux.run
tests/zfs-tests/include/libtest.shlib
tests/zfs-tests/tests/functional/atime/Makefile.am
tests/zfs-tests/tests/functional/atime/atime_common.kshlib
tests/zfs-tests/tests/functional/atime/root_atime_off.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/atime/root_atime_on.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/atime/root_relatime_on.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/atime/setup.ksh