From: Hongchao Zhang Date: Tue, 7 Aug 2012 00:43:11 +0000 (+0800) Subject: LU-657 obdfilter: commit pending journals if -ENOSPC X-Git-Tag: 2.2.93~17 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=a9597791b658ff51474c06f419162d0a0bf03c65 LU-657 obdfilter: commit pending journals if -ENOSPC in filter_preprw_write, if there is no enough space for this write operation, then commit the pending journals to get some more disk space and retry it. Signed-off-by: Hongchao Zhang Change-Id: I46106b26443bb203eee6f01a0795b47be09170a6 Reviewed-on: http://review.whamcloud.com/3446 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin --- diff --git a/lustre/obdfilter/filter_io.c b/lustre/obdfilter/filter_io.c index 701cdfd..df261ab 100644 --- a/lustre/obdfilter/filter_io.c +++ b/lustre/obdfilter/filter_io.c @@ -657,6 +657,7 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa, obd_size left; unsigned long now = jiffies, timediff; int rc = 0, i, tot_bytes = 0, cleanup_phase = 0, localreq = 0; + int retries = 0; ENTRY; LASSERT(objcount == 1); LASSERT(obj->ioo_bufcnt > 0); @@ -744,38 +745,55 @@ 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_seq); - LASSERT(oa != NULL); - cfs_spin_lock(&obd->obd_osfs_lock); - 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); - - fso.fso_dentry = dentry; - fso.fso_bufcnt = *npages; - - rc = filter_grant_check(exp, oa, objcount, &fso, *npages, 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 OBD_FL_SHRINK_GRANT is set, the client just returned us some grant - * so no sense in allocating it some more. We either return the grant - * back to the client if we have plenty of space or we don't return - * anything if we are short. This was decided in filter_grant_incoming*/ - if ((oa->o_valid & OBD_MD_FLGRANT) && - (!(oa->o_valid & OBD_MD_FLFLAGS) || - !(oa->o_flags & OBD_FL_SHRINK_GRANT))) - oa->o_grant = filter_grant(exp, oa->o_grant, oa->o_undirty, - left, 1); - - cfs_spin_unlock(&obd->obd_osfs_lock); + LASSERT(oa != NULL); +retry: + cfs_spin_lock(&obd->obd_osfs_lock); + if (retries == 0) + 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); + + fso.fso_dentry = dentry; + fso.fso_bufcnt = *npages; + + rc = filter_grant_check(exp, oa, objcount, &fso, *npages, 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 OBD_FL_SHRINK_GRANT is set, the client just returned us some grant + * so no sense in allocating it some more. We either return the grant + * back to the client if we have plenty of space or we don't return + * anything if we are short. This was decided in filter_grant_incoming*/ + if ((retries == 0) && (oa->o_valid & OBD_MD_FLGRANT) && + (!(oa->o_valid & OBD_MD_FLFLAGS) || + !(oa->o_flags & OBD_FL_SHRINK_GRANT))) + oa->o_grant = filter_grant(exp, oa->o_grant, oa->o_undirty, + left, 1); + + cfs_spin_unlock(&obd->obd_osfs_lock); + + if (rc == -ENOSPC && retries == 0) { + void *handle = NULL; + + CDEBUG(D_INODE, "retry after commit pending journals"); + + retries = 1; + handle = fsfilt_start_log(obd, dentry->d_inode, + FSFILT_OP_SETATTR, NULL, 1); + if (handle != NULL) { + fsfilt_commit_wait(obd, dentry->d_inode, handle); + goto retry; + } + } + filter_fmd_put(exp, fmd); OBD_FAIL_TIMEOUT(OBD_FAIL_OST_BRW_PAUSE_BULK2, (obd_timeout + 1) / 4);