From 6dd64da78d85d62df96946d82418cc5b0760ff86 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Wed, 3 Dec 2014 15:45:14 +0800 Subject: [PATCH] LU-4389 clio: update file attributes after sync This really only affects ZFS, because zfs does not update # of blocks until the blocks are flushed to disk. This patch update file's blocks attribute after OST_SYNC completes. Signed-off-by: Bobi Jam Change-Id: I2b62dff5acda2984f60d5ed5df4ad19144cd6829 Reviewed-on: http://review.whamcloud.com/12915 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Nathaniel Clark Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/osc/osc_internal.h | 2 +- lustre/osc/osc_io.c | 3 +-- lustre/osc/osc_request.c | 43 +++++++++++++++++++++++++++++++------------ lustre/tests/sanityn.sh | 12 ++++++++++++ 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h index 01854e9..7e2348c 100644 --- a/lustre/osc/osc_internal.h +++ b/lustre/osc/osc_internal.h @@ -122,7 +122,7 @@ int osc_setattr_async(struct obd_export *exp, struct obdo *oa, int osc_punch_base(struct obd_export *exp, struct obdo *oa, obd_enqueue_update_f upcall, void *cookie, struct ptlrpc_request_set *rqset); -int osc_sync_base(struct obd_export *exp, struct obdo *oa, +int osc_sync_base(struct osc_object *obj, struct obdo *oa, obd_enqueue_update_f upcall, void *cookie, struct ptlrpc_request_set *rqset); diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index 1dfebe3..4fb098c 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -772,8 +772,7 @@ static int osc_fsync_ost(const struct lu_env *env, struct osc_object *obj, init_completion(&cbargs->opc_sync); - rc = osc_sync_base(osc_export(obj), oa, osc_async_upcall, cbargs, - PTLRPCD_SET); + rc = osc_sync_base(obj, oa, osc_async_upcall, cbargs, PTLRPCD_SET); RETURN(rc); } diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 009280b..e02698e 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -74,8 +74,9 @@ struct osc_setattr_args { }; struct osc_fsync_args { + struct osc_object *fa_obj; struct obdo *fa_oa; - obd_enqueue_update_f fa_upcall; + obd_enqueue_update_f fa_upcall; void *fa_cookie; }; @@ -354,29 +355,46 @@ static int osc_sync_interpret(const struct lu_env *env, struct ptlrpc_request *req, void *arg, int rc) { - struct osc_fsync_args *fa = arg; - struct ost_body *body; - ENTRY; + struct osc_fsync_args *fa = arg; + struct ost_body *body; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; + unsigned long valid = 0; + struct cl_object *obj; + ENTRY; - if (rc) - GOTO(out, rc); + if (rc != 0) + GOTO(out, rc); - body = req_capsule_server_get(&req->rq_pill, &RMF_OST_BODY); - if (body == NULL) { - CERROR ("can't unpack ost_body\n"); - GOTO(out, rc = -EPROTO); - } + body = req_capsule_server_get(&req->rq_pill, &RMF_OST_BODY); + if (body == NULL) { + CERROR("can't unpack ost_body\n"); + GOTO(out, rc = -EPROTO); + } *fa->fa_oa = body->oa; + obj = osc2cl(fa->fa_obj); + + /* Update osc object's blocks attribute */ + cl_object_attr_lock(obj); + if (body->oa.o_valid & OBD_MD_FLBLOCKS) { + attr->cat_blocks = body->oa.o_blocks; + valid |= CAT_BLOCKS; + } + + if (valid != 0) + cl_object_attr_update(env, obj, attr, valid); + cl_object_attr_unlock(obj); + out: rc = fa->fa_upcall(fa->fa_cookie, rc); RETURN(rc); } -int osc_sync_base(struct obd_export *exp, struct obdo *oa, +int osc_sync_base(struct osc_object *obj, struct obdo *oa, obd_enqueue_update_f upcall, void *cookie, struct ptlrpc_request_set *rqset) { + struct obd_export *exp = osc_export(obj); struct ptlrpc_request *req; struct ost_body *body; struct osc_fsync_args *fa; @@ -403,6 +421,7 @@ int osc_sync_base(struct obd_export *exp, struct obdo *oa, CLASSERT(sizeof(*fa) <= sizeof(req->rq_async_args)); fa = ptlrpc_req_async_args(req); + fa->fa_obj = obj; fa->fa_oa = oa; fa->fa_upcall = upcall; fa->fa_cookie = cookie; diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index 6c0cd31..a69053d 100644 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -164,6 +164,18 @@ test_2f() { } run_test 2f "check attr/owner updates on DNE with 2 mtpt's" +test_2g() { + dd if=/dev/zero of=$DIR1/$tfile oflag=sync bs=1M count=2 + + local block1=$(stat $DIR1/$tfile | awk '/Blocks/ {print $4} ') + cancel_lru_locks osc + local block2=$(stat $DIR2/$tfile | awk '/Blocks/ {print $4} ') + echo "$DIR1/$tfile has $block1 blocks" + echo "$DIR2/$tfile has $block2 blocks" + [ $block1 -eq $block2 ] || error +} +run_test 2g "check blocks update on sync write" + test_3() { local target="this/is/good" ln -s $target $DIR1/$tfile || error "ln -s $target $DIR1/$tfile failed" -- 1.8.3.1