]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From ac60e745d0187b11d9e7f9fcb37e64cc7c02ded0 Mon Sep 17 00:00:00 2001 |
2 | From: Jan Kara <jack@suse.cz> | |
3 | Date: Wed, 17 Jun 2009 19:09:19 +0200 | |
4 | Subject: [PATCH 3/6] ocfs2: Initialize blocks allocated to local quota file | |
5 | ||
6 | When we extend local quota file, we should initialize data | |
7 | in newly allocated block. Firstly because on recovery we could | |
8 | parse bogus data, secondly so that block checksums are properly | |
9 | computed. | |
10 | ||
11 | Signed-off-by: Jan Kara <jack@suse.cz> | |
12 | --- | |
13 | fs/ocfs2/quota_local.c | 98 ++++++++++++++++++++++++++++++++++++++++------- | |
14 | 1 files changed, 83 insertions(+), 15 deletions(-) | |
15 | ||
16 | Index: linux-2.6.27-SLE11_BRANCH/fs/ocfs2/quota_local.c | |
17 | =================================================================== | |
18 | --- linux-2.6.27-SLE11_BRANCH.orig/fs/ocfs2/quota_local.c 2009-07-16 13:26:06.000000000 +0200 | |
19 | +++ linux-2.6.27-SLE11_BRANCH/fs/ocfs2/quota_local.c 2009-07-16 14:00:23.000000000 +0200 | |
20 | @@ -930,7 +930,7 @@ | |
21 | struct ocfs2_local_disk_chunk *dchunk; | |
22 | int status; | |
23 | handle_t *handle; | |
24 | - struct buffer_head *bh = NULL; | |
25 | + struct buffer_head *bh = NULL, *dbh = NULL; | |
26 | u64 p_blkno; | |
27 | ||
28 | /* We are protected by dqio_sem so no locking needed */ | |
29 | @@ -973,7 +973,7 @@ | |
30 | ||
31 | dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data; | |
32 | ||
33 | - handle = ocfs2_start_trans(OCFS2_SB(sb), 2); | |
34 | + handle = ocfs2_start_trans(OCFS2_SB(sb), 3); | |
35 | if (IS_ERR(handle)) { | |
36 | status = PTR_ERR(handle); | |
37 | mlog_errno(status); | |
38 | @@ -998,6 +998,38 @@ | |
39 | goto out_trans; | |
40 | } | |
41 | ||
42 | + /* Initialize new block with structures */ | |
43 | + down_read(&OCFS2_I(lqinode)->ip_alloc_sem); | |
44 | + status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks + 1, | |
45 | + &p_blkno, NULL, NULL); | |
46 | + up_read(&OCFS2_I(lqinode)->ip_alloc_sem); | |
47 | + if (status < 0) { | |
48 | + mlog_errno(status); | |
49 | + goto out_trans; | |
50 | + } | |
51 | + dbh = sb_getblk(sb, p_blkno); | |
52 | + if (!dbh) { | |
53 | + status = -ENOMEM; | |
54 | + mlog_errno(status); | |
55 | + goto out_trans; | |
56 | + } | |
57 | + ocfs2_set_new_buffer_uptodate(lqinode, dbh); | |
58 | + status = ocfs2_journal_access(handle, lqinode, dbh, | |
59 | + OCFS2_JOURNAL_ACCESS_CREATE); | |
60 | + if (status < 0) { | |
61 | + mlog_errno(status); | |
62 | + goto out_trans; | |
63 | + } | |
64 | + lock_buffer(dbh); | |
65 | + memset(dbh->b_data, 0, sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE); | |
66 | + unlock_buffer(dbh); | |
67 | + status = ocfs2_journal_dirty(handle, dbh); | |
68 | + if (status < 0) { | |
69 | + mlog_errno(status); | |
70 | + goto out_trans; | |
71 | + } | |
72 | + | |
73 | + /* Update local quotafile info */ | |
74 | oinfo->dqi_blocks += 2; | |
75 | oinfo->dqi_chunks++; | |
76 | status = ocfs2_local_write_info(sb, type); | |
77 | @@ -1022,6 +1054,7 @@ | |
78 | ocfs2_commit_trans(OCFS2_SB(sb), handle); | |
79 | out: | |
80 | brelse(bh); | |
81 | + brelse(dbh); | |
82 | kmem_cache_free(ocfs2_qf_chunk_cachep, chunk); | |
83 | return ERR_PTR(status); | |
84 | } | |
85 | @@ -1039,6 +1072,8 @@ | |
86 | struct ocfs2_local_disk_chunk *dchunk; | |
87 | int epb = ol_quota_entries_per_block(sb); | |
88 | unsigned int chunk_blocks; | |
89 | + struct buffer_head *bh; | |
90 | + u64 p_blkno; | |
91 | int status; | |
92 | handle_t *handle; | |
93 | ||
94 | @@ -1066,12 +1101,46 @@ | |
95 | mlog_errno(status); | |
96 | goto out; | |
97 | } | |
98 | - handle = ocfs2_start_trans(OCFS2_SB(sb), 2); | |
99 | + | |
100 | + /* Get buffer from the just added block */ | |
101 | + down_read(&OCFS2_I(lqinode)->ip_alloc_sem); | |
102 | + status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks, | |
103 | + &p_blkno, NULL, NULL); | |
104 | + up_read(&OCFS2_I(lqinode)->ip_alloc_sem); | |
105 | + if (status < 0) { | |
106 | + mlog_errno(status); | |
107 | + goto out; | |
108 | + } | |
109 | + bh = sb_getblk(sb, p_blkno); | |
110 | + if (!bh) { | |
111 | + status = -ENOMEM; | |
112 | + mlog_errno(status); | |
113 | + goto out; | |
114 | + } | |
115 | + ocfs2_set_new_buffer_uptodate(lqinode, bh); | |
116 | + | |
117 | + handle = ocfs2_start_trans(OCFS2_SB(sb), 3); | |
118 | if (IS_ERR(handle)) { | |
119 | status = PTR_ERR(handle); | |
120 | mlog_errno(status); | |
121 | goto out; | |
122 | } | |
123 | + /* Zero created block */ | |
124 | + status = ocfs2_journal_access(handle, lqinode, bh, | |
125 | + OCFS2_JOURNAL_ACCESS_CREATE); | |
126 | + if (status < 0) { | |
127 | + mlog_errno(status); | |
128 | + goto out_trans; | |
129 | + } | |
130 | + lock_buffer(bh); | |
131 | + memset(bh->b_data, 0, sb->s_blocksize); | |
132 | + unlock_buffer(bh); | |
133 | + status = ocfs2_journal_dirty(handle, bh); | |
134 | + if (status < 0) { | |
135 | + mlog_errno(status); | |
136 | + goto out_trans; | |
137 | + } | |
138 | + /* Update chunk header */ | |
139 | status = ocfs2_journal_access(handle, lqinode, chunk->qc_headerbh, | |
140 | OCFS2_JOURNAL_ACCESS_WRITE); | |
141 | if (status < 0) { | |
142 | @@ -1088,6 +1157,7 @@ | |
143 | mlog_errno(status); | |
144 | goto out_trans; | |
145 | } | |
146 | + /* Update file header */ | |
147 | oinfo->dqi_blocks++; | |
148 | status = ocfs2_local_write_info(sb, type); | |
149 | if (status < 0) { |