]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.suse/ocfs2-Add-quota-calls-for-allocation-and-freeing-of.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / ocfs2-Add-quota-calls-for-allocation-and-freeing-of.patch
CommitLineData
2cb7cef9
BS
1From: Jan Kara <jack@suse.cz>
2References: fate#302681
3Subject: [PATCH 25/28] ocfs2: Add quota calls for allocation and freeing of inodes and space
4Patch-mainline: 2.6.29?
5
6Add quota calls for allocation and freeing of inodes and space, also update
7estimates on number of needed credits for a transaction. Move out inode
8allocation from ocfs2_mknod_locked() because vfs_dq_init() must be called
9outside of a transaction.
10
11Signed-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
22Index: 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:
95Index: 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
156Index: 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 }
242Index: 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)
370Index: 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 }
412Index: 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
589Index: 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
728Index: 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);