Document update
[ct-quota-pq.git] / quota-transfer.patch
blob2ca75226d3cf4e4e25e2bcc871e265a40d808d95
1 quota: generalize quota transfer interface
3 Current quota transfer interface support only uid/gid.
4 This patch extend interface in order to support various quotas types
5 The goal is accomplished without changes in most frequently used
6 vfs_dq_transfer() func.
9 diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
10 index 39b49c4..9e51459 100644
11 --- a/fs/quota/dquot.c
12 +++ b/fs/quota/dquot.c
13 @@ -1697,15 +1697,13 @@ qsize_t dquot_get_reserved_space(struct inode *inode)
14 * This operation can block, but only after everything is updated
15 * A transaction must be started when entering this function.
17 -int dquot_transfer(struct inode *inode, struct iattr *iattr)
18 +int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask)
20 qsize_t space, cur_space;
21 qsize_t rsv_space = 0;
22 struct dquot *transfer_from[MAXQUOTAS];
23 struct dquot *transfer_to[MAXQUOTAS];
24 int cnt, ret = QUOTA_OK;
25 - int chuid = iattr->ia_valid & ATTR_UID && inode->i_uid != iattr->ia_uid,
26 - chgid = iattr->ia_valid & ATTR_GID && inode->i_gid != iattr->ia_gid;
27 char warntype_to[MAXQUOTAS];
28 char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
30 @@ -1719,13 +1717,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
31 transfer_to[cnt] = NULL;
32 warntype_to[cnt] = QUOTA_NL_NOWARN;
34 - if (chuid)
35 - transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid,
36 - USRQUOTA);
37 - if (chgid)
38 - transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid,
39 - GRPQUOTA);
41 + for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
42 + if (mask & (1 << cnt))
43 + transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt);
44 + }
45 down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
46 /* Now recheck reliably when holding dqptr_sem */
47 if (IS_NOQUOTA(inode)) { /* File without quota accounting? */
48 @@ -1809,12 +1804,25 @@ over_quota:
50 EXPORT_SYMBOL(dquot_transfer);
52 -/* Wrapper for transferring ownership of an inode */
53 +/* Wrapper for transferring ownership of an inode for uid/gid only
54 + * Called from FSXXX_setattr()
55 + */
56 int vfs_dq_transfer(struct inode *inode, struct iattr *iattr)
58 + qid_t chid[MAXQUOTAS];
59 + unsigned long mask = 0;
61 + if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) {
62 + mask |= 1 << USRQUOTA;
63 + chid[USRQUOTA] = iattr->ia_uid;
64 + }
65 + if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) {
66 + mask |= 1 << GRPQUOTA;
67 + chid[GRPQUOTA] = iattr->ia_gid;
68 + }
69 if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) {
70 vfs_dq_init(inode);
71 - if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
72 + if (inode->i_sb->dq_op->transfer(inode, chid, mask) == NO_QUOTA)
73 return 1;
75 return 0;
76 diff --git a/include/linux/quota.h b/include/linux/quota.h
77 index 78c4889..09c52b9 100644
78 --- a/include/linux/quota.h
79 +++ b/include/linux/quota.h
80 @@ -299,7 +299,7 @@ struct dquot_operations {
81 int (*alloc_inode) (const struct inode *, qsize_t);
82 int (*free_space) (struct inode *, qsize_t);
83 int (*free_inode) (const struct inode *, qsize_t);
84 - int (*transfer) (struct inode *, struct iattr *);
85 + int (*transfer) (struct inode *, qid_t *, unsigned long);
86 int (*write_dquot) (struct dquot *); /* Ordinary dquot write */
87 struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */
88 void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */
89 diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
90 index 3ebb231..6554348 100644
91 --- a/include/linux/quotaops.h
92 +++ b/include/linux/quotaops.h
93 @@ -47,7 +47,7 @@ qsize_t dquot_get_reserved_space(struct inode *inode);
94 int dquot_free_space(struct inode *inode, qsize_t number);
95 int dquot_free_inode(const struct inode *inode, qsize_t number);
97 -int dquot_transfer(struct inode *inode, struct iattr *iattr);
98 +int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask);
99 int dquot_commit(struct dquot *dquot);
100 int dquot_acquire(struct dquot *dquot);
101 int dquot_release(struct dquot *dquot);