.. | .. |
---|
16 | 16 | #include "xfs_trans.h" |
---|
17 | 17 | #include "xfs_qm.h" |
---|
18 | 18 | #include "xfs_error.h" |
---|
19 | | -#include "xfs_cksum.h" |
---|
20 | | -#include "xfs_trace.h" |
---|
21 | 19 | |
---|
22 | 20 | int |
---|
23 | 21 | xfs_calc_dquots_per_chunk( |
---|
.. | .. |
---|
37 | 35 | |
---|
38 | 36 | xfs_failaddr_t |
---|
39 | 37 | xfs_dquot_verify( |
---|
40 | | - struct xfs_mount *mp, |
---|
41 | | - xfs_disk_dquot_t *ddq, |
---|
42 | | - xfs_dqid_t id, |
---|
43 | | - uint type) /* used only during quotacheck */ |
---|
| 38 | + struct xfs_mount *mp, |
---|
| 39 | + struct xfs_disk_dquot *ddq, |
---|
| 40 | + xfs_dqid_t id) /* used only during quotacheck */ |
---|
44 | 41 | { |
---|
| 42 | + __u8 ddq_type; |
---|
| 43 | + |
---|
45 | 44 | /* |
---|
46 | 45 | * We can encounter an uninitialized dquot buffer for 2 reasons: |
---|
47 | 46 | * 1. If we crash while deleting the quotainode(s), and those blks got |
---|
.. | .. |
---|
62 | 61 | if (ddq->d_version != XFS_DQUOT_VERSION) |
---|
63 | 62 | return __this_address; |
---|
64 | 63 | |
---|
65 | | - if (type && ddq->d_flags != type) |
---|
| 64 | + if (ddq->d_type & ~XFS_DQTYPE_ANY) |
---|
66 | 65 | return __this_address; |
---|
67 | | - if (ddq->d_flags != XFS_DQ_USER && |
---|
68 | | - ddq->d_flags != XFS_DQ_PROJ && |
---|
69 | | - ddq->d_flags != XFS_DQ_GROUP) |
---|
| 66 | + ddq_type = ddq->d_type & XFS_DQTYPE_REC_MASK; |
---|
| 67 | + if (ddq_type != XFS_DQTYPE_USER && |
---|
| 68 | + ddq_type != XFS_DQTYPE_PROJ && |
---|
| 69 | + ddq_type != XFS_DQTYPE_GROUP) |
---|
| 70 | + return __this_address; |
---|
| 71 | + |
---|
| 72 | + if ((ddq->d_type & XFS_DQTYPE_BIGTIME) && |
---|
| 73 | + !xfs_sb_version_hasbigtime(&mp->m_sb)) |
---|
| 74 | + return __this_address; |
---|
| 75 | + |
---|
| 76 | + if ((ddq->d_type & XFS_DQTYPE_BIGTIME) && !ddq->d_id) |
---|
70 | 77 | return __this_address; |
---|
71 | 78 | |
---|
72 | 79 | if (id != -1 && id != be32_to_cpu(ddq->d_id)) |
---|
.. | .. |
---|
97 | 104 | xfs_dqblk_verify( |
---|
98 | 105 | struct xfs_mount *mp, |
---|
99 | 106 | struct xfs_dqblk *dqb, |
---|
100 | | - xfs_dqid_t id, |
---|
101 | | - uint type) /* used only during quotacheck */ |
---|
| 107 | + xfs_dqid_t id) /* used only during quotacheck */ |
---|
102 | 108 | { |
---|
103 | 109 | if (xfs_sb_version_hascrc(&mp->m_sb) && |
---|
104 | 110 | !uuid_equal(&dqb->dd_uuid, &mp->m_sb.sb_meta_uuid)) |
---|
105 | 111 | return __this_address; |
---|
106 | 112 | |
---|
107 | | - return xfs_dquot_verify(mp, &dqb->dd_diskdq, id, type); |
---|
| 113 | + return xfs_dquot_verify(mp, &dqb->dd_diskdq, id); |
---|
108 | 114 | } |
---|
109 | 115 | |
---|
110 | 116 | /* |
---|
111 | 117 | * Do some primitive error checking on ondisk dquot data structures. |
---|
112 | 118 | */ |
---|
113 | | -int |
---|
| 119 | +void |
---|
114 | 120 | xfs_dqblk_repair( |
---|
115 | 121 | struct xfs_mount *mp, |
---|
116 | 122 | struct xfs_dqblk *dqb, |
---|
117 | 123 | xfs_dqid_t id, |
---|
118 | | - uint type) |
---|
| 124 | + xfs_dqtype_t type) |
---|
119 | 125 | { |
---|
120 | 126 | /* |
---|
121 | 127 | * Typically, a repair is only requested by quotacheck. |
---|
.. | .. |
---|
125 | 131 | |
---|
126 | 132 | dqb->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); |
---|
127 | 133 | dqb->dd_diskdq.d_version = XFS_DQUOT_VERSION; |
---|
128 | | - dqb->dd_diskdq.d_flags = type; |
---|
| 134 | + dqb->dd_diskdq.d_type = type; |
---|
129 | 135 | dqb->dd_diskdq.d_id = cpu_to_be32(id); |
---|
130 | 136 | |
---|
131 | 137 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
---|
.. | .. |
---|
133 | 139 | xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk), |
---|
134 | 140 | XFS_DQUOT_CRC_OFF); |
---|
135 | 141 | } |
---|
136 | | - |
---|
137 | | - return 0; |
---|
138 | 142 | } |
---|
139 | 143 | |
---|
140 | 144 | STATIC bool |
---|
.. | .. |
---|
209 | 213 | if (i == 0) |
---|
210 | 214 | id = be32_to_cpu(ddq->d_id); |
---|
211 | 215 | |
---|
212 | | - fa = xfs_dqblk_verify(mp, &dqb[i], id + i, 0); |
---|
| 216 | + fa = xfs_dqblk_verify(mp, &dqb[i], id + i); |
---|
213 | 217 | if (fa) { |
---|
214 | 218 | if (!readahead) |
---|
215 | 219 | xfs_buf_verifier_error(bp, -EFSCORRUPTED, |
---|
.. | .. |
---|
226 | 230 | xfs_dquot_buf_verify_struct( |
---|
227 | 231 | struct xfs_buf *bp) |
---|
228 | 232 | { |
---|
229 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 233 | + struct xfs_mount *mp = bp->b_mount; |
---|
230 | 234 | |
---|
231 | 235 | return xfs_dquot_buf_verify(mp, bp, false); |
---|
232 | 236 | } |
---|
.. | .. |
---|
235 | 239 | xfs_dquot_buf_read_verify( |
---|
236 | 240 | struct xfs_buf *bp) |
---|
237 | 241 | { |
---|
238 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 242 | + struct xfs_mount *mp = bp->b_mount; |
---|
239 | 243 | |
---|
240 | 244 | if (!xfs_dquot_buf_verify_crc(mp, bp, false)) |
---|
241 | 245 | return; |
---|
.. | .. |
---|
252 | 256 | xfs_dquot_buf_readahead_verify( |
---|
253 | 257 | struct xfs_buf *bp) |
---|
254 | 258 | { |
---|
255 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 259 | + struct xfs_mount *mp = bp->b_mount; |
---|
256 | 260 | |
---|
257 | 261 | if (!xfs_dquot_buf_verify_crc(mp, bp, true) || |
---|
258 | 262 | xfs_dquot_buf_verify(mp, bp, true) != NULL) { |
---|
.. | .. |
---|
270 | 274 | xfs_dquot_buf_write_verify( |
---|
271 | 275 | struct xfs_buf *bp) |
---|
272 | 276 | { |
---|
273 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 277 | + struct xfs_mount *mp = bp->b_mount; |
---|
274 | 278 | |
---|
275 | 279 | xfs_dquot_buf_verify(mp, bp, false); |
---|
276 | 280 | } |
---|
277 | 281 | |
---|
278 | 282 | const struct xfs_buf_ops xfs_dquot_buf_ops = { |
---|
279 | 283 | .name = "xfs_dquot", |
---|
| 284 | + .magic16 = { cpu_to_be16(XFS_DQUOT_MAGIC), |
---|
| 285 | + cpu_to_be16(XFS_DQUOT_MAGIC) }, |
---|
280 | 286 | .verify_read = xfs_dquot_buf_read_verify, |
---|
281 | 287 | .verify_write = xfs_dquot_buf_write_verify, |
---|
282 | 288 | .verify_struct = xfs_dquot_buf_verify_struct, |
---|
.. | .. |
---|
284 | 290 | |
---|
285 | 291 | const struct xfs_buf_ops xfs_dquot_buf_ra_ops = { |
---|
286 | 292 | .name = "xfs_dquot_ra", |
---|
| 293 | + .magic16 = { cpu_to_be16(XFS_DQUOT_MAGIC), |
---|
| 294 | + cpu_to_be16(XFS_DQUOT_MAGIC) }, |
---|
287 | 295 | .verify_read = xfs_dquot_buf_readahead_verify, |
---|
288 | 296 | .verify_write = xfs_dquot_buf_write_verify, |
---|
289 | 297 | }; |
---|
| 298 | + |
---|
| 299 | +/* Convert an on-disk timer value into an incore timer value. */ |
---|
| 300 | +time64_t |
---|
| 301 | +xfs_dquot_from_disk_ts( |
---|
| 302 | + struct xfs_disk_dquot *ddq, |
---|
| 303 | + __be32 dtimer) |
---|
| 304 | +{ |
---|
| 305 | + uint32_t t = be32_to_cpu(dtimer); |
---|
| 306 | + |
---|
| 307 | + if (t != 0 && (ddq->d_type & XFS_DQTYPE_BIGTIME)) |
---|
| 308 | + return xfs_dq_bigtime_to_unix(t); |
---|
| 309 | + |
---|
| 310 | + return t; |
---|
| 311 | +} |
---|
| 312 | + |
---|
| 313 | +/* Convert an incore timer value into an on-disk timer value. */ |
---|
| 314 | +__be32 |
---|
| 315 | +xfs_dquot_to_disk_ts( |
---|
| 316 | + struct xfs_dquot *dqp, |
---|
| 317 | + time64_t timer) |
---|
| 318 | +{ |
---|
| 319 | + uint32_t t = timer; |
---|
| 320 | + |
---|
| 321 | + if (timer != 0 && (dqp->q_type & XFS_DQTYPE_BIGTIME)) |
---|
| 322 | + t = xfs_dq_unix_to_bigtime(timer); |
---|
| 323 | + |
---|
| 324 | + return cpu_to_be32(t); |
---|
| 325 | +} |
---|