infra: account for truncated files

This commit is contained in:
Thomas Schoebel-Theuer 2020-04-04 10:42:01 +02:00
parent 5d4f14c43d
commit 48c53bbe47
2 changed files with 26 additions and 1 deletions

View File

@ -146,9 +146,22 @@ struct mapfree_info *mapfree_get(const char *name, int flags)
} }
up_read(&mapfree_mutex); 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; goto done;
} }
}
for (;;) { for (;;) {
struct address_space *mapping; struct address_space *mapping;
@ -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); 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) loff_t mf_dirty_length(struct mapfree_info *mf, enum dirty_stage stage)
{ {
struct dirty_length *dl = _get_dl(mf, stage); struct dirty_length *dl = _get_dl(mf, stage);

View File

@ -87,6 +87,7 @@ void mapfree_pages(struct mapfree_info *mf, int grace_keep);
////////////////// dirty IOs in append mode ////////////////// ////////////////// dirty IOs in append mode //////////////////
void mf_dirty_append(struct mapfree_info *mf, enum dirty_stage stage, loff_t newlen); 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); loff_t mf_dirty_length(struct mapfree_info *mf, enum dirty_stage stage);
////////////////// dirty IOs on the fly ////////////////// ////////////////// dirty IOs on the fly //////////////////