]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/ocfs2-Add-quota-calls-for-allocation-and-freeing-of.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / ocfs2-Add-quota-calls-for-allocation-and-freeing-of.patch
1 From: Jan Kara <jack@suse.cz>
2 References: fate#302681
3 Subject: [PATCH 25/28] ocfs2: Add quota calls for allocation and freeing of inodes and space
4 Patch-mainline: 2.6.29?
5
6 Add quota calls for allocation and freeing of inodes and space, also update
7 estimates on number of needed credits for a transaction. Move out inode
8 allocation from ocfs2_mknod_locked() because vfs_dq_init() must be called
9 outside of a transaction.
10
11 Signed-off-by: Jan Kara <jack@suse.cz>
12 ---
13 fs/ocfs2/alloc.c | 18 ++++++-
14 fs/ocfs2/aops.c | 16 +++++-
15 fs/ocfs2/dir.c | 24 ++++++++-
16 fs/ocfs2/file.c | 70 ++++++++++++++++++++++--
17 fs/ocfs2/inode.c | 10 +++-
18 fs/ocfs2/journal.h | 99 ++++++++++++++++++++++++----------
19 fs/ocfs2/namei.c | 151 +++++++++++++++++++++++++++++++++++----------------
20 7 files changed, 296 insertions(+), 92 deletions(-)
21
22 Index: linux-2.6.27-ocfs2/fs/ocfs2/alloc.c
23 ===================================================================
24 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/alloc.c
25 +++ linux-2.6.27-ocfs2/fs/ocfs2/alloc.c
26 @@ -28,6 +28,7 @@
27 #include <linux/slab.h>
28 #include <linux/highmem.h>
29 #include <linux/swap.h>
30 +#include <linux/quotaops.h>
31
32 #define MLOG_MASK_PREFIX ML_DISK_ALLOC
33 #include <cluster/masklog.h>
34 @@ -5292,7 +5293,7 @@ int ocfs2_remove_btree_range(struct inod
35 }
36 }
37
38 - handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
39 + handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(inode->i_sb));
40 if (IS_ERR(handle)) {
41 ret = PTR_ERR(handle);
42 mlog_errno(ret);
43 @@ -6523,6 +6524,8 @@ static int ocfs2_do_truncate(struct ocfs
44 goto bail;
45 }
46
47 + vfs_dq_free_space_nodirty(inode,
48 + ocfs2_clusters_to_bytes(osb->sb, clusters_to_del));
49 spin_lock(&OCFS2_I(inode)->ip_lock);
50 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) -
51 clusters_to_del;
52 @@ -6836,6 +6839,7 @@ int ocfs2_convert_inline_data_to_extents
53 struct page **pages = NULL;
54 loff_t end = osb->s_clustersize;
55 struct ocfs2_extent_tree et;
56 + int did_quota = 0;
57
58 has_data = i_size_read(inode) ? 1 : 0;
59
60 @@ -6855,7 +6859,8 @@ int ocfs2_convert_inline_data_to_extents
61 }
62 }
63
64 - handle = ocfs2_start_trans(osb, OCFS2_INLINE_TO_EXTENTS_CREDITS);
65 + handle = ocfs2_start_trans(osb,
66 + ocfs2_inline_to_extents_credits(osb->sb));
67 if (IS_ERR(handle)) {
68 ret = PTR_ERR(handle);
69 mlog_errno(ret);
70 @@ -6874,6 +6879,13 @@ int ocfs2_convert_inline_data_to_extents
71 unsigned int page_end;
72 u64 phys;
73
74 + if (vfs_dq_alloc_space_nodirty(inode,
75 + ocfs2_clusters_to_bytes(osb->sb, 1))) {
76 + ret = -EDQUOT;
77 + goto out_commit;
78 + }
79 + did_quota = 1;
80 +
81 ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off,
82 &num);
83 if (ret) {
84 @@ -6947,6 +6959,10 @@ int ocfs2_convert_inline_data_to_extents
85 }
86
87 out_commit:
88 + if (ret < 0 && did_quota)
89 + vfs_dq_free_space_nodirty(inode,
90 + ocfs2_clusters_to_bytes(osb->sb, 1));
91 +
92 ocfs2_commit_trans(osb, handle);
93
94 out_unlock:
95 Index: linux-2.6.27-ocfs2/fs/ocfs2/aops.c
96 ===================================================================
97 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/aops.c
98 +++ linux-2.6.27-ocfs2/fs/ocfs2/aops.c
99 @@ -27,6 +27,7 @@
100 #include <linux/swap.h>
101 #include <linux/pipe_fs_i.h>
102 #include <linux/mpage.h>
103 +#include <linux/quotaops.h>
104
105 #define MLOG_MASK_PREFIX ML_FILE_IO
106 #include <cluster/masklog.h>
107 @@ -1750,6 +1751,11 @@ int ocfs2_write_begin_nolock(struct addr
108
109 wc->w_handle = handle;
110
111 + if (clusters_to_alloc && vfs_dq_alloc_space_nodirty(inode,
112 + ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc))) {
113 + ret = -EDQUOT;
114 + goto out_commit;
115 + }
116 /*
117 * We don't want this to fail in ocfs2_write_end(), so do it
118 * here.
119 @@ -1758,7 +1764,7 @@ int ocfs2_write_begin_nolock(struct addr
120 OCFS2_JOURNAL_ACCESS_WRITE);
121 if (ret) {
122 mlog_errno(ret);
123 - goto out_commit;
124 + goto out_quota;
125 }
126
127 /*
128 @@ -1771,14 +1777,14 @@ int ocfs2_write_begin_nolock(struct addr
129 mmap_page);
130 if (ret) {
131 mlog_errno(ret);
132 - goto out_commit;
133 + goto out_quota;
134 }
135
136 ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos,
137 len);
138 if (ret) {
139 mlog_errno(ret);
140 - goto out_commit;
141 + goto out_quota;
142 }
143
144 if (data_ac)
145 @@ -1790,6 +1796,10 @@ success:
146 *pagep = wc->w_target_page;
147 *fsdata = wc;
148 return 0;
149 +out_quota:
150 + if (clusters_to_alloc)
151 + vfs_dq_free_space(inode,
152 + ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc));
153 out_commit:
154 ocfs2_commit_trans(osb, handle);
155
156 Index: linux-2.6.27-ocfs2/fs/ocfs2/dir.c
157 ===================================================================
158 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/dir.c
159 +++ linux-2.6.27-ocfs2/fs/ocfs2/dir.c
160 @@ -40,6 +40,7 @@
161 #include <linux/types.h>
162 #include <linux/slab.h>
163 #include <linux/highmem.h>
164 +#include <linux/quotaops.h>
165
166 #define MLOG_MASK_PREFIX ML_NAMEI
167 #include <cluster/masklog.h>
168 @@ -1216,9 +1217,9 @@ static int ocfs2_expand_inline_dir(struc
169 unsigned int blocks_wanted,
170 struct buffer_head **first_block_bh)
171 {
172 - int ret, credits = OCFS2_INLINE_TO_EXTENTS_CREDITS;
173 u32 alloc, bit_off, len;
174 struct super_block *sb = dir->i_sb;
175 + int ret, credits = ocfs2_inline_to_extents_credits(sb);
176 u64 blkno, bytes = blocks_wanted << sb->s_blocksize_bits;
177 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
178 struct ocfs2_inode_info *oi = OCFS2_I(dir);
179 @@ -1227,6 +1228,7 @@ static int ocfs2_expand_inline_dir(struc
180 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
181 handle_t *handle;
182 struct ocfs2_extent_tree et;
183 + int did_quota = 0;
184
185 ocfs2_init_dinode_extent_tree(&et, dir, di_bh);
186
187 @@ -1264,6 +1266,12 @@ static int ocfs2_expand_inline_dir(struc
188 goto out_sem;
189 }
190
191 + if (vfs_dq_alloc_space_nodirty(dir,
192 + ocfs2_clusters_to_bytes(osb->sb, alloc))) {
193 + ret = -EDQUOT;
194 + goto out_commit;
195 + }
196 + did_quota = 1;
197 /*
198 * Try to claim as many clusters as the bitmap can give though
199 * if we only get one now, that's enough to continue. The rest
200 @@ -1386,6 +1394,9 @@ static int ocfs2_expand_inline_dir(struc
201 dirdata_bh = NULL;
202
203 out_commit:
204 + if (ret < 0 && did_quota)
205 + vfs_dq_free_space_nodirty(dir,
206 + ocfs2_clusters_to_bytes(osb->sb, 2));
207 ocfs2_commit_trans(osb, handle);
208
209 out_sem:
210 @@ -1410,7 +1421,7 @@ static int ocfs2_do_extend_dir(struct su
211 struct buffer_head **new_bh)
212 {
213 int status;
214 - int extend;
215 + int extend, did_quota = 0;
216 u64 p_blkno, v_blkno;
217
218 spin_lock(&OCFS2_I(dir)->ip_lock);
219 @@ -1420,6 +1431,13 @@ static int ocfs2_do_extend_dir(struct su
220 if (extend) {
221 u32 offset = OCFS2_I(dir)->ip_clusters;
222
223 + if (vfs_dq_alloc_space_nodirty(dir,
224 + ocfs2_clusters_to_bytes(sb, 1))) {
225 + status = -EDQUOT;
226 + goto bail;
227 + }
228 + did_quota = 1;
229 +
230 status = ocfs2_add_inode_data(OCFS2_SB(sb), dir, &offset,
231 1, 0, parent_fe_bh, handle,
232 data_ac, meta_ac, NULL);
233 @@ -1445,6 +1463,8 @@ static int ocfs2_do_extend_dir(struct su
234 }
235 status = 0;
236 bail:
237 + if (did_quota && status < 0)
238 + vfs_dq_free_space_nodirty(dir, ocfs2_clusters_to_bytes(sb, 1));
239 mlog_exit(status);
240 return status;
241 }
242 Index: linux-2.6.27-ocfs2/fs/ocfs2/file.c
243 ===================================================================
244 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/file.c
245 +++ linux-2.6.27-ocfs2/fs/ocfs2/file.c
246 @@ -35,6 +35,7 @@
247 #include <linux/mount.h>
248 #include <linux/writeback.h>
249 #include <linux/falloc.h>
250 +#include <linux/quotaops.h>
251
252 #define MLOG_MASK_PREFIX ML_INODE
253 #include <cluster/masklog.h>
254 @@ -57,6 +58,7 @@
255 #include "super.h"
256 #include "xattr.h"
257 #include "acl.h"
258 +#include "quota.h"
259
260 #include "buffer_head_io.h"
261
262 @@ -537,6 +539,8 @@ static int __ocfs2_extend_allocation(str
263 enum ocfs2_alloc_restarted why;
264 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
265 struct ocfs2_extent_tree et;
266 + u32 total_clusters = clusters_to_add;
267 + int did_quota = 0;
268
269 mlog_entry("(clusters_to_add = %u)\n", clusters_to_add);
270
271 @@ -585,6 +589,12 @@ restart_all:
272 goto leave;
273 }
274
275 + if (!did_quota && vfs_dq_alloc_space_nodirty(inode,
276 + ocfs2_clusters_to_bytes(osb->sb, total_clusters))) {
277 + status = -EDQUOT;
278 + goto leave;
279 + }
280 + did_quota = 1;
281 restarted_transaction:
282 /* reserve a write to the file entry early on - that we if we
283 * run out of credits in the allocation path, we can still
284 @@ -655,6 +665,9 @@ restarted_transaction:
285 OCFS2_I(inode)->ip_clusters, (long long)i_size_read(inode));
286
287 leave:
288 + if (status < 0 && did_quota)
289 + vfs_dq_free_space(inode,
290 + ocfs2_clusters_to_bytes(osb->sb, total_clusters));
291 if (handle) {
292 ocfs2_commit_trans(osb, handle);
293 handle = NULL;
294 @@ -886,6 +899,9 @@ int ocfs2_setattr(struct dentry *dentry,
295 struct ocfs2_super *osb = OCFS2_SB(sb);
296 struct buffer_head *bh = NULL;
297 handle_t *handle = NULL;
298 + int locked[MAXQUOTAS] = {0, 0};
299 + int credits, qtype;
300 + struct ocfs2_mem_dqinfo *oinfo;
301
302 mlog_entry("(0x%p, '%.*s')\n", dentry,
303 dentry->d_name.len, dentry->d_name.name);
304 @@ -956,11 +972,47 @@ int ocfs2_setattr(struct dentry *dentry,
305 }
306 }
307
308 - handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
309 - if (IS_ERR(handle)) {
310 - status = PTR_ERR(handle);
311 - mlog_errno(status);
312 - goto bail_unlock;
313 + if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
314 + (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
315 + credits = OCFS2_INODE_UPDATE_CREDITS;
316 + if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid
317 + && OCFS2_HAS_RO_COMPAT_FEATURE(sb,
318 + OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
319 + oinfo = sb_dqinfo(sb, USRQUOTA)->dqi_priv;
320 + status = ocfs2_lock_global_qf(oinfo, 1);
321 + if (status < 0)
322 + goto bail_unlock;
323 + credits += ocfs2_calc_qinit_credits(sb, USRQUOTA) +
324 + ocfs2_calc_qdel_credits(sb, USRQUOTA);
325 + locked[USRQUOTA] = 1;
326 + }
327 + if (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid
328 + && OCFS2_HAS_RO_COMPAT_FEATURE(sb,
329 + OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
330 + oinfo = sb_dqinfo(sb, GRPQUOTA)->dqi_priv;
331 + status = ocfs2_lock_global_qf(oinfo, 1);
332 + if (status < 0)
333 + goto bail_unlock;
334 + credits += ocfs2_calc_qinit_credits(sb, GRPQUOTA) +
335 + ocfs2_calc_qdel_credits(sb, GRPQUOTA);
336 + locked[GRPQUOTA] = 1;
337 + }
338 + handle = ocfs2_start_trans(osb, credits);
339 + if (IS_ERR(handle)) {
340 + status = PTR_ERR(handle);
341 + mlog_errno(status);
342 + goto bail_unlock;
343 + }
344 + status = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
345 + if (status < 0)
346 + goto bail_commit;
347 + } else {
348 + handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
349 + if (IS_ERR(handle)) {
350 + status = PTR_ERR(handle);
351 + mlog_errno(status);
352 + goto bail_unlock;
353 + }
354 }
355
356 /*
357 @@ -983,6 +1035,12 @@ int ocfs2_setattr(struct dentry *dentry,
358 bail_commit:
359 ocfs2_commit_trans(osb, handle);
360 bail_unlock:
361 + for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
362 + if (!locked[qtype])
363 + continue;
364 + oinfo = sb_dqinfo(sb, qtype)->dqi_priv;
365 + ocfs2_unlock_global_qf(oinfo, 1);
366 + }
367 ocfs2_inode_unlock(inode, 1);
368 bail_unlock_rw:
369 if (size_change)
370 Index: linux-2.6.27-ocfs2/fs/ocfs2/inode.c
371 ===================================================================
372 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/inode.c
373 +++ linux-2.6.27-ocfs2/fs/ocfs2/inode.c
374 @@ -28,6 +28,7 @@
375 #include <linux/slab.h>
376 #include <linux/highmem.h>
377 #include <linux/pagemap.h>
378 +#include <linux/quotaops.h>
379
380 #include <asm/byteorder.h>
381
382 @@ -619,7 +620,8 @@ static int ocfs2_remove_inode(struct ino
383 goto bail;
384 }
385
386 - handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS);
387 + handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS +
388 + ocfs2_quota_trans_credits(inode->i_sb));
389 if (IS_ERR(handle)) {
390 status = PTR_ERR(handle);
391 mlog_errno(status);
392 @@ -651,6 +653,7 @@ static int ocfs2_remove_inode(struct ino
393 }
394
395 ocfs2_remove_from_cache(inode, di_bh);
396 + vfs_dq_free_inode(inode);
397
398 status = ocfs2_free_dinode(handle, inode_alloc_inode,
399 inode_alloc_bh, di);
400 @@ -933,7 +936,10 @@ void ocfs2_delete_inode(struct inode *in
401
402 mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
403
404 - if (is_bad_inode(inode)) {
405 + /* When we fail in read_inode() we mark inode as bad. The second test
406 + * catches the case when inode allocation fails before allocating
407 + * a block for inode. */
408 + if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno) {
409 mlog(0, "Skipping delete of bad inode\n");
410 goto bail;
411 }
412 Index: linux-2.6.27-ocfs2/fs/ocfs2/journal.h
413 ===================================================================
414 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/journal.h
415 +++ linux-2.6.27-ocfs2/fs/ocfs2/journal.h
416 @@ -293,6 +293,37 @@ int ocfs2_journal_dirty
417 /* extended attribute block update */
418 #define OCFS2_XATTR_BLOCK_UPDATE_CREDITS 1
419
420 +/* global quotafile inode update, data block */
421 +#define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
422 +
423 +/*
424 + * The two writes below can accidentally see global info dirty due
425 + * to set_info() quotactl so make them prepared for the writes.
426 + */
427 +/* quota data block, global info */
428 +/* Write to local quota file */
429 +#define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + 1)
430 +
431 +/* global quota data block, local quota data block, global quota inode,
432 + * global quota info */
433 +#define OCFS2_QSYNC_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 3)
434 +
435 +static inline int ocfs2_quota_trans_credits(struct super_block *sb)
436 +{
437 + int credits = 0;
438 +
439 + if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_USRQUOTA))
440 + credits += OCFS2_QWRITE_CREDITS;
441 + if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA))
442 + credits += OCFS2_QWRITE_CREDITS;
443 + return credits;
444 +}
445 +
446 +/* Number of credits needed for removing quota structure from file */
447 +int ocfs2_calc_qdel_credits(struct super_block *sb, int type);
448 +/* Number of credits needed for initialization of new quota structure */
449 +int ocfs2_calc_qinit_credits(struct super_block *sb, int type);
450 +
451 /* group extend. inode update and last group update. */
452 #define OCFS2_GROUP_EXTEND_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
453
454 @@ -303,8 +334,11 @@ int ocfs2_journal_dirty
455 * prev. group desc. if we relink. */
456 #define OCFS2_SUBALLOC_ALLOC (3)
457
458 -#define OCFS2_INLINE_TO_EXTENTS_CREDITS (OCFS2_SUBALLOC_ALLOC \
459 - + OCFS2_INODE_UPDATE_CREDITS)
460 +static inline int ocfs2_inline_to_extents_credits(struct super_block *sb)
461 +{
462 + return OCFS2_SUBALLOC_ALLOC + OCFS2_INODE_UPDATE_CREDITS +
463 + ocfs2_quota_trans_credits(sb);
464 +}
465
466 /* dinode + group descriptor update. We don't relink on free yet. */
467 #define OCFS2_SUBALLOC_FREE (2)
468 @@ -313,16 +347,23 @@ int ocfs2_journal_dirty
469 #define OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC (OCFS2_SUBALLOC_FREE \
470 + OCFS2_TRUNCATE_LOG_UPDATE)
471
472 -#define OCFS2_REMOVE_EXTENT_CREDITS (OCFS2_TRUNCATE_LOG_UPDATE + OCFS2_INODE_UPDATE_CREDITS)
473 +static inline int ocfs2_remove_extent_credits(struct super_block *sb)
474 +{
475 + return OCFS2_TRUNCATE_LOG_UPDATE + OCFS2_INODE_UPDATE_CREDITS +
476 + ocfs2_quota_trans_credits(sb);
477 +}
478
479 /* data block for new dir/symlink, 2 for bitmap updates (bitmap fe +
480 * bitmap block for the new bit) */
481 #define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2)
482
483 /* parent fe, parent block, new file entry, inode alloc fe, inode alloc
484 - * group descriptor + mkdir/symlink blocks */
485 -#define OCFS2_MKNOD_CREDITS (3 + OCFS2_SUBALLOC_ALLOC \
486 - + OCFS2_DIR_LINK_ADDITIONAL_CREDITS)
487 + * group descriptor + mkdir/symlink blocks + quota update */
488 +static inline int ocfs2_mknod_credits(struct super_block *sb)
489 +{
490 + return 3 + OCFS2_SUBALLOC_ALLOC + OCFS2_DIR_LINK_ADDITIONAL_CREDITS +
491 + ocfs2_quota_trans_credits(sb);
492 +}
493
494 /* local alloc metadata change + main bitmap updates */
495 #define OCFS2_WINDOW_MOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS \
496 @@ -332,13 +373,21 @@ int ocfs2_journal_dirty
497 * for the dinode, one for the new block. */
498 #define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
499
500 -/* file update (nlink, etc) + directory mtime/ctime + dir entry block */
501 -#define OCFS2_LINK_CREDITS (2*OCFS2_INODE_UPDATE_CREDITS + 1)
502 +/* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota
503 + * update on dir */
504 +static inline int ocfs2_link_credits(struct super_block *sb)
505 +{
506 + return 2*OCFS2_INODE_UPDATE_CREDITS + 1 +
507 + ocfs2_quota_trans_credits(sb);
508 +}
509
510 /* inode + dir inode (if we unlink a dir), + dir entry block + orphan
511 * dir inode link */
512 -#define OCFS2_UNLINK_CREDITS (2 * OCFS2_INODE_UPDATE_CREDITS + 1 \
513 - + OCFS2_LINK_CREDITS)
514 +static inline int ocfs2_unlink_credits(struct super_block *sb)
515 +{
516 + /* The quota update from ocfs2_link_credits is unused here... */
517 + return 2 * OCFS2_INODE_UPDATE_CREDITS + 1 + ocfs2_link_credits(sb);
518 +}
519
520 /* dinode + orphan dir dinode + inode alloc dinode + orphan dir entry +
521 * inode alloc group descriptor */
522 @@ -347,8 +396,10 @@ int ocfs2_journal_dirty
523 /* dinode update, old dir dinode update, new dir dinode update, old
524 * dir dir entry, new dir dir entry, dir entry update for renaming
525 * directory + target unlink */
526 -#define OCFS2_RENAME_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 3 \
527 - + OCFS2_UNLINK_CREDITS)
528 +static inline int ocfs2_rename_credits(struct super_block *sb)
529 +{
530 + return 3 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_unlink_credits(sb);
531 +}
532
533 /* global bitmap dinode, group desc., relinked group,
534 * suballocator dinode, group desc., relinked group,
535 @@ -357,21 +408,6 @@ int ocfs2_journal_dirty
536 + OCFS2_INODE_UPDATE_CREDITS \
537 + OCFS2_XATTR_BLOCK_UPDATE_CREDITS)
538
539 -/* global quotafile inode update, data block */
540 -#define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
541 -
542 -/*
543 - * The two writes below can accidentally see global info dirty due
544 - * to set_info() quotactl so make them prepared for the writes.
545 - */
546 -/* quota data block, global info */
547 -/* Write to local quota file */
548 -#define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + 1)
549 -
550 -/* global quota data block, local quota data block, global quota inode,
551 - * global quota info */
552 -#define OCFS2_QSYNC_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 3)
553 -
554 /*
555 * Please note that the caller must make sure that root_el is the root
556 * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
557 @@ -401,18 +437,19 @@ static inline int ocfs2_calc_extend_cred
558 * credit for the dinode there. */
559 extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth);
560
561 - return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks;
562 + return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks +
563 + ocfs2_quota_trans_credits(sb);
564 }
565
566 static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
567 {
568 - int blocks = OCFS2_MKNOD_CREDITS;
569 + int blocks = ocfs2_mknod_credits(sb);
570
571 /* links can be longer than one block so we may update many
572 * within our single allocated extent. */
573 blocks += ocfs2_clusters_to_blocks(sb, 1);
574
575 - return blocks;
576 + return blocks + ocfs2_quota_trans_credits(sb);
577 }
578
579 static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb,
580 @@ -449,6 +486,8 @@ static inline int ocfs2_calc_tree_trunc_
581 /* update to the truncate log. */
582 credits += OCFS2_TRUNCATE_LOG_UPDATE;
583
584 + credits += ocfs2_quota_trans_credits(sb);
585 +
586 return credits;
587 }
588
589 Index: linux-2.6.27-ocfs2/fs/ocfs2/namei.c
590 ===================================================================
591 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/namei.c
592 +++ linux-2.6.27-ocfs2/fs/ocfs2/namei.c
593 @@ -40,6 +40,7 @@
594 #include <linux/types.h>
595 #include <linux/slab.h>
596 #include <linux/highmem.h>
597 +#include <linux/quotaops.h>
598
599 #define MLOG_MASK_PREFIX ML_NAMEI
600 #include <cluster/masklog.h>
601 @@ -212,6 +213,7 @@ static struct inode *ocfs2_get_init_inod
602 } else
603 inode->i_gid = current->fsgid;
604 inode->i_mode = mode;
605 + vfs_dq_init(inode);
606 return inode;
607 }
608
609 @@ -233,6 +235,7 @@ static int ocfs2_mknod(struct inode *dir
610 struct ocfs2_alloc_context *xattr_ac = NULL;
611 int want_clusters = 0;
612 int xattr_credits = 0;
613 + int did_quota_inode = 0;
614 struct ocfs2_security_xattr_info si = {
615 .enable = 1,
616 };
617 @@ -323,7 +326,8 @@ static int ocfs2_mknod(struct inode *dir
618 goto leave;
619 }
620
621 - handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS + xattr_credits);
622 + handle = ocfs2_start_trans(osb,
623 + ocfs2_mknod_credits(dir->i_sb) + xattr_credits);
624 if (IS_ERR(handle)) {
625 status = PTR_ERR(handle);
626 handle = NULL;
627 @@ -331,6 +335,15 @@ static int ocfs2_mknod(struct inode *dir
628 goto leave;
629 }
630
631 + /* We don't use standard VFS wrapper because we don't want vfs_dq_init
632 + * to be called. */
633 + if (sb_any_quota_active(osb->sb) &&
634 + osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) {
635 + status = -EDQUOT;
636 + goto leave;
637 + }
638 + did_quota_inode = 1;
639 +
640 /* do the real work now. */
641 status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev,
642 &new_fe_bh, parent_fe_bh, handle,
643 @@ -399,6 +412,8 @@ static int ocfs2_mknod(struct inode *dir
644 d_instantiate(dentry, inode);
645 status = 0;
646 leave:
647 + if (status < 0 && did_quota_inode)
648 + vfs_dq_free_inode(inode);
649 if (handle)
650 ocfs2_commit_trans(osb, handle);
651
652 @@ -649,7 +664,7 @@ static int ocfs2_link(struct dentry *old
653 goto out_unlock_inode;
654 }
655
656 - handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS);
657 + handle = ocfs2_start_trans(osb, ocfs2_link_credits(osb->sb));
658 if (IS_ERR(handle)) {
659 err = PTR_ERR(handle);
660 handle = NULL;
661 @@ -836,7 +851,7 @@ static int ocfs2_unlink(struct inode *di
662 }
663 }
664
665 - handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS);
666 + handle = ocfs2_start_trans(osb, ocfs2_unlink_credits(osb->sb));
667 if (IS_ERR(handle)) {
668 status = PTR_ERR(handle);
669 handle = NULL;
670 @@ -1242,7 +1257,7 @@ static int ocfs2_rename(struct inode *ol
671 }
672 }
673
674 - handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS);
675 + handle = ocfs2_start_trans(osb, ocfs2_rename_credits(osb->sb));
676 if (IS_ERR(handle)) {
677 status = PTR_ERR(handle);
678 handle = NULL;
679 @@ -1560,6 +1575,7 @@ static int ocfs2_symlink(struct inode *d
680 struct ocfs2_alloc_context *xattr_ac = NULL;
681 int want_clusters = 0;
682 int xattr_credits = 0;
683 + int did_quota = 0, did_quota_inode = 0;
684 struct ocfs2_security_xattr_info si = {
685 .enable = 1,
686 };
687 @@ -1656,6 +1672,15 @@ static int ocfs2_symlink(struct inode *d
688 goto bail;
689 }
690
691 + /* We don't use standard VFS wrapper because we don't want vfs_dq_init
692 + * to be called. */
693 + if (sb_any_quota_active(osb->sb) &&
694 + osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) {
695 + status = -EDQUOT;
696 + goto bail;
697 + }
698 + did_quota_inode = 1;
699 +
700 status = ocfs2_mknod_locked(osb, dir, inode, dentry,
701 0, &new_fe_bh, parent_fe_bh, handle,
702 inode_ac);
703 @@ -1671,6 +1696,12 @@ static int ocfs2_symlink(struct inode *d
704 u32 offset = 0;
705
706 inode->i_op = &ocfs2_symlink_inode_operations;
707 + if (vfs_dq_alloc_space_nodirty(inode,
708 + ocfs2_clusters_to_bytes(osb->sb, 1))) {
709 + status = -EDQUOT;
710 + goto bail;
711 + }
712 + did_quota = 1;
713 status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0,
714 new_fe_bh,
715 handle, data_ac, NULL,
716 @@ -1736,6 +1767,11 @@ static int ocfs2_symlink(struct inode *d
717 dentry->d_op = &ocfs2_dentry_ops;
718 d_instantiate(dentry, inode);
719 bail:
720 + if (status < 0 && did_quota)
721 + vfs_dq_free_space_nodirty(inode,
722 + ocfs2_clusters_to_bytes(osb->sb, 1));
723 + if (status < 0 && did_quota_inode)
724 + vfs_dq_free_inode(inode);
725 if (handle)
726 ocfs2_commit_trans(osb, handle);
727
728 Index: linux-2.6.27-ocfs2/fs/ocfs2/xattr.c
729 ===================================================================
730 --- linux-2.6.27-ocfs2.orig/fs/ocfs2/xattr.c
731 +++ linux-2.6.27-ocfs2/fs/ocfs2/xattr.c
732 @@ -1613,7 +1613,7 @@ static int ocfs2_remove_value_outside(st
733
734 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
735
736 - ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
737 + ctxt.handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(inode->i_sb));
738 if (IS_ERR(ctxt.handle)) {
739 ret = PTR_ERR(ctxt.handle);
740 mlog_errno(ret);
741 @@ -2190,7 +2190,7 @@ static int ocfs2_calc_xattr_set_need(str
742 */
743 if (!xi->value) {
744 if (!ocfs2_xattr_is_local(xe))
745 - credits += OCFS2_REMOVE_EXTENT_CREDITS;
746 + credits += ocfs2_remove_extent_credits(inode->i_sb);
747
748 goto out;
749 }
750 @@ -2207,7 +2207,7 @@ static int ocfs2_calc_xattr_set_need(str
751 */
752 if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) {
753 clusters_add += new_clusters;
754 - credits += OCFS2_REMOVE_EXTENT_CREDITS +
755 + credits += ocfs2_remove_extent_credits(inode->i_sb) +
756 OCFS2_INODE_UPDATE_CREDITS;
757 if (!ocfs2_xattr_is_local(xe))
758 credits += ocfs2_calc_extend_credits(
759 @@ -2231,7 +2231,7 @@ static int ocfs2_calc_xattr_set_need(str
760 xv = &def_xv.xv;
761
762 if (old_clusters >= new_clusters) {
763 - credits += OCFS2_REMOVE_EXTENT_CREDITS;
764 + credits += ocfs2_remove_extent_credits(inode->i_sb);
765 goto out;
766 } else {
767 meta_add += ocfs2_extend_meta_needed(&xv->xr_list);
768 @@ -4700,7 +4700,7 @@ static int ocfs2_rm_xattr_cluster(struct
769 }
770 }
771
772 - handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
773 + handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(inode->i_sb));
774 if (IS_ERR(handle)) {
775 ret = -ENOMEM;
776 mlog_errno(ret);
777 @@ -5059,7 +5059,7 @@ static int ocfs2_delete_xattr_in_bucket(
778
779 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
780
781 - ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
782 + ctxt.handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(inode->i_sb));
783 if (IS_ERR(ctxt.handle)) {
784 ret = PTR_ERR(ctxt.handle);
785 mlog_errno(ret);