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); |
