diff --git a/kernel/lib_mapfree.c b/kernel/lib_mapfree.c index 1c219665..9111e192 100644 --- a/kernel/lib_mapfree.c +++ b/kernel/lib_mapfree.c @@ -146,8 +146,21 @@ struct mapfree_info *mapfree_get(const char *name, int flags) } up_read(&mapfree_mutex); - if (mf) + if (mf) { + struct inode *inode = mf->mf_filp->f_mapping->host; + loff_t length; + int i; + + /* In some cases like truncated logfiles, + * account for any shortenings. + */ + length = i_size_read(inode); + mf->mf_max = length; + for (i = 0; i < DIRTY_MAX; i++) + mf_dirty_reduce(mf, i, length); + goto done; + } } for (;;) { @@ -338,6 +351,17 @@ void mf_dirty_append(struct mapfree_info *mf, enum dirty_stage stage, loff_t new traced_writeunlock(&dl->dl_lock, flags); } +void mf_dirty_reduce(struct mapfree_info *mf, enum dirty_stage stage, loff_t newlen) +{ + struct dirty_length *dl = _get_dl(mf, stage); + unsigned long flags; + + traced_writelock(&dl->dl_lock, flags); + if (dl->dl_length > newlen) + dl->dl_length = newlen; + traced_writeunlock(&dl->dl_lock, flags); +} + loff_t mf_dirty_length(struct mapfree_info *mf, enum dirty_stage stage) { struct dirty_length *dl = _get_dl(mf, stage); diff --git a/kernel/lib_mapfree.h b/kernel/lib_mapfree.h index 90156b74..e9b4c128 100644 --- a/kernel/lib_mapfree.h +++ b/kernel/lib_mapfree.h @@ -87,6 +87,7 @@ void mapfree_pages(struct mapfree_info *mf, int grace_keep); ////////////////// dirty IOs in append mode ////////////////// void mf_dirty_append(struct mapfree_info *mf, enum dirty_stage stage, loff_t newlen); +void mf_dirty_reduce(struct mapfree_info *mf, enum dirty_stage stage, loff_t newlen); loff_t mf_dirty_length(struct mapfree_info *mf, enum dirty_stage stage); ////////////////// dirty IOs on the fly //////////////////