diff --git a/lustre/ChangeLog b/lustre/ChangeLog index dbf2052856843b34913516d9829724f8ddf68aaa..2813bb5d0a0bc3005aa5bbd52b9bd37ca3ba2fdc 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -159,6 +159,15 @@ Details : When osc reconnect ost, OST(filter) should check whether it of "new granted" space, because client will call osc_init_grant to update the client grant space info. +Severity : normal +Frequency : when client reconnect to OST +Bugzilla : 11662 +Description: Grant Leak when osc do resend and replay bulk write +Details : When osc reconnect to OST, OST(filter)should clear grant info of + bulk write request, because the grant info while be sync between + OSC and OST when reconnect, and we should ignore the grant info + these of resend/replay write req. + Severity : normal Frequency : when client is evicted Bugzilla : 12371 diff --git a/lustre/obdfilter/filter_io.c b/lustre/obdfilter/filter_io.c index 3948593da05c3dff56fe7f6eb00cc09b7462f3cc..2f486a2762cc1d94571631e1cfda606a5d133cd5 100644 --- a/lustre/obdfilter/filter_io.c +++ b/lustre/obdfilter/filter_io.c @@ -258,8 +258,10 @@ long filter_grant(struct obd_export *exp, obd_size current_grant, } } - CDEBUG(D_CACHE,"%s: cli %s/%p wants: "LPU64" granting: "LPU64"\n", - obd->obd_name, exp->exp_client_uuid.uuid, exp, want, grant); + CDEBUG(D_CACHE, + "%s: cli %s/%p wants: "LPU64" current grant "LPU64 + " granting: "LPU64"\n", obd->obd_name, exp->exp_client_uuid.uuid, + exp, want, current_grant, grant); CDEBUG(D_CACHE, "%s: cli %s/%p tot cached:"LPU64" granted:"LPU64 " num_exports: %d\n", obd->obd_name, exp->exp_client_uuid.uuid, @@ -386,9 +388,9 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa, * right on through. * * Caller must hold obd_osfs_lock. */ -static int filter_grant_check(struct obd_export *exp, int objcount, - struct fsfilt_objinfo *fso, int niocount, - struct niobuf_remote *rnb, +static int filter_grant_check(struct obd_export *exp, struct obdo *oa, + int objcount, struct fsfilt_objinfo *fso, + int niocount, struct niobuf_remote *rnb, struct niobuf_local *lnb, obd_size *left, struct inode *inode) { @@ -410,7 +412,8 @@ static int filter_grant_check(struct obd_export *exp, int objcount, if (tmp) bytes += blocksize - tmp; - if (rnb[n].flags & OBD_BRW_FROM_GRANT) { + if ((rnb[n].flags & OBD_BRW_FROM_GRANT) && + (oa->o_valid & OBD_MD_FLGRANT)) { if (fed->fed_grant < used + bytes) { CDEBUG(D_CACHE, "%s: cli %s/%p claims %ld+%d " @@ -552,26 +555,26 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa, * already exist so we can store the reservation handle there. */ fmd = filter_fmd_find(exp, obj->ioo_id, obj->ioo_gr); + LASSERT(oa != NULL); spin_lock(&exp->exp_obd->obd_osfs_lock); - if (oa) { - filter_grant_incoming(exp, oa); - if (fmd && fmd->fmd_mactime_xid > oti->oti_xid) - oa->o_valid &= ~(OBD_MD_FLMTIME | OBD_MD_FLCTIME | - OBD_MD_FLATIME); - else - obdo_to_inode(dentry->d_inode, oa, OBD_MD_FLATIME | - OBD_MD_FLMTIME | OBD_MD_FLCTIME); - } + + filter_grant_incoming(exp, oa); + if (fmd && fmd->fmd_mactime_xid > oti->oti_xid) + oa->o_valid &= ~(OBD_MD_FLMTIME | OBD_MD_FLCTIME | + OBD_MD_FLATIME); + else + obdo_to_inode(dentry->d_inode, oa, OBD_MD_FLATIME | + OBD_MD_FLMTIME | OBD_MD_FLCTIME); cleanup_phase = 3; left = filter_grant_space_left(exp); - rc = filter_grant_check(exp, objcount, &fso, niocount, nb, res, + rc = filter_grant_check(exp, oa, objcount, &fso, niocount, nb, res, &left, dentry->d_inode); /* do not zero out oa->o_valid as it is used in filter_commitrw_write() * for setting UID/GID and fid EA in first write time. */ - if (oa && oa->o_valid & OBD_MD_FLGRANT) { + if (oa->o_valid & OBD_MD_FLGRANT) { oa->o_grant = filter_grant(exp,oa->o_grant,oa->o_undirty,left); oa->o_valid |= OBD_MD_FLGRANT; } diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 19923939871af0e65c31f66a565f74b1a4d5f2b1..78672c9d29e1b6651b2944668f91388e3bf1dc5b 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -975,6 +975,14 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) /* obd_preprw clobbers oa->valid, so save what we need */ client_cksum = body->oa.o_valid & OBD_MD_FLCKSUM ? body->oa.o_cksum : 0; + /* Because we already sync grant info with client when reconnect, + * grant info will be cleared for resent req, then fed_grant and + * total_grant will not be modified in following preprw_write*/ + if (lustre_msg_get_flags(req->rq_reqmsg) & (MSG_RESENT | MSG_REPLAY)) { + DEBUG_REQ(D_CACHE, req, "clear resent/replay req grant info\n"); + body->oa.o_valid &= ~OBD_MD_FLGRANT; + } + rc = obd_preprw(OBD_BRW_WRITE, req->rq_export, &body->oa, objcount, ioo, npages, pp_rnb, local_nb, oti); if (rc != 0)