From 565b6203761a09b28f6aee08c4dd4a5f6dbaf4f1 Mon Sep 17 00:00:00 2001 From: Emoly Liu Date: Mon, 8 Apr 2013 02:16:15 +0800 Subject: [PATCH] LU-3036 mdt: set ATTR_xTIME_SET to make atime update properly To make atime update properly between 1.8 client and 2.x server, this patch includes the following fixes: - if MDS_ATTR_xTIME is set without MDS_ATTR_xTIME_SET and the client does not have OBD_CONNECT_FULL20, convert it to LA_xTIME in mdt_setattr_unpack(). - set both MDS_ATTR_xTIME | MDS_ATTR_xTIME_SET for timestamps in ll_prepare_close(). This allows us to fix the server-side timestamp setting in the future. - remove attr_unpack() and convert the flags from MDS_ATTR_ to LA_* directly in mdt_attr_valid_xlate() instead. - improve sanityn.sh test_23(). Signed-off-by: Liu Ying Change-Id: I9454d7689243a268ebd4f40566f77e4f53996d5f Reviewed-on: http://review.whamcloud.com/6327 Tested-by: Hudson Reviewed-by: Fan Yong Tested-by: Maloo Reviewed-by: Andreas Dilger --- lustre/llite/file.c | 5 +- lustre/mdt/mdt_lib.c | 144 ++++++++++++++++++------------------------------ lustre/tests/sanityn.sh | 31 +++++------ 3 files changed, 73 insertions(+), 107 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index cfb48ca..94f7784 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -95,8 +95,9 @@ static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data, { ENTRY; - op_data->op_attr.ia_valid = ATTR_MODE | ATTR_ATIME_SET | - ATTR_MTIME_SET | ATTR_CTIME_SET; + op_data->op_attr.ia_valid = ATTR_MODE | ATTR_ATIME | ATTR_ATIME_SET | + ATTR_MTIME | ATTR_MTIME_SET | + ATTR_CTIME | ATTR_CTIME_SET; if (!(och->och_flags & FMODE_WRITE)) goto out; diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index d2e6e45..d39c531 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -710,99 +710,51 @@ int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo, RETURN(0); } -static inline unsigned int attr_unpack(__u64 sa_valid) { - unsigned int ia_valid = 0; - - if (sa_valid & MDS_ATTR_MODE) - ia_valid |= ATTR_MODE; - if (sa_valid & MDS_ATTR_UID) - ia_valid |= ATTR_UID; - if (sa_valid & MDS_ATTR_GID) - ia_valid |= ATTR_GID; - if (sa_valid & MDS_ATTR_SIZE) - ia_valid |= ATTR_SIZE; - if (sa_valid & MDS_ATTR_ATIME) - ia_valid |= ATTR_ATIME; - if (sa_valid & MDS_ATTR_MTIME) - ia_valid |= ATTR_MTIME; - if (sa_valid & MDS_ATTR_CTIME) - ia_valid |= ATTR_CTIME; - if (sa_valid & MDS_ATTR_ATIME_SET) - ia_valid |= ATTR_ATIME_SET; - if (sa_valid & MDS_ATTR_MTIME_SET) - ia_valid |= ATTR_MTIME_SET; - if (sa_valid & MDS_ATTR_FORCE) - ia_valid |= ATTR_FORCE; - if (sa_valid & MDS_ATTR_ATTR_FLAG) - ia_valid |= ATTR_ATTR_FLAG; - if (sa_valid & MDS_ATTR_KILL_SUID) - ia_valid |= ATTR_KILL_SUID; - if (sa_valid & MDS_ATTR_KILL_SGID) - ia_valid |= ATTR_KILL_SGID; - if (sa_valid & MDS_ATTR_CTIME_SET) - ia_valid |= ATTR_CTIME_SET; - if (sa_valid & MDS_ATTR_FROM_OPEN) - ia_valid |= ATTR_FROM_OPEN; - if (sa_valid & MDS_ATTR_BLOCKS) - ia_valid |= ATTR_BLOCKS; - if (sa_valid & MDS_OPEN_OWNEROVERRIDE) - ia_valid |= MDS_OPEN_OWNEROVERRIDE; - return ia_valid; -} - static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr, struct md_attr *ma) { - __u64 out; - - out = 0; - if (in & ATTR_MODE) - out |= LA_MODE; - if (in & ATTR_UID) - out |= LA_UID; - if (in & ATTR_GID) - out |= LA_GID; - if (in & ATTR_SIZE) - out |= LA_SIZE; - if (in & ATTR_BLOCKS) - out |= LA_BLOCKS; - - if (in & ATTR_FROM_OPEN) - rr->rr_flags |= MRF_OPEN_TRUNC; - - if (in & ATTR_ATIME_SET) - out |= LA_ATIME; - - if (in & ATTR_CTIME_SET) - out |= LA_CTIME; - - if (in & ATTR_MTIME_SET) - out |= LA_MTIME; - - if (in & ATTR_ATTR_FLAG) - out |= LA_FLAGS; - - if (in & ATTR_KILL_SUID) - out |= LA_KILL_SUID; - - if (in & ATTR_KILL_SGID) - out |= LA_KILL_SGID; - + __u64 out; + + out = 0; + if (in & MDS_ATTR_MODE) + out |= LA_MODE; + if (in & MDS_ATTR_UID) + out |= LA_UID; + if (in & MDS_ATTR_GID) + out |= LA_GID; + if (in & MDS_ATTR_SIZE) + out |= LA_SIZE; + if (in & MDS_ATTR_BLOCKS) + out |= LA_BLOCKS; + if (in & MDS_ATTR_ATIME_SET) + out |= LA_ATIME; + if (in & MDS_ATTR_CTIME_SET) + out |= LA_CTIME; + if (in & MDS_ATTR_MTIME_SET) + out |= LA_MTIME; + if (in & MDS_ATTR_ATTR_FLAG) + out |= LA_FLAGS; + if (in & MDS_ATTR_KILL_SUID) + out |= LA_KILL_SUID; + if (in & MDS_ATTR_KILL_SGID) + out |= LA_KILL_SGID; + + if (in & MDS_ATTR_FROM_OPEN) + rr->rr_flags |= MRF_OPEN_TRUNC; if (in & MDS_OPEN_OWNEROVERRIDE) ma->ma_attr_flags |= MDS_OWNEROVERRIDE; - - if (in & ATTR_FORCE) - ma->ma_attr_flags |= MDS_PERM_BYPASS; - - /*XXX need ATTR_RAW?*/ - in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_BLOCKS| - ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN| - ATTR_ATIME_SET|ATTR_CTIME_SET|ATTR_MTIME_SET| - ATTR_ATTR_FLAG|ATTR_RAW|MDS_OPEN_OWNEROVERRIDE| - ATTR_FORCE|ATTR_KILL_SUID|ATTR_KILL_SGID); - if (in != 0) - CERROR("Unknown attr bits: "LPX64"\n", in); - return out; + if (in & MDS_ATTR_FORCE) + ma->ma_attr_flags |= MDS_PERM_BYPASS; + + in &= ~(MDS_ATTR_MODE | MDS_ATTR_UID | MDS_ATTR_GID | + MDS_ATTR_ATIME | MDS_ATTR_MTIME | MDS_ATTR_CTIME | + MDS_ATTR_ATIME_SET | MDS_ATTR_CTIME_SET | MDS_ATTR_MTIME_SET | + MDS_ATTR_SIZE | MDS_ATTR_BLOCKS | MDS_ATTR_ATTR_FLAG | + MDS_ATTR_FORCE | MDS_ATTR_KILL_SUID | MDS_ATTR_KILL_SGID | + MDS_ATTR_FROM_OPEN | MDS_OPEN_OWNEROVERRIDE); + if (in != 0) + CERROR("Unknown attr bits: "LPX64"\n", in); + return out; } /* unpacking */ @@ -829,7 +781,21 @@ static int mdt_setattr_unpack_rec(struct mdt_thread_info *info) uc->uc_suppgids[1] = -1; rr->rr_fid1 = &rec->sa_fid; - la->la_valid = mdt_attr_valid_xlate(attr_unpack(rec->sa_valid), rr, ma); + la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr, ma); + /* If MDS_ATTR_xTIME is set without MDS_ATTR_xTIME_SET and + * the client does not have OBD_CONNECT_FULL20, convert it + * to LA_xTIME. LU-3036 */ + if (!(exp_connect_flags(info->mti_exp) & OBD_CONNECT_FULL20)) { + if (!(rec->sa_valid & MDS_ATTR_ATIME_SET) && + (rec->sa_valid & MDS_ATTR_ATIME)) + la->la_valid |= LA_ATIME; + if (!(rec->sa_valid & MDS_ATTR_MTIME_SET) && + (rec->sa_valid & MDS_ATTR_MTIME)) + la->la_valid |= LA_MTIME; + if (!(rec->sa_valid & MDS_ATTR_CTIME_SET) && + (rec->sa_valid & MDS_ATTR_CTIME)) + la->la_valid |= LA_CTIME; + } la->la_mode = rec->sa_mode; la->la_flags = rec->sa_attr_flags; la->la_uid = rec->sa_uid; diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index 6b031a7..56c3da6 100644 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -489,28 +489,27 @@ test_21() { # Bug 5907 run_test 21 " Try to remove mountpoint on another dir ====" test_23() { # Bug 5972 - echo "others should see updated atime while another read" > $DIR1/f23 - + local at_diff=$(do_facet $SINGLEMDS $LCTL get_param -n mdd.*.atime_diff) + echo "atime should be updated while another read" > $DIR1/$tfile + # clear the lock(mode: LCK_PW) gotten from creating operation cancel_lru_locks osc - - time1=`date +%s` - #MAX_ATIME_DIFF 60, we update atime only if older than 60 seconds - sleep 61 - - multiop_bg_pause $DIR1/f23 or20_c || return 1 + time1=$(date +%s) + echo "now is $time1" + sleep $((at_diff + 1)) + + echo "starting reads" + multiop_bg_pause $DIR1/$tfile or20_c || return 1 # with SOM and opencache enabled, we need to close a file and cancel # open lock to get atime propogated to MDS - kill -USR1 $! + kill -USR1 $! || return 2 cancel_lru_locks mdc - time2=`stat -c "%X" $DIR2/f23` + time2=$(stat -c "%X" $DIR/$tfile) + echo "new atime is $time2" - if (( $time2 <= $time1 )); then - error "atime doesn't update among nodes" - fi - - rm -f $DIR1/f23 || error "rm -f $DIR1/f23 failed" + [ $time2 -gt $time1 ] || error "atime was not updated" + rm -f $DIR1/$tfile || error "rm -f $DIR1/$tfile failed" true } run_test 23 " others should see updated atime while another read====" @@ -523,7 +522,7 @@ test_24a() { lfs df -i $DIR2 || error "lfs df -i $DIR2 failed" lfs df $DIR1/$tfile || error "lfs df $DIR1/$tfile failed" lfs df -ih $DIR2/$tfile || error "lfs df -ih $DIR2/$tfile failed" - + OSC=`lctl dl | awk '/-osc-|OSC.*MNT/ {print $4}' | head -n 1` # OSC=`lctl dl | awk '/-osc-/ {print $4}' | head -n 1` lctl --device %$OSC deactivate -- 1.8.3.1