From 716de353b7b65fa506ce7f31f59c187a19f44b64 Mon Sep 17 00:00:00 2001 From: Alexey Lyashkov Date: Thu, 10 Feb 2022 15:46:00 +0300 Subject: [PATCH] LU-15542 osd-ldiskfs: exclude EA inode from processing EA inode is ldiskfs internal object and this should be excluded at any osd access. Panic fixed by this change because iterator will return an error when tries to access to the ea inode. osd_ea_fid_get()) Process leaving (rc=18446744073709551614 : -2 osd_it_ea_rec()) Process leaving (rc=18446744073709551614 : -2) osd_it_ea_next()) Process entered HPe-bug-id: LUS-10683 Signed-off-by: Alexey Lyashkov Change-Id: I73e5325721ae28ea380e9d216c6c6cf7fa0ac4ea Reviewed-on: https://review.whamcloud.com/46486 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andrew Perepechko Reviewed-by: Alexander Zarochentsev Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_compat.c | 9 ----- lustre/osd-ldiskfs/osd_handler.c | 64 +++++++-------------------------- lustre/osd-ldiskfs/osd_oi.c | 8 ----- lustre/osd-ldiskfs/osd_scrub.c | 12 ------- lustre/tests/conf-sanity.sh | 76 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 86 insertions(+), 83 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_compat.c b/lustre/osd-ldiskfs/osd_compat.c index 23e623a..80a87a0 100644 --- a/lustre/osd-ldiskfs/osd_compat.c +++ b/lustre/osd-ldiskfs/osd_compat.c @@ -726,15 +726,6 @@ static int osd_obj_update_entry(struct osd_thread_info *info, GOTO(out, rc); } - /* - * The EA inode should NOT be in OI, old OI scrub may added - * such OI mapping by wrong, replace it. - */ - if (unlikely(osd_is_ea_inode(inode))) { - iput(inode); - goto update; - } - rc = osd_get_lma(info, inode, dentry, &info->oti_ost_attrs); if (rc == -ENODATA) { rc = osd_get_idif(info, inode, dentry, oi_fid); diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index cac70ab..c0f3da9 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -517,11 +517,18 @@ struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev, iput(inode); inode = ERR_PTR(-ESTALE); } else if (is_bad_inode(inode)) { - rc = -ENOENT; CWARN("%s: bad inode: ino = %u: rc = %d\n", - osd_dev2name(dev), id->oii_ino, rc); + osd_dev2name(dev), id->oii_ino, -ENOENT); iput(inode); - inode = ERR_PTR(rc); + inode = ERR_PTR(-ENOENT); + } else if (osd_is_ea_inode(inode)) { + /* + * EA inode is internal ldiskfs object, should don't visible + * on osd + */ + CDEBUG(D_INODE, "EA inode: ino = %u\n", id->oii_ino); + iput(inode); + inode = ERR_PTR(-ENOENT); } else if ((rc = osd_attach_jinode(inode))) { iput(inode); inode = ERR_PTR(rc); @@ -634,7 +641,7 @@ static struct inode *osd_iget_check(struct osd_thread_info *info, */ again: - inode = osd_ldiskfs_iget(osd_sb(dev), id->oii_ino); + inode = osd_iget(info, dev, id); if (IS_ERR(inode)) { rc = PTR_ERR(inode); if (!trusted && (rc == -ENOENT || rc == -ESTALE)) @@ -645,40 +652,6 @@ again: GOTO(put, rc); } - if (is_bad_inode(inode)) { - rc = -ENOENT; - if (!trusted) - goto check_oi; - - CDEBUG(D_INODE, "bad inode for FID: "DFID", ino = %u\n", - PFID(fid), id->oii_ino); - GOTO(put, rc); - } - - if (id->oii_gen != OSD_OII_NOGEN && - inode->i_generation != id->oii_gen) { - rc = -ESTALE; - if (!trusted) - goto check_oi; - - CDEBUG(D_INODE, "unmatched inode for FID: "DFID", ino = %u, " - "oii_gen = %u, i_generation = %u\n", PFID(fid), - id->oii_ino, id->oii_gen, inode->i_generation); - GOTO(put, rc); - } - - if (inode->i_nlink == 0) { - rc = -ENOENT; - if (!trusted) - goto check_oi; - - CDEBUG(D_INODE, "stale inode for FID: "DFID", ino = %u\n", - PFID(fid), id->oii_ino); - GOTO(put, rc); - } - - ldiskfs_clear_inode_state(inode, LDISKFS_STATE_LUSTRE_DESTROY); - check_oi: if (rc != 0) { __u32 saved_ino = id->oii_ino; @@ -752,19 +725,6 @@ check_oi: rc = -ENOENT; else rc = -EREMCHG; - } else { - if (id->oii_gen == OSD_OII_NOGEN) - osd_id_gen(id, inode->i_ino, inode->i_generation); - - /* - * Do not update file c/mtime in ldiskfs. - * NB: we don't have any lock to protect this because we don't - * have reference on osd_object now, but contention with - * another lookup + attr_set can't happen in the tiny window - * between if (...) and set S_NOCMTIME. - */ - if (!(inode->i_flags & S_NOCMTIME)) - inode->i_flags |= S_NOCMTIME; } GOTO(put, rc); @@ -1179,7 +1139,7 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj, /* Search order: 3. OI files. */ result = osd_oi_lookup(info, dev, fid, id, OI_CHECK_FLD); if (result == -ENOENT) { - if (!(fid_is_norm(fid) || fid_is_igif(fid)) || + if (!fid_is_norm(fid) || fid_is_on_ost(info, dev, fid, OI_CHECK_FLD) || !ldiskfs_test_bit(osd_oi_fid2idx(dev, fid), sf->sf_oi_bitmap)) diff --git a/lustre/osd-ldiskfs/osd_oi.c b/lustre/osd-ldiskfs/osd_oi.c index 7fb40f3..47df02b 100644 --- a/lustre/osd-ldiskfs/osd_oi.c +++ b/lustre/osd-ldiskfs/osd_oi.c @@ -742,14 +742,6 @@ int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, return rc; } - /* The EA inode should NOT be in OI, old OI scrub may added - * such OI mapping by wrong, replace it. - */ - if (unlikely(osd_is_ea_inode(inode))) { - iput(inode); - goto update; - } - rc = osd_get_lma(info, inode, &info->oti_obj_dentry, &info->oti_ost_attrs); iput(inode); diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index ffe4a0b..0605c31 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -290,10 +290,6 @@ osd_scrub_check_update(struct osd_thread_info *info, struct osd_device *dev, GOTO(out, rc); } - /* The inode has been reused as EA inode, ignore it. */ - if (unlikely(osd_is_ea_inode(inode))) - GOTO(out, rc = 0); - sf->sf_flags |= SF_UPGRADE; sf->sf_internal_flags &= ~SIF_NO_HANDLE_OLD_FID; dev->od_check_ff = 1; @@ -333,10 +329,6 @@ iget: rc = 0; GOTO(out, rc); } - - /* The inode has been reused as EA inode, ignore it. */ - if (unlikely(osd_is_ea_inode(inode))) - GOTO(out, rc = 0); } switch (val) { @@ -628,10 +620,6 @@ static int osd_iit_iget(struct osd_thread_info *info, struct osd_device *dev, if (dev->od_is_ost && S_ISREG(inode->i_mode) && inode->i_nlink > 1) dev->od_scrub.os_scrub.os_has_ml_file = 1; - /* It is an EA inode, no OI mapping for it, skip it. */ - if (osd_is_ea_inode(inode)) - GOTO(put, rc = SCRUB_NEXT_CONTINUE); - if (scrub && ldiskfs_test_inode_state(inode, LDISKFS_STATE_LUSTRE_NOSCRUB)) { /* Only skip it for the first OI scrub accessing. */ diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 81c9a1e..e7de934 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -5041,7 +5041,7 @@ test_60() { # LU-471 } run_test 60 "check mkfs.lustre --mkfsoptions -E -O options setting" -test_61() { # LU-80 +test_61a() { # LU-80 local lxattr=$(large_xattr_enabled) [ "$MDS1_VERSION" -ge $(version_code 2.1.53) ] || @@ -5115,7 +5115,79 @@ test_61() { # LU-80 rm -f $file cleanup || error "stopping systems failed" } -run_test 61 "large xattr" +run_test 61a "large xattr" + +test_61b() { # LU-80 + local lxattr=$(large_xattr_enabled) + + [ "$MDS1_VERSION" -ge $(version_code 2.1.53) ] || + skip "Need MDS version at least 2.1.53" + + if [ "$mds1_FSTYPE" != ldiskfs ]; then + skip "ldiskfs specific bug" + fi + + if ! large_xattr_enabled; then + lxattr=true + + for num in $(seq $MDSCOUNT); do + do_facet mds${num} $TUNE2FS -O ea_inode \ + $(mdsdevname $num) || + error "tune2fs on mds $num failed" + done + fi + + setup || error "setting up the filesystem failed" + client_up || error "starting client failed" + + local _file=$MOUNT/panda + local large_value="$(generate_string $(max_xattr_size))" + local name="trusted.big" + + touch ${_file} || error "touch ${_file} failed" + setfattr -n $name -v $large_value ${_file} || + error "saving $name on $file failed" + + MDT_DEV="${FSNAME}-MDT0000" + MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/}) + + stopall || error "stopping for e2fsck run" + + + ino=$(do_facet $SINGLEMDS "$DEBUGFS -R 'stat /ROOT/panda' \ + ${MDT_DEVNAME} | grep trusted.big") + ino=$(echo "${ino}" | awk '{print $2;}') + echo "large ea "${ino} + + do_facet $SINGLEMDS "$DEBUGFS -w -R \\\"ln $ino /lost+found\\\" \ + ${MDT_DEVNAME}" + + setup_noconfig || error "remounting the filesystem failed" + + do_facet $SINGLEMDS $LCTL lfsck_start -M ${MDT_DEV} -t namespace || { + error "can't start lfsck namespace" + } + + sleep 5 + wait_update_facet $SINGLEMDS "$LCTL get_param -n \ + mdd.${MDT_DEV}.lfsck_namespace | + awk '/^status/ { print \\\$2 }'" "completed" 32 || { + error "(2) unexpected status" + } + + stopall || error "stopping for e2fsck run" + for num in $(seq $MDSCOUNT); do + run_e2fsck $(facet_active_host mds$num) \ + $(mdsdevname $num) "-y" || + error "e2fsck MDT$num failed" + done + setup_noconfig || error "remounting the filesystem failed" + + # need to delete this file to avoid problems in other tests + rm -f $file + cleanup || error "stopping systems failed" +} +run_test 61b "large xattr" test_62() { if [ "$mds1_FSTYPE" != ldiskfs ]; then -- 1.8.3.1