From: wang di Date: Tue, 5 May 2015 04:15:37 +0000 (-0700) Subject: LU-6565 llog: Do not update the whole llog header X-Git-Tag: 2.7.55~55 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=refs%2Fchanges%2F78%2F14678%2F8;p=fs%2Flustre-release.git LU-6565 llog: Do not update the whole llog header During adding llog record ( see llog_osd_write_rec()), do not update the whole llog header, but only update the byte where the bit locates and the counter. So cross-MDT operation, which needs to write all of updates of the operation in the llog record, does not have to write the whole llog header(8K bytes) into the update record, instead only writing a few bytes. It will save a lot space for update logs and ptlrpc request, and help to pack more updates into the update log. Signed-off-by: Alex Zhuravlev Signed-off-by: wang di Change-Id: I777afbb111da6c1bc291735f9c4f105c48b3966b Reviewed-on: http://review.whamcloud.com/14678 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Andreas Dilger --- diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index 5d3e246..b4ef51a 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -347,7 +347,6 @@ static int llog_osd_write_rec(const struct lu_env *env, struct llog_rec_tail *lrt; struct dt_object *o; size_t left; - bool header_is_updated = false; ENTRY; @@ -518,14 +517,46 @@ static int llog_osd_write_rec(const struct lu_env *env, llh->llh_count++; spin_unlock(&loghandle->lgh_hdr_lock); - lgi->lgi_off = 0; - lgi->lgi_buf.lb_len = llh->llh_hdr.lrh_len; - lgi->lgi_buf.lb_buf = &llh->llh_hdr; - rc = dt_record_write(env, o, &lgi->lgi_buf, &lgi->lgi_off, th); - if (rc) - GOTO(out, rc); + if (lgi->lgi_attr.la_size == 0) { + lgi->lgi_off = 0; + lgi->lgi_buf.lb_len = llh->llh_hdr.lrh_len; + lgi->lgi_buf.lb_buf = &llh->llh_hdr; + rc = dt_record_write(env, o, &lgi->lgi_buf, &lgi->lgi_off, th); + if (rc != 0) + GOTO(out, rc); + } else { + /* Note: If this is not initialization (size == 0), then do not + * write the whole header (8k bytes), only update header/tail + * and bits needs to be updated. Because this update might be + * part of cross-MDT operation, which needs to write these + * updates into the update log(32KB limit) and also pack inside + * the RPC (1MB limit), if we write 8K for each operation, which + * will cost a lot space, and keep us adding more updates to one + * update log.*/ + lgi->lgi_off = offsetof(typeof(*llh), llh_count); + lgi->lgi_buf.lb_len = sizeof(llh->llh_count); + lgi->lgi_buf.lb_buf = &llh->llh_count; + rc = dt_record_write(env, o, &lgi->lgi_buf, &lgi->lgi_off, th); + if (rc != 0) + GOTO(out, rc); + + lgi->lgi_off = offsetof(typeof(*llh), + llh_bitmap[index / (sizeof(*llh->llh_bitmap) * 8)]); + lgi->lgi_buf.lb_len = sizeof(*llh->llh_bitmap); + lgi->lgi_buf.lb_buf = + &llh->llh_bitmap[index/(sizeof(*llh->llh_bitmap)*8)]; + rc = dt_record_write(env, o, &lgi->lgi_buf, &lgi->lgi_off, th); + if (rc != 0) + GOTO(out, rc); + + lgi->lgi_off = offsetof(typeof(*llh), llh_tail); + lgi->lgi_buf.lb_len = sizeof(llh->llh_tail); + lgi->lgi_buf.lb_buf = &llh->llh_tail; + rc = dt_record_write(env, o, &lgi->lgi_buf, &lgi->lgi_off, th); + if (rc != 0) + GOTO(out, rc); + } - header_is_updated = true; rc = dt_attr_get(env, o, &lgi->lgi_attr); if (rc) GOTO(out, rc); @@ -564,14 +595,6 @@ out: loghandle->lgh_last_idx--; llh->llh_tail.lrt_index = loghandle->lgh_last_idx; - /* restore the header on disk if it was written */ - if (header_is_updated) { - lgi->lgi_off = 0; - lgi->lgi_buf.lb_len = llh->llh_hdr.lrh_len; - lgi->lgi_buf.lb_buf = &llh->llh_hdr; - dt_record_write(env, o, &lgi->lgi_buf, &lgi->lgi_off, th); - } - RETURN(rc); }