Signed-off-by: Christoph Hellwig <hch@xxxxxx> Index: linux-2.6/fs/quota/dquot.c =================================================================== --- linux-2.6.orig/fs/quota/dquot.c 2010-03-06 12:47:10.086024843 +0100 +++ linux-2.6/fs/quota/dquot.c 2010-03-06 12:47:42.171272853 +0100 @@ -1676,8 +1676,10 @@ EXPORT_SYMBOL(dquot_free_inode); * * This operation can block, but only after everything is updated * A transaction must be started when entering this function. + * + * Called from ->setattr. */ -static int __dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask) +int dquot_transfer(struct inode *inode, struct iattr *iattr) { qsize_t space, cur_space; qsize_t rsv_space = 0; @@ -1689,18 +1691,23 @@ static int __dquot_transfer(struct inode /* First test before acquiring mutex - solves deadlocks when we * re-enter the quota code and are already holding the mutex */ - if (IS_NOQUOTA(inode)) + if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) return 0; + + dquot_initialize(inode); + /* Initialize the arrays */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { transfer_from[cnt] = NULL; transfer_to[cnt] = NULL; warntype_to[cnt] = QUOTA_NL_NOWARN; } - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (mask & (1 << cnt)) - transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt); - } + + if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) + transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid, cnt); + if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) + transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid, cnt); + down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); @@ -1775,29 +1782,6 @@ over_quota: transfer_from[cnt] = NULL; goto warn_put_all; } - -/* Wrapper for transferring ownership of an inode for uid/gid only - * Called from FSXXX_setattr() - */ -int dquot_transfer(struct inode *inode, struct iattr *iattr) -{ - qid_t chid[MAXQUOTAS]; - unsigned long mask = 0; - - if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) { - mask |= 1 << USRQUOTA; - chid[USRQUOTA] = iattr->ia_uid; - } - if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) { - mask |= 1 << GRPQUOTA; - chid[GRPQUOTA] = iattr->ia_gid; - } - if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { - dquot_initialize(inode); - return __dquot_transfer(inode, chid, mask); - } - return 0; -} EXPORT_SYMBOL(dquot_transfer); /* -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html