diff options
-rw-r--r-- | fs/quota/dquot.c | 32 | ||||
-rw-r--r-- | include/linux/quota.h | 2 | ||||
-rw-r--r-- | include/linux/quotaops.h | 2 |
3 files changed, 22 insertions, 14 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 5a831dc5ab28..4d2041fddefc 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -1695,15 +1695,13 @@ EXPORT_SYMBOL(dquot_free_inode); | |||
1695 | * This operation can block, but only after everything is updated | 1695 | * This operation can block, but only after everything is updated |
1696 | * A transaction must be started when entering this function. | 1696 | * A transaction must be started when entering this function. |
1697 | */ | 1697 | */ |
1698 | int dquot_transfer(struct inode *inode, struct iattr *iattr) | 1698 | int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask) |
1699 | { | 1699 | { |
1700 | qsize_t space, cur_space; | 1700 | qsize_t space, cur_space; |
1701 | qsize_t rsv_space = 0; | 1701 | qsize_t rsv_space = 0; |
1702 | struct dquot *transfer_from[MAXQUOTAS]; | 1702 | struct dquot *transfer_from[MAXQUOTAS]; |
1703 | struct dquot *transfer_to[MAXQUOTAS]; | 1703 | struct dquot *transfer_to[MAXQUOTAS]; |
1704 | int cnt, ret = QUOTA_OK; | 1704 | int cnt, ret = QUOTA_OK; |
1705 | int chuid = iattr->ia_valid & ATTR_UID && inode->i_uid != iattr->ia_uid, | ||
1706 | chgid = iattr->ia_valid & ATTR_GID && inode->i_gid != iattr->ia_gid; | ||
1707 | char warntype_to[MAXQUOTAS]; | 1705 | char warntype_to[MAXQUOTAS]; |
1708 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; | 1706 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; |
1709 | 1707 | ||
@@ -1717,13 +1715,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1717 | transfer_to[cnt] = NULL; | 1715 | transfer_to[cnt] = NULL; |
1718 | warntype_to[cnt] = QUOTA_NL_NOWARN; | 1716 | warntype_to[cnt] = QUOTA_NL_NOWARN; |
1719 | } | 1717 | } |
1720 | if (chuid) | 1718 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1721 | transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid, | 1719 | if (mask & (1 << cnt)) |
1722 | USRQUOTA); | 1720 | transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt); |
1723 | if (chgid) | 1721 | } |
1724 | transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid, | ||
1725 | GRPQUOTA); | ||
1726 | |||
1727 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1722 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1728 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | 1723 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ |
1729 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1724 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
@@ -1799,12 +1794,25 @@ over_quota: | |||
1799 | } | 1794 | } |
1800 | EXPORT_SYMBOL(dquot_transfer); | 1795 | EXPORT_SYMBOL(dquot_transfer); |
1801 | 1796 | ||
1802 | /* Wrapper for transferring ownership of an inode */ | 1797 | /* Wrapper for transferring ownership of an inode for uid/gid only |
1798 | * Called from FSXXX_setattr() | ||
1799 | */ | ||
1803 | int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) | 1800 | int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) |
1804 | { | 1801 | { |
1802 | qid_t chid[MAXQUOTAS]; | ||
1803 | unsigned long mask = 0; | ||
1804 | |||
1805 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) { | ||
1806 | mask |= 1 << USRQUOTA; | ||
1807 | chid[USRQUOTA] = iattr->ia_uid; | ||
1808 | } | ||
1809 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) { | ||
1810 | mask |= 1 << GRPQUOTA; | ||
1811 | chid[GRPQUOTA] = iattr->ia_gid; | ||
1812 | } | ||
1805 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { | 1813 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { |
1806 | vfs_dq_init(inode); | 1814 | vfs_dq_init(inode); |
1807 | if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) | 1815 | if (inode->i_sb->dq_op->transfer(inode, chid, mask) == NO_QUOTA) |
1808 | return 1; | 1816 | return 1; |
1809 | } | 1817 | } |
1810 | return 0; | 1818 | return 0; |
diff --git a/include/linux/quota.h b/include/linux/quota.h index 92547a57e25a..edf34f2fe87d 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -301,7 +301,7 @@ struct dquot_operations { | |||
301 | int (*alloc_inode) (const struct inode *, qsize_t); | 301 | int (*alloc_inode) (const struct inode *, qsize_t); |
302 | int (*free_space) (struct inode *, qsize_t); | 302 | int (*free_space) (struct inode *, qsize_t); |
303 | int (*free_inode) (const struct inode *, qsize_t); | 303 | int (*free_inode) (const struct inode *, qsize_t); |
304 | int (*transfer) (struct inode *, struct iattr *); | 304 | int (*transfer) (struct inode *, qid_t *, unsigned long); |
305 | int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ | 305 | int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ |
306 | struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */ | 306 | struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */ |
307 | void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */ | 307 | void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */ |
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index e563a20cff4f..e1cae204b5d9 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
@@ -43,7 +43,7 @@ void dquot_release_reserved_space(struct inode *inode, qsize_t number); | |||
43 | int dquot_free_space(struct inode *inode, qsize_t number); | 43 | int dquot_free_space(struct inode *inode, qsize_t number); |
44 | int dquot_free_inode(const struct inode *inode, qsize_t number); | 44 | int dquot_free_inode(const struct inode *inode, qsize_t number); |
45 | 45 | ||
46 | int dquot_transfer(struct inode *inode, struct iattr *iattr); | 46 | int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask); |
47 | int dquot_commit(struct dquot *dquot); | 47 | int dquot_commit(struct dquot *dquot); |
48 | int dquot_acquire(struct dquot *dquot); | 48 | int dquot_acquire(struct dquot *dquot); |
49 | int dquot_release(struct dquot *dquot); | 49 | int dquot_release(struct dquot *dquot); |