| .. | .. |
|---|
| 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 | +} |
|---|