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 <wshilong@ddn.com>
Reviewed-on: https://review.whamcloud.com/38505
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Yang Sheng <ys@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
}
#ifdef HAVE_PROJECT_QUOTA
}
#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);
{
struct super_block *sb = inode->i_sb;
struct ldiskfs_inode_info *ei = LDISKFS_I(inode);
raw_inode = ldiskfs_raw_inode(&iloc);
if (!LDISKFS_FITS_IN_INODE(raw_inode, ei, i_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;
+ }
-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)
if (attr->la_valid & LA_PROJID &&
attr->la_projid != i_projid_read(inode)) {
#ifdef HAVE_PROJECT_QUOTA
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
#else
rc = -ENOTSUPP;
#endif
- rc = osd_quota_transfer(inode, attr);
+ rc = osd_quota_transfer(inode, attr, handle);
}
static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj,
}
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;
{
struct inode *inode = obj->oo_inode;
__u64 valid = attr->la_valid;
if ((valid & LA_MTIME) && (attr->la_mtime == inode->i_mtime.tv_sec))
attr->la_valid &= ~LA_MTIME;
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 (likely(result == 0)) {
}
if (likely(result == 0)) {
- osd_attr_init(info, obj, attr, dof);
+ osd_attr_init(info, obj, attr, dof, th);
#ifdef HAVE_PROJECT_QUOTA
if (LDISKFS_I(pobj->oo_inode)->i_flags & LUSTRE_PROJINHERIT_FL &&
i_projid_read(pobj->oo_inode) != 0) {
#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 "
if (rc) {
CERROR("%s: quota transfer failed: rc = %d. Is project "
"quota enforcement enabled on the ldiskfs "
local writeconf=$2
local dne_upgrade=${dne_upgrade:-"no"}
local dom_upgrade=${dom_upgrade:-"no"}
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
local ff_convert=${ff_convert:-"no"}
local shall_cleanup_mdt=false
local shall_cleanup_mdt1=false
error_noexit "import zfs pool failed"
return 1
}
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"
fi
$r $LCTL set_param debug="$PTLDEBUG"
+ 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"
[[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) == 0 ]] ||
error "MDD orphan cleanup thread not quit"
t32_check
for tarball in $tarballs; do
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=$?
-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) ]] ||
test_32e() {
[[ "$MDS1_VERSION" -ge $(version_code 2.10.56) ]] ||