From 6fbfb566d114168b7d5fd01092c1ecdd17d91116 Mon Sep 17 00:00:00 2001 From: Andrew Perepechko Date: Wed, 9 Jun 2010 05:32:43 +0400 Subject: [PATCH] b=22679 quota fixes for mds_orphan_add_link allow quota overruns when linking orphans to PENDING i=Johann Lombardi i=ZhiYong Tian --- lustre/ChangeLog | 7 +++++++ lustre/mds/mds_reint.c | 9 +++++++++ lustre/quota/quota_interface.c | 10 +++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 590acf2..d16a87c 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -12,6 +12,13 @@ tbd Oracle, Inc. * The async journal commit feature (bug 19128) and the cancel lock before replay feature (bug 16774) are disabled by default. +Severity : normal +Bugzilla : 22679 +Description: mds_orphan_add_link()) error linking orphan to PENDING +Details : quota limits might disallow linking orphans to PENDING + when unlinking a file - temporary raise threads' privileges + when processing unlinks. + Severity : enhancement Bugzilla : 15253 Description: add conf-param -d option to remove permanent settings. diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 843ca39..98a4b85 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -1726,6 +1726,7 @@ static int mds_orphan_add_link(struct mds_update_record *rec, struct dentry *pending_child; char fidname[LL_FID_NAMELEN]; int fidlen = 0, rc, mode; + int ignoring_quota; ENTRY; LASSERT(inode != NULL); @@ -1759,6 +1760,11 @@ static int mds_orphan_add_link(struct mds_update_record *rec, /* avoid vfs_link upon 0 nlink inode, inc by 2 instead of 1 because * ext3_inc_count() can reset i_nlink for indexed directory */ inode->i_nlink += 2; + + /* Temporarily raise the resource capability as we do not want to + * get -EDQUOT from VFS during this unlink operation */ + ignoring_quota = lquota_enforce(mds_quota_interface_ref, obd, 1); + rc = ll_vfs_link(dentry, mds->mds_vfsmnt, pending_dir, pending_child, mds->mds_vfsmnt); if (rc) @@ -1784,6 +1790,9 @@ static int mds_orphan_add_link(struct mds_update_record *rec, if (inode->i_sb->s_op->dirty_inode) inode->i_sb->s_op->dirty_inode(inode); + if (!ignoring_quota) + lquota_enforce(mds_quota_interface_ref, obd, 0); + if (rc) GOTO(out_dput, rc); diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c index 849d890..fbd2602 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -145,12 +145,15 @@ static int filter_quota_clearinfo(struct obd_export *exp, struct obd_device *obd RETURN(0); } -static int filter_quota_enforce(struct obd_device *obd, unsigned int ignore) +static int target_quota_enforce(struct obd_device *obd, unsigned int ignore) { ENTRY; if (!ll_sb_any_quota_active(obd->u.obt.obt_sb)) - RETURN(0); + RETURN(-EINVAL); + + if (!!cfs_cap_raised(CFS_CAP_SYS_RESOURCE) == !!ignore) + RETURN(-EALREADY); if (ignore) { CDEBUG(D_QUOTA, "blocks will be written with ignoring quota.\n"); @@ -895,6 +898,7 @@ quota_interface_t mds_quota_interface = { .quota_recovery = mds_quota_recovery, .quota_adjust = mds_quota_adjust, .quota_chkquota = mds_quota_check, + .quota_enforce = target_quota_enforce, .quota_acquire = mds_quota_acquire, .quota_pending_commit = mds_quota_pending_commit, }; @@ -906,7 +910,7 @@ quota_interface_t filter_quota_interface = { .quota_ctl = filter_quota_ctl, .quota_setinfo = filter_quota_setinfo, .quota_clearinfo = filter_quota_clearinfo, - .quota_enforce = filter_quota_enforce, + .quota_enforce = target_quota_enforce, .quota_getflag = filter_quota_getflag, .quota_acquire = filter_quota_acquire, .quota_adjust = filter_quota_adjust, -- 1.8.3.1