From a9a1e19b0f55e2f54a6b1384af41707d951033da Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Tue, 27 Apr 2021 21:43:06 +0300 Subject: [PATCH] LU-14644 vvp: wait for nrpages to be updated truncate_inode_pages() says there still may be a page in a process of deletion upon return. wait for another thread which is doing __delete_from_page_cache() to get nrpages updated. Lustre-change: https://review.whamcloud.com/43464 Lustre-commit: 7d5d004506650c3739898e70d72c9a86b8aeeb88 Signed-off-by: Vitaly Fertman Change-Id: I165b3d0866efaf2eb7e977520ebba4ee831874ab HPE-bug-id: LUS-8842 --- lustre/include/lustre_compat.h | 2 ++ lustre/llite/llite_internal.h | 1 + lustre/llite/llite_lib.c | 56 ++++++++++++++++++++++++------------------ lustre/llite/vvp_object.c | 9 ++----- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/lustre/include/lustre_compat.h b/lustre/include/lustre_compat.h index c36f2bf..e2734c2 100644 --- a/lustre/include/lustre_compat.h +++ b/lustre/include/lustre_compat.h @@ -811,6 +811,8 @@ static inline bool bdev_integrity_enabled(struct block_device *bdev, int rw) #define page_tree i_pages #else #define i_pages tree_lock +#define xa_lock_irqsave(lockp, flags) spin_lock_irqsave(lockp, flags) +#define xa_unlock_irqrestore(lockp, flags) spin_unlock_irqrestore(lockp, flags) #define xa_lock_irq(lockp) spin_lock_irq(lockp) #define xa_unlock_irq(lockp) spin_unlock_irq(lockp) #endif diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 4bfa305..4f156ee 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -957,6 +957,7 @@ int ll_statfs_internal(struct ll_sb_info *sbi, struct obd_statfs *osfs, int ll_update_inode(struct inode *inode, struct lustre_md *md); void ll_update_inode_flags(struct inode *inode, int ext_flags); int ll_read_inode2(struct inode *inode, void *opaque); +void ll_truncate_inode_pages_final(struct inode *inode); void ll_delete_inode(struct inode *inode); int ll_iocontrol(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 80b3293..3b9809e 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1427,7 +1427,7 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md) lsm_md_dump(D_ERROR, lsm); GOTO(unlock, rc = -EINVAL); } - + up_read(&lli->lli_lsm_sem); down_write(&lli->lli_lsm_sem); /* clear existing lsm */ @@ -1440,7 +1440,7 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md) up_write(&lli->lli_lsm_sem); if (rc) RETURN(rc); - + /* set md->lmv to NULL, so the following free lustre_md will not free * this lsm. */ @@ -1453,7 +1453,7 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md) OBD_ALLOC_PTR(attr); if (!attr) GOTO(unlock, rc = -ENOMEM); - + /* validate the lsm */ rc = md_merge_attr(ll_i2mdexp(inode), lli->lli_lsm_md, attr, ll_md_blocking_ast); @@ -2053,6 +2053,34 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) return 0; } +void ll_truncate_inode_pages_final(struct inode *inode) +{ + struct address_space *mapping = &inode->i_data; + unsigned long nrpages; + unsigned long flags; + + truncate_inode_pages_final(mapping); + + /* Workaround for LU-118: Note nrpages may not be totally updated when + * truncate_inode_pages() returns, as there can be a page in the process + * of deletion (inside __delete_from_page_cache()) in the specified + * range. Thus mapping->nrpages can be non-zero when this function + * returns even after truncation of the whole mapping. Only do this if + * npages isn't already zero. + */ + nrpages = mapping->nrpages; + if (nrpages) { + xa_lock_irqsave(&mapping->i_pages, flags); + nrpages = mapping->nrpages; + xa_unlock_irqrestore(&mapping->i_pages, flags); + } /* Workaround end */ + + LASSERTF(nrpages == 0, "%s: inode="DFID"(%p) nrpages=%lu, " + "see https://jira.whamcloud.com/browse/LU-118\n", + ll_get_fsname(inode->i_sb, NULL, 0), + PFID(ll_inode2fid(inode)), inode, nrpages); +} + int ll_read_inode2(struct inode *inode, void *opaque) { struct lustre_md *md = opaque; @@ -2110,8 +2138,6 @@ int ll_read_inode2(struct inode *inode, void *opaque) void ll_delete_inode(struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); - struct address_space *mapping = &inode->i_data; - unsigned long nrpages; ENTRY; if (S_ISREG(inode->i_mode) && lli->lli_clob != NULL) { @@ -2125,26 +2151,8 @@ void ll_delete_inode(struct inode *inode) cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, inode->i_nlink ? CL_FSYNC_LOCAL : CL_FSYNC_DISCARD, 1); } - truncate_inode_pages_final(mapping); - /* Workaround for LU-118: Note nrpages may not be totally updated when - * truncate_inode_pages() returns, as there can be a page in the process - * of deletion (inside __delete_from_page_cache()) in the specified - * range. Thus mapping->nrpages can be non-zero when this function - * returns even after truncation of the whole mapping. Only do this if - * npages isn't already zero. - */ - nrpages = mapping->nrpages; - if (nrpages) { - xa_lock_irq(&mapping->i_pages); - nrpages = mapping->nrpages; - xa_unlock_irq(&mapping->i_pages); - } /* Workaround end */ - - LASSERTF(nrpages == 0, "%s: inode="DFID"(%p) nrpages=%lu, " - "see https://jira.whamcloud.com/browse/LU-118\n", - ll_get_fsname(inode->i_sb, NULL, 0), - PFID(ll_inode2fid(inode)), inode, nrpages); + ll_truncate_inode_pages_final(inode); #ifdef HAVE_SBOPS_EVICT_INODE ll_clear_inode(inode); diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index c3bf715..de4ecd8 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -168,13 +168,8 @@ static int vvp_prune(const struct lu_env *env, struct cl_object *obj) RETURN(rc); } - truncate_inode_pages(inode->i_mapping, 0); - if (inode->i_mapping->nrpages) { - CDEBUG(D_VFSTRACE, DFID ": still has %lu pages remaining\n", - PFID(lu_object_fid(&obj->co_lu)), - inode->i_mapping->nrpages); - RETURN(-EIO); - } + ll_truncate_inode_pages_final(inode); + clear_bit(AS_EXITING, &inode->i_mapping->flags); RETURN(0); } -- 1.8.3.1