Blame view
fs/xfs/xfs_dquot.c
34.3 KB
0b61f8a40 xfs: convert to S... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
4ce3121f6 [XFS] Update lice... |
3 4 |
* Copyright (c) 2000-2003 Silicon Graphics, Inc. * All Rights Reserved. |
1da177e4c Linux-2.6.12-rc2 |
5 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
6 7 |
#include "xfs.h" #include "xfs_fs.h" |
6ca1c9063 xfs: separate dqu... |
8 |
#include "xfs_format.h" |
239880ef6 xfs: decouple log... |
9 |
#include "xfs_log_format.h" |
70a9883c5 xfs: create a sha... |
10 |
#include "xfs_shared.h" |
239880ef6 xfs: decouple log... |
11 |
#include "xfs_trans_resv.h" |
a844f4510 [XFS] Remove xfs_... |
12 |
#include "xfs_bit.h" |
1da177e4c Linux-2.6.12-rc2 |
13 |
#include "xfs_mount.h" |
3ab78df2a xfs: rework xfs_b... |
14 |
#include "xfs_defer.h" |
1da177e4c Linux-2.6.12-rc2 |
15 16 |
#include "xfs_inode.h" #include "xfs_bmap.h" |
239880ef6 xfs: decouple log... |
17 |
#include "xfs_quota.h" |
239880ef6 xfs: decouple log... |
18 |
#include "xfs_trans.h" |
1da177e4c Linux-2.6.12-rc2 |
19 20 21 |
#include "xfs_buf_item.h" #include "xfs_trans_space.h" #include "xfs_trans_priv.h" |
1da177e4c Linux-2.6.12-rc2 |
22 |
#include "xfs_qm.h" |
0b1b213fc xfs: event tracin... |
23 |
#include "xfs_trace.h" |
239880ef6 xfs: decouple log... |
24 |
#include "xfs_log.h" |
a4fbe6ab1 xfs: decouple ino... |
25 |
#include "xfs_bmap_btree.h" |
afeda6000 xfs: validate ond... |
26 |
#include "xfs_error.h" |
1da177e4c Linux-2.6.12-rc2 |
27 |
|
1da177e4c Linux-2.6.12-rc2 |
28 |
/* |
bf72de319 xfs: nest qm_dqfr... |
29 30 31 |
* Lock order: * * ip->i_lock |
9f920f116 xfs: use per-file... |
32 |
* qi->qi_tree_lock |
b84a3a967 xfs: remove the p... |
33 34 35 |
* dquot->q_qlock (xfs_dqlock() and friends) * dquot->q_flush (xfs_dqflock() and friends) * qi->qi_lru_lock |
bf72de319 xfs: nest qm_dqfr... |
36 37 38 39 |
* * If two dquots need to be locked the order is user before group/project, * otherwise by the lowest id first, see xfs_dqlock2. */ |
1da177e4c Linux-2.6.12-rc2 |
40 |
|
a05931ceb xfs: remove the g... |
41 42 |
struct kmem_zone *xfs_qm_dqtrxzone; static struct kmem_zone *xfs_qm_dqzone; |
f112a0497 xfs: lockdep need... |
43 44 |
static struct lock_class_key xfs_dquot_group_class; static struct lock_class_key xfs_dquot_project_class; |
98b8c7a0c xfs: add a lock c... |
45 |
|
1da177e4c Linux-2.6.12-rc2 |
46 |
/* |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 50 |
* This is called to free all the memory associated with a dquot */ void xfs_qm_dqdestroy( |
aefe69a45 xfs: remove the x... |
51 |
struct xfs_dquot *dqp) |
1da177e4c Linux-2.6.12-rc2 |
52 |
{ |
f8739c3ce xfs: per-filesyst... |
53 |
ASSERT(list_empty(&dqp->q_lru)); |
1da177e4c Linux-2.6.12-rc2 |
54 |
|
b1c5ebb21 xfs: allocate log... |
55 |
kmem_free(dqp->q_logitem.qli_item.li_lv_shadow); |
1da177e4c Linux-2.6.12-rc2 |
56 |
mutex_destroy(&dqp->q_qlock); |
0b1b213fc xfs: event tracin... |
57 |
|
ff6d6af23 xfs: per-filesyst... |
58 |
XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot); |
377bcd5f3 xfs: Remove kmem_... |
59 |
kmem_cache_free(xfs_qm_dqzone, dqp); |
1da177e4c Linux-2.6.12-rc2 |
60 61 62 |
} /* |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 66 67 68 |
* If default limits are in force, push them into the dquot now. * We overwrite the dquot limits only if they are zero and this * is not the root dquot. */ void xfs_qm_adjust_dqlimits( |
4b6eae2e6 xfs: pass xfs_dqu... |
69 |
struct xfs_dquot *dq) |
1da177e4c Linux-2.6.12-rc2 |
70 |
{ |
c8c753e19 xfs: remove unnec... |
71 |
struct xfs_mount *mp = dq->q_mount; |
4b6eae2e6 xfs: pass xfs_dqu... |
72 |
struct xfs_quotainfo *q = mp->m_quotainfo; |
be6079461 xfs: Split defaul... |
73 |
struct xfs_def_quota *defq; |
b13664511 xfs: xfs_dquot pr... |
74 |
int prealloc = 0; |
1da177e4c Linux-2.6.12-rc2 |
75 |
|
c51df7334 xfs: stop using q... |
76 |
ASSERT(dq->q_id); |
ce6e7e79c xfs: switch xfs_g... |
77 |
defq = xfs_get_defquota(q, xfs_dquot_type(dq)); |
1da177e4c Linux-2.6.12-rc2 |
78 |
|
12d720fb8 xfs: assume the d... |
79 |
if (!dq->q_blk.softlimit) { |
438769e31 xfs: refactor def... |
80 |
dq->q_blk.softlimit = defq->blk.soft; |
b13664511 xfs: xfs_dquot pr... |
81 82 |
prealloc = 1; } |
12d720fb8 xfs: assume the d... |
83 |
if (!dq->q_blk.hardlimit) { |
438769e31 xfs: refactor def... |
84 |
dq->q_blk.hardlimit = defq->blk.hard; |
b13664511 xfs: xfs_dquot pr... |
85 86 |
prealloc = 1; } |
12d720fb8 xfs: assume the d... |
87 |
if (!dq->q_ino.softlimit) |
438769e31 xfs: refactor def... |
88 |
dq->q_ino.softlimit = defq->ino.soft; |
12d720fb8 xfs: assume the d... |
89 |
if (!dq->q_ino.hardlimit) |
438769e31 xfs: refactor def... |
90 |
dq->q_ino.hardlimit = defq->ino.hard; |
12d720fb8 xfs: assume the d... |
91 |
if (!dq->q_rtb.softlimit) |
438769e31 xfs: refactor def... |
92 |
dq->q_rtb.softlimit = defq->rtb.soft; |
12d720fb8 xfs: assume the d... |
93 |
if (!dq->q_rtb.hardlimit) |
438769e31 xfs: refactor def... |
94 |
dq->q_rtb.hardlimit = defq->rtb.hard; |
b13664511 xfs: xfs_dquot pr... |
95 96 97 |
if (prealloc) xfs_dquot_set_prealloc_limits(dq); |
1da177e4c Linux-2.6.12-rc2 |
98 |
} |
11d8a9190 xfs: refactor quo... |
99 100 101 102 103 104 105 106 107 108 109 |
/* Set the expiration time of a quota's grace period. */ time64_t xfs_dquot_set_timeout( struct xfs_mount *mp, time64_t timeout) { struct xfs_quotainfo *qi = mp->m_quotainfo; return clamp_t(time64_t, timeout, qi->qi_expiry_min, qi->qi_expiry_max); } |
ccc8e771a xfs: refactor def... |
110 111 112 113 114 115 116 |
/* Set the length of the default grace period. */ time64_t xfs_dquot_set_grace_period( time64_t grace) { return clamp_t(time64_t, grace, XFS_DQ_GRACE_MIN, XFS_DQ_GRACE_MAX); } |
1da177e4c Linux-2.6.12-rc2 |
117 |
/* |
ea0cc6fa8 xfs: refactor quo... |
118 119 120 121 122 |
* Determine if this quota counter is over either limit and set the quota * timers as appropriate. */ static inline void xfs_qm_adjust_res_timer( |
11d8a9190 xfs: refactor quo... |
123 |
struct xfs_mount *mp, |
ea0cc6fa8 xfs: refactor quo... |
124 125 126 127 128 129 130 131 |
struct xfs_dquot_res *res, struct xfs_quota_limits *qlim) { ASSERT(res->hardlimit == 0 || res->softlimit <= res->hardlimit); if ((res->softlimit && res->count > res->softlimit) || (res->hardlimit && res->count > res->hardlimit)) { if (res->timer == 0) |
11d8a9190 xfs: refactor quo... |
132 133 |
res->timer = xfs_dquot_set_timeout(mp, ktime_get_real_seconds() + qlim->time); |
ea0cc6fa8 xfs: refactor quo... |
134 135 136 137 138 139 140 141 142 |
} else { if (res->timer == 0) res->warnings = 0; else res->timer = 0; } } /* |
1da177e4c Linux-2.6.12-rc2 |
143 144 145 146 147 148 149 150 |
* Check the limits and timers of a dquot and start or reset timers * if necessary. * This gets called even when quota enforcement is OFF, which makes our * life a little less complicated. (We just don't reject any quota * reservations in that case, when enforcement is off). * We also return 0 as the values of the timers in Q_GETQUOTA calls, when * enforcement's off. * In contrast, warnings are a little different in that they don't |
754002b4f [XFS] Merge a few... |
151 152 153 |
* 'automatically' get started when limits get exceeded. They do * get reset to zero, however, when we find the count to be under * the soft limit (they are only ever set non-zero via userspace). |
1da177e4c Linux-2.6.12-rc2 |
154 155 156 |
*/ void xfs_qm_adjust_dqtimers( |
3dbb9aa31 xfs: pass xfs_dqu... |
157 |
struct xfs_dquot *dq) |
1da177e4c Linux-2.6.12-rc2 |
158 |
{ |
c8c753e19 xfs: remove unnec... |
159 |
struct xfs_mount *mp = dq->q_mount; |
e850301f0 xfs: per-type quo... |
160 |
struct xfs_quotainfo *qi = mp->m_quotainfo; |
e850301f0 xfs: per-type quo... |
161 |
struct xfs_def_quota *defq; |
c51df7334 xfs: stop using q... |
162 |
ASSERT(dq->q_id); |
e850301f0 xfs: per-type quo... |
163 |
defq = xfs_get_defquota(qi, xfs_dquot_type(dq)); |
1da177e4c Linux-2.6.12-rc2 |
164 |
|
11d8a9190 xfs: refactor quo... |
165 166 167 |
xfs_qm_adjust_res_timer(dq->q_mount, &dq->q_blk, &defq->blk); xfs_qm_adjust_res_timer(dq->q_mount, &dq->q_ino, &defq->ino); xfs_qm_adjust_res_timer(dq->q_mount, &dq->q_rtb, &defq->rtb); |
1da177e4c Linux-2.6.12-rc2 |
168 169 170 |
} /* |
1da177e4c Linux-2.6.12-rc2 |
171 172 173 174 |
* initialize a buffer full of dquots and log the whole thing */ STATIC void xfs_qm_init_dquot_blk( |
78bba5c81 xfs: use ordered ... |
175 176 177 |
struct xfs_trans *tp, struct xfs_mount *mp, xfs_dqid_t id, |
1a7ed2716 xfs: create xfs_d... |
178 |
xfs_dqtype_t type, |
78bba5c81 xfs: use ordered ... |
179 |
struct xfs_buf *bp) |
1da177e4c Linux-2.6.12-rc2 |
180 |
{ |
8a7b8a89a xfs: access quota... |
181 |
struct xfs_quotainfo *q = mp->m_quotainfo; |
78bba5c81 xfs: use ordered ... |
182 183 184 185 186 |
struct xfs_dqblk *d; xfs_dqid_t curid; unsigned int qflag; unsigned int blftype; int i; |
1da177e4c Linux-2.6.12-rc2 |
187 188 |
ASSERT(tp); |
0c842ad46 xfs: clean up buf... |
189 |
ASSERT(xfs_buf_islocked(bp)); |
1da177e4c Linux-2.6.12-rc2 |
190 |
|
e6eb603c7 xfs: refactor quo... |
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
switch (type) { case XFS_DQTYPE_USER: qflag = XFS_UQUOTA_CHKD; blftype = XFS_BLF_UDQUOT_BUF; break; case XFS_DQTYPE_PROJ: qflag = XFS_PQUOTA_CHKD; blftype = XFS_BLF_PDQUOT_BUF; break; case XFS_DQTYPE_GROUP: qflag = XFS_GQUOTA_CHKD; blftype = XFS_BLF_GDQUOT_BUF; break; default: ASSERT(0); return; } |
629260444 xfs: Remove the m... |
208 |
d = bp->b_addr; |
1da177e4c Linux-2.6.12-rc2 |
209 210 211 212 |
/* * ID of the first dquot in the block - id's are zero based. */ |
8a7b8a89a xfs: access quota... |
213 |
curid = id - (id % q->qi_dqperchunk); |
8a7b8a89a xfs: access quota... |
214 |
memset(d, 0, BBTOB(q->qi_dqchunklen)); |
49d35a5cf xfs: merge xfs_qm... |
215 216 217 218 |
for (i = 0; i < q->qi_dqperchunk; i++, d++, curid++) { d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); d->dd_diskdq.d_version = XFS_DQUOT_VERSION; d->dd_diskdq.d_id = cpu_to_be32(curid); |
d8c1af0d6 xfs: rename the o... |
219 |
d->dd_diskdq.d_type = type; |
4ea1ff3b4 xfs: widen ondisk... |
220 221 |
if (curid > 0 && xfs_sb_version_hasbigtime(&mp->m_sb)) d->dd_diskdq.d_type |= XFS_DQTYPE_BIGTIME; |
6fcdc59de xfs: rework dquot... |
222 |
if (xfs_sb_version_hascrc(&mp->m_sb)) { |
928634514 xfs: dquots shoul... |
223 |
uuid_copy(&d->dd_uuid, &mp->m_sb.sb_meta_uuid); |
6fcdc59de xfs: rework dquot... |
224 225 226 |
xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), XFS_DQUOT_CRC_OFF); } |
49d35a5cf xfs: merge xfs_qm... |
227 |
} |
78bba5c81 xfs: use ordered ... |
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
xfs_trans_dquot_buf(tp, bp, blftype); /* * quotacheck uses delayed writes to update all the dquots on disk in an * efficient manner instead of logging the individual dquot changes as * they are made. However if we log the buffer allocated here and crash * after quotacheck while the logged initialisation is still in the * active region of the log, log recovery can replay the dquot buffer * initialisation over the top of the checked dquots and corrupt quota * accounting. * * To avoid this problem, quotacheck cannot log the initialised buffer. * We must still dirty the buffer and write it back before the * allocation transaction clears the log. Therefore, mark the buffer as * ordered instead of logging it directly. This is safe for quotacheck * because it detects and repairs allocated but initialized dquot blocks * in the quota inodes. */ if (!(mp->m_qflags & qflag)) xfs_trans_ordered_buf(tp, bp); else xfs_trans_log_buf(tp, bp, 0, BBTOB(q->qi_dqchunklen) - 1); |
1da177e4c Linux-2.6.12-rc2 |
250 |
} |
b13664511 xfs: xfs_dquot pr... |
251 252 253 254 255 256 257 258 |
/* * Initialize the dynamic speculative preallocation thresholds. The lo/hi * watermarks correspond to the soft and hard limits by default. If a soft limit * is not specified, we use 95% of the hard limit. */ void xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp) { |
c8ce540db xfs: remove doubl... |
259 |
uint64_t space; |
b13664511 xfs: xfs_dquot pr... |
260 |
|
d3537cf93 xfs: stop using q... |
261 262 |
dqp->q_prealloc_hi_wmark = dqp->q_blk.hardlimit; dqp->q_prealloc_lo_wmark = dqp->q_blk.softlimit; |
b13664511 xfs: xfs_dquot pr... |
263 264 265 266 267 268 269 270 271 272 273 274 275 |
if (!dqp->q_prealloc_lo_wmark) { dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark; do_div(dqp->q_prealloc_lo_wmark, 100); dqp->q_prealloc_lo_wmark *= 95; } space = dqp->q_prealloc_hi_wmark; do_div(space, 100); dqp->q_low_space[XFS_QLOWSP_1_PCNT] = space; dqp->q_low_space[XFS_QLOWSP_3_PCNT] = space * 3; dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5; } |
1da177e4c Linux-2.6.12-rc2 |
276 |
/* |
d63192c89 xfs: refactor xfs... |
277 |
* Ensure that the given in-core dquot has a buffer on disk backing it, and |
710d707d2 xfs: always rejoi... |
278 279 |
* return the buffer locked and held. This is called when the bmapi finds a * hole. |
1da177e4c Linux-2.6.12-rc2 |
280 281 |
*/ STATIC int |
d63192c89 xfs: refactor xfs... |
282 283 284 285 |
xfs_dquot_disk_alloc( struct xfs_trans **tpp, struct xfs_dquot *dqp, struct xfs_buf **bpp) |
1da177e4c Linux-2.6.12-rc2 |
286 |
{ |
d63192c89 xfs: refactor xfs... |
287 |
struct xfs_bmbt_irec map; |
2ba137212 xfs: use ->t_dfop... |
288 289 |
struct xfs_trans *tp = *tpp; struct xfs_mount *mp = tp->t_mountp; |
d63192c89 xfs: refactor xfs... |
290 |
struct xfs_buf *bp; |
1a7ed2716 xfs: create xfs_d... |
291 |
xfs_dqtype_t qtype = xfs_dquot_type(dqp); |
0b04dd5d7 xfs: always use x... |
292 |
struct xfs_inode *quotip = xfs_quota_inode(mp, qtype); |
d63192c89 xfs: refactor xfs... |
293 294 |
int nmaps = 1; int error; |
0b1b213fc xfs: event tracin... |
295 296 |
trace_xfs_dqalloc(dqp); |
1da177e4c Linux-2.6.12-rc2 |
297 |
|
1da177e4c Linux-2.6.12-rc2 |
298 |
xfs_ilock(quotip, XFS_ILOCK_EXCL); |
0b04dd5d7 xfs: always use x... |
299 |
if (!xfs_this_quota_on(dqp->q_mount, qtype)) { |
d63192c89 xfs: refactor xfs... |
300 301 302 303 |
/* * Return if this type of quotas is turned off while we didn't * have an inode lock */ |
1da177e4c Linux-2.6.12-rc2 |
304 |
xfs_iunlock(quotip, XFS_ILOCK_EXCL); |
2451337dd xfs: global error... |
305 |
return -ESRCH; |
1da177e4c Linux-2.6.12-rc2 |
306 |
} |
d63192c89 xfs: refactor xfs... |
307 |
/* Create the block mapping. */ |
2ba137212 xfs: use ->t_dfop... |
308 309 |
xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL); error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset, |
da781e64b xfs: don't set bm... |
310 311 |
XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 0, &map, &nmaps); |
c0dc7828a xfs: rename xfs_b... |
312 |
if (error) |
73971b172 xfs: remove dead ... |
313 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
314 315 316 317 318 319 320 321 322 323 324 |
ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); ASSERT(nmaps == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && (map.br_startblock != HOLESTARTBLOCK)); /* * Keep track of the blkno to save a lookup later */ dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock); /* now we can just get the buffer (there's nothing to read yet) */ |
ce92464c1 xfs: make xfs_tra... |
325 326 327 328 |
error = xfs_trans_get_buf(tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, 0, &bp); if (error) return error; |
1813dd640 xfs: convert buff... |
329 |
bp->b_ops = &xfs_dquot_buf_ops; |
2a30f36d9 xfs: Check the re... |
330 |
|
1da177e4c Linux-2.6.12-rc2 |
331 332 333 334 |
/* * Make a chunk of dquots out of this buffer and log * the entire thing. */ |
0b04dd5d7 xfs: always use x... |
335 |
xfs_qm_init_dquot_blk(tp, mp, dqp->q_id, qtype, bp); |
d63192c89 xfs: refactor xfs... |
336 |
xfs_buf_set_ref(bp, XFS_DQUOT_REF); |
1da177e4c Linux-2.6.12-rc2 |
337 |
|
efa092f3d [XFS] Fixes a bug... |
338 |
/* |
7b6b50f55 xfs: release new ... |
339 340 341 342 343 344 345 346 |
* Hold the buffer and join it to the dfops so that we'll still own * the buffer when we return to the caller. The buffer disposal on * error must be paid attention to very carefully, as it has been * broken since commit efa092f3d4c6 "[XFS] Fixes a bug in the quota * code when allocating a new dquot record" in 2005, and the later * conversion to xfs_defer_ops in commit 310a75a3c6c747 failed to keep * the buffer locked across the _defer_finish call. We can now do * this correctly with xfs_defer_bjoin. |
efa092f3d [XFS] Fixes a bug... |
347 |
* |
73971b172 xfs: remove dead ... |
348 349 |
* Above, we allocated a disk block for the dquot information and used * get_buf to initialize the dquot. If the _defer_finish fails, the old |
7b6b50f55 xfs: release new ... |
350 351 |
* transaction is gone but the new buffer is not joined or held to any * transaction, so we must _buf_relse it. |
efa092f3d [XFS] Fixes a bug... |
352 |
* |
7b6b50f55 xfs: release new ... |
353 |
* If everything succeeds, the caller of this function is returned a |
d63192c89 xfs: refactor xfs... |
354 |
* buffer that is locked and held to the transaction. The caller |
7b6b50f55 xfs: release new ... |
355 |
* is responsible for unlocking any buffer passed back, either |
710d707d2 xfs: always rejoi... |
356 357 |
* manually or by committing the transaction. On error, the buffer is * released and not passed back. |
efa092f3d [XFS] Fixes a bug... |
358 |
*/ |
2ba137212 xfs: use ->t_dfop... |
359 |
xfs_trans_bhold(tp, bp); |
9e28a242b xfs: drop unneces... |
360 |
error = xfs_defer_finish(tpp); |
7b6b50f55 xfs: release new ... |
361 |
if (error) { |
710d707d2 xfs: always rejoi... |
362 363 |
xfs_trans_bhold_release(*tpp, bp); xfs_trans_brelse(*tpp, bp); |
73971b172 xfs: remove dead ... |
364 |
return error; |
efa092f3d [XFS] Fixes a bug... |
365 |
} |
d63192c89 xfs: refactor xfs... |
366 |
*bpp = bp; |
1da177e4c Linux-2.6.12-rc2 |
367 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
368 |
} |
9aede1d81 xfs: split dquot ... |
369 |
|
1da177e4c Linux-2.6.12-rc2 |
370 |
/* |
d63192c89 xfs: refactor xfs... |
371 372 |
* Read in the in-core dquot's on-disk metadata and return the buffer. * Returns ENOENT to signal a hole. |
1da177e4c Linux-2.6.12-rc2 |
373 374 |
*/ STATIC int |
d63192c89 xfs: refactor xfs... |
375 376 377 378 |
xfs_dquot_disk_read( struct xfs_mount *mp, struct xfs_dquot *dqp, struct xfs_buf **bpp) |
1da177e4c Linux-2.6.12-rc2 |
379 |
{ |
113a56835 xfs: Code cleanup... |
380 |
struct xfs_bmbt_irec map; |
113a56835 xfs: Code cleanup... |
381 |
struct xfs_buf *bp; |
1a7ed2716 xfs: create xfs_d... |
382 |
xfs_dqtype_t qtype = xfs_dquot_type(dqp); |
0b04dd5d7 xfs: always use x... |
383 |
struct xfs_inode *quotip = xfs_quota_inode(mp, qtype); |
0891f9971 Revert "xfs: grab... |
384 |
uint lock_mode; |
d63192c89 xfs: refactor xfs... |
385 386 |
int nmaps = 1; int error; |
1da177e4c Linux-2.6.12-rc2 |
387 |
|
0891f9971 Revert "xfs: grab... |
388 |
lock_mode = xfs_ilock_data_map_shared(quotip); |
0b04dd5d7 xfs: always use x... |
389 |
if (!xfs_this_quota_on(mp, qtype)) { |
1da177e4c Linux-2.6.12-rc2 |
390 |
/* |
acecf1b5d xfs: stop using x... |
391 392 |
* Return if this type of quotas is turned off while we * didn't have the quota inode lock. |
1da177e4c Linux-2.6.12-rc2 |
393 |
*/ |
0891f9971 Revert "xfs: grab... |
394 |
xfs_iunlock(quotip, lock_mode); |
2451337dd xfs: global error... |
395 |
return -ESRCH; |
acecf1b5d xfs: stop using x... |
396 397 398 399 400 |
} /* * Find the block map; no allocations yet */ |
5c8ed2021 xfs: introduce xf... |
401 |
error = xfs_bmapi_read(quotip, dqp->q_fileoffset, |
d63192c89 xfs: refactor xfs... |
402 |
XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0); |
0891f9971 Revert "xfs: grab... |
403 |
xfs_iunlock(quotip, lock_mode); |
acecf1b5d xfs: stop using x... |
404 405 406 407 |
if (error) return error; ASSERT(nmaps == 1); |
d63192c89 xfs: refactor xfs... |
408 409 410 411 412 413 |
ASSERT(map.br_blockcount >= 1); ASSERT(map.br_startblock != DELAYSTARTBLOCK); if (map.br_startblock == HOLESTARTBLOCK) return -ENOENT; trace_xfs_dqtobp_read(dqp); |
acecf1b5d xfs: stop using x... |
414 415 |
/* |
d63192c89 xfs: refactor xfs... |
416 417 |
* store the blkno etc so that we don't have to do the * mapping all the time |
acecf1b5d xfs: stop using x... |
418 |
*/ |
d63192c89 xfs: refactor xfs... |
419 |
dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock); |
1da177e4c Linux-2.6.12-rc2 |
420 |
|
d63192c89 xfs: refactor xfs... |
421 422 423 424 425 426 |
error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, 0, &bp, &xfs_dquot_buf_ops); if (error) { ASSERT(bp == NULL); return error; |
1da177e4c Linux-2.6.12-rc2 |
427 |
} |
c63191987 xfs: verify dquot... |
428 |
ASSERT(xfs_buf_islocked(bp)); |
d63192c89 xfs: refactor xfs... |
429 430 |
xfs_buf_set_ref(bp, XFS_DQUOT_REF); *bpp = bp; |
1da177e4c Linux-2.6.12-rc2 |
431 |
|
d99831ff3 xfs: return is no... |
432 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
433 |
} |
617cd5c12 xfs: refactor inc... |
434 435 436 |
/* Allocate and initialize everything we need for an incore dquot. */ STATIC struct xfs_dquot * xfs_dquot_alloc( |
97e7ade50 xfs: kill xfs_qm_... |
437 438 |
struct xfs_mount *mp, xfs_dqid_t id, |
1a7ed2716 xfs: create xfs_d... |
439 |
xfs_dqtype_t type) |
1da177e4c Linux-2.6.12-rc2 |
440 |
{ |
97e7ade50 xfs: kill xfs_qm_... |
441 |
struct xfs_dquot *dqp; |
92b2e5b31 xfs: use a normal... |
442 |
|
32a2b11f4 xfs: Remove kmem_... |
443 |
dqp = kmem_cache_zalloc(xfs_qm_dqzone, GFP_KERNEL | __GFP_NOFAIL); |
92b2e5b31 xfs: use a normal... |
444 |
|
1a7ed2716 xfs: create xfs_d... |
445 |
dqp->q_type = type; |
c51df7334 xfs: stop using q... |
446 |
dqp->q_id = id; |
92b2e5b31 xfs: use a normal... |
447 |
dqp->q_mount = mp; |
f8739c3ce xfs: per-filesyst... |
448 |
INIT_LIST_HEAD(&dqp->q_lru); |
92b2e5b31 xfs: use a normal... |
449 450 |
mutex_init(&dqp->q_qlock); init_waitqueue_head(&dqp->q_pinwait); |
d63192c89 xfs: refactor xfs... |
451 452 453 454 455 456 |
dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk; /* * Offset of dquot in the (fixed sized) dquot chunk. */ dqp->q_bufoffset = (id % mp->m_quotainfo->qi_dqperchunk) * sizeof(xfs_dqblk_t); |
92b2e5b31 xfs: use a normal... |
457 458 459 460 461 462 463 464 465 466 467 468 469 |
/* * Because we want to use a counting completion, complete * the flush completion once to allow a single access to * the flush completion without blocking. */ init_completion(&dqp->q_flush); complete(&dqp->q_flush); /* * Make sure group quotas have a different lock class than user * quotas. */ |
f112a0497 xfs: lockdep need... |
470 |
switch (type) { |
8cd4901da xfs: rename XFS_D... |
471 |
case XFS_DQTYPE_USER: |
f112a0497 xfs: lockdep need... |
472 473 |
/* uses the default lock class */ break; |
8cd4901da xfs: rename XFS_D... |
474 |
case XFS_DQTYPE_GROUP: |
f112a0497 xfs: lockdep need... |
475 476 |
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_group_class); break; |
8cd4901da xfs: rename XFS_D... |
477 |
case XFS_DQTYPE_PROJ: |
f112a0497 xfs: lockdep need... |
478 479 480 481 482 483 |
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_project_class); break; default: ASSERT(0); break; } |
92b2e5b31 xfs: use a normal... |
484 |
|
617cd5c12 xfs: refactor inc... |
485 |
xfs_qm_dquot_logitem_init(dqp); |
ff6d6af23 xfs: per-filesyst... |
486 |
XFS_STATS_INC(mp, xs_qm_dquot); |
617cd5c12 xfs: refactor inc... |
487 488 489 490 |
return dqp; } /* Copy the in-core quota fields in from the on-disk buffer. */ |
afeda6000 xfs: validate ond... |
491 |
STATIC int |
617cd5c12 xfs: refactor inc... |
492 493 |
xfs_dquot_from_disk( struct xfs_dquot *dqp, |
d63192c89 xfs: refactor xfs... |
494 |
struct xfs_buf *bp) |
617cd5c12 xfs: refactor inc... |
495 |
{ |
d63192c89 xfs: refactor xfs... |
496 |
struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; |
afeda6000 xfs: validate ond... |
497 498 499 500 |
/* * Ensure that we got the type and ID we were looking for. * Everything else was checked by the dquot buffer verifier. */ |
d8c1af0d6 xfs: rename the o... |
501 |
if ((ddqp->d_type & XFS_DQTYPE_REC_MASK) != xfs_dquot_type(dqp) || |
c51df7334 xfs: stop using q... |
502 |
be32_to_cpu(ddqp->d_id) != dqp->q_id) { |
afeda6000 xfs: validate ond... |
503 504 |
xfs_alert_tag(bp->b_mount, XFS_PTAG_VERIFIER_ERROR, "Metadata corruption detected at %pS, quota %u", |
c51df7334 xfs: stop using q... |
505 |
__this_address, dqp->q_id); |
afeda6000 xfs: validate ond... |
506 507 508 |
xfs_alert(bp->b_mount, "Unmount and run xfs_repair"); return -EFSCORRUPTED; } |
617cd5c12 xfs: refactor inc... |
509 |
/* copy everything from disk dquot to the incore dquot */ |
d8c1af0d6 xfs: rename the o... |
510 |
dqp->q_type = ddqp->d_type; |
d3537cf93 xfs: stop using q... |
511 512 513 514 515 516 |
dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit); dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit); dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit); dqp->q_ino.softlimit = be64_to_cpu(ddqp->d_ino_softlimit); dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit); |
617cd5c12 xfs: refactor inc... |
517 |
|
be37d40c1 xfs: stop using q... |
518 519 520 |
dqp->q_blk.count = be64_to_cpu(ddqp->d_bcount); dqp->q_ino.count = be64_to_cpu(ddqp->d_icount); dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount); |
c8c45fb2f xfs: stop using q... |
521 522 523 |
dqp->q_blk.warnings = be16_to_cpu(ddqp->d_bwarns); dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns); dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns); |
9f99c8fe5 xfs: refactor quo... |
524 525 526 |
dqp->q_blk.timer = xfs_dquot_from_disk_ts(ddqp, ddqp->d_btimer); dqp->q_ino.timer = xfs_dquot_from_disk_ts(ddqp, ddqp->d_itimer); dqp->q_rtb.timer = xfs_dquot_from_disk_ts(ddqp, ddqp->d_rtbtimer); |
19dce7eae xfs: stop using q... |
527 |
|
617cd5c12 xfs: refactor inc... |
528 529 530 531 |
/* * Reservation counters are defined as reservation plus current usage * to avoid having to add every time. */ |
be37d40c1 xfs: stop using q... |
532 533 534 |
dqp->q_blk.reserved = dqp->q_blk.count; dqp->q_ino.reserved = dqp->q_ino.count; dqp->q_rtb.reserved = dqp->q_rtb.count; |
617cd5c12 xfs: refactor inc... |
535 536 537 |
/* initialize the dquot speculative prealloc thresholds */ xfs_dquot_set_prealloc_limits(dqp); |
afeda6000 xfs: validate ond... |
538 |
return 0; |
617cd5c12 xfs: refactor inc... |
539 |
} |
1da177e4c Linux-2.6.12-rc2 |
540 |
|
0b0fa1d1d xfs: stop using q... |
541 542 543 544 545 546 |
/* Copy the in-core quota fields into the on-disk buffer. */ void xfs_dquot_to_disk( struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp) { |
51dbb1be5 xfs: remove qcore... |
547 548 |
ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); ddqp->d_version = XFS_DQUOT_VERSION; |
d8c1af0d6 xfs: rename the o... |
549 |
ddqp->d_type = dqp->q_type; |
51dbb1be5 xfs: remove qcore... |
550 551 552 |
ddqp->d_id = cpu_to_be32(dqp->q_id); ddqp->d_pad0 = 0; ddqp->d_pad = 0; |
d3537cf93 xfs: stop using q... |
553 554 555 556 557 558 |
ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit); ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit); ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit); ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit); ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit); ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit); |
be37d40c1 xfs: stop using q... |
559 560 561 562 |
ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count); ddqp->d_icount = cpu_to_be64(dqp->q_ino.count); ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count); |
c8c45fb2f xfs: stop using q... |
563 564 565 566 |
ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings); ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings); ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings); |
19dce7eae xfs: stop using q... |
567 |
|
9f99c8fe5 xfs: refactor quo... |
568 569 570 |
ddqp->d_btimer = xfs_dquot_to_disk_ts(dqp, dqp->q_blk.timer); ddqp->d_itimer = xfs_dquot_to_disk_ts(dqp, dqp->q_ino.timer); ddqp->d_rtbtimer = xfs_dquot_to_disk_ts(dqp, dqp->q_rtb.timer); |
0b0fa1d1d xfs: stop using q... |
571 |
} |
d63192c89 xfs: refactor xfs... |
572 573 574 575 576 577 578 579 |
/* Allocate and initialize the dquot buffer for this in-core dquot. */ static int xfs_qm_dqread_alloc( struct xfs_mount *mp, struct xfs_dquot *dqp, struct xfs_buf **bpp) { struct xfs_trans *tp; |
d63192c89 xfs: refactor xfs... |
580 581 582 583 584 585 |
int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc, XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp); if (error) goto err; |
710d707d2 xfs: always rejoi... |
586 |
error = xfs_dquot_disk_alloc(&tp, dqp, bpp); |
d63192c89 xfs: refactor xfs... |
587 588 589 590 591 592 593 594 595 |
if (error) goto err_cancel; error = xfs_trans_commit(tp); if (error) { /* * Buffer was held to the transaction, so we have to unlock it * manually here because we're not passing it back. */ |
710d707d2 xfs: always rejoi... |
596 597 |
xfs_buf_relse(*bpp); *bpp = NULL; |
d63192c89 xfs: refactor xfs... |
598 599 |
goto err; } |
d63192c89 xfs: refactor xfs... |
600 601 602 603 604 605 606 |
return 0; err_cancel: xfs_trans_cancel(tp); err: return error; } |
617cd5c12 xfs: refactor inc... |
607 608 |
/* * Read in the ondisk dquot using dqtobp() then copy it to an incore version, |
30ab2dcf2 xfs: replace XFS_... |
609 610 |
* and release the buffer immediately. If @can_alloc is true, fill any * holes in the on-disk metadata. |
617cd5c12 xfs: refactor inc... |
611 |
*/ |
114e73ccf xfs: remove direc... |
612 |
static int |
617cd5c12 xfs: refactor inc... |
613 614 615 |
xfs_qm_dqread( struct xfs_mount *mp, xfs_dqid_t id, |
1a7ed2716 xfs: create xfs_d... |
616 |
xfs_dqtype_t type, |
30ab2dcf2 xfs: replace XFS_... |
617 |
bool can_alloc, |
d63192c89 xfs: refactor xfs... |
618 |
struct xfs_dquot **dqpp) |
617cd5c12 xfs: refactor inc... |
619 620 |
{ struct xfs_dquot *dqp; |
617cd5c12 xfs: refactor inc... |
621 |
struct xfs_buf *bp; |
617cd5c12 xfs: refactor inc... |
622 623 624 |
int error; dqp = xfs_dquot_alloc(mp, id, type); |
0b1b213fc xfs: event tracin... |
625 |
trace_xfs_dqread(dqp); |
d63192c89 xfs: refactor xfs... |
626 627 |
/* Try to read the buffer, allocating if necessary. */ error = xfs_dquot_disk_read(mp, dqp, &bp); |
30ab2dcf2 xfs: replace XFS_... |
628 |
if (error == -ENOENT && can_alloc) |
d63192c89 xfs: refactor xfs... |
629 630 631 |
error = xfs_qm_dqread_alloc(mp, dqp, &bp); if (error) goto err; |
1da177e4c Linux-2.6.12-rc2 |
632 633 |
/* |
d63192c89 xfs: refactor xfs... |
634 635 636 637 |
* At this point we should have a clean locked buffer. Copy the data * to the incore dquot and release the buffer since the incore dquot * has its own locking protocol so we needn't tie up the buffer any * further. |
1da177e4c Linux-2.6.12-rc2 |
638 |
*/ |
0c842ad46 xfs: clean up buf... |
639 |
ASSERT(xfs_buf_islocked(bp)); |
afeda6000 xfs: validate ond... |
640 |
error = xfs_dquot_from_disk(dqp, bp); |
d63192c89 xfs: refactor xfs... |
641 |
xfs_buf_relse(bp); |
afeda6000 xfs: validate ond... |
642 643 |
if (error) goto err; |
d63192c89 xfs: refactor xfs... |
644 |
*dqpp = dqp; |
97e7ade50 xfs: kill xfs_qm_... |
645 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
646 |
|
d63192c89 xfs: refactor xfs... |
647 648 |
err: trace_xfs_dqread_fail(dqp); |
1da177e4c Linux-2.6.12-rc2 |
649 |
xfs_qm_dqdestroy(dqp); |
d63192c89 xfs: refactor xfs... |
650 |
*dqpp = NULL; |
97e7ade50 xfs: kill xfs_qm_... |
651 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
652 653 654 |
} /* |
296c24e26 xfs: wire up Q_XG... |
655 656 657 658 |
* Advance to the next id in the current chunk, or if at the * end of the chunk, skip ahead to first id in next allocated chunk * using the SEEK_DATA interface. */ |
6e3e6d55e xfs: mute some sp... |
659 |
static int |
296c24e26 xfs: wire up Q_XG... |
660 |
xfs_dq_get_next_id( |
bda250dba xfs: rewrite xfs_... |
661 |
struct xfs_mount *mp, |
1a7ed2716 xfs: create xfs_d... |
662 |
xfs_dqtype_t type, |
bda250dba xfs: rewrite xfs_... |
663 |
xfs_dqid_t *id) |
296c24e26 xfs: wire up Q_XG... |
664 |
{ |
bda250dba xfs: rewrite xfs_... |
665 666 667 668 |
struct xfs_inode *quotip = xfs_quota_inode(mp, type); xfs_dqid_t next_id = *id + 1; /* simple advance */ uint lock_flags; struct xfs_bmbt_irec got; |
b2b1712a6 xfs: introduce th... |
669 |
struct xfs_iext_cursor cur; |
296c24e26 xfs: wire up Q_XG... |
670 |
xfs_fsblock_t start; |
296c24e26 xfs: wire up Q_XG... |
671 |
int error = 0; |
657bdfb7f xfs: don't wrap I... |
672 673 674 |
/* If we'd wrap past the max ID, stop */ if (next_id < *id) return -ENOENT; |
296c24e26 xfs: wire up Q_XG... |
675 676 677 678 679 680 681 682 |
/* If new ID is within the current chunk, advancing it sufficed */ if (next_id % mp->m_quotainfo->qi_dqperchunk) { *id = next_id; return 0; } /* Nope, next_id is now past the current chunk, so find the next one */ start = (xfs_fsblock_t)next_id / mp->m_quotainfo->qi_dqperchunk; |
bda250dba xfs: rewrite xfs_... |
683 684 685 686 687 688 |
lock_flags = xfs_ilock_data_map_shared(quotip); if (!(quotip->i_df.if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(NULL, quotip, XFS_DATA_FORK); if (error) return error; } |
296c24e26 xfs: wire up Q_XG... |
689 |
|
b2b1712a6 xfs: introduce th... |
690 |
if (xfs_iext_lookup_extent(quotip, "ip->i_df, start, &cur, &got)) { |
2192b0bae xfs: fix contiguo... |
691 692 693 |
/* contiguous chunk, bump startoff for the id calculation */ if (got.br_startoff < start) got.br_startoff = start; |
bda250dba xfs: rewrite xfs_... |
694 |
*id = got.br_startoff * mp->m_quotainfo->qi_dqperchunk; |
2192b0bae xfs: fix contiguo... |
695 |
} else { |
bda250dba xfs: rewrite xfs_... |
696 |
error = -ENOENT; |
2192b0bae xfs: fix contiguo... |
697 |
} |
bda250dba xfs: rewrite xfs_... |
698 |
xfs_iunlock(quotip, lock_flags); |
296c24e26 xfs: wire up Q_XG... |
699 |
|
bda250dba xfs: rewrite xfs_... |
700 |
return error; |
296c24e26 xfs: wire up Q_XG... |
701 702 703 |
} /* |
cc2047c4d xfs: refactor dqu... |
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
* Look up the dquot in the in-core cache. If found, the dquot is returned * locked and ready to go. */ static struct xfs_dquot * xfs_qm_dqget_cache_lookup( struct xfs_mount *mp, struct xfs_quotainfo *qi, struct radix_tree_root *tree, xfs_dqid_t id) { struct xfs_dquot *dqp; restart: mutex_lock(&qi->qi_tree_lock); dqp = radix_tree_lookup(tree, id); if (!dqp) { mutex_unlock(&qi->qi_tree_lock); XFS_STATS_INC(mp, xs_qm_dqcachemisses); return NULL; } xfs_dqlock(dqp); |
985a78fdd xfs: rename dquot... |
726 |
if (dqp->q_flags & XFS_DQFLAG_FREEING) { |
cc2047c4d xfs: refactor dqu... |
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 |
xfs_dqunlock(dqp); mutex_unlock(&qi->qi_tree_lock); trace_xfs_dqget_freeing(dqp); delay(1); goto restart; } dqp->q_nrefs++; mutex_unlock(&qi->qi_tree_lock); trace_xfs_dqget_hit(dqp); XFS_STATS_INC(mp, xs_qm_dqcachehits); return dqp; } /* * Try to insert a new dquot into the in-core cache. If an error occurs the * caller should throw away the dquot and start over. Otherwise, the dquot * is returned locked (and held by the cache) as if there had been a cache * hit. */ static int xfs_qm_dqget_cache_insert( struct xfs_mount *mp, struct xfs_quotainfo *qi, struct radix_tree_root *tree, xfs_dqid_t id, struct xfs_dquot *dqp) { int error; mutex_lock(&qi->qi_tree_lock); error = radix_tree_insert(tree, id, dqp); if (unlikely(error)) { /* Duplicate found! Caller must try again. */ WARN_ON(error != -EEXIST); mutex_unlock(&qi->qi_tree_lock); trace_xfs_dqget_dup(dqp); return error; } /* Return a locked dquot to the caller, with a reference taken. */ xfs_dqlock(dqp); dqp->q_nrefs = 1; qi->qi_dquots++; mutex_unlock(&qi->qi_tree_lock); return 0; } |
d7103eeb0 xfs: delegate dqg... |
777 778 779 780 |
/* Check our input parameters. */ static int xfs_qm_dqget_checks( struct xfs_mount *mp, |
1a7ed2716 xfs: create xfs_d... |
781 |
xfs_dqtype_t type) |
d7103eeb0 xfs: delegate dqg... |
782 783 784 785 786 |
{ if (WARN_ON_ONCE(!XFS_IS_QUOTA_RUNNING(mp))) return -ESRCH; switch (type) { |
8cd4901da xfs: rename XFS_D... |
787 |
case XFS_DQTYPE_USER: |
d7103eeb0 xfs: delegate dqg... |
788 789 790 |
if (!XFS_IS_UQUOTA_ON(mp)) return -ESRCH; return 0; |
8cd4901da xfs: rename XFS_D... |
791 |
case XFS_DQTYPE_GROUP: |
d7103eeb0 xfs: delegate dqg... |
792 793 794 |
if (!XFS_IS_GQUOTA_ON(mp)) return -ESRCH; return 0; |
8cd4901da xfs: rename XFS_D... |
795 |
case XFS_DQTYPE_PROJ: |
d7103eeb0 xfs: delegate dqg... |
796 797 798 799 800 801 802 803 |
if (!XFS_IS_PQUOTA_ON(mp)) return -ESRCH; return 0; default: WARN_ON_ONCE(0); return -EINVAL; } } |
cc2047c4d xfs: refactor dqu... |
804 |
/* |
a647d109e xfs: fix some com... |
805 806 |
* Given the file system, id, and type (UDQUOT/GDQUOT/PDQUOT), return a * locked dquot, doing an allocation (if requested) as needed. |
1da177e4c Linux-2.6.12-rc2 |
807 808 809 |
*/ int xfs_qm_dqget( |
4882c19d2 xfs: split out dq... |
810 811 |
struct xfs_mount *mp, xfs_dqid_t id, |
1a7ed2716 xfs: create xfs_d... |
812 |
xfs_dqtype_t type, |
30ab2dcf2 xfs: replace XFS_... |
813 |
bool can_alloc, |
4882c19d2 xfs: split out dq... |
814 |
struct xfs_dquot **O_dqpp) |
1da177e4c Linux-2.6.12-rc2 |
815 |
{ |
9f920f116 xfs: use per-file... |
816 |
struct xfs_quotainfo *qi = mp->m_quotainfo; |
4882c19d2 xfs: split out dq... |
817 |
struct radix_tree_root *tree = xfs_dquot_tree(qi, type); |
9f920f116 xfs: use per-file... |
818 819 |
struct xfs_dquot *dqp; int error; |
1da177e4c Linux-2.6.12-rc2 |
820 |
|
d7103eeb0 xfs: delegate dqg... |
821 822 823 |
error = xfs_qm_dqget_checks(mp, type); if (error) return error; |
1da177e4c Linux-2.6.12-rc2 |
824 |
|
4882c19d2 xfs: split out dq... |
825 826 827 828 829 830 |
restart: dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id); if (dqp) { *O_dqpp = dqp; return 0; } |
30ab2dcf2 xfs: replace XFS_... |
831 |
error = xfs_qm_dqread(mp, id, type, can_alloc, &dqp); |
4882c19d2 xfs: split out dq... |
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 |
if (error) return error; error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp); if (error) { /* * Duplicate found. Just throw away the new dquot and start * over. */ xfs_qm_dqdestroy(dqp); XFS_STATS_INC(mp, xs_qm_dquot_dups); goto restart; } trace_xfs_dqget_miss(dqp); *O_dqpp = dqp; return 0; } |
114e73ccf xfs: remove direc... |
850 851 852 853 854 855 856 857 858 859 |
/* * Given a dquot id and type, read and initialize a dquot from the on-disk * metadata. This function is only for use during quota initialization so * it ignores the dquot cache assuming that the dquot shrinker isn't set up. * The caller is responsible for _qm_dqdestroy'ing the returned dquot. */ int xfs_qm_dqget_uncached( struct xfs_mount *mp, xfs_dqid_t id, |
1a7ed2716 xfs: create xfs_d... |
860 |
xfs_dqtype_t type, |
114e73ccf xfs: remove direc... |
861 862 863 864 865 866 867 868 869 870 |
struct xfs_dquot **dqpp) { int error; error = xfs_qm_dqget_checks(mp, type); if (error) return error; return xfs_qm_dqread(mp, id, type, 0, dqpp); } |
4882c19d2 xfs: split out dq... |
871 872 873 874 |
/* Return the quota id for a given inode and type. */ xfs_dqid_t xfs_qm_id_for_quotatype( struct xfs_inode *ip, |
1a7ed2716 xfs: create xfs_d... |
875 |
xfs_dqtype_t type) |
4882c19d2 xfs: split out dq... |
876 877 |
{ switch (type) { |
8cd4901da xfs: rename XFS_D... |
878 |
case XFS_DQTYPE_USER: |
ba8adad5d xfs: remove the k... |
879 |
return i_uid_read(VFS_I(ip)); |
8cd4901da xfs: rename XFS_D... |
880 |
case XFS_DQTYPE_GROUP: |
ba8adad5d xfs: remove the k... |
881 |
return i_gid_read(VFS_I(ip)); |
8cd4901da xfs: rename XFS_D... |
882 |
case XFS_DQTYPE_PROJ: |
de7a866fd xfs: merge the pr... |
883 |
return ip->i_d.di_projid; |
1da177e4c Linux-2.6.12-rc2 |
884 |
} |
4882c19d2 xfs: split out dq... |
885 886 887 888 889 890 891 892 893 894 895 896 |
ASSERT(0); return 0; } /* * Return the dquot for a given inode and type. If @can_alloc is true, then * allocate blocks if needed. The inode's ILOCK must be held and it must not * have already had an inode attached. */ int xfs_qm_dqget_inode( struct xfs_inode *ip, |
1a7ed2716 xfs: create xfs_d... |
897 |
xfs_dqtype_t type, |
4882c19d2 xfs: split out dq... |
898 899 900 901 902 903 904 905 |
bool can_alloc, struct xfs_dquot **O_dqpp) { struct xfs_mount *mp = ip->i_mount; struct xfs_quotainfo *qi = mp->m_quotainfo; struct radix_tree_root *tree = xfs_dquot_tree(qi, type); struct xfs_dquot *dqp; xfs_dqid_t id; |
4882c19d2 xfs: split out dq... |
906 907 908 909 910 |
int error; error = xfs_qm_dqget_checks(mp, type); if (error) return error; |
4882c19d2 xfs: split out dq... |
911 912 913 914 |
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_inode_dquot(ip, type) == NULL); id = xfs_qm_id_for_quotatype(ip, type); |
92678554a xfs: flatten the ... |
915 916 |
restart: |
cc2047c4d xfs: refactor dqu... |
917 |
dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id); |
9f920f116 xfs: use per-file... |
918 |
if (dqp) { |
9f920f116 xfs: use per-file... |
919 920 |
*O_dqpp = dqp; return 0; |
1da177e4c Linux-2.6.12-rc2 |
921 |
} |
1da177e4c Linux-2.6.12-rc2 |
922 923 924 925 926 927 928 929 |
/* * Dquot cache miss. We don't want to keep the inode lock across * a (potential) disk read. Also we don't want to deal with the lock * ordering between quotainode and this inode. OTOH, dropping the inode * lock here means dealing with a chown that can happen before * we re-acquire the lock. */ |
4882c19d2 xfs: split out dq... |
930 |
xfs_iunlock(ip, XFS_ILOCK_EXCL); |
30ab2dcf2 xfs: replace XFS_... |
931 |
error = xfs_qm_dqread(mp, id, type, can_alloc, &dqp); |
4882c19d2 xfs: split out dq... |
932 |
xfs_ilock(ip, XFS_ILOCK_EXCL); |
7ae444072 xfs: remove XFS_Q... |
933 934 |
if (error) return error; |
1da177e4c Linux-2.6.12-rc2 |
935 |
|
4882c19d2 xfs: split out dq... |
936 937 938 939 940 941 942 943 944 |
/* * A dquot could be attached to this inode by now, since we had * dropped the ilock. */ if (xfs_this_quota_on(mp, type)) { struct xfs_dquot *dqp1; dqp1 = xfs_inode_dquot(ip, type); if (dqp1) { |
367314108 Define a new func... |
945 |
xfs_qm_dqdestroy(dqp); |
4882c19d2 xfs: split out dq... |
946 947 948 |
dqp = dqp1; xfs_dqlock(dqp); goto dqret; |
1da177e4c Linux-2.6.12-rc2 |
949 |
} |
4882c19d2 xfs: split out dq... |
950 951 952 953 |
} else { /* inode stays locked on return */ xfs_qm_dqdestroy(dqp); return -ESRCH; |
1da177e4c Linux-2.6.12-rc2 |
954 |
} |
cc2047c4d xfs: refactor dqu... |
955 956 |
error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp); if (error) { |
1da177e4c Linux-2.6.12-rc2 |
957 |
/* |
9f920f116 xfs: use per-file... |
958 959 |
* Duplicate found. Just throw away the new dquot and start * over. |
1da177e4c Linux-2.6.12-rc2 |
960 |
*/ |
9f920f116 xfs: use per-file... |
961 |
xfs_qm_dqdestroy(dqp); |
ff6d6af23 xfs: per-filesyst... |
962 |
XFS_STATS_INC(mp, xs_qm_dquot_dups); |
9f920f116 xfs: use per-file... |
963 |
goto restart; |
1da177e4c Linux-2.6.12-rc2 |
964 |
} |
4882c19d2 xfs: split out dq... |
965 966 |
dqret: ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
0b1b213fc xfs: event tracin... |
967 |
trace_xfs_dqget_miss(dqp); |
1da177e4c Linux-2.6.12-rc2 |
968 |
*O_dqpp = dqp; |
d99831ff3 xfs: return is no... |
969 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
970 |
} |
f8739c3ce xfs: per-filesyst... |
971 |
/* |
2e330e76e xfs: refactor XFS... |
972 973 974 975 976 977 978 |
* Starting at @id and progressing upwards, look for an initialized incore * dquot, lock it, and return it. */ int xfs_qm_dqget_next( struct xfs_mount *mp, xfs_dqid_t id, |
1a7ed2716 xfs: create xfs_d... |
979 |
xfs_dqtype_t type, |
2e330e76e xfs: refactor XFS... |
980 981 982 983 984 985 986 |
struct xfs_dquot **dqpp) { struct xfs_dquot *dqp; int error = 0; *dqpp = NULL; for (; !error; error = xfs_dq_get_next_id(mp, type, &id)) { |
30ab2dcf2 xfs: replace XFS_... |
987 |
error = xfs_qm_dqget(mp, id, type, false, &dqp); |
2e330e76e xfs: refactor XFS... |
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 |
if (error == -ENOENT) continue; else if (error != 0) break; if (!XFS_IS_DQUOT_UNINITIALIZED(dqp)) { *dqpp = dqp; return 0; } xfs_qm_dqput(dqp); } return error; } /* |
f8739c3ce xfs: per-filesyst... |
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 |
* Release a reference to the dquot (decrement ref-count) and unlock it. * * If there is a group quota attached to this dquot, carefully release that * too without tripping over deadlocks'n'stuff. */ void xfs_qm_dqput( struct xfs_dquot *dqp) { ASSERT(dqp->q_nrefs > 0); ASSERT(XFS_DQ_IS_LOCKED(dqp)); trace_xfs_dqput(dqp); |
3c3533757 xfs: remove dquot... |
1018 1019 1020 1021 1022 |
if (--dqp->q_nrefs == 0) { struct xfs_quotainfo *qi = dqp->q_mount->m_quotainfo; trace_xfs_dqput_free(dqp); if (list_lru_add(&qi->qi_lru, &dqp->q_lru)) |
ff6d6af23 xfs: per-filesyst... |
1023 |
XFS_STATS_INC(dqp->q_mount, xs_qm_dquot_unused); |
3c3533757 xfs: remove dquot... |
1024 1025 |
} xfs_dqunlock(dqp); |
1da177e4c Linux-2.6.12-rc2 |
1026 1027 1028 1029 1030 1031 1032 1033 |
} /* * Release a dquot. Flush it if dirty, then dqput() it. * dquot must not be locked. */ void xfs_qm_dqrele( |
aefe69a45 xfs: remove the x... |
1034 |
struct xfs_dquot *dqp) |
1da177e4c Linux-2.6.12-rc2 |
1035 |
{ |
7d095257e xfs: kill xfs_qmops |
1036 1037 |
if (!dqp) return; |
0b1b213fc xfs: event tracin... |
1038 |
trace_xfs_dqrele(dqp); |
1da177e4c Linux-2.6.12-rc2 |
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 |
xfs_dqlock(dqp); /* * We don't care to flush it if the dquot is dirty here. * That will create stutters that we want to avoid. * Instead we do a delayed write when we try to reclaim * a dirty dquot. Also xfs_sync will take part of the burden... */ xfs_qm_dqput(dqp); } |
ca30b2a7b xfs: give li_cb c... |
1049 1050 1051 1052 1053 1054 1055 |
/* * This is the dquot flushing I/O completion routine. It is called * from interrupt level when the buffer containing the dquot is * flushed to disk. It is responsible for removing the dquot logitem * from the AIL if it has not been re-logged, and unlocking the dquot's * flush lock. This behavior is very similar to that of inodes.. */ |
6f5de1808 xfs: use direct c... |
1056 |
static void |
ca30b2a7b xfs: give li_cb c... |
1057 |
xfs_qm_dqflush_done( |
ca30b2a7b xfs: give li_cb c... |
1058 1059 |
struct xfs_log_item *lip) { |
fd8b81dbb xfs: remove the x... |
1060 |
struct xfs_dq_logitem *qip = (struct xfs_dq_logitem *)lip; |
aefe69a45 xfs: remove the x... |
1061 |
struct xfs_dquot *dqp = qip->qli_dquot; |
ca30b2a7b xfs: give li_cb c... |
1062 |
struct xfs_ail *ailp = lip->li_ailp; |
849274c10 xfs: acquire ->ai... |
1063 |
xfs_lsn_t tail_lsn; |
ca30b2a7b xfs: give li_cb c... |
1064 1065 1066 1067 1068 1069 1070 1071 1072 |
/* * We only want to pull the item from the AIL if its * location in the log has not changed since we started the flush. * Thus, we only bother if the dquot's lsn has * not changed. First we check the lsn outside the lock * since it's cheaper, and then we recheck while * holding the lock before removing the dquot from the AIL. */ |
22525c17e xfs: log item fla... |
1073 |
if (test_bit(XFS_LI_IN_AIL, &lip->li_flags) && |
373b0589d xfs: Properly ret... |
1074 |
((lip->li_lsn == qip->qli_flush_lsn) || |
22525c17e xfs: log item fla... |
1075 |
test_bit(XFS_LI_FAILED, &lip->li_flags))) { |
ca30b2a7b xfs: give li_cb c... |
1076 |
|
57e809561 xfs: Rename xa_ e... |
1077 |
spin_lock(&ailp->ail_lock); |
e98084b8b xfs: move xfs_cle... |
1078 |
xfs_clear_li_failed(lip); |
373b0589d xfs: Properly ret... |
1079 |
if (lip->li_lsn == qip->qli_flush_lsn) { |
849274c10 xfs: acquire ->ai... |
1080 1081 1082 |
/* xfs_ail_update_finish() drops the AIL lock */ tail_lsn = xfs_ail_delete_one(ailp, lip); xfs_ail_update_finish(ailp, tail_lsn); |
373b0589d xfs: Properly ret... |
1083 |
} else { |
57e809561 xfs: Rename xa_ e... |
1084 |
spin_unlock(&ailp->ail_lock); |
373b0589d xfs: Properly ret... |
1085 |
} |
ca30b2a7b xfs: give li_cb c... |
1086 1087 1088 1089 1090 1091 1092 |
} /* * Release the dq's flush lock since we're done with it. */ xfs_dqfunlock(dqp); } |
1da177e4c Linux-2.6.12-rc2 |
1093 |
|
6f5de1808 xfs: use direct c... |
1094 |
void |
664ffb8a4 xfs: move the buf... |
1095 |
xfs_buf_dquot_iodone( |
6f5de1808 xfs: use direct c... |
1096 1097 1098 1099 1100 1101 1102 1103 1104 |
struct xfs_buf *bp) { struct xfs_log_item *lip, *n; list_for_each_entry_safe(lip, n, &bp->b_li_list, li_bio_list) { list_del_init(&lip->li_bio_list); xfs_qm_dqflush_done(lip); } } |
664ffb8a4 xfs: move the buf... |
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 |
void xfs_buf_dquot_io_fail( struct xfs_buf *bp) { struct xfs_log_item *lip; spin_lock(&bp->b_mount->m_ail->ail_lock); list_for_each_entry(lip, &bp->b_li_list, li_bio_list) xfs_set_li_failed(lip, bp); spin_unlock(&bp->b_mount->m_ail->ail_lock); } |
0b0fa1d1d xfs: stop using q... |
1116 1117 1118 1119 1120 |
/* Check incore dquot for errors before we flush. */ static xfs_failaddr_t xfs_qm_dqflush_check( struct xfs_dquot *dqp) { |
1a7ed2716 xfs: create xfs_d... |
1121 |
xfs_dqtype_t type = xfs_dquot_type(dqp); |
0b0fa1d1d xfs: stop using q... |
1122 |
|
8cd4901da xfs: rename XFS_D... |
1123 1124 1125 |
if (type != XFS_DQTYPE_USER && type != XFS_DQTYPE_GROUP && type != XFS_DQTYPE_PROJ) |
0b0fa1d1d xfs: stop using q... |
1126 |
return __this_address; |
d3537cf93 xfs: stop using q... |
1127 1128 |
if (dqp->q_id == 0) return NULL; |
be37d40c1 xfs: stop using q... |
1129 |
if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit && |
19dce7eae xfs: stop using q... |
1130 |
!dqp->q_blk.timer) |
d3537cf93 xfs: stop using q... |
1131 |
return __this_address; |
be37d40c1 xfs: stop using q... |
1132 |
if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit && |
19dce7eae xfs: stop using q... |
1133 |
!dqp->q_ino.timer) |
d3537cf93 xfs: stop using q... |
1134 |
return __this_address; |
be37d40c1 xfs: stop using q... |
1135 |
if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit && |
19dce7eae xfs: stop using q... |
1136 |
!dqp->q_rtb.timer) |
d3537cf93 xfs: stop using q... |
1137 |
return __this_address; |
4ea1ff3b4 xfs: widen ondisk... |
1138 1139 1140 1141 1142 1143 1144 |
/* bigtime flag should never be set on root dquots */ if (dqp->q_type & XFS_DQTYPE_BIGTIME) { if (!xfs_sb_version_hasbigtime(&dqp->q_mount->m_sb)) return __this_address; if (dqp->q_id == 0) return __this_address; } |
0b0fa1d1d xfs: stop using q... |
1145 1146 |
return NULL; } |
1da177e4c Linux-2.6.12-rc2 |
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 |
/* * Write a modified dquot to disk. * The dquot must be locked and the flush lock too taken by caller. * The flush lock will not be unlocked until the dquot reaches the disk, * but the dquot is free to be unlocked and modified by the caller * in the interim. Dquot is still locked on return. This behavior is * identical to that of inodes. */ int xfs_qm_dqflush( |
fe7257fd4 xfs: do not write... |
1157 1158 |
struct xfs_dquot *dqp, struct xfs_buf **bpp) |
1da177e4c Linux-2.6.12-rc2 |
1159 |
{ |
acecf1b5d xfs: stop using x... |
1160 |
struct xfs_mount *mp = dqp->q_mount; |
b707fffda xfs: abort consis... |
1161 |
struct xfs_log_item *lip = &dqp->q_logitem.qli_item; |
acecf1b5d xfs: stop using x... |
1162 |
struct xfs_buf *bp; |
51dbb1be5 xfs: remove qcore... |
1163 |
struct xfs_dqblk *dqblk; |
eebf3cab9 xfs: standardize ... |
1164 |
xfs_failaddr_t fa; |
1da177e4c Linux-2.6.12-rc2 |
1165 |
int error; |
1da177e4c Linux-2.6.12-rc2 |
1166 1167 |
ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
e1f49cf20 [XFS] replace dqu... |
1168 |
ASSERT(!completion_done(&dqp->q_flush)); |
acecf1b5d xfs: stop using x... |
1169 |
|
0b1b213fc xfs: event tracin... |
1170 |
trace_xfs_dqflush(dqp); |
1da177e4c Linux-2.6.12-rc2 |
1171 |
|
fe7257fd4 xfs: do not write... |
1172 |
*bpp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1173 1174 1175 |
xfs_qm_dqunpin_wait(dqp); /* |
1da177e4c Linux-2.6.12-rc2 |
1176 |
* Get the buffer containing the on-disk dquot |
1da177e4c Linux-2.6.12-rc2 |
1177 |
*/ |
acecf1b5d xfs: stop using x... |
1178 |
error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, |
8d3d7e2b3 xfs: trylock unde... |
1179 1180 |
mp->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK, &bp, &xfs_dquot_buf_ops); |
b707fffda xfs: abort consis... |
1181 |
if (error == -EAGAIN) |
fe7257fd4 xfs: do not write... |
1182 |
goto out_unlock; |
b707fffda xfs: abort consis... |
1183 1184 |
if (error) goto out_abort; |
1da177e4c Linux-2.6.12-rc2 |
1185 |
|
0b0fa1d1d xfs: stop using q... |
1186 1187 1188 |
fa = xfs_qm_dqflush_check(dqp); if (fa) { xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", |
c51df7334 xfs: stop using q... |
1189 |
dqp->q_id, fa); |
0b0fa1d1d xfs: stop using q... |
1190 1191 1192 1193 |
xfs_buf_relse(bp); error = -EFSCORRUPTED; goto out_abort; } |
51dbb1be5 xfs: remove qcore... |
1194 1195 1196 |
/* Flush the incore dquot to the ondisk buffer. */ dqblk = bp->b_addr + dqp->q_bufoffset; xfs_dquot_to_disk(&dqblk->dd_diskdq, dqp); |
1da177e4c Linux-2.6.12-rc2 |
1197 1198 1199 1200 |
/* * Clear the dirty field and remember the flush lsn for later use. */ |
985a78fdd xfs: rename dquot... |
1201 |
dqp->q_flags &= ~XFS_DQFLAG_DIRTY; |
1da177e4c Linux-2.6.12-rc2 |
1202 |
|
7b2e2a31f [XFS] Allow 64 bi... |
1203 1204 |
xfs_trans_ail_copy_lsn(mp->m_ail, &dqp->q_logitem.qli_flush_lsn, &dqp->q_logitem.qli_item.li_lsn); |
1da177e4c Linux-2.6.12-rc2 |
1205 1206 |
/* |
3fe58f30b xfs: add CRC chec... |
1207 1208 1209 |
* copy the lsn into the on-disk dquot now while we have the in memory * dquot here. This can't be done later in the write verifier as we * can't get access to the log item at that point in time. |
6fcdc59de xfs: rework dquot... |
1210 1211 1212 1213 |
* * We also calculate the CRC here so that the on-disk dquot in the * buffer always has a valid CRC. This ensures there is no possibility * of a dquot without an up-to-date CRC getting to disk. |
3fe58f30b xfs: add CRC chec... |
1214 1215 |
*/ if (xfs_sb_version_hascrc(&mp->m_sb)) { |
51dbb1be5 xfs: remove qcore... |
1216 1217 |
dqblk->dd_lsn = cpu_to_be64(dqp->q_logitem.qli_item.li_lsn); xfs_update_cksum((char *)dqblk, sizeof(struct xfs_dqblk), |
6fcdc59de xfs: rework dquot... |
1218 |
XFS_DQUOT_CRC_OFF); |
3fe58f30b xfs: add CRC chec... |
1219 1220 1221 |
} /* |
2ef3f7f5d xfs: get rid of l... |
1222 1223 |
* Attach the dquot to the buffer so that we can remove this dquot from * the AIL and release the flush lock once the dquot is synced to disk. |
1da177e4c Linux-2.6.12-rc2 |
1224 |
*/ |
0c7e5afbe xfs: mark dquot b... |
1225 |
bp->b_flags |= _XBF_DQUOTS; |
2ef3f7f5d xfs: get rid of l... |
1226 |
list_add_tail(&dqp->q_logitem.qli_item.li_bio_list, &bp->b_li_list); |
ca30b2a7b xfs: give li_cb c... |
1227 |
|
1da177e4c Linux-2.6.12-rc2 |
1228 1229 1230 1231 |
/* * If the buffer is pinned then push on the log so we won't * get stuck waiting in the write for too long. */ |
811e64c71 Replace the macro... |
1232 |
if (xfs_buf_ispinned(bp)) { |
0b1b213fc xfs: event tracin... |
1233 |
trace_xfs_dqflush_force(dqp); |
a14a348bf xfs: cleanup up x... |
1234 |
xfs_log_force(mp, 0); |
1da177e4c Linux-2.6.12-rc2 |
1235 |
} |
0b1b213fc xfs: event tracin... |
1236 |
trace_xfs_dqflush_done(dqp); |
fe7257fd4 xfs: do not write... |
1237 1238 |
*bpp = bp; return 0; |
0b1b213fc xfs: event tracin... |
1239 |
|
b707fffda xfs: abort consis... |
1240 |
out_abort: |
985a78fdd xfs: rename dquot... |
1241 |
dqp->q_flags &= ~XFS_DQFLAG_DIRTY; |
2b3cf0935 xfs: combine xfs_... |
1242 |
xfs_trans_ail_delete(lip, 0); |
b707fffda xfs: abort consis... |
1243 |
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
fe7257fd4 xfs: do not write... |
1244 1245 |
out_unlock: xfs_dqfunlock(dqp); |
8d3d7e2b3 xfs: trylock unde... |
1246 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
1247 |
} |
5bb87a33b xfs: lockdep anno... |
1248 1249 1250 1251 1252 1253 |
/* * Lock two xfs_dquot structures. * * To avoid deadlocks we always lock the quota structure with * the lowerd id first. */ |
1da177e4c Linux-2.6.12-rc2 |
1254 1255 |
void xfs_dqlock2( |
aefe69a45 xfs: remove the x... |
1256 1257 |
struct xfs_dquot *d1, struct xfs_dquot *d2) |
1da177e4c Linux-2.6.12-rc2 |
1258 1259 1260 |
{ if (d1 && d2) { ASSERT(d1 != d2); |
c51df7334 xfs: stop using q... |
1261 |
if (d1->q_id > d2->q_id) { |
5bb87a33b xfs: lockdep anno... |
1262 1263 |
mutex_lock(&d2->q_qlock); mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED); |
1da177e4c Linux-2.6.12-rc2 |
1264 |
} else { |
5bb87a33b xfs: lockdep anno... |
1265 1266 |
mutex_lock(&d1->q_qlock); mutex_lock_nested(&d2->q_qlock, XFS_QLOCK_NESTED); |
1da177e4c Linux-2.6.12-rc2 |
1267 |
} |
5bb87a33b xfs: lockdep anno... |
1268 1269 1270 1271 |
} else if (d1) { mutex_lock(&d1->q_qlock); } else if (d2) { mutex_lock(&d2->q_qlock); |
1da177e4c Linux-2.6.12-rc2 |
1272 1273 |
} } |
a05931ceb xfs: remove the g... |
1274 1275 1276 |
int __init xfs_qm_init(void) { |
b1231760e xfs: Remove slab ... |
1277 1278 1279 |
xfs_qm_dqzone = kmem_cache_create("xfs_dquot", sizeof(struct xfs_dquot), 0, 0, NULL); |
a05931ceb xfs: remove the g... |
1280 1281 |
if (!xfs_qm_dqzone) goto out; |
b1231760e xfs: Remove slab ... |
1282 1283 1284 |
xfs_qm_dqtrxzone = kmem_cache_create("xfs_dqtrx", sizeof(struct xfs_dquot_acct), 0, 0, NULL); |
a05931ceb xfs: remove the g... |
1285 1286 1287 1288 1289 1290 |
if (!xfs_qm_dqtrxzone) goto out_free_dqzone; return 0; out_free_dqzone: |
aaf54eb8b xfs: Remove kmem_... |
1291 |
kmem_cache_destroy(xfs_qm_dqzone); |
a05931ceb xfs: remove the g... |
1292 1293 1294 |
out: return -ENOMEM; } |
1c2ccc66b fs: xfs: fix sect... |
1295 |
void |
a05931ceb xfs: remove the g... |
1296 1297 |
xfs_qm_exit(void) { |
aaf54eb8b xfs: Remove kmem_... |
1298 1299 |
kmem_cache_destroy(xfs_qm_dqtrxzone); kmem_cache_destroy(xfs_qm_dqzone); |
a05931ceb xfs: remove the g... |
1300 |
} |
554ba9654 xfs: refactor dqu... |
1301 1302 1303 1304 |
/* * Iterate every dquot of a particular type. The caller must ensure that the * particular quota type is active. iter_fn can return negative error codes, |
e7ee96dfb xfs: remove all *... |
1305 |
* or -ECANCELED to indicate that it wants to stop iterating. |
554ba9654 xfs: refactor dqu... |
1306 1307 1308 1309 |
*/ int xfs_qm_dqiterate( struct xfs_mount *mp, |
1a7ed2716 xfs: create xfs_d... |
1310 |
xfs_dqtype_t type, |
554ba9654 xfs: refactor dqu... |
1311 1312 1313 1314 1315 1316 1317 1318 |
xfs_qm_dqiterate_fn iter_fn, void *priv) { struct xfs_dquot *dq; xfs_dqid_t id = 0; int error; do { |
1a7ed2716 xfs: create xfs_d... |
1319 |
error = xfs_qm_dqget_next(mp, id, type, &dq); |
554ba9654 xfs: refactor dqu... |
1320 1321 1322 1323 |
if (error == -ENOENT) return 0; if (error) return error; |
1a7ed2716 xfs: create xfs_d... |
1324 |
error = iter_fn(dq, type, priv); |
c51df7334 xfs: stop using q... |
1325 |
id = dq->q_id; |
554ba9654 xfs: refactor dqu... |
1326 |
xfs_qm_dqput(dq); |
554ba9654 xfs: refactor dqu... |
1327 1328 1329 1330 |
} while (error == 0 && id != 0); return error; } |