From 57108489a3eb2ff6fc3994dbda0649ae445d6cb7 Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Wed, 6 May 2020 12:45:25 +0800 Subject: [PATCH] LU-13519 osd-ldiskfs: expand inode project quota for upgrading When upgrading filesystem, it is possible that inode it not big enough to hold project id field, and in that case set project ID will return EOVERFLOW error. Since ldiskfs have the logic to expand inode size automatically, we could add similar logic for project quota. Considering this as an rare case, we just call ldiskfs_mark_inode_dirty() which will try to expand instead of exporting more functions. Change-Id: I941f33ce8f45d2015acc0a33c5b54cf3a771a452 Signed-off-by: Wang Shilong Reviewed-on: https://review.whamcloud.com/38505 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Yang Sheng Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_handler.c | 34 +++++++++++++++++++++++----------- lustre/tests/conf-sanity.sh | 29 ++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index ef29623..58a8cc2 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2926,7 +2926,8 @@ static int osd_inode_setattr(const struct lu_env *env, } #ifdef HAVE_PROJECT_QUOTA -static int osd_transfer_project(struct inode *inode, __u32 projid) +static int osd_transfer_project(struct inode *inode, __u32 projid, + struct thandle *handle) { struct super_block *sb = inode->i_sb; struct ldiskfs_inode_info *ei = LDISKFS_I(inode); @@ -2958,9 +2959,18 @@ static int osd_transfer_project(struct inode *inode, __u32 projid) raw_inode = ldiskfs_raw_inode(&iloc); if (!LDISKFS_FITS_IN_INODE(raw_inode, ei, i_projid)) { - err = -EOVERFLOW; - brelse(iloc.bh); - return err; + struct osd_thandle *oh = + container_of0(handle, struct osd_thandle, + ot_super); + /** + * try to expand inode size automatically. + */ + ldiskfs_mark_inode_dirty(oh->ot_handle, inode); + if (!LDISKFS_FITS_IN_INODE(raw_inode, ei, i_projid)) { + err = -EOVERFLOW; + brelse(iloc.bh); + return err; + } } brelse(iloc.bh); @@ -2977,7 +2987,8 @@ static int osd_transfer_project(struct inode *inode, __u32 projid) } #endif -static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr) +static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr, + struct thandle *handle) { int rc; @@ -3012,7 +3023,7 @@ static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr) if (attr->la_valid & LA_PROJID && attr->la_projid != i_projid_read(inode)) { #ifdef HAVE_PROJECT_QUOTA - rc = osd_transfer_project(inode, attr->la_projid); + rc = osd_transfer_project(inode, attr->la_projid, handle); #else rc = -ENOTSUPP; #endif @@ -3073,7 +3084,7 @@ static int osd_attr_set(const struct lu_env *env, inode = obj->oo_inode; - rc = osd_quota_transfer(inode, attr); + rc = osd_quota_transfer(inode, attr, handle); if (rc) return rc; @@ -3361,7 +3372,8 @@ static void osd_ah_init(const struct lu_env *env, struct dt_allocation_hint *ah, } static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj, - struct lu_attr *attr, struct dt_object_format *dof) + struct lu_attr *attr, struct dt_object_format *dof, + struct thandle *handle) { struct inode *inode = obj->oo_inode; __u64 valid = attr->la_valid; @@ -3378,7 +3390,7 @@ static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj, if ((valid & LA_MTIME) && (attr->la_mtime == inode->i_mtime.tv_sec)) attr->la_valid &= ~LA_MTIME; - result = osd_quota_transfer(inode, attr); + result = osd_quota_transfer(inode, attr, handle); if (result) return; @@ -3429,7 +3441,7 @@ static int __osd_create(struct osd_thread_info *info, struct osd_object *obj, } if (likely(result == 0)) { - osd_attr_init(info, obj, attr, dof); + osd_attr_init(info, obj, attr, dof, th); osd_object_init0(obj); } @@ -3894,7 +3906,7 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env, #ifdef HAVE_PROJECT_QUOTA if (LDISKFS_I(pobj->oo_inode)->i_flags & LUSTRE_PROJINHERIT_FL && i_projid_read(pobj->oo_inode) != 0) { - rc = osd_transfer_project(local, 0); + rc = osd_transfer_project(local, 0, th); if (rc) { CERROR("%s: quota transfer failed: rc = %d. Is project " "quota enforcement enabled on the ldiskfs " diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 3c6a42a..9e5dae1 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -1681,6 +1681,7 @@ t32_test() { local writeconf=$2 local dne_upgrade=${dne_upgrade:-"no"} local dom_upgrade=${dom_upgrade:-"no"} + local project_upgrade=${project_upgrade:-"no"} local ff_convert=${ff_convert:-"no"} local shall_cleanup_mdt=false local shall_cleanup_mdt1=false @@ -1777,6 +1778,16 @@ t32_test() { error_noexit "import zfs pool failed" return 1 } + elif [ "$project_upgrade" != "no" ]; then + ! $r tune2fs -O project $mdt_dev && + error_noexit "enable project on mdt0 failed" && + return 1 + $mdt2_is_available && ! $r tune2fs "-O project" $mdt2_dev && + error_noexit "enable project on mdt failed" && + return 1 + ! $r tune2fs -O project $ost_dev && + error_noexit "enable project on mdt failed" && + return 1 fi $r $LCTL set_param debug="$PTLDEBUG" @@ -2342,6 +2353,13 @@ t32_test() { return 1 } + if [ "$mds1_FSTYPE" == ldiskfs -a \ + "$project_upgrade" != "no" ]; then + ! $LFS project -d -p 1 $tmp/mnt/lustre/* && + error_noexit "set project failed" && + return 1 + fi + [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) == 0 ]] || error "MDD orphan cleanup thread not quit" @@ -2468,12 +2486,17 @@ test_32d() { t32_check for tarball in $tarballs; do - banner "testing $tarball upgrade with ff convert" - ff_convert=yes t32_test $tarball || rc=$? + banner "testing $tarball upgrade with ff convert and project upgrade" + project_upgrade="no" + [[ "$MDS1_VERSION" -ge $(version_code 2.13.54) ]] && + [[ "$tarball" =~ "disk2_4-ldiskfs" ]] && + project_upgrade="yes" + project_upgrade=$project_upgrade ff_convert=yes t32_test \ + $tarball || rc=$? done return $rc } -run_test 32d "convert ff test" +run_test 32d "convert ff and project quota upgrade test" test_32e() { [[ "$MDS1_VERSION" -ge $(version_code 2.10.56) ]] || -- 1.8.3.1