This source file includes following definitions.
- DQUOT_ITEM
- xfs_qm_dquot_logitem_size
- xfs_qm_dquot_logitem_format
- xfs_qm_dquot_logitem_pin
- xfs_qm_dquot_logitem_unpin
- xfs_qm_dqunpin_wait
- xfs_dquot_item_error
- xfs_qm_dquot_logitem_push
- xfs_qm_dquot_logitem_release
- xfs_qm_dquot_logitem_committing
- xfs_qm_dquot_logitem_init
- QOFF_ITEM
- xfs_qm_qoff_logitem_size
- xfs_qm_qoff_logitem_format
- xfs_qm_qoff_logitem_push
- xfs_qm_qoffend_logitem_committed
- xfs_qm_qoff_logitem_init
1
2
3
4
5
6 #include "xfs.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_mount.h"
13 #include "xfs_inode.h"
14 #include "xfs_quota.h"
15 #include "xfs_trans.h"
16 #include "xfs_buf_item.h"
17 #include "xfs_trans_priv.h"
18 #include "xfs_qm.h"
19 #include "xfs_log.h"
20
21 static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip)
22 {
23 return container_of(lip, struct xfs_dq_logitem, qli_item);
24 }
25
26
27
28
29 STATIC void
30 xfs_qm_dquot_logitem_size(
31 struct xfs_log_item *lip,
32 int *nvecs,
33 int *nbytes)
34 {
35 *nvecs += 2;
36 *nbytes += sizeof(struct xfs_dq_logformat) +
37 sizeof(struct xfs_disk_dquot);
38 }
39
40
41
42
43 STATIC void
44 xfs_qm_dquot_logitem_format(
45 struct xfs_log_item *lip,
46 struct xfs_log_vec *lv)
47 {
48 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
49 struct xfs_log_iovec *vecp = NULL;
50 struct xfs_dq_logformat *qlf;
51
52 qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT);
53 qlf->qlf_type = XFS_LI_DQUOT;
54 qlf->qlf_size = 2;
55 qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id);
56 qlf->qlf_blkno = qlip->qli_dquot->q_blkno;
57 qlf->qlf_len = 1;
58 qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
59 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat));
60
61 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT,
62 &qlip->qli_dquot->q_core,
63 sizeof(struct xfs_disk_dquot));
64 }
65
66
67
68
69 STATIC void
70 xfs_qm_dquot_logitem_pin(
71 struct xfs_log_item *lip)
72 {
73 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
74
75 ASSERT(XFS_DQ_IS_LOCKED(dqp));
76 atomic_inc(&dqp->q_pincount);
77 }
78
79
80
81
82
83
84
85 STATIC void
86 xfs_qm_dquot_logitem_unpin(
87 struct xfs_log_item *lip,
88 int remove)
89 {
90 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
91
92 ASSERT(atomic_read(&dqp->q_pincount) > 0);
93 if (atomic_dec_and_test(&dqp->q_pincount))
94 wake_up(&dqp->q_pinwait);
95 }
96
97
98
99
100
101 void
102 xfs_qm_dqunpin_wait(
103 struct xfs_dquot *dqp)
104 {
105 ASSERT(XFS_DQ_IS_LOCKED(dqp));
106 if (atomic_read(&dqp->q_pincount) == 0)
107 return;
108
109
110
111
112 xfs_log_force(dqp->q_mount, 0);
113 wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
114 }
115
116
117
118
119
120
121
122
123
124 STATIC void
125 xfs_dquot_item_error(
126 struct xfs_log_item *lip,
127 struct xfs_buf *bp)
128 {
129 ASSERT(!completion_done(&DQUOT_ITEM(lip)->qli_dquot->q_flush));
130 xfs_set_li_failed(lip, bp);
131 }
132
133 STATIC uint
134 xfs_qm_dquot_logitem_push(
135 struct xfs_log_item *lip,
136 struct list_head *buffer_list)
137 __releases(&lip->li_ailp->ail_lock)
138 __acquires(&lip->li_ailp->ail_lock)
139 {
140 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
141 struct xfs_buf *bp = lip->li_buf;
142 uint rval = XFS_ITEM_SUCCESS;
143 int error;
144
145 if (atomic_read(&dqp->q_pincount) > 0)
146 return XFS_ITEM_PINNED;
147
148
149
150
151
152 if (test_bit(XFS_LI_FAILED, &lip->li_flags)) {
153 if (!xfs_buf_trylock(bp))
154 return XFS_ITEM_LOCKED;
155
156 if (!xfs_buf_resubmit_failed_buffers(bp, buffer_list))
157 rval = XFS_ITEM_FLUSHING;
158
159 xfs_buf_unlock(bp);
160 return rval;
161 }
162
163 if (!xfs_dqlock_nowait(dqp))
164 return XFS_ITEM_LOCKED;
165
166
167
168
169
170 if (atomic_read(&dqp->q_pincount) > 0) {
171 rval = XFS_ITEM_PINNED;
172 goto out_unlock;
173 }
174
175
176
177
178
179
180 if (!xfs_dqflock_nowait(dqp)) {
181 rval = XFS_ITEM_FLUSHING;
182 goto out_unlock;
183 }
184
185 spin_unlock(&lip->li_ailp->ail_lock);
186
187 error = xfs_qm_dqflush(dqp, &bp);
188 if (!error) {
189 if (!xfs_buf_delwri_queue(bp, buffer_list))
190 rval = XFS_ITEM_FLUSHING;
191 xfs_buf_relse(bp);
192 }
193
194 spin_lock(&lip->li_ailp->ail_lock);
195 out_unlock:
196 xfs_dqunlock(dqp);
197 return rval;
198 }
199
200 STATIC void
201 xfs_qm_dquot_logitem_release(
202 struct xfs_log_item *lip)
203 {
204 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
205
206 ASSERT(XFS_DQ_IS_LOCKED(dqp));
207
208
209
210
211
212
213
214 xfs_dqunlock(dqp);
215 }
216
217 STATIC void
218 xfs_qm_dquot_logitem_committing(
219 struct xfs_log_item *lip,
220 xfs_lsn_t commit_lsn)
221 {
222 return xfs_qm_dquot_logitem_release(lip);
223 }
224
225 static const struct xfs_item_ops xfs_dquot_item_ops = {
226 .iop_size = xfs_qm_dquot_logitem_size,
227 .iop_format = xfs_qm_dquot_logitem_format,
228 .iop_pin = xfs_qm_dquot_logitem_pin,
229 .iop_unpin = xfs_qm_dquot_logitem_unpin,
230 .iop_release = xfs_qm_dquot_logitem_release,
231 .iop_committing = xfs_qm_dquot_logitem_committing,
232 .iop_push = xfs_qm_dquot_logitem_push,
233 .iop_error = xfs_dquot_item_error
234 };
235
236
237
238
239
240
241 void
242 xfs_qm_dquot_logitem_init(
243 struct xfs_dquot *dqp)
244 {
245 struct xfs_dq_logitem *lp = &dqp->q_logitem;
246
247 xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT,
248 &xfs_dquot_item_ops);
249 lp->qli_dquot = dqp;
250 }
251
252
253
254 static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip)
255 {
256 return container_of(lip, struct xfs_qoff_logitem, qql_item);
257 }
258
259
260
261
262
263
264
265 STATIC void
266 xfs_qm_qoff_logitem_size(
267 struct xfs_log_item *lip,
268 int *nvecs,
269 int *nbytes)
270 {
271 *nvecs += 1;
272 *nbytes += sizeof(struct xfs_qoff_logitem);
273 }
274
275 STATIC void
276 xfs_qm_qoff_logitem_format(
277 struct xfs_log_item *lip,
278 struct xfs_log_vec *lv)
279 {
280 struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip);
281 struct xfs_log_iovec *vecp = NULL;
282 struct xfs_qoff_logformat *qlf;
283
284 qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF);
285 qlf->qf_type = XFS_LI_QUOTAOFF;
286 qlf->qf_size = 1;
287 qlf->qf_flags = qflip->qql_flags;
288 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_qoff_logitem));
289 }
290
291
292
293
294
295 STATIC uint
296 xfs_qm_qoff_logitem_push(
297 struct xfs_log_item *lip,
298 struct list_head *buffer_list)
299 {
300 return XFS_ITEM_LOCKED;
301 }
302
303 STATIC xfs_lsn_t
304 xfs_qm_qoffend_logitem_committed(
305 struct xfs_log_item *lip,
306 xfs_lsn_t lsn)
307 {
308 struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip);
309 struct xfs_qoff_logitem *qfs = qfe->qql_start_lip;
310 struct xfs_ail *ailp = qfs->qql_item.li_ailp;
311
312
313
314
315
316 spin_lock(&ailp->ail_lock);
317 xfs_trans_ail_delete(ailp, &qfs->qql_item, SHUTDOWN_LOG_IO_ERROR);
318
319 kmem_free(qfs->qql_item.li_lv_shadow);
320 kmem_free(lip->li_lv_shadow);
321 kmem_free(qfs);
322 kmem_free(qfe);
323 return (xfs_lsn_t)-1;
324 }
325
326 static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
327 .iop_size = xfs_qm_qoff_logitem_size,
328 .iop_format = xfs_qm_qoff_logitem_format,
329 .iop_committed = xfs_qm_qoffend_logitem_committed,
330 .iop_push = xfs_qm_qoff_logitem_push,
331 };
332
333 static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
334 .iop_size = xfs_qm_qoff_logitem_size,
335 .iop_format = xfs_qm_qoff_logitem_format,
336 .iop_push = xfs_qm_qoff_logitem_push,
337 };
338
339
340
341
342 struct xfs_qoff_logitem *
343 xfs_qm_qoff_logitem_init(
344 struct xfs_mount *mp,
345 struct xfs_qoff_logitem *start,
346 uint flags)
347 {
348 struct xfs_qoff_logitem *qf;
349
350 qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), 0);
351
352 xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ?
353 &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops);
354 qf->qql_item.li_mountp = mp;
355 qf->qql_start_lip = start;
356 qf->qql_flags = flags;
357 return qf;
358 }