if (rc < 0)
GOTO(out_trans, rc);
}
+ if (llh->llh_flags & LLOG_F_IS_CAT)
+ dt_declare_attr_set(env, loghandle->lgh_obj, NULL, th);
th->th_wait_submit = 1;
rc = dt_trans_start_local(env, dt, th);
rc = LLOG_DEL_PLAIN;
}
+ /* update for catalog which doesn't happen very often */
+ if (llh->llh_flags & LLOG_F_IS_CAT) {
+ lgi->lgi_attr.la_valid = LA_MTIME;
+ lgi->lgi_attr.la_mtime = ktime_get_real_seconds();
+ dt_attr_set(env, loghandle->lgh_obj, &lgi->lgi_attr, th);
+ }
+
out_unlock:
if (rc < 0) {
/* restore bitmap while holding a mutex */
{
struct dt_device *dt;
struct thandle *th;
- bool need_cookie;
- int rc;
+ struct llog_thread_info *lgi = llog_info(env);
+ bool need_cookie;
+ bool update_attr;
+ int rc;
ENTRY;
if (rc)
GOTO(out_trans, rc);
+ /*
+ * update mtime given 1) append mode, no overhead since inode
+ * size/block needs to be written anyway; 2) update for catalog
+ * since this doesn't happen very often
+ */
+ update_attr = (idx == LLOG_NEXT_IDX ||
+ (loghandle->lgh_hdr &&
+ loghandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT));
+ if (update_attr)
+ dt_declare_attr_set(env, loghandle->lgh_obj, NULL, th);
+
th->th_wait_submit = 1;
rc = dt_trans_start_local(env, dt, th);
if (rc)
} else {
rc = llog_write_rec(env, loghandle, rec, NULL, idx, th);
}
+ if (rc == 0 && update_attr) {
+ lgi->lgi_attr.la_valid = LA_MTIME;
+ lgi->lgi_attr.la_mtime = ktime_get_real_seconds();
+ dt_attr_set(env, loghandle->lgh_obj, &lgi->lgi_attr, th);
+ }
up_write(&loghandle->lgh_lock);
out_trans:
handle);
if (rc != 0)
GOTO(out, rc);
+ dt_declare_attr_set(env, cathandle->lgh_obj, NULL, handle);
rc = dt_trans_start_local(env, dt, handle);
if (rc != 0)
&loghandle->u.phd.phd_cookie, LLOG_NEXT_IDX, th);
if (rc < 0)
GOTO(out_destroy, rc);
+ /* update for catalog which doesn't happen very often */
+ lgi->lgi_attr.la_valid = LA_MTIME;
+ lgi->lgi_attr.la_mtime = ktime_get_real_seconds();
+ dt_attr_set(env, cathandle->lgh_obj, &lgi->lgi_attr, th);
CDEBUG(D_OTHER, "new plain log "DFID".%u of catalog "DFID"\n",
PLOGID(&loghandle->lgh_id), rec->lid_hdr.lrh_index,
lirec->lid_hdr.lrh_len = sizeof(*lirec);
rc = llog_declare_write_rec(env, cathandle, &lirec->lid_hdr, -1,
th);
+ dt_declare_attr_set(env, cathandle->lgh_obj, NULL, th);
}
out:
struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
struct thandle *th)
{
- struct llog_handle *loghandle;
+ struct llog_handle *loghandle;
+ struct llog_thread_info *lgi = llog_info(env);
int rc, retried = 0;
ENTRY;
* actual cause here */
if (rc == -ENOSPC && llog_is_full(loghandle))
rc = -ENOBUFS;
+ } else {
+ /* no overhead since inode size needs to be written anyway */
+ lgi->lgi_attr.la_valid = LA_MTIME;
+ lgi->lgi_attr.la_mtime = ktime_get_real_seconds();
+ dt_attr_set(env, loghandle->lgh_obj, &lgi->lgi_attr, th);
}
+
up_write(&loghandle->lgh_lock);
if (rc == -ENOBUFS) {
RETURN(rc);
goto start;
}
+ dt_declare_attr_set(env, cathandle->u.chd.chd_current_log->lgh_obj,
+ NULL, th);
#if 0
/*
{
struct llog_thread_info *lgi = llog_info(env);
- lgi->lgi_attr.la_valid = LA_MODE;
+ lgi->lgi_attr.la_valid = LA_MODE | LA_CTIME | LA_MTIME | LA_ATIME;
lgi->lgi_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
+ lgi->lgi_attr.la_ctime = lgi->lgi_attr.la_mtime =
+ lgi->lgi_attr.la_atime = ktime_get_real_seconds();
lgi->lgi_dof.dof_type = dt_mode_to_dft(S_IFREG);
return local_object_create(env, los, o, &lgi->lgi_attr,
if (res->lgh_ctxt->loc_flags & LLOG_CTXT_FLAG_NORMAL_FID) {
struct llog_thread_info *lgi = llog_info(env);
- lgi->lgi_attr.la_valid = LA_MODE | LA_SIZE | LA_TYPE;
+ lgi->lgi_attr.la_valid = LA_MODE | LA_SIZE | LA_TYPE |
+ LA_CTIME | LA_MTIME | LA_ATIME;
lgi->lgi_attr.la_size = 0;
lgi->lgi_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
+ lgi->lgi_attr.la_ctime = lgi->lgi_attr.la_mtime =
+ lgi->lgi_attr.la_atime = ktime_get_real_seconds();
lgi->lgi_dof.dof_type = dt_mode_to_dft(S_IFREG);
dt_write_lock(env, o, 0);
}
run_test 907 "write rpc error during unlink"
+test_908a() {
+ (( MDS1_VERSION >= $(version_code 2.16.0) )) ||
+ skip "need MDS >= 2.16.0 for llog timestamps"
+ [[ "$mds1_FSTYPE" == ldiskfs ]] || skip "ldiskfs only test"
+
+ local dev=$(mdsdevname 1)
+ local cmd="debugfs -c -R \\\"stat CONFIGS/params\\\" $dev"
+
+ # ctime_mds value is in hex
+ local base_time=`date -d "24 hours ago" +%s`
+ local ctime_mds=$(do_facet mds1 "$cmd" |&
+ awk -F'[: ]' '/ctime:/ { print $4 }')
+ ctime_mds=$((ctime_mds))
+ echo "ctime_mds=$ctime_mds, base_time=$base_time"
+ (( "$ctime_mds" > "$base_time" )) ||
+ error "invalid ctime $ctime_mds <= $base_time"
+}
+run_test 908a "llog created with valid ctime"
+
+test_908b() {
+ (( MDS1_VERSION >= $(version_code 2.16.0) )) ||
+ skip "need MDS >= 2.16.0 for llog timestamps"
+ [[ "$mds1_FSTYPE" == ldiskfs ]] || skip "ldiskfs only test"
+
+ local dev=$(mdsdevname 1)
+
+ changelog_register || error "cannot register changelog user"
+ # set changelog_mask to ALL
+ changelog_chmask "ALL"
+ changelog_clear
+
+ for ((i=0; i<100; i++)); do
+ echo "$i" > $DIR/$tfile${i}
+ rm $DIR/$tfile${i}
+ done
+ sleep 5
+
+ changelog_deregister || error "changelog_deregister failed"
+
+ local cmd="debugfs -c -R \\\"stat changelog_catalog\\\" $dev"
+
+ # ctime_mdt value is in hex
+ local ctime_mds=$(do_facet mds1 "$cmd" |&
+ awk -F'[: ]' '/ctime:/ { print $4 }')
+ ctime_mds=$((ctime_mds))
+ local mtime_mds=$(do_facet mds1 "$cmd" |&
+ awk -F'[: ]' '/mtime:/ { print $4 }')
+ mtime_mds=$((mtime_mds))
+
+ echo "ctime_mds=$ctime_mds, mtime_mds=$mtime_mds"
+ (( "$mtime_mds" > "$ctime_mds" )) ||
+ error "invalid mtime $mtime_mds <= $ctime_mds"
+}
+run_test 908b "changelog stores valid mtime"
+
complete_test $SECONDS
[ -f $EXT2_DEV ] && rm $EXT2_DEV || true
check_and_cleanup_lustre