RETURN(rc);
}
- if (la->la_valid == LA_ATIME) {
- /* This is an atime-only attribute update for close RPCs. */
- if (la->la_atime < (oattr->la_atime +
+ if (flags & MDS_CLOSE_UPDATE_TIMES &&
+ la->la_valid & (LA_ATIME | LA_MTIME | LA_CTIME)) {
+ /* This is an atime/mtime/ctime attribute update for
+ * close RPCs.
+ */
+ if (la->la_valid & LA_ATIME &&
+ la->la_atime <= (oattr->la_atime +
mdd_obj2mdd_dev(obj)->mdd_atime_diff))
la->la_valid &= ~LA_ATIME;
+ if (la->la_valid & LA_CTIME && la->la_ctime <= oattr->la_ctime)
+ la->la_valid &= ~LA_CTIME;
+ if (la->la_valid & LA_MTIME && la->la_mtime <= oattr->la_mtime)
+ la->la_valid &= ~LA_MTIME;
RETURN(0);
}
else if (open_flags & MDS_FMODE_EXEC)
mdt_write_allow(o);
- /* Update atime on close only. */
+ /* Update atime|mtime|ctime on close. */
if ((open_flags & MDS_FMODE_EXEC || open_flags & MDS_FMODE_READ ||
open_flags & MDS_FMODE_WRITE) && (ma->ma_valid & MA_INODE) &&
- (ma->ma_attr.la_valid & LA_ATIME)) {
- /* Set the atime only. */
- ma->ma_valid = MA_INODE;
- ma->ma_attr.la_valid = LA_ATIME;
- rc = mo_attr_set(info->mti_env, next, ma);
- }
+ (ma->ma_attr.la_valid & LA_ATIME ||
+ ma->ma_attr.la_valid & LA_MTIME ||
+ ma->ma_attr.la_valid & LA_CTIME)) {
+ ma->ma_valid = MA_INODE;
+ ma->ma_attr_flags |= MDS_CLOSE_UPDATE_TIMES;
+ ma->ma_attr.la_valid &= (LA_ATIME | LA_MTIME | LA_CTIME);
+ rc = mo_attr_set(info->mti_env, next, ma);
+ }
/* If file data is modified, add the dirty flag. */
if (ma->ma_attr_flags & MDS_DATA_MODIFIED)
}
run_test 103 "Test size correctness with lockahead"
+get_stat_xtimes()
+{
+ local xtimes
+
+ xtimes=$(stat -c "%X %Y %Z" $DIR/$tfile)
+
+ echo ${xtimes[*]}
+}
+
+get_mdt_xtimes()
+{
+ local mdtdev=$1
+ local output
+ local xtimes
+
+ output=$(do_facet mds1 "$DEBUGFS -c -R 'stat ROOT/$tfile' $mdtdev")
+ ((xtimes[0]=$(awk -F ':' /atime/'{ print $2 }' <<< "$output")))
+ ((xtimes[1]=$(awk -F ':' /mtime/'{ print $2 }' <<< "$output")))
+ ((xtimes[2]=$(awk -F ':' /ctime/'{ print $2 }' <<< "$output")))
+
+ echo ${xtimes[*]}
+}
+
+check_mdt_xtimes()
+{
+ local mdtdev=$1
+ local xtimes=($(get_stat_xtimes))
+ local mdt_xtimes=($(get_mdt_xtimes $mdtdev))
+
+ echo "STAT a|m|ctime ${xtimes[*]}"
+ echo "MDT a|m|ctime ${xtimes[*]}"
+ [[ ${xtimes[0]} == ${mdt_xtimes[0]} ]] ||
+ error "$DIR/$tfile atime (${xtimes[0]}:${mdt_xtimes[0]}) diff"
+ [[ ${xtimes[1]} == ${mdt_xtimes[1]} ]] ||
+ error "$DIR/$tfile mtime (${xtimes[1]}:${mdt_xtimes[1]}) diff"
+ [[ ${xtimes[2]} == ${mdt_xtimes[2]} ]] ||
+ error "$DIR/$tfile ctime (${xtimes[2]}:${mdt_xtimes[2]}) diff"
+}
+
+test_104() {
+ [ "$mds1_FSTYPE" == "ldiskfs" ] || skip_env "ldiskfs only test"
+
+ local pid
+ local mdtdev=$(mdsdevname ${SINGLEMDS//mds/})
+ local atime_diff=$(do_facet $SINGLEMDS \
+ lctl get_param -n mdd.*MDT0000*.atime_diff)
+
+ do_facet $SINGLEMDS \
+ lctl set_param -n mdd.*MDT0000*.atime_diff=0
+
+ stack_trap "do_facet $SINGLEMDS \
+ lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff" EXIT
+
+ dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
+ check_mdt_xtimes $mdtdev
+ sleep 2
+
+ dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
+ check_mdt_xtimes $mdtdev
+ sleep 2
+ $MULTIOP $DIR2/$tfile Oz8192w8192_c &
+ pid=$!
+ sleep 2
+ dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
+ sleep 2
+ kill -USR1 $pid && wait $pid || error "multiop failure"
+ check_mdt_xtimes $mdtdev
+
+ local xtimes
+ local mdt_xtimes
+
+ # Verify mtime/ctime is NOT upated on MDS when there is no modification
+ # on the client side
+ xtimes=($(get_stat_xtimes))
+ $MULTIOP $DIR/$tfile O_c &
+ pid=$!
+ sleep 2
+ kill -USR1 $pid && wait $pid || error "multiop failure"
+ mdt_xtimes=($(get_mdt_xtimes $mdtdev))
+ [[ ${xtimes[1]} == ${mdt_xtimes[1]} ]] ||
+ error "$DIR/$tfile mtime (${xtimes[1]}:${mdt_xtimes[1]}) diff"
+ [[ ${xtimes[2]} == ${mdt_xtimes[2]} ]] ||
+ error "$DIR/$tfile ctime (${xtimes[2]}:${mdt_xtimes[2]}) diff"
+ check_mdt_xtimes $mdtdev
+
+ sleep 2
+ # Change ctime via chmod
+ $MULTIOP $DIR/$tfile o_tc &
+ pid=$!
+ sleep 2
+ kill -USR1 $pid && wait $pid || error "multiop failure"
+ check_mdt_xtimes $mdtdev
+}
+run_test 104 "Verify that MDS stores atime/mtime/ctime during close"
+
log "cleanup: ======================================================"
# kill and wait in each test only guarentee script finish, but command in script