From: Aurelien Degremont Date: Thu, 7 Apr 2022 12:58:00 +0000 (+0000) Subject: LU-15728 llite: fix relatime support X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=8a51a653af049701aef101c869e456f28d767e72;p=fs%2Flustre-release.git LU-15728 llite: fix relatime support relatime behavior is properly managed by VFS, however Lustre also stores acmtime on OST objects and atime updates for OST objects should honor relatime behavior. This patch updates 'ci_noatime' feature which was introduced to properly honor noatime option for OST objects, to also support 'relatime'. file_is_noatime() code already comes from upstream touch_atime(). Add missing parts from touch_atime() to also support relatime. It also forces atime to disk on MDD if ondisk atime is older than ondisk mtime/ctime to match relatime (even if relatime is not enabled) Add a new test for relatime feature. Lustre-change: https://review.whamcloud.com/47017 Lustre-commit: c10c6eeb37dd553166367b96369dca25183ace3b Signed-off-by: Aurelien Degremont Change-Id: I7a26f39841300a60c015944f9e544115b4446ead Reviewed-by: Shaun Tancheff Reviewed-by: Yang Sheng Reviewed-by: Andreas Dilger LU-15728 mdd: fix sanity-56oc failure sanity 56oc starts failing since relatime patch was landed. 'relatime' patch introduced an atime behavior change. It was forcing atime uptime to disk on MDD if ondisk atime is older than ondisk mtime/ctime to match relatime (even if relatime was not enabled). This was an optimization, trying to have a slightly better atime value cheaply. This is unfortunately causing regression in sanity-56oc. Let's remove it for now until we understand that better. Lustre-change: https://review.whamcloud.com/50009 Lustre-commit: 8beeec77c3b426a01e1f10ca51149c7ca7e01b7e Fixes: c10c6ee ("LU-15728 llite: fix relatime support") Change-Id: Ieed4d4c7523c26cfc5bc230986d96b2acf152dee Signed-off-by: Aurelien Degremont Reviewed-by: Alex Zhuravlev Reviewed-by: Andreas Dilger Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/51858 Tested-by: jenkins Tested-by: Maloo --- diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 29ab6b3..0d0794e 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1578,12 +1578,47 @@ void ll_io_set_mirror(struct cl_io *io, const struct file *file) file->f_path.dentry->d_name.name, io->ci_designated_mirror); } +/* + * This is relatime_need_update() from Linux 5.17, which is not exported. + */ +static int relatime_need_update(struct vfsmount *mnt, struct inode *inode, + struct timespec64 now) +{ + + if (!(mnt->mnt_flags & MNT_RELATIME)) + return 1; + /* + * Is mtime younger than atime? If yes, update atime: + */ + if (timespec64_compare(&inode->i_mtime, &inode->i_atime) >= 0) + return 1; + /* + * Is ctime younger than atime? If yes, update atime: + */ + if (timespec64_compare(&inode->i_ctime, &inode->i_atime) >= 0) + return 1; + + /* + * Is the previous atime value older than a day? If yes, + * update atime: + */ + if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60) + return 1; + /* + * Good, we can skip the atime update: + */ + return 0; +} + +/* + * Very similar to kernel function: !__atime_needs_update() + */ static bool file_is_noatime(const struct file *file) { - const struct vfsmount *mnt = file->f_path.mnt; - const struct inode *inode = file_inode((struct file *)file); + struct vfsmount *mnt = file->f_path.mnt; + struct inode *inode = file_inode((struct file *)file); + struct timespec64 now; - /* Adapted from file_accessed() and touch_atime().*/ if (file->f_flags & O_NOATIME) return true; @@ -1602,6 +1637,11 @@ static bool file_is_noatime(const struct file *file) if ((inode->i_sb->s_flags & SB_NODIRATIME) && S_ISDIR(inode->i_mode)) return true; + now = current_time(inode); + + if (!relatime_need_update(mnt, inode, now)) + return true; + return false; } diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 3da4924..81d8131 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -656,6 +656,11 @@ static bool is_project_state_change(const struct lu_attr *oattr, * chown_common and inode_setattr * utimes and inode_setattr * This API is ported from mds_fix_attr but remove some unnecesssary stuff. + * + * @param[in] oattr Original, current object attributes. + * @param[in,out] la New attributes to be evaluated and potentially + * modified depending on oattr content and other rules. + * @param[in] ma md_attr to be evaluated for that object. */ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, const struct lu_attr *oattr, struct lu_attr *la, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 0b219ff..08d8f5f 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -4877,6 +4877,53 @@ test_39q() { # LU-8041 } run_test 39q "close won't zero out atime" +test_39s() { + local atime0 + local atime1 + local atime2 + local atime3 + local atime4 + + umount_client $MOUNT + mount_client $MOUNT relatime + + dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync + atime0=$(stat -c %X $DIR/$tfile) + + # First read updates atime + sleep 1 + cat $DIR/$tfile >/dev/null + atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1) + + # Next reads do not update atime + sleep 1 + cat $DIR/$tfile >/dev/null + atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1) + + # If mtime is greater than atime, atime is updated + sleep 1 + touch -m $DIR/$tfile # (mtime = now) + sleep 1 + cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime) + atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3) + + # Next reads do not update atime + sleep 1 + cat $DIR/$tfile >/dev/null + atime4=$(stat -c %X $DIR/$tfile) + + # Remount the client to clear 'relatime' option + remount_client $MOUNT + + (( atime0 < atime1 )) || + error "atime $atime0 should be smaller than $atime1" + (( atime1 == atime2 )) || + error "atime $atime1 was updated to $atime2" + (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3" + (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4" +} +run_test 39s "relatime is supported" + test_40() { dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&