From: John L. Hammond Date: Fri, 23 Aug 2013 19:50:17 +0000 (-0500) Subject: LU-3832 clio: honor O_NOATIME X-Git-Tag: 2.4.92~29 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=6c74e4d72fe4f37a1487de24214a3ca75e57080c LU-3832 clio: honor O_NOATIME Add a ci_noatime bit to struct cl_io. In ll_io_init() set this bit if O_NOATIME is set in f_flags. Ensure that this bit is propagated down to lower layers. In osc_io_read_start() don't update atime if this bit is set. Add sanity test 39n to check that passing O_NOATIME to open() is honored. Signed-off-by: John L. Hammond Change-Id: I3e7ab1d777e897ce7840ad6b1b067a571fa2bff4 Reviewed-on: http://review.whamcloud.com/7442 Tested-by: Hudson Reviewed-by: Jinshan Xiong Reviewed-by: Lai Siyao Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index db81fb1..03ee887 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -2394,11 +2394,15 @@ struct cl_io { /** * file is released, restore has to to be triggered by vvp layer */ - ci_restore_needed:1; - /** - * Number of pages owned by this IO. For invariant checking. - */ - unsigned ci_owned_nr; + ci_restore_needed:1, + /** + * O_NOATIME + */ + ci_noatime:1; + /** + * Number of pages owned by this IO. For invariant checking. + */ + unsigned ci_owned_nr; }; /** @} cl_io */ diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 6d94033..0179dd0 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1055,6 +1055,33 @@ int ll_glimpse_ioctl(struct ll_sb_info *sbi, struct lov_stripe_md *lsm, return rc; } +static bool file_is_noatime(const struct file *file) +{ + const struct vfsmount *mnt = file->f_path.mnt; + const struct inode *inode = file->f_path.dentry->d_inode; + + /* Adapted from file_accessed() and touch_atime().*/ + if (file->f_flags & O_NOATIME) + return true; + + if (inode->i_flags & S_NOATIME) + return true; + + if (IS_NOATIME(inode)) + return true; + + if (mnt->mnt_flags & (MNT_NOATIME | MNT_READONLY)) + return true; + + if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) + return true; + + if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) + return true; + + return false; +} + void ll_io_init(struct cl_io *io, const struct file *file, int write) { struct inode *inode = file->f_dentry->d_inode; @@ -1074,6 +1101,8 @@ void ll_io_init(struct cl_io *io, const struct file *file, int write) } else if (file->f_flags & O_APPEND) { io->ci_lockreq = CILR_MANDATORY; } + + io->ci_noatime = file_is_noatime(file); } static ssize_t diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index 3a0222b..21e7da7 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -197,6 +197,7 @@ static int lov_io_sub_init(const struct lu_env *env, struct lov_io *lio, sub_io->ci_lockreq = io->ci_lockreq; sub_io->ci_type = io->ci_type; sub_io->ci_no_srvlock = io->ci_no_srvlock; + sub_io->ci_noatime = io->ci_noatime; lov_sub_enter(sub); result = cl_io_sub_init(sub->sub_env, sub_io, diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index 3535bbe..110704c 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -523,23 +523,20 @@ static void osc_io_setattr_end(const struct lu_env *env, static int osc_io_read_start(const struct lu_env *env, const struct cl_io_slice *slice) { - struct osc_io *oio = cl2osc_io(env, slice); - struct cl_object *obj = slice->cis_obj; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; - int result = 0; - ENTRY; + struct osc_io *oio = cl2osc_io(env, slice); + struct cl_object *obj = slice->cis_obj; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; + int rc = 0; + ENTRY; - if (oio->oi_lockless == 0) { - cl_object_attr_lock(obj); - result = cl_object_attr_get(env, obj, attr); - if (result == 0) { - attr->cat_atime = LTIME_S(CFS_CURRENT_TIME); - result = cl_object_attr_set(env, obj, attr, - CAT_ATIME); - } - cl_object_attr_unlock(obj); - } - RETURN(result); + if (oio->oi_lockless == 0 && !slice->cis_io->ci_noatime) { + cl_object_attr_lock(obj); + attr->cat_atime = LTIME_S(CFS_CURRENT_TIME); + rc = cl_object_attr_set(env, obj, attr, CAT_ATIME); + cl_object_attr_unlock(obj); + } + + RETURN(rc); } static int osc_io_write_start(const struct lu_env *env, diff --git a/lustre/tests/multiop.c b/lustre/tests/multiop.c index 519e77f..0bb9826 100644 --- a/lustre/tests/multiop.c +++ b/lustre/tests/multiop.c @@ -150,6 +150,9 @@ struct flag_mapping { #ifdef O_DIRECT {"O_DIRECT", O_DIRECT}, #endif +#ifdef O_NOATIME + {"O_NOATIME", O_NOATIME}, +#endif {"O_LARGEFILE", O_LARGEFILE}, {"O_DIRECTORY", O_DIRECTORY}, {"O_NOFOLLOW", O_NOFOLLOW}, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 2312176..f046122 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -3093,6 +3093,37 @@ test_39m() { } run_test 39m "test atime and mtime before 1970" +test_39n() { # LU-3832 + local atime_diff=$(do_facet $SINGLEMDS \ + lctl get_param -n mdd.*MDT0000*.atime_diff) + local atime0 + local atime1 + local atime2 + + do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1 + + rm -rf $DIR/$tfile + dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer + atime0=$(stat -c %X $DIR/$tfile) + + sleep 5 + $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c + atime1=$(stat -c %X $DIR/$tfile) + + sleep 5 + cancel_lru_locks mdc + cancel_lru_locks osc + $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c + atime2=$(stat -c %X $DIR/$tfile) + + do_facet $SINGLEMDS \ + lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff + + [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1" + [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1" +} +run_test 39n "check that O_NOATIME is honored" + test_40() { dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&