Blame view

fs/xfs/xfs_dquot_item.c 14.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
4ce3121f6   Nathan Scott   [XFS] Update lice...
2
3
   * Copyright (c) 2000-2003 Silicon Graphics, Inc.
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   *
4ce3121f6   Nathan Scott   [XFS] Update lice...
5
6
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
   * published by the Free Software Foundation.
   *
4ce3121f6   Nathan Scott   [XFS] Update lice...
9
10
11
12
   * This program is distributed in the hope that it would be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
   *
4ce3121f6   Nathan Scott   [XFS] Update lice...
14
15
16
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write the Free Software Foundation,
   * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
  #include "xfs.h"
  #include "xfs_fs.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
20
  #include "xfs_bit.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #include "xfs_log.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
22
  #include "xfs_inum.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
  #include "xfs_trans.h"
  #include "xfs_sb.h"
  #include "xfs_ag.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  #include "xfs_alloc.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
  #include "xfs_quota.h"
  #include "xfs_mount.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  #include "xfs_bmap_btree.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
  #include "xfs_inode.h"
  #include "xfs_bmap.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
  #include "xfs_rtalloc.h"
  #include "xfs_error.h"
  #include "xfs_itable.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
  #include "xfs_attr.h"
  #include "xfs_buf_item.h"
  #include "xfs_trans_priv.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
  #include "xfs_qm.h"
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
39
40
41
42
  static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip)
  {
  	return container_of(lip, struct xfs_dq_logitem, qli_item);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
  /*
   * returns the number of iovecs needed to log the given dquot item.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
  STATIC uint
  xfs_qm_dquot_logitem_size(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
48
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
  {
  	/*
  	 * we need only two iovecs, one for the format, one for the real thing
  	 */
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
53
  	return 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
59
60
  }
  
  /*
   * fills in the vector of log iovecs for the given dquot log item.
   */
  STATIC void
  xfs_qm_dquot_logitem_format(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
61
62
  	struct xfs_log_item	*lip,
  	struct xfs_log_iovec	*logvec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
64
  	struct xfs_dq_logitem	*qlip = DQUOT_ITEM(lip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65

4e0d5f926   Christoph Hellwig   xfs: fix the xfs_...
66
  	logvec->i_addr = &qlip->qli_format;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  	logvec->i_len  = sizeof(xfs_dq_logformat_t);
4139b3b33   Christoph Hellwig   xfs: kill XLOG_VE...
68
  	logvec->i_type = XLOG_REG_TYPE_QFORMAT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  	logvec++;
4e0d5f926   Christoph Hellwig   xfs: fix the xfs_...
70
  	logvec->i_addr = &qlip->qli_dquot->q_core;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  	logvec->i_len  = sizeof(xfs_disk_dquot_t);
4139b3b33   Christoph Hellwig   xfs: kill XLOG_VE...
72
  	logvec->i_type = XLOG_REG_TYPE_DQUOT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73

7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
74
  	qlip->qli_format.qlf_size = 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
78
79
  
  }
  
  /*
   * Increment the pin count of the given dquot.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
   */
  STATIC void
  xfs_qm_dquot_logitem_pin(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
83
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
85
  	struct xfs_dquot	*dqp = DQUOT_ITEM(lip)->qli_dquot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
  	ASSERT(XFS_DQ_IS_LOCKED(dqp));
d1de80215   Peter Leckie   [XFS] Fix build b...
88
  	atomic_inc(&dqp->q_pincount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
91
92
93
  }
  
  /*
   * Decrement the pin count of the given dquot, and wake up
   * anyone in xfs_dqwait_unpin() if the count goes to 0.	 The
bc3048e3c   Peter Leckie   [XFS] Clean up dq...
94
95
   * dquot must have been previously pinned with a call to
   * xfs_qm_dquot_logitem_pin().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
  STATIC void
  xfs_qm_dquot_logitem_unpin(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
99
  	struct xfs_log_item	*lip,
9412e3181   Christoph Hellwig   xfs: merge iop_un...
100
  	int			remove)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
102
  	struct xfs_dquot	*dqp = DQUOT_ITEM(lip)->qli_dquot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103

bc3048e3c   Peter Leckie   [XFS] Clean up dq...
104
105
106
  	ASSERT(atomic_read(&dqp->q_pincount) > 0);
  	if (atomic_dec_and_test(&dqp->q_pincount))
  		wake_up(&dqp->q_pinwait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
111
112
113
114
115
  /*
   * Given the logitem, this writes the corresponding dquot entry to disk
   * asynchronously. This is called with the dquot entry securely locked;
   * we simply get xfs_qm_dqflush() to do the work, and unlock the dquot
   * at the end.
   */
  STATIC void
  xfs_qm_dquot_logitem_push(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
116
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
118
119
  	struct xfs_dquot	*dqp = DQUOT_ITEM(lip)->qli_dquot;
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
  
  	ASSERT(XFS_DQ_IS_LOCKED(dqp));
e1f49cf20   David Chinner   [XFS] replace dqu...
122
  	ASSERT(!completion_done(&dqp->q_flush));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
125
126
127
128
129
130
131
132
  
  	/*
  	 * Since we were able to lock the dquot's flush lock and
  	 * we found it on the AIL, the dquot must be dirty.  This
  	 * is because the dquot is removed from the AIL while still
  	 * holding the flush lock in xfs_dqflush_done().  Thus, if
  	 * we found it in the AIL and were able to obtain the flush
  	 * lock without sleeping, then there must not have been
  	 * anyone in the process of flushing the dquot.
  	 */
fdedf28b9   Christoph Hellwig   xfs: untangle SYN...
133
  	error = xfs_qm_dqflush(dqp, SYNC_TRYLOCK);
3c56836f9   David Chinner   [XFS] Check for d...
134
  	if (error)
534877869   Dave Chinner   xfs: convert xfs_...
135
136
  		xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p",
  			__func__, error, dqp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
  	xfs_dqunlock(dqp);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
  STATIC xfs_lsn_t
  xfs_qm_dquot_logitem_committed(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
141
  	struct xfs_log_item	*lip,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
147
  	xfs_lsn_t		lsn)
  {
  	/*
  	 * We always re-log the entire dquot when it becomes dirty,
  	 * so, the latest copy _is_ the only one that matters.
  	 */
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
148
  	return lsn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
152
153
154
155
  /*
   * This is called to wait for the given dquot to be unpinned.
   * Most of these pin/unpin routines are plagiarized from inode code.
   */
  void
  xfs_qm_dqunpin_wait(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
156
  	struct xfs_dquot	*dqp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  	ASSERT(XFS_DQ_IS_LOCKED(dqp));
bc3048e3c   Peter Leckie   [XFS] Clean up dq...
159
  	if (atomic_read(&dqp->q_pincount) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
  
  	/*
  	 * Give the log a push so we don't wait here too long.
  	 */
a14a348bf   Christoph Hellwig   xfs: cleanup up x...
165
  	xfs_log_force(dqp->q_mount, 0);
bc3048e3c   Peter Leckie   [XFS] Clean up dq...
166
  	wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
169
170
171
172
173
174
175
  }
  
  /*
   * This is called when IOP_TRYLOCK returns XFS_ITEM_PUSHBUF to indicate that
   * the dquot is locked by us, but the flush lock isn't. So, here we are
   * going to see if the relevant dquot buffer is incore, waiting on DELWRI.
   * If so, we want to push it out to help us take this item off the AIL as soon
   * as possible.
   *
287f3dad1   Donald Douwsma   [XFS] Unwrap AIL_...
176
177
   * We must not be holding the AIL lock at this point. Calling incore() to
   * search the buffer cache can be a time consuming thing, and AIL lock is a
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
   * spinlock.
   */
17b38471c   Christoph Hellwig   xfs: force the lo...
180
  STATIC bool
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  xfs_qm_dquot_logitem_pushbuf(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
182
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
184
185
186
  	struct xfs_dq_logitem	*qlip = DQUOT_ITEM(lip);
  	struct xfs_dquot	*dqp = qlip->qli_dquot;
  	struct xfs_buf		*bp;
17b38471c   Christoph Hellwig   xfs: force the lo...
187
  	bool			ret = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
191
  	ASSERT(XFS_DQ_IS_LOCKED(dqp));
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
  	 * If flushlock isn't locked anymore, chances are that the
  	 * inode flush completed and the inode was taken off the AIL.
  	 * So, just get out.
  	 */
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
196
197
  	if (completion_done(&dqp->q_flush) ||
  	    !(lip->li_flags & XFS_LI_IN_AIL)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
  		xfs_dqunlock(dqp);
17b38471c   Christoph Hellwig   xfs: force the lo...
199
  		return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  	}
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
201
202
203
  
  	bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno,
  			dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
d808f617a   Dave Chinner   xfs: Don't issue ...
204
205
  	xfs_dqunlock(dqp);
  	if (!bp)
17b38471c   Christoph Hellwig   xfs: force the lo...
206
  		return true;
d808f617a   Dave Chinner   xfs: Don't issue ...
207
208
  	if (XFS_BUF_ISDELAYWRITE(bp))
  		xfs_buf_delwri_promote(bp);
17b38471c   Christoph Hellwig   xfs: force the lo...
209
210
  	if (xfs_buf_ispinned(bp))
  		ret = false;
d808f617a   Dave Chinner   xfs: Don't issue ...
211
  	xfs_buf_relse(bp);
17b38471c   Christoph Hellwig   xfs: force the lo...
212
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  }
  
  /*
   * This is called to attempt to lock the dquot associated with this
   * dquot log item.  Don't sleep on the dquot lock or the flush lock.
   * If the flush lock is already held, indicating that the dquot has
   * been or is in the process of being flushed, then see if we can
   * find the dquot's buffer in the buffer cache without sleeping.  If
   * we can and it is marked delayed write, then we want to send it out.
   * We delay doing so until the push routine, though, to avoid sleeping
   * in any device strategy routines.
   */
  STATIC uint
  xfs_qm_dquot_logitem_trylock(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
227
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
229
  	struct xfs_dquot	*dqp = DQUOT_ITEM(lip)->qli_dquot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230

bc3048e3c   Peter Leckie   [XFS] Clean up dq...
231
  	if (atomic_read(&dqp->q_pincount) > 0)
d808f617a   Dave Chinner   xfs: Don't issue ...
232
  		return XFS_ITEM_PINNED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233

800b484ec   Christoph Hellwig   xfs: cleanup dquo...
234
  	if (!xfs_dqlock_nowait(dqp))
d808f617a   Dave Chinner   xfs: Don't issue ...
235
  		return XFS_ITEM_LOCKED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236

e1f49cf20   David Chinner   [XFS] replace dqu...
237
  	if (!xfs_dqflock_nowait(dqp)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
  		/*
d808f617a   Dave Chinner   xfs: Don't issue ...
239
240
  		 * dquot has already been flushed to the backing buffer,
  		 * leave it locked, pushbuf routine will unlock it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
  		 */
d808f617a   Dave Chinner   xfs: Don't issue ...
242
  		return XFS_ITEM_PUSHBUF;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  	}
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
244
  	ASSERT(lip->li_flags & XFS_LI_IN_AIL);
d808f617a   Dave Chinner   xfs: Don't issue ...
245
  	return XFS_ITEM_SUCCESS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
249
250
251
252
253
254
  /*
   * Unlock the dquot associated with the log item.
   * Clear the fields of the dquot and dquot log item that
   * are specific to the current transaction.  If the
   * hold flags is set, do not unlock the dquot.
   */
  STATIC void
  xfs_qm_dquot_logitem_unlock(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
255
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
257
  	struct xfs_dquot	*dqp = DQUOT_ITEM(lip)->qli_dquot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
  	ASSERT(XFS_DQ_IS_LOCKED(dqp));
  
  	/*
  	 * Clear the transaction pointer in the dquot
  	 */
  	dqp->q_transp = NULL;
  
  	/*
  	 * dquots are never 'held' from getting unlocked at the end of
  	 * a transaction.  Their locking and unlocking is hidden inside the
  	 * transaction layer, within trans_commit. Hence, no LI_HOLD flag
  	 * for the logitem.
  	 */
  	xfs_dqunlock(dqp);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
   * this needs to stamp an lsn into the dquot, I think.
   * rpc's that look at user dquot's would then have to
   * push on the dependency recorded in the dquot
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
280
  STATIC void
  xfs_qm_dquot_logitem_committing(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
281
  	struct xfs_log_item	*lip,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
  	xfs_lsn_t		lsn)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
  /*
   * This is the ops vector for dquots
   */
272e42b21   Christoph Hellwig   xfs: constify xfs...
288
  static const struct xfs_item_ops xfs_dquot_item_ops = {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
289
290
291
292
293
294
295
296
297
298
  	.iop_size	= xfs_qm_dquot_logitem_size,
  	.iop_format	= xfs_qm_dquot_logitem_format,
  	.iop_pin	= xfs_qm_dquot_logitem_pin,
  	.iop_unpin	= xfs_qm_dquot_logitem_unpin,
  	.iop_trylock	= xfs_qm_dquot_logitem_trylock,
  	.iop_unlock	= xfs_qm_dquot_logitem_unlock,
  	.iop_committed	= xfs_qm_dquot_logitem_committed,
  	.iop_push	= xfs_qm_dquot_logitem_push,
  	.iop_pushbuf	= xfs_qm_dquot_logitem_pushbuf,
  	.iop_committing = xfs_qm_dquot_logitem_committing
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
301
302
303
304
305
306
307
  };
  
  /*
   * Initialize the dquot log item for a newly allocated dquot.
   * The dquot isn't locked at this point, but it isn't on any of the lists
   * either, so we don't care.
   */
  void
  xfs_qm_dquot_logitem_init(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
308
  	struct xfs_dquot	*dqp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
310
  	struct xfs_dq_logitem	*lp = &dqp->q_logitem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311

43f5efc5b   Dave Chinner   xfs: factor log i...
312
313
  	xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT,
  					&xfs_dquot_item_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
315
  	lp->qli_dquot = dqp;
  	lp->qli_format.qlf_type = XFS_LI_DQUOT;
1149d96ae   Christoph Hellwig   [XFS] endianess a...
316
  	lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
319
320
321
322
323
324
325
326
327
328
329
  	lp->qli_format.qlf_blkno = dqp->q_blkno;
  	lp->qli_format.qlf_len = 1;
  	/*
  	 * This is just the offset of this dquot within its buffer
  	 * (which is currently 1 FSB and probably won't change).
  	 * Hence 32 bits for this offset should be just fine.
  	 * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t))
  	 * here, and recompute it at recovery time.
  	 */
  	lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset;
  }
  
  /*------------------  QUOTAOFF LOG ITEMS  -------------------*/
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
330
331
332
333
  static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip)
  {
  	return container_of(lip, struct xfs_qoff_logitem, qql_item);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
335
336
337
338
  /*
   * This returns the number of iovecs needed to log the given quotaoff item.
   * We only need 1 iovec for an quotaoff item.  It just logs the
   * quotaoff_log_format structure.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  STATIC uint
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
340
341
  xfs_qm_qoff_logitem_size(
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
343
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
347
348
349
350
351
352
353
  }
  
  /*
   * This is called to fill in the vector of log iovecs for the
   * given quotaoff log item. We use only 1 iovec, and we point that
   * at the quotaoff_log_format structure embedded in the quotaoff item.
   * It is at this point that we assert that all of the extent
   * slots in the quotaoff item have been filled.
   */
  STATIC void
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
354
355
356
  xfs_qm_qoff_logitem_format(
  	struct xfs_log_item	*lip,
  	struct xfs_log_iovec	*log_vector)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
358
  	struct xfs_qoff_logitem	*qflip = QOFF_ITEM(lip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359

7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
360
  	ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF);
4e0d5f926   Christoph Hellwig   xfs: fix the xfs_...
361
  	log_vector->i_addr = &qflip->qql_format;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  	log_vector->i_len = sizeof(xfs_qoff_logitem_t);
4139b3b33   Christoph Hellwig   xfs: kill XLOG_VE...
363
  	log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF;
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
364
  	qflip->qql_format.qf_size = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
367
368
  /*
   * Pinning has no meaning for an quotaoff item, so just return.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
  STATIC void
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
370
371
  xfs_qm_qoff_logitem_pin(
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
375
376
377
  /*
   * Since pinning has no meaning for an quotaoff item, unpinning does
   * not either.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
  STATIC void
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
379
380
381
  xfs_qm_qoff_logitem_unpin(
  	struct xfs_log_item	*lip,
  	int			remove)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
385
386
387
  }
  
  /*
   * Quotaoff items have no locking, so just return success.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
  STATIC uint
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
389
390
  xfs_qm_qoff_logitem_trylock(
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
392
393
394
395
396
397
398
  {
  	return XFS_ITEM_LOCKED;
  }
  
  /*
   * Quotaoff items have no locking or pushing, so return failure
   * so that the caller doesn't bother with us.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
  STATIC void
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
400
401
  xfs_qm_qoff_logitem_unlock(
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
404
405
406
407
408
  }
  
  /*
   * The quotaoff-start-item is logged only once and cannot be moved in the log,
   * so simply return the lsn at which it's been logged.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  STATIC xfs_lsn_t
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
410
411
412
  xfs_qm_qoff_logitem_committed(
  	struct xfs_log_item	*lip,
  	xfs_lsn_t		lsn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
414
  	return lsn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
416
417
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
419
420
   * There isn't much you can do to push on an quotaoff item.  It is simply
   * stuck waiting for the log to be flushed to disk.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  STATIC void
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
422
423
  xfs_qm_qoff_logitem_push(
  	struct xfs_log_item	*lip)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
  STATIC xfs_lsn_t
  xfs_qm_qoffend_logitem_committed(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
428
429
  	struct xfs_log_item	*lip,
  	xfs_lsn_t		lsn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
431
432
433
  	struct xfs_qoff_logitem	*qfe = QOFF_ITEM(lip);
  	struct xfs_qoff_logitem	*qfs = qfe->qql_start_lip;
  	struct xfs_ail		*ailp = qfs->qql_item.li_ailp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
436
  	/*
  	 * Delete the qoff-start logitem from the AIL.
783a2f656   David Chinner   [XFS] Finish remo...
437
  	 * xfs_trans_ail_delete() drops the AIL lock.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
  	 */
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
439
  	spin_lock(&ailp->xa_lock);
783a2f656   David Chinner   [XFS] Finish remo...
440
  	xfs_trans_ail_delete(ailp, (xfs_log_item_t *)qfs);
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
441

f0e2d93c2   Denys Vlasenko   [XFS] Remove unus...
442
443
  	kmem_free(qfs);
  	kmem_free(qfe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
  	return (xfs_lsn_t)-1;
  }
  
  /*
   * XXX rcc - don't know quite what to do with this.  I think we can
   * just ignore it.  The only time that isn't the case is if we allow
   * the client to somehow see that quotas have been turned off in which
   * we can't allow that to get back until the quotaoff hits the disk.
   * So how would that happen?  Also, do we need different routines for
   * quotaoff start and quotaoff end?  I suspect the answer is yes but
   * to be sure, I need to look at the recovery code and see how quota off
   * recovery is handled (do we roll forward or back or do something else).
   * If we roll forwards or backwards, then we need two separate routines,
   * one that does nothing and one that stamps in the lsn that matters
   * (truly makes the quotaoff irrevocable).  If we do something else,
   * then maybe we don't need two.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
  STATIC void
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
462
463
464
  xfs_qm_qoff_logitem_committing(
  	struct xfs_log_item	*lip,
  	xfs_lsn_t		commit_lsn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
  }
272e42b21   Christoph Hellwig   xfs: constify xfs...
467
  static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
468
469
470
471
472
473
474
475
476
  	.iop_size	= xfs_qm_qoff_logitem_size,
  	.iop_format	= xfs_qm_qoff_logitem_format,
  	.iop_pin	= xfs_qm_qoff_logitem_pin,
  	.iop_unpin	= xfs_qm_qoff_logitem_unpin,
  	.iop_trylock	= xfs_qm_qoff_logitem_trylock,
  	.iop_unlock	= xfs_qm_qoff_logitem_unlock,
  	.iop_committed	= xfs_qm_qoffend_logitem_committed,
  	.iop_push	= xfs_qm_qoff_logitem_push,
  	.iop_committing = xfs_qm_qoff_logitem_committing
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
479
480
481
  };
  
  /*
   * This is the ops vector shared by all quotaoff-start log items.
   */
272e42b21   Christoph Hellwig   xfs: constify xfs...
482
  static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
483
484
485
486
487
488
489
490
491
  	.iop_size	= xfs_qm_qoff_logitem_size,
  	.iop_format	= xfs_qm_qoff_logitem_format,
  	.iop_pin	= xfs_qm_qoff_logitem_pin,
  	.iop_unpin	= xfs_qm_qoff_logitem_unpin,
  	.iop_trylock	= xfs_qm_qoff_logitem_trylock,
  	.iop_unlock	= xfs_qm_qoff_logitem_unlock,
  	.iop_committed	= xfs_qm_qoff_logitem_committed,
  	.iop_push	= xfs_qm_qoff_logitem_push,
  	.iop_committing = xfs_qm_qoff_logitem_committing
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
494
495
496
  };
  
  /*
   * Allocate and initialize an quotaoff item of the correct quota type(s).
   */
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
497
  struct xfs_qoff_logitem *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
  xfs_qm_qoff_logitem_init(
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
499
500
501
  	struct xfs_mount	*mp,
  	struct xfs_qoff_logitem	*start,
  	uint			flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
  {
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
503
  	struct xfs_qoff_logitem	*qf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504

7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
505
  	qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), KM_SLEEP);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506

43f5efc5b   Dave Chinner   xfs: factor log i...
507
508
  	xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ?
  			&xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
510
511
512
  	qf->qql_item.li_mountp = mp;
  	qf->qql_format.qf_type = XFS_LI_QUOTAOFF;
  	qf->qql_format.qf_flags = flags;
  	qf->qql_start_lip = start;
7bfa31d8e   Christoph Hellwig   xfs: give xfs_ite...
513
  	return qf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
  }