diff options
-rw-r--r-- | fs/xfs/xfs_quota.h | 25 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_dquot.c | 9 |
2 files changed, 25 insertions, 9 deletions
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index c3483bab9cde..40d508be9a00 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h | |||
@@ -108,11 +108,28 @@ typedef struct xfs_dqblk { | |||
108 | { XFS_DQ_FREEING, "FREEING" } | 108 | { XFS_DQ_FREEING, "FREEING" } |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * In the worst case, when both user and group quotas are on, | 111 | * We have the possibility of all three quota types being active at once, and |
112 | * we can have a max of three dquots changing in a single transaction. | 112 | * hence free space modification requires modification of all three current |
113 | * dquots in a single transaction. For this case we need to have a reservation | ||
114 | * of at least 3 dquots. | ||
115 | * | ||
116 | * However, a chmod operation can change both UID and GID in a single | ||
117 | * transaction, resulting in requiring {old, new} x {uid, gid} dquots to be | ||
118 | * modified. Hence for this case we need to reserve space for at least 4 dquots. | ||
119 | * | ||
120 | * And in the worst case, there's a rename operation that can be modifying up to | ||
121 | * 4 inodes with dquots attached to them. In reality, the only inodes that can | ||
122 | * have their dquots modified are the source and destination directory inodes | ||
123 | * due to directory name creation and removal. That can require space allocation | ||
124 | * and/or freeing on both directory inodes, and hence all three dquots on each | ||
125 | * inode can be modified. And if the directories are world writeable, all the | ||
126 | * dquots can be unique and so 6 dquots can be modified.... | ||
127 | * | ||
128 | * And, of course, we also need to take into account the dquot log format item | ||
129 | * used to describe each dquot. | ||
113 | */ | 130 | */ |
114 | #define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3) | 131 | #define XFS_DQUOT_LOGRES(mp) \ |
115 | 132 | ((sizeof(struct xfs_dq_logformat) + sizeof(struct xfs_disk_dquot)) * 6) | |
116 | 133 | ||
117 | /* | 134 | /* |
118 | * These are the structures used to lay out dquots and quotaoff | 135 | * These are the structures used to lay out dquots and quotaoff |
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 3ba64d540168..db041a5e1f6d 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c | |||
@@ -291,11 +291,10 @@ xfs_trans_mod_dquot( | |||
291 | 291 | ||
292 | 292 | ||
293 | /* | 293 | /* |
294 | * Given an array of dqtrx structures, lock all the dquots associated | 294 | * Given an array of dqtrx structures, lock all the dquots associated and join |
295 | * and join them to the transaction, provided they have been modified. | 295 | * them to the transaction, provided they have been modified. We know that the |
296 | * We know that the highest number of dquots (of one type - usr OR grp), | 296 | * highest number of dquots of one type - usr, grp OR prj - involved in a |
297 | * involved in a transaction is 2 and that both usr and grp combined - 3. | 297 | * transaction is 2 so we don't need to make this very generic. |
298 | * So, we don't attempt to make this very generic. | ||
299 | */ | 298 | */ |
300 | STATIC void | 299 | STATIC void |
301 | xfs_trans_dqlockedjoin( | 300 | xfs_trans_dqlockedjoin( |