xfs: merge iop_unpin_remove into iop_unpin
[deliverable/linux.git] / fs / xfs / quota / xfs_dquot_item.c
1 /*
2 * Copyright (c) 2000-2003 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_bit.h"
21 #include "xfs_log.h"
22 #include "xfs_inum.h"
23 #include "xfs_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_alloc.h"
27 #include "xfs_quota.h"
28 #include "xfs_mount.h"
29 #include "xfs_bmap_btree.h"
30 #include "xfs_inode.h"
31 #include "xfs_bmap.h"
32 #include "xfs_rtalloc.h"
33 #include "xfs_error.h"
34 #include "xfs_itable.h"
35 #include "xfs_attr.h"
36 #include "xfs_buf_item.h"
37 #include "xfs_trans_priv.h"
38 #include "xfs_qm.h"
39
40 /*
41 * returns the number of iovecs needed to log the given dquot item.
42 */
43 /* ARGSUSED */
44 STATIC uint
45 xfs_qm_dquot_logitem_size(
46 xfs_dq_logitem_t *logitem)
47 {
48 /*
49 * we need only two iovecs, one for the format, one for the real thing
50 */
51 return (2);
52 }
53
54 /*
55 * fills in the vector of log iovecs for the given dquot log item.
56 */
57 STATIC void
58 xfs_qm_dquot_logitem_format(
59 xfs_dq_logitem_t *logitem,
60 xfs_log_iovec_t *logvec)
61 {
62 ASSERT(logitem);
63 ASSERT(logitem->qli_dquot);
64
65 logvec->i_addr = (xfs_caddr_t)&logitem->qli_format;
66 logvec->i_len = sizeof(xfs_dq_logformat_t);
67 logvec->i_type = XLOG_REG_TYPE_QFORMAT;
68 logvec++;
69 logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core;
70 logvec->i_len = sizeof(xfs_disk_dquot_t);
71 logvec->i_type = XLOG_REG_TYPE_DQUOT;
72
73 ASSERT(2 == logitem->qli_item.li_desc->lid_size);
74 logitem->qli_format.qlf_size = 2;
75
76 }
77
78 /*
79 * Increment the pin count of the given dquot.
80 */
81 STATIC void
82 xfs_qm_dquot_logitem_pin(
83 xfs_dq_logitem_t *logitem)
84 {
85 xfs_dquot_t *dqp = logitem->qli_dquot;
86
87 ASSERT(XFS_DQ_IS_LOCKED(dqp));
88 atomic_inc(&dqp->q_pincount);
89 }
90
91 /*
92 * Decrement the pin count of the given dquot, and wake up
93 * anyone in xfs_dqwait_unpin() if the count goes to 0. The
94 * dquot must have been previously pinned with a call to
95 * xfs_qm_dquot_logitem_pin().
96 */
97 /* ARGSUSED */
98 STATIC void
99 xfs_qm_dquot_logitem_unpin(
100 xfs_dq_logitem_t *logitem,
101 int remove)
102 {
103 xfs_dquot_t *dqp = logitem->qli_dquot;
104
105 ASSERT(atomic_read(&dqp->q_pincount) > 0);
106 if (atomic_dec_and_test(&dqp->q_pincount))
107 wake_up(&dqp->q_pinwait);
108 }
109
110 /*
111 * Given the logitem, this writes the corresponding dquot entry to disk
112 * asynchronously. This is called with the dquot entry securely locked;
113 * we simply get xfs_qm_dqflush() to do the work, and unlock the dquot
114 * at the end.
115 */
116 STATIC void
117 xfs_qm_dquot_logitem_push(
118 xfs_dq_logitem_t *logitem)
119 {
120 xfs_dquot_t *dqp;
121 int error;
122
123 dqp = logitem->qli_dquot;
124
125 ASSERT(XFS_DQ_IS_LOCKED(dqp));
126 ASSERT(!completion_done(&dqp->q_flush));
127
128 /*
129 * Since we were able to lock the dquot's flush lock and
130 * we found it on the AIL, the dquot must be dirty. This
131 * is because the dquot is removed from the AIL while still
132 * holding the flush lock in xfs_dqflush_done(). Thus, if
133 * we found it in the AIL and were able to obtain the flush
134 * lock without sleeping, then there must not have been
135 * anyone in the process of flushing the dquot.
136 */
137 error = xfs_qm_dqflush(dqp, 0);
138 if (error)
139 xfs_fs_cmn_err(CE_WARN, dqp->q_mount,
140 "xfs_qm_dquot_logitem_push: push error %d on dqp %p",
141 error, dqp);
142 xfs_dqunlock(dqp);
143 }
144
145 /*ARGSUSED*/
146 STATIC xfs_lsn_t
147 xfs_qm_dquot_logitem_committed(
148 xfs_dq_logitem_t *l,
149 xfs_lsn_t lsn)
150 {
151 /*
152 * We always re-log the entire dquot when it becomes dirty,
153 * so, the latest copy _is_ the only one that matters.
154 */
155 return (lsn);
156 }
157
158
159 /*
160 * This is called to wait for the given dquot to be unpinned.
161 * Most of these pin/unpin routines are plagiarized from inode code.
162 */
163 void
164 xfs_qm_dqunpin_wait(
165 xfs_dquot_t *dqp)
166 {
167 ASSERT(XFS_DQ_IS_LOCKED(dqp));
168 if (atomic_read(&dqp->q_pincount) == 0)
169 return;
170
171 /*
172 * Give the log a push so we don't wait here too long.
173 */
174 xfs_log_force(dqp->q_mount, 0);
175 wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
176 }
177
178 /*
179 * This is called when IOP_TRYLOCK returns XFS_ITEM_PUSHBUF to indicate that
180 * the dquot is locked by us, but the flush lock isn't. So, here we are
181 * going to see if the relevant dquot buffer is incore, waiting on DELWRI.
182 * If so, we want to push it out to help us take this item off the AIL as soon
183 * as possible.
184 *
185 * We must not be holding the AIL lock at this point. Calling incore() to
186 * search the buffer cache can be a time consuming thing, and AIL lock is a
187 * spinlock.
188 */
189 STATIC void
190 xfs_qm_dquot_logitem_pushbuf(
191 xfs_dq_logitem_t *qip)
192 {
193 xfs_dquot_t *dqp;
194 xfs_mount_t *mp;
195 xfs_buf_t *bp;
196
197 dqp = qip->qli_dquot;
198 ASSERT(XFS_DQ_IS_LOCKED(dqp));
199
200 /*
201 * If flushlock isn't locked anymore, chances are that the
202 * inode flush completed and the inode was taken off the AIL.
203 * So, just get out.
204 */
205 if (completion_done(&dqp->q_flush) ||
206 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
207 xfs_dqunlock(dqp);
208 return;
209 }
210 mp = dqp->q_mount;
211 bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno,
212 mp->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
213 xfs_dqunlock(dqp);
214 if (!bp)
215 return;
216 if (XFS_BUF_ISDELAYWRITE(bp))
217 xfs_buf_delwri_promote(bp);
218 xfs_buf_relse(bp);
219 return;
220
221 }
222
223 /*
224 * This is called to attempt to lock the dquot associated with this
225 * dquot log item. Don't sleep on the dquot lock or the flush lock.
226 * If the flush lock is already held, indicating that the dquot has
227 * been or is in the process of being flushed, then see if we can
228 * find the dquot's buffer in the buffer cache without sleeping. If
229 * we can and it is marked delayed write, then we want to send it out.
230 * We delay doing so until the push routine, though, to avoid sleeping
231 * in any device strategy routines.
232 */
233 STATIC uint
234 xfs_qm_dquot_logitem_trylock(
235 xfs_dq_logitem_t *qip)
236 {
237 xfs_dquot_t *dqp;
238
239 dqp = qip->qli_dquot;
240 if (atomic_read(&dqp->q_pincount) > 0)
241 return XFS_ITEM_PINNED;
242
243 if (! xfs_qm_dqlock_nowait(dqp))
244 return XFS_ITEM_LOCKED;
245
246 if (!xfs_dqflock_nowait(dqp)) {
247 /*
248 * dquot has already been flushed to the backing buffer,
249 * leave it locked, pushbuf routine will unlock it.
250 */
251 return XFS_ITEM_PUSHBUF;
252 }
253
254 ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL);
255 return XFS_ITEM_SUCCESS;
256 }
257
258
259 /*
260 * Unlock the dquot associated with the log item.
261 * Clear the fields of the dquot and dquot log item that
262 * are specific to the current transaction. If the
263 * hold flags is set, do not unlock the dquot.
264 */
265 STATIC void
266 xfs_qm_dquot_logitem_unlock(
267 xfs_dq_logitem_t *ql)
268 {
269 xfs_dquot_t *dqp;
270
271 ASSERT(ql != NULL);
272 dqp = ql->qli_dquot;
273 ASSERT(XFS_DQ_IS_LOCKED(dqp));
274
275 /*
276 * Clear the transaction pointer in the dquot
277 */
278 dqp->q_transp = NULL;
279
280 /*
281 * dquots are never 'held' from getting unlocked at the end of
282 * a transaction. Their locking and unlocking is hidden inside the
283 * transaction layer, within trans_commit. Hence, no LI_HOLD flag
284 * for the logitem.
285 */
286 xfs_dqunlock(dqp);
287 }
288
289
290 /*
291 * this needs to stamp an lsn into the dquot, I think.
292 * rpc's that look at user dquot's would then have to
293 * push on the dependency recorded in the dquot
294 */
295 /* ARGSUSED */
296 STATIC void
297 xfs_qm_dquot_logitem_committing(
298 xfs_dq_logitem_t *l,
299 xfs_lsn_t lsn)
300 {
301 return;
302 }
303
304
305 /*
306 * This is the ops vector for dquots
307 */
308 static struct xfs_item_ops xfs_dquot_item_ops = {
309 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
310 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
311 xfs_qm_dquot_logitem_format,
312 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin,
313 .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_qm_dquot_logitem_unpin,
314 .iop_trylock = (uint(*)(xfs_log_item_t*))
315 xfs_qm_dquot_logitem_trylock,
316 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unlock,
317 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
318 xfs_qm_dquot_logitem_committed,
319 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push,
320 .iop_pushbuf = (void(*)(xfs_log_item_t*))
321 xfs_qm_dquot_logitem_pushbuf,
322 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
323 xfs_qm_dquot_logitem_committing
324 };
325
326 /*
327 * Initialize the dquot log item for a newly allocated dquot.
328 * The dquot isn't locked at this point, but it isn't on any of the lists
329 * either, so we don't care.
330 */
331 void
332 xfs_qm_dquot_logitem_init(
333 struct xfs_dquot *dqp)
334 {
335 xfs_dq_logitem_t *lp;
336 lp = &dqp->q_logitem;
337
338 xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT,
339 &xfs_dquot_item_ops);
340 lp->qli_dquot = dqp;
341 lp->qli_format.qlf_type = XFS_LI_DQUOT;
342 lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id);
343 lp->qli_format.qlf_blkno = dqp->q_blkno;
344 lp->qli_format.qlf_len = 1;
345 /*
346 * This is just the offset of this dquot within its buffer
347 * (which is currently 1 FSB and probably won't change).
348 * Hence 32 bits for this offset should be just fine.
349 * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t))
350 * here, and recompute it at recovery time.
351 */
352 lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset;
353 }
354
355 /*------------------ QUOTAOFF LOG ITEMS -------------------*/
356
357 /*
358 * This returns the number of iovecs needed to log the given quotaoff item.
359 * We only need 1 iovec for an quotaoff item. It just logs the
360 * quotaoff_log_format structure.
361 */
362 /*ARGSUSED*/
363 STATIC uint
364 xfs_qm_qoff_logitem_size(xfs_qoff_logitem_t *qf)
365 {
366 return (1);
367 }
368
369 /*
370 * This is called to fill in the vector of log iovecs for the
371 * given quotaoff log item. We use only 1 iovec, and we point that
372 * at the quotaoff_log_format structure embedded in the quotaoff item.
373 * It is at this point that we assert that all of the extent
374 * slots in the quotaoff item have been filled.
375 */
376 STATIC void
377 xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t *qf,
378 xfs_log_iovec_t *log_vector)
379 {
380 ASSERT(qf->qql_format.qf_type == XFS_LI_QUOTAOFF);
381
382 log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format);
383 log_vector->i_len = sizeof(xfs_qoff_logitem_t);
384 log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF;
385 qf->qql_format.qf_size = 1;
386 }
387
388
389 /*
390 * Pinning has no meaning for an quotaoff item, so just return.
391 */
392 /*ARGSUSED*/
393 STATIC void
394 xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t *qf)
395 {
396 return;
397 }
398
399
400 /*
401 * Since pinning has no meaning for an quotaoff item, unpinning does
402 * not either.
403 */
404 /*ARGSUSED*/
405 STATIC void
406 xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int remove)
407 {
408 return;
409 }
410
411 /*
412 * Quotaoff items have no locking, so just return success.
413 */
414 /*ARGSUSED*/
415 STATIC uint
416 xfs_qm_qoff_logitem_trylock(xfs_qoff_logitem_t *qf)
417 {
418 return XFS_ITEM_LOCKED;
419 }
420
421 /*
422 * Quotaoff items have no locking or pushing, so return failure
423 * so that the caller doesn't bother with us.
424 */
425 /*ARGSUSED*/
426 STATIC void
427 xfs_qm_qoff_logitem_unlock(xfs_qoff_logitem_t *qf)
428 {
429 return;
430 }
431
432 /*
433 * The quotaoff-start-item is logged only once and cannot be moved in the log,
434 * so simply return the lsn at which it's been logged.
435 */
436 /*ARGSUSED*/
437 STATIC xfs_lsn_t
438 xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn)
439 {
440 return (lsn);
441 }
442
443 /*
444 * There isn't much you can do to push on an quotaoff item. It is simply
445 * stuck waiting for the log to be flushed to disk.
446 */
447 /*ARGSUSED*/
448 STATIC void
449 xfs_qm_qoff_logitem_push(xfs_qoff_logitem_t *qf)
450 {
451 return;
452 }
453
454
455 /*ARGSUSED*/
456 STATIC xfs_lsn_t
457 xfs_qm_qoffend_logitem_committed(
458 xfs_qoff_logitem_t *qfe,
459 xfs_lsn_t lsn)
460 {
461 xfs_qoff_logitem_t *qfs;
462 struct xfs_ail *ailp;
463
464 qfs = qfe->qql_start_lip;
465 ailp = qfs->qql_item.li_ailp;
466 spin_lock(&ailp->xa_lock);
467 /*
468 * Delete the qoff-start logitem from the AIL.
469 * xfs_trans_ail_delete() drops the AIL lock.
470 */
471 xfs_trans_ail_delete(ailp, (xfs_log_item_t *)qfs);
472 kmem_free(qfs);
473 kmem_free(qfe);
474 return (xfs_lsn_t)-1;
475 }
476
477 /*
478 * XXX rcc - don't know quite what to do with this. I think we can
479 * just ignore it. The only time that isn't the case is if we allow
480 * the client to somehow see that quotas have been turned off in which
481 * we can't allow that to get back until the quotaoff hits the disk.
482 * So how would that happen? Also, do we need different routines for
483 * quotaoff start and quotaoff end? I suspect the answer is yes but
484 * to be sure, I need to look at the recovery code and see how quota off
485 * recovery is handled (do we roll forward or back or do something else).
486 * If we roll forwards or backwards, then we need two separate routines,
487 * one that does nothing and one that stamps in the lsn that matters
488 * (truly makes the quotaoff irrevocable). If we do something else,
489 * then maybe we don't need two.
490 */
491 /* ARGSUSED */
492 STATIC void
493 xfs_qm_qoff_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
494 {
495 return;
496 }
497
498 /* ARGSUSED */
499 STATIC void
500 xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
501 {
502 return;
503 }
504
505 static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
506 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
507 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
508 xfs_qm_qoff_logitem_format,
509 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
510 .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_qm_qoff_logitem_unpin,
511 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
512 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
513 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
514 xfs_qm_qoffend_logitem_committed,
515 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
516 .iop_pushbuf = NULL,
517 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
518 xfs_qm_qoffend_logitem_committing
519 };
520
521 /*
522 * This is the ops vector shared by all quotaoff-start log items.
523 */
524 static struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
525 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
526 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
527 xfs_qm_qoff_logitem_format,
528 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
529 .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_qm_qoff_logitem_unpin,
530 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
531 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
532 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
533 xfs_qm_qoff_logitem_committed,
534 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
535 .iop_pushbuf = NULL,
536 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
537 xfs_qm_qoff_logitem_committing
538 };
539
540 /*
541 * Allocate and initialize an quotaoff item of the correct quota type(s).
542 */
543 xfs_qoff_logitem_t *
544 xfs_qm_qoff_logitem_init(
545 struct xfs_mount *mp,
546 xfs_qoff_logitem_t *start,
547 uint flags)
548 {
549 xfs_qoff_logitem_t *qf;
550
551 qf = (xfs_qoff_logitem_t*) kmem_zalloc(sizeof(xfs_qoff_logitem_t), KM_SLEEP);
552
553 xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ?
554 &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops);
555 qf->qql_item.li_mountp = mp;
556 qf->qql_format.qf_type = XFS_LI_QUOTAOFF;
557 qf->qql_format.qf_flags = flags;
558 qf->qql_start_lip = start;
559 return (qf);
560 }
This page took 0.042369 seconds and 5 git commands to generate.