1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_log.h"
21#include "xfs_trans.h"
22#include "xfs_sb.h"
23#include "xfs_ag.h"
24#include "xfs_alloc.h"
25#include "xfs_quota.h"
26#include "xfs_mount.h"
27#include "xfs_bmap_btree.h"
28#include "xfs_inode.h"
29#include "xfs_bmap.h"
30#include "xfs_rtalloc.h"
31#include "xfs_error.h"
32#include "xfs_itable.h"
33#include "xfs_attr.h"
34#include "xfs_buf_item.h"
35#include "xfs_trans_priv.h"
36#include "xfs_qm.h"
37
38static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip)
39{
40 return container_of(lip, struct xfs_dq_logitem, qli_item);
41}
42
43
44
45
46STATIC uint
47xfs_qm_dquot_logitem_size(
48 struct xfs_log_item *lip)
49{
50
51
52
53 return 2;
54}
55
56
57
58
59STATIC void
60xfs_qm_dquot_logitem_format(
61 struct xfs_log_item *lip,
62 struct xfs_log_iovec *logvec)
63{
64 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
65
66 logvec->i_addr = &qlip->qli_format;
67 logvec->i_len = sizeof(xfs_dq_logformat_t);
68 logvec->i_type = XLOG_REG_TYPE_QFORMAT;
69 logvec++;
70 logvec->i_addr = &qlip->qli_dquot->q_core;
71 logvec->i_len = sizeof(xfs_disk_dquot_t);
72 logvec->i_type = XLOG_REG_TYPE_DQUOT;
73
74 qlip->qli_format.qlf_size = 2;
75
76}
77
78
79
80
81STATIC void
82xfs_qm_dquot_logitem_pin(
83 struct xfs_log_item *lip)
84{
85 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
86
87 ASSERT(XFS_DQ_IS_LOCKED(dqp));
88 atomic_inc(&dqp->q_pincount);
89}
90
91
92
93
94
95
96
97STATIC void
98xfs_qm_dquot_logitem_unpin(
99 struct xfs_log_item *lip,
100 int remove)
101{
102 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
103
104 ASSERT(atomic_read(&dqp->q_pincount) > 0);
105 if (atomic_dec_and_test(&dqp->q_pincount))
106 wake_up(&dqp->q_pinwait);
107}
108
109STATIC xfs_lsn_t
110xfs_qm_dquot_logitem_committed(
111 struct xfs_log_item *lip,
112 xfs_lsn_t lsn)
113{
114
115
116
117
118 return lsn;
119}
120
121
122
123
124
125void
126xfs_qm_dqunpin_wait(
127 struct xfs_dquot *dqp)
128{
129 ASSERT(XFS_DQ_IS_LOCKED(dqp));
130 if (atomic_read(&dqp->q_pincount) == 0)
131 return;
132
133
134
135
136 xfs_log_force(dqp->q_mount, 0);
137 wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
138}
139
140STATIC uint
141xfs_qm_dquot_logitem_push(
142 struct xfs_log_item *lip,
143 struct list_head *buffer_list)
144{
145 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
146 struct xfs_buf *bp = NULL;
147 uint rval = XFS_ITEM_SUCCESS;
148 int error;
149
150 if (atomic_read(&dqp->q_pincount) > 0)
151 return XFS_ITEM_PINNED;
152
153 if (!xfs_dqlock_nowait(dqp))
154 return XFS_ITEM_LOCKED;
155
156
157
158
159
160 if (atomic_read(&dqp->q_pincount) > 0) {
161 rval = XFS_ITEM_PINNED;
162 goto out_unlock;
163 }
164
165
166
167
168
169
170 if (!xfs_dqflock_nowait(dqp)) {
171 rval = XFS_ITEM_FLUSHING;
172 goto out_unlock;
173 }
174
175 spin_unlock(&lip->li_ailp->xa_lock);
176
177 error = xfs_qm_dqflush(dqp, &bp);
178 if (error) {
179 xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p",
180 __func__, error, dqp);
181 } else {
182 if (!xfs_buf_delwri_queue(bp, buffer_list))
183 rval = XFS_ITEM_FLUSHING;
184 xfs_buf_relse(bp);
185 }
186
187 spin_lock(&lip->li_ailp->xa_lock);
188out_unlock:
189 xfs_dqunlock(dqp);
190 return rval;
191}
192
193
194
195
196
197
198
199STATIC void
200xfs_qm_dquot_logitem_unlock(
201 struct xfs_log_item *lip)
202{
203 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
204
205 ASSERT(XFS_DQ_IS_LOCKED(dqp));
206
207
208
209
210 dqp->q_transp = NULL;
211
212
213
214
215
216
217
218 xfs_dqunlock(dqp);
219}
220
221
222
223
224
225
226STATIC void
227xfs_qm_dquot_logitem_committing(
228 struct xfs_log_item *lip,
229 xfs_lsn_t lsn)
230{
231}
232
233
234
235
236static const struct xfs_item_ops xfs_dquot_item_ops = {
237 .iop_size = xfs_qm_dquot_logitem_size,
238 .iop_format = xfs_qm_dquot_logitem_format,
239 .iop_pin = xfs_qm_dquot_logitem_pin,
240 .iop_unpin = xfs_qm_dquot_logitem_unpin,
241 .iop_unlock = xfs_qm_dquot_logitem_unlock,
242 .iop_committed = xfs_qm_dquot_logitem_committed,
243 .iop_push = xfs_qm_dquot_logitem_push,
244 .iop_committing = xfs_qm_dquot_logitem_committing
245};
246
247
248
249
250
251
252void
253xfs_qm_dquot_logitem_init(
254 struct xfs_dquot *dqp)
255{
256 struct xfs_dq_logitem *lp = &dqp->q_logitem;
257
258 xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT,
259 &xfs_dquot_item_ops);
260 lp->qli_dquot = dqp;
261 lp->qli_format.qlf_type = XFS_LI_DQUOT;
262 lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id);
263 lp->qli_format.qlf_blkno = dqp->q_blkno;
264 lp->qli_format.qlf_len = 1;
265
266
267
268
269
270
271
272 lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset;
273}
274
275
276
277static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip)
278{
279 return container_of(lip, struct xfs_qoff_logitem, qql_item);
280}
281
282
283
284
285
286
287
288STATIC uint
289xfs_qm_qoff_logitem_size(
290 struct xfs_log_item *lip)
291{
292 return 1;
293}
294
295
296
297
298
299
300
301
302STATIC void
303xfs_qm_qoff_logitem_format(
304 struct xfs_log_item *lip,
305 struct xfs_log_iovec *log_vector)
306{
307 struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip);
308
309 ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF);
310
311 log_vector->i_addr = &qflip->qql_format;
312 log_vector->i_len = sizeof(xfs_qoff_logitem_t);
313 log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF;
314 qflip->qql_format.qf_size = 1;
315}
316
317
318
319
320STATIC void
321xfs_qm_qoff_logitem_pin(
322 struct xfs_log_item *lip)
323{
324}
325
326
327
328
329
330STATIC void
331xfs_qm_qoff_logitem_unpin(
332 struct xfs_log_item *lip,
333 int remove)
334{
335}
336
337
338
339
340
341STATIC uint
342xfs_qm_qoff_logitem_push(
343 struct xfs_log_item *lip,
344 struct list_head *buffer_list)
345{
346 return XFS_ITEM_LOCKED;
347}
348
349
350
351
352
353STATIC void
354xfs_qm_qoff_logitem_unlock(
355 struct xfs_log_item *lip)
356{
357}
358
359
360
361
362
363STATIC xfs_lsn_t
364xfs_qm_qoff_logitem_committed(
365 struct xfs_log_item *lip,
366 xfs_lsn_t lsn)
367{
368 return lsn;
369}
370
371STATIC xfs_lsn_t
372xfs_qm_qoffend_logitem_committed(
373 struct xfs_log_item *lip,
374 xfs_lsn_t lsn)
375{
376 struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip);
377 struct xfs_qoff_logitem *qfs = qfe->qql_start_lip;
378 struct xfs_ail *ailp = qfs->qql_item.li_ailp;
379
380
381
382
383
384 spin_lock(&ailp->xa_lock);
385 xfs_trans_ail_delete(ailp, &qfs->qql_item, SHUTDOWN_LOG_IO_ERROR);
386
387 kmem_free(qfs);
388 kmem_free(qfe);
389 return (xfs_lsn_t)-1;
390}
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406STATIC void
407xfs_qm_qoff_logitem_committing(
408 struct xfs_log_item *lip,
409 xfs_lsn_t commit_lsn)
410{
411}
412
413static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
414 .iop_size = xfs_qm_qoff_logitem_size,
415 .iop_format = xfs_qm_qoff_logitem_format,
416 .iop_pin = xfs_qm_qoff_logitem_pin,
417 .iop_unpin = xfs_qm_qoff_logitem_unpin,
418 .iop_unlock = xfs_qm_qoff_logitem_unlock,
419 .iop_committed = xfs_qm_qoffend_logitem_committed,
420 .iop_push = xfs_qm_qoff_logitem_push,
421 .iop_committing = xfs_qm_qoff_logitem_committing
422};
423
424
425
426
427static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
428 .iop_size = xfs_qm_qoff_logitem_size,
429 .iop_format = xfs_qm_qoff_logitem_format,
430 .iop_pin = xfs_qm_qoff_logitem_pin,
431 .iop_unpin = xfs_qm_qoff_logitem_unpin,
432 .iop_unlock = xfs_qm_qoff_logitem_unlock,
433 .iop_committed = xfs_qm_qoff_logitem_committed,
434 .iop_push = xfs_qm_qoff_logitem_push,
435 .iop_committing = xfs_qm_qoff_logitem_committing
436};
437
438
439
440
441struct xfs_qoff_logitem *
442xfs_qm_qoff_logitem_init(
443 struct xfs_mount *mp,
444 struct xfs_qoff_logitem *start,
445 uint flags)
446{
447 struct xfs_qoff_logitem *qf;
448
449 qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), KM_SLEEP);
450
451 xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ?
452 &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops);
453 qf->qql_item.li_mountp = mp;
454 qf->qql_format.qf_type = XFS_LI_QUOTAOFF;
455 qf->qql_format.qf_flags = flags;
456 qf->qql_start_lip = start;
457 return qf;
458}
459