aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-10-14 18:17:52 -0400
committerBen Myers <bpm@sgi.com>2013-10-23 15:28:35 -0400
commit9aede1d81b12a95771db0e2f9196dd37e10aaf20 (patch)
tree380d499202c6d3f5874cff2c32693db8d4d2af81 /fs
parent5706278758e334bf6a15f57c18dc16df19c83957 (diff)
xfs: split dquot buffer operations out
Parts of userspace want to be able to read and modify dquot buffers (e.g. xfs_db) so we need to split out the reading and writing of these buffers so it is easy to shared code with libxfs in userspace. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/xfs_dquot.c117
-rw-r--r--fs/xfs/xfs_dquot_buf.c288
-rw-r--r--fs/xfs/xfs_log_recover.c133
-rw-r--r--fs/xfs/xfs_qm.c22
-rw-r--r--fs/xfs/xfs_qm.h2
-rw-r--r--fs/xfs/xfs_quota.h2
-rw-r--r--fs/xfs/xfs_quota_defs.h4
8 files changed, 303 insertions, 266 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 0719e4db93f2..08f11bbf56ae 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -72,6 +72,7 @@ xfs-y += xfs_alloc.o \
72 xfs_dir2_leaf.o \ 72 xfs_dir2_leaf.o \
73 xfs_dir2_node.o \ 73 xfs_dir2_node.o \
74 xfs_dir2_sf.o \ 74 xfs_dir2_sf.o \
75 xfs_dquot_buf.o \
75 xfs_ialloc.o \ 76 xfs_ialloc.o \
76 xfs_ialloc_btree.o \ 77 xfs_ialloc_btree.o \
77 xfs_icreate_item.o \ 78 xfs_icreate_item.o \
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 8b1d2c0a9054..f85a893c2398 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -293,118 +293,6 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
293 dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5; 293 dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
294} 294}
295 295
296STATIC bool
297xfs_dquot_buf_verify_crc(
298 struct xfs_mount *mp,
299 struct xfs_buf *bp)
300{
301 struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
302 int ndquots;
303 int i;
304
305 if (!xfs_sb_version_hascrc(&mp->m_sb))
306 return true;
307
308 /*
309 * if we are in log recovery, the quota subsystem has not been
310 * initialised so we have no quotainfo structure. In that case, we need
311 * to manually calculate the number of dquots in the buffer.
312 */
313 if (mp->m_quotainfo)
314 ndquots = mp->m_quotainfo->qi_dqperchunk;
315 else
316 ndquots = xfs_qm_calc_dquots_per_chunk(mp,
317 XFS_BB_TO_FSB(mp, bp->b_length));
318
319 for (i = 0; i < ndquots; i++, d++) {
320 if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
321 XFS_DQUOT_CRC_OFF))
322 return false;
323 if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid))
324 return false;
325 }
326 return true;
327}
328
329STATIC bool
330xfs_dquot_buf_verify(
331 struct xfs_mount *mp,
332 struct xfs_buf *bp)
333{
334 struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
335 xfs_dqid_t id = 0;
336 int ndquots;
337 int i;
338
339 /*
340 * if we are in log recovery, the quota subsystem has not been
341 * initialised so we have no quotainfo structure. In that case, we need
342 * to manually calculate the number of dquots in the buffer.
343 */
344 if (mp->m_quotainfo)
345 ndquots = mp->m_quotainfo->qi_dqperchunk;
346 else
347 ndquots = xfs_qm_calc_dquots_per_chunk(mp, bp->b_length);
348
349 /*
350 * On the first read of the buffer, verify that each dquot is valid.
351 * We don't know what the id of the dquot is supposed to be, just that
352 * they should be increasing monotonically within the buffer. If the
353 * first id is corrupt, then it will fail on the second dquot in the
354 * buffer so corruptions could point to the wrong dquot in this case.
355 */
356 for (i = 0; i < ndquots; i++) {
357 struct xfs_disk_dquot *ddq;
358 int error;
359
360 ddq = &d[i].dd_diskdq;
361
362 if (i == 0)
363 id = be32_to_cpu(ddq->d_id);
364
365 error = xfs_qm_dqcheck(mp, ddq, id + i, 0, XFS_QMOPT_DOWARN,
366 "xfs_dquot_buf_verify");
367 if (error)
368 return false;
369 }
370 return true;
371}
372
373static void
374xfs_dquot_buf_read_verify(
375 struct xfs_buf *bp)
376{
377 struct xfs_mount *mp = bp->b_target->bt_mount;
378
379 if (!xfs_dquot_buf_verify_crc(mp, bp) || !xfs_dquot_buf_verify(mp, bp)) {
380 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
381 xfs_buf_ioerror(bp, EFSCORRUPTED);
382 }
383}
384
385/*
386 * we don't calculate the CRC here as that is done when the dquot is flushed to
387 * the buffer after the update is done. This ensures that the dquot in the
388 * buffer always has an up-to-date CRC value.
389 */
390void
391xfs_dquot_buf_write_verify(
392 struct xfs_buf *bp)
393{
394 struct xfs_mount *mp = bp->b_target->bt_mount;
395
396 if (!xfs_dquot_buf_verify(mp, bp)) {
397 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
398 xfs_buf_ioerror(bp, EFSCORRUPTED);
399 return;
400 }
401}
402
403const struct xfs_buf_ops xfs_dquot_buf_ops = {
404 .verify_read = xfs_dquot_buf_read_verify,
405 .verify_write = xfs_dquot_buf_write_verify,
406};
407
408/* 296/*
409 * Allocate a block and fill it with dquots. 297 * Allocate a block and fill it with dquots.
410 * This is called when the bmapi finds a hole. 298 * This is called when the bmapi finds a hole.
@@ -515,6 +403,7 @@ xfs_qm_dqalloc(
515 403
516 return (error); 404 return (error);
517} 405}
406
518STATIC int 407STATIC int
519xfs_qm_dqrepair( 408xfs_qm_dqrepair(
520 struct xfs_mount *mp, 409 struct xfs_mount *mp,
@@ -548,7 +437,7 @@ xfs_qm_dqrepair(
548 /* Do the actual repair of dquots in this buffer */ 437 /* Do the actual repair of dquots in this buffer */
549 for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++) { 438 for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++) {
550 ddq = &d[i].dd_diskdq; 439 ddq = &d[i].dd_diskdq;
551 error = xfs_qm_dqcheck(mp, ddq, firstid + i, 440 error = xfs_dqcheck(mp, ddq, firstid + i,
552 dqp->dq_flags & XFS_DQ_ALLTYPES, 441 dqp->dq_flags & XFS_DQ_ALLTYPES,
553 XFS_QMOPT_DQREPAIR, "xfs_qm_dqrepair"); 442 XFS_QMOPT_DQREPAIR, "xfs_qm_dqrepair");
554 if (error) { 443 if (error) {
@@ -1134,7 +1023,7 @@ xfs_qm_dqflush(
1134 /* 1023 /*
1135 * A simple sanity check in case we got a corrupted dquot.. 1024 * A simple sanity check in case we got a corrupted dquot..
1136 */ 1025 */
1137 error = xfs_qm_dqcheck(mp, &dqp->q_core, be32_to_cpu(ddqp->d_id), 0, 1026 error = xfs_dqcheck(mp, &dqp->q_core, be32_to_cpu(ddqp->d_id), 0,
1138 XFS_QMOPT_DOWARN, "dqflush (incore copy)"); 1027 XFS_QMOPT_DOWARN, "dqflush (incore copy)");
1139 if (error) { 1028 if (error) {
1140 xfs_buf_relse(bp); 1029 xfs_buf_relse(bp);
diff --git a/fs/xfs/xfs_dquot_buf.c b/fs/xfs/xfs_dquot_buf.c
new file mode 100644
index 000000000000..ad2c18fbdb05
--- /dev/null
+++ b/fs/xfs/xfs_dquot_buf.c
@@ -0,0 +1,288 @@
1/*
2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * Copyright (c) 2013 Red Hat, Inc.
4 * All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#include "xfs.h"
20#include "xfs_fs.h"
21#include "xfs_format.h"
22#include "xfs_bit.h"
23#include "xfs_log.h"
24#include "xfs_trans.h"
25#include "xfs_sb.h"
26#include "xfs_ag.h"
27#include "xfs_mount.h"
28#include "xfs_bmap_btree.h"
29#include "xfs_inode.h"
30#include "xfs_quota.h"
31#include "xfs_qm.h"
32#include "xfs_error.h"
33#include "xfs_cksum.h"
34#include "xfs_trace.h"
35
36int
37xfs_calc_dquots_per_chunk(
38 struct xfs_mount *mp,
39 unsigned int nbblks) /* basic block units */
40{
41 unsigned int ndquots;
42
43 ASSERT(nbblks > 0);
44 ndquots = BBTOB(nbblks);
45 do_div(ndquots, sizeof(xfs_dqblk_t));
46
47 return ndquots;
48}
49
50/*
51 * Do some primitive error checking on ondisk dquot data structures.
52 */
53int
54xfs_dqcheck(
55 struct xfs_mount *mp,
56 xfs_disk_dquot_t *ddq,
57 xfs_dqid_t id,
58 uint type, /* used only when IO_dorepair is true */
59 uint flags,
60 char *str)
61{
62 xfs_dqblk_t *d = (xfs_dqblk_t *)ddq;
63 int errs = 0;
64
65 /*
66 * We can encounter an uninitialized dquot buffer for 2 reasons:
67 * 1. If we crash while deleting the quotainode(s), and those blks got
68 * used for user data. This is because we take the path of regular
69 * file deletion; however, the size field of quotainodes is never
70 * updated, so all the tricks that we play in itruncate_finish
71 * don't quite matter.
72 *
73 * 2. We don't play the quota buffers when there's a quotaoff logitem.
74 * But the allocation will be replayed so we'll end up with an
75 * uninitialized quota block.
76 *
77 * This is all fine; things are still consistent, and we haven't lost
78 * any quota information. Just don't complain about bad dquot blks.
79 */
80 if (ddq->d_magic != cpu_to_be16(XFS_DQUOT_MAGIC)) {
81 if (flags & XFS_QMOPT_DOWARN)
82 xfs_alert(mp,
83 "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
84 str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC);
85 errs++;
86 }
87 if (ddq->d_version != XFS_DQUOT_VERSION) {
88 if (flags & XFS_QMOPT_DOWARN)
89 xfs_alert(mp,
90 "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
91 str, id, ddq->d_version, XFS_DQUOT_VERSION);
92 errs++;
93 }
94
95 if (ddq->d_flags != XFS_DQ_USER &&
96 ddq->d_flags != XFS_DQ_PROJ &&
97 ddq->d_flags != XFS_DQ_GROUP) {
98 if (flags & XFS_QMOPT_DOWARN)
99 xfs_alert(mp,
100 "%s : XFS dquot ID 0x%x, unknown flags 0x%x",
101 str, id, ddq->d_flags);
102 errs++;
103 }
104
105 if (id != -1 && id != be32_to_cpu(ddq->d_id)) {
106 if (flags & XFS_QMOPT_DOWARN)
107 xfs_alert(mp,
108 "%s : ondisk-dquot 0x%p, ID mismatch: "
109 "0x%x expected, found id 0x%x",
110 str, ddq, id, be32_to_cpu(ddq->d_id));
111 errs++;
112 }
113
114 if (!errs && ddq->d_id) {
115 if (ddq->d_blk_softlimit &&
116 be64_to_cpu(ddq->d_bcount) >
117 be64_to_cpu(ddq->d_blk_softlimit)) {
118 if (!ddq->d_btimer) {
119 if (flags & XFS_QMOPT_DOWARN)
120 xfs_alert(mp,
121 "%s : Dquot ID 0x%x (0x%p) BLK TIMER NOT STARTED",
122 str, (int)be32_to_cpu(ddq->d_id), ddq);
123 errs++;
124 }
125 }
126 if (ddq->d_ino_softlimit &&
127 be64_to_cpu(ddq->d_icount) >
128 be64_to_cpu(ddq->d_ino_softlimit)) {
129 if (!ddq->d_itimer) {
130 if (flags & XFS_QMOPT_DOWARN)
131 xfs_alert(mp,
132 "%s : Dquot ID 0x%x (0x%p) INODE TIMER NOT STARTED",
133 str, (int)be32_to_cpu(ddq->d_id), ddq);
134 errs++;
135 }
136 }
137 if (ddq->d_rtb_softlimit &&
138 be64_to_cpu(ddq->d_rtbcount) >
139 be64_to_cpu(ddq->d_rtb_softlimit)) {
140 if (!ddq->d_rtbtimer) {
141 if (flags & XFS_QMOPT_DOWARN)
142 xfs_alert(mp,
143 "%s : Dquot ID 0x%x (0x%p) RTBLK TIMER NOT STARTED",
144 str, (int)be32_to_cpu(ddq->d_id), ddq);
145 errs++;
146 }
147 }
148 }
149
150 if (!errs || !(flags & XFS_QMOPT_DQREPAIR))
151 return errs;
152
153 if (flags & XFS_QMOPT_DOWARN)
154 xfs_notice(mp, "Re-initializing dquot ID 0x%x", id);
155
156 /*
157 * Typically, a repair is only requested by quotacheck.
158 */
159 ASSERT(id != -1);
160 ASSERT(flags & XFS_QMOPT_DQREPAIR);
161 memset(d, 0, sizeof(xfs_dqblk_t));
162
163 d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
164 d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
165 d->dd_diskdq.d_flags = type;
166 d->dd_diskdq.d_id = cpu_to_be32(id);
167
168 if (xfs_sb_version_hascrc(&mp->m_sb)) {
169 uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
170 xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
171 XFS_DQUOT_CRC_OFF);
172 }
173
174 return errs;
175}
176
177STATIC bool
178xfs_dquot_buf_verify_crc(
179 struct xfs_mount *mp,
180 struct xfs_buf *bp)
181{
182 struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
183 int ndquots;
184 int i;
185
186 if (!xfs_sb_version_hascrc(&mp->m_sb))
187 return true;
188
189 /*
190 * if we are in log recovery, the quota subsystem has not been
191 * initialised so we have no quotainfo structure. In that case, we need
192 * to manually calculate the number of dquots in the buffer.
193 */
194 if (mp->m_quotainfo)
195 ndquots = mp->m_quotainfo->qi_dqperchunk;
196 else
197 ndquots = xfs_calc_dquots_per_chunk(mp,
198 XFS_BB_TO_FSB(mp, bp->b_length));
199
200 for (i = 0; i < ndquots; i++, d++) {
201 if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
202 XFS_DQUOT_CRC_OFF))
203 return false;
204 if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid))
205 return false;
206 }
207 return true;
208}
209
210STATIC bool
211xfs_dquot_buf_verify(
212 struct xfs_mount *mp,
213 struct xfs_buf *bp)
214{
215 struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
216 xfs_dqid_t id = 0;
217 int ndquots;
218 int i;
219
220 /*
221 * if we are in log recovery, the quota subsystem has not been
222 * initialised so we have no quotainfo structure. In that case, we need
223 * to manually calculate the number of dquots in the buffer.
224 */
225 if (mp->m_quotainfo)
226 ndquots = mp->m_quotainfo->qi_dqperchunk;
227 else
228 ndquots = xfs_calc_dquots_per_chunk(mp, bp->b_length);
229
230 /*
231 * On the first read of the buffer, verify that each dquot is valid.
232 * We don't know what the id of the dquot is supposed to be, just that
233 * they should be increasing monotonically within the buffer. If the
234 * first id is corrupt, then it will fail on the second dquot in the
235 * buffer so corruptions could point to the wrong dquot in this case.
236 */
237 for (i = 0; i < ndquots; i++) {
238 struct xfs_disk_dquot *ddq;
239 int error;
240
241 ddq = &d[i].dd_diskdq;
242
243 if (i == 0)
244 id = be32_to_cpu(ddq->d_id);
245
246 error = xfs_dqcheck(mp, ddq, id + i, 0, XFS_QMOPT_DOWARN,
247 "xfs_dquot_buf_verify");
248 if (error)
249 return false;
250 }
251 return true;
252}
253
254static void
255xfs_dquot_buf_read_verify(
256 struct xfs_buf *bp)
257{
258 struct xfs_mount *mp = bp->b_target->bt_mount;
259
260 if (!xfs_dquot_buf_verify_crc(mp, bp) || !xfs_dquot_buf_verify(mp, bp)) {
261 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
262 xfs_buf_ioerror(bp, EFSCORRUPTED);
263 }
264}
265
266/*
267 * we don't calculate the CRC here as that is done when the dquot is flushed to
268 * the buffer after the update is done. This ensures that the dquot in the
269 * buffer always has an up-to-date CRC value.
270 */
271void
272xfs_dquot_buf_write_verify(
273 struct xfs_buf *bp)
274{
275 struct xfs_mount *mp = bp->b_target->bt_mount;
276
277 if (!xfs_dquot_buf_verify(mp, bp)) {
278 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
279 xfs_buf_ioerror(bp, EFSCORRUPTED);
280 return;
281 }
282}
283
284const struct xfs_buf_ops xfs_dquot_buf_ops = {
285 .verify_read = xfs_dquot_buf_read_verify,
286 .verify_write = xfs_dquot_buf_write_verify,
287};
288
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 4d4f4a0bb5e4..cb3277e07844 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2363,7 +2363,7 @@ xlog_recover_do_reg_buffer(
2363 item->ri_buf[i].i_len, __func__); 2363 item->ri_buf[i].i_len, __func__);
2364 goto next; 2364 goto next;
2365 } 2365 }
2366 error = xfs_qm_dqcheck(mp, item->ri_buf[i].i_addr, 2366 error = xfs_dqcheck(mp, item->ri_buf[i].i_addr,
2367 -1, 0, XFS_QMOPT_DOWARN, 2367 -1, 0, XFS_QMOPT_DOWARN,
2368 "dquot_buf_recover"); 2368 "dquot_buf_recover");
2369 if (error) 2369 if (error)
@@ -2395,133 +2395,6 @@ xlog_recover_do_reg_buffer(
2395} 2395}
2396 2396
2397/* 2397/*
2398 * Do some primitive error checking on ondisk dquot data structures.
2399 */
2400int
2401xfs_qm_dqcheck(
2402 struct xfs_mount *mp,
2403 xfs_disk_dquot_t *ddq,
2404 xfs_dqid_t id,
2405 uint type, /* used only when IO_dorepair is true */
2406 uint flags,
2407 char *str)
2408{
2409 xfs_dqblk_t *d = (xfs_dqblk_t *)ddq;
2410 int errs = 0;
2411
2412 /*
2413 * We can encounter an uninitialized dquot buffer for 2 reasons:
2414 * 1. If we crash while deleting the quotainode(s), and those blks got
2415 * used for user data. This is because we take the path of regular
2416 * file deletion; however, the size field of quotainodes is never
2417 * updated, so all the tricks that we play in itruncate_finish
2418 * don't quite matter.
2419 *
2420 * 2. We don't play the quota buffers when there's a quotaoff logitem.
2421 * But the allocation will be replayed so we'll end up with an
2422 * uninitialized quota block.
2423 *
2424 * This is all fine; things are still consistent, and we haven't lost
2425 * any quota information. Just don't complain about bad dquot blks.
2426 */
2427 if (ddq->d_magic != cpu_to_be16(XFS_DQUOT_MAGIC)) {
2428 if (flags & XFS_QMOPT_DOWARN)
2429 xfs_alert(mp,
2430 "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
2431 str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC);
2432 errs++;
2433 }
2434 if (ddq->d_version != XFS_DQUOT_VERSION) {
2435 if (flags & XFS_QMOPT_DOWARN)
2436 xfs_alert(mp,
2437 "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
2438 str, id, ddq->d_version, XFS_DQUOT_VERSION);
2439 errs++;
2440 }
2441
2442 if (ddq->d_flags != XFS_DQ_USER &&
2443 ddq->d_flags != XFS_DQ_PROJ &&
2444 ddq->d_flags != XFS_DQ_GROUP) {
2445 if (flags & XFS_QMOPT_DOWARN)
2446 xfs_alert(mp,
2447 "%s : XFS dquot ID 0x%x, unknown flags 0x%x",
2448 str, id, ddq->d_flags);
2449 errs++;
2450 }
2451
2452 if (id != -1 && id != be32_to_cpu(ddq->d_id)) {
2453 if (flags & XFS_QMOPT_DOWARN)
2454 xfs_alert(mp,
2455 "%s : ondisk-dquot 0x%p, ID mismatch: "
2456 "0x%x expected, found id 0x%x",
2457 str, ddq, id, be32_to_cpu(ddq->d_id));
2458 errs++;
2459 }
2460
2461 if (!errs && ddq->d_id) {
2462 if (ddq->d_blk_softlimit &&
2463 be64_to_cpu(ddq->d_bcount) >
2464 be64_to_cpu(ddq->d_blk_softlimit)) {
2465 if (!ddq->d_btimer) {
2466 if (flags & XFS_QMOPT_DOWARN)
2467 xfs_alert(mp,
2468 "%s : Dquot ID 0x%x (0x%p) BLK TIMER NOT STARTED",
2469 str, (int)be32_to_cpu(ddq->d_id), ddq);
2470 errs++;
2471 }
2472 }
2473 if (ddq->d_ino_softlimit &&
2474 be64_to_cpu(ddq->d_icount) >
2475 be64_to_cpu(ddq->d_ino_softlimit)) {
2476 if (!ddq->d_itimer) {
2477 if (flags & XFS_QMOPT_DOWARN)
2478 xfs_alert(mp,
2479 "%s : Dquot ID 0x%x (0x%p) INODE TIMER NOT STARTED",
2480 str, (int)be32_to_cpu(ddq->d_id), ddq);
2481 errs++;
2482 }
2483 }
2484 if (ddq->d_rtb_softlimit &&
2485 be64_to_cpu(ddq->d_rtbcount) >
2486 be64_to_cpu(ddq->d_rtb_softlimit)) {
2487 if (!ddq->d_rtbtimer) {
2488 if (flags & XFS_QMOPT_DOWARN)
2489 xfs_alert(mp,
2490 "%s : Dquot ID 0x%x (0x%p) RTBLK TIMER NOT STARTED",
2491 str, (int)be32_to_cpu(ddq->d_id), ddq);
2492 errs++;
2493 }
2494 }
2495 }
2496
2497 if (!errs || !(flags & XFS_QMOPT_DQREPAIR))
2498 return errs;
2499
2500 if (flags & XFS_QMOPT_DOWARN)
2501 xfs_notice(mp, "Re-initializing dquot ID 0x%x", id);
2502
2503 /*
2504 * Typically, a repair is only requested by quotacheck.
2505 */
2506 ASSERT(id != -1);
2507 ASSERT(flags & XFS_QMOPT_DQREPAIR);
2508 memset(d, 0, sizeof(xfs_dqblk_t));
2509
2510 d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
2511 d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
2512 d->dd_diskdq.d_flags = type;
2513 d->dd_diskdq.d_id = cpu_to_be32(id);
2514
2515 if (xfs_sb_version_hascrc(&mp->m_sb)) {
2516 uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
2517 xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
2518 XFS_DQUOT_CRC_OFF);
2519 }
2520
2521 return errs;
2522}
2523
2524/*
2525 * Perform a dquot buffer recovery. 2398 * Perform a dquot buffer recovery.
2526 * Simple algorithm: if we have found a QUOTAOFF log item of the same type 2399 * Simple algorithm: if we have found a QUOTAOFF log item of the same type
2527 * (ie. USR or GRP), then just toss this buffer away; don't recover it. 2400 * (ie. USR or GRP), then just toss this buffer away; don't recover it.
@@ -3126,7 +2999,7 @@ xlog_recover_dquot_pass2(
3126 */ 2999 */
3127 dq_f = item->ri_buf[0].i_addr; 3000 dq_f = item->ri_buf[0].i_addr;
3128 ASSERT(dq_f); 3001 ASSERT(dq_f);
3129 error = xfs_qm_dqcheck(mp, recddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, 3002 error = xfs_dqcheck(mp, recddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN,
3130 "xlog_recover_dquot_pass2 (log copy)"); 3003 "xlog_recover_dquot_pass2 (log copy)");
3131 if (error) 3004 if (error)
3132 return XFS_ERROR(EIO); 3005 return XFS_ERROR(EIO);
@@ -3146,7 +3019,7 @@ xlog_recover_dquot_pass2(
3146 * was among a chunk of dquots created earlier, and we did some 3019 * was among a chunk of dquots created earlier, and we did some
3147 * minimal initialization then. 3020 * minimal initialization then.
3148 */ 3021 */
3149 error = xfs_qm_dqcheck(mp, ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, 3022 error = xfs_dqcheck(mp, ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN,
3150 "xlog_recover_dquot_pass2"); 3023 "xlog_recover_dquot_pass2");
3151 if (error) { 3024 if (error) {
3152 xfs_buf_relse(bp); 3025 xfs_buf_relse(bp);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index dc2d4f7ad7c9..6dfb4e320498 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -665,20 +665,6 @@ xfs_qm_dqdetach(
665 } 665 }
666} 666}
667 667
668int
669xfs_qm_calc_dquots_per_chunk(
670 struct xfs_mount *mp,
671 unsigned int nbblks) /* basic block units */
672{
673 unsigned int ndquots;
674
675 ASSERT(nbblks > 0);
676 ndquots = BBTOB(nbblks);
677 do_div(ndquots, sizeof(xfs_dqblk_t));
678
679 return ndquots;
680}
681
682struct xfs_qm_isolate { 668struct xfs_qm_isolate {
683 struct list_head buffers; 669 struct list_head buffers;
684 struct list_head dispose; 670 struct list_head dispose;
@@ -859,7 +845,7 @@ xfs_qm_init_quotainfo(
859 845
860 /* Precalc some constants */ 846 /* Precalc some constants */
861 qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB); 847 qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
862 qinf->qi_dqperchunk = xfs_qm_calc_dquots_per_chunk(mp, 848 qinf->qi_dqperchunk = xfs_calc_dquots_per_chunk(mp,
863 qinf->qi_dqchunklen); 849 qinf->qi_dqchunklen);
864 850
865 mp->m_qflags |= (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD); 851 mp->m_qflags |= (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD);
@@ -1093,10 +1079,10 @@ xfs_qm_reset_dqcounts(
1093 /* 1079 /*
1094 * Do a sanity check, and if needed, repair the dqblk. Don't 1080 * Do a sanity check, and if needed, repair the dqblk. Don't
1095 * output any warnings because it's perfectly possible to 1081 * output any warnings because it's perfectly possible to
1096 * find uninitialised dquot blks. See comment in xfs_qm_dqcheck. 1082 * find uninitialised dquot blks. See comment in xfs_dqcheck.
1097 */ 1083 */
1098 (void) xfs_qm_dqcheck(mp, ddq, id+j, type, XFS_QMOPT_DQREPAIR, 1084 xfs_dqcheck(mp, ddq, id+j, type, XFS_QMOPT_DQREPAIR,
1099 "xfs_quotacheck"); 1085 "xfs_quotacheck");
1100 ddq->d_bcount = 0; 1086 ddq->d_bcount = 0;
1101 ddq->d_icount = 0; 1087 ddq->d_icount = 0;
1102 ddq->d_rtbcount = 0; 1088 ddq->d_rtbcount = 0;
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 2b602df9c242..a788b66a5cb1 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -103,8 +103,6 @@ xfs_dq_to_quota_inode(struct xfs_dquot *dqp)
103 return NULL; 103 return NULL;
104} 104}
105 105
106extern int xfs_qm_calc_dquots_per_chunk(struct xfs_mount *mp,
107 unsigned int nbblks);
108extern void xfs_trans_mod_dquot(struct xfs_trans *, 106extern void xfs_trans_mod_dquot(struct xfs_trans *,
109 struct xfs_dquot *, uint, long); 107 struct xfs_dquot *, uint, long);
110extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *, 108extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 84661d4431fa..5376dd406ba2 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -150,8 +150,6 @@ static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp,
150 xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, pd, nb, ni, \ 150 xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, pd, nb, ni, \
151 f | XFS_QMOPT_RES_REGBLKS) 151 f | XFS_QMOPT_RES_REGBLKS)
152 152
153extern int xfs_qm_dqcheck(struct xfs_mount *, xfs_disk_dquot_t *,
154 xfs_dqid_t, uint, uint, char *);
155extern int xfs_mount_reset_sbqflags(struct xfs_mount *); 153extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
156 154
157#endif /* __XFS_QUOTA_H__ */ 155#endif /* __XFS_QUOTA_H__ */
diff --git a/fs/xfs/xfs_quota_defs.h b/fs/xfs/xfs_quota_defs.h
index e6b0d6e1f4f2..b3b2b1065c0f 100644
--- a/fs/xfs/xfs_quota_defs.h
+++ b/fs/xfs/xfs_quota_defs.h
@@ -154,4 +154,8 @@ typedef __uint16_t xfs_qwarncnt_t;
154 (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA) 154 (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
155#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) 155#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
156 156
157extern int xfs_dqcheck(struct xfs_mount *mp, xfs_disk_dquot_t *ddq,
158 xfs_dqid_t id, uint type, uint flags, char *str);
159extern int xfs_calc_dquots_per_chunk(struct xfs_mount *mp, unsigned int nbblks);
160
157#endif /* __XFS_QUOTA_H__ */ 161#endif /* __XFS_QUOTA_H__ */