0001
0002
0003
0004
0005
0006
0007 #include "xfs.h"
0008 #include "xfs_fs.h"
0009 #include "xfs_shared.h"
0010 #include "xfs_format.h"
0011 #include "xfs_log_format.h"
0012 #include "xfs_trans_resv.h"
0013 #include "xfs_bit.h"
0014 #include "xfs_mount.h"
0015 #include "xfs_da_format.h"
0016 #include "xfs_da_btree.h"
0017 #include "xfs_inode.h"
0018 #include "xfs_attr.h"
0019 #include "xfs_attr_remote.h"
0020 #include "xfs_trans.h"
0021 #include "xfs_bmap.h"
0022 #include "xfs_attr_leaf.h"
0023 #include "xfs_quota.h"
0024 #include "xfs_dir2.h"
0025 #include "xfs_error.h"
0026
0027
0028
0029
0030
0031
0032
0033 STATIC int
0034 xfs_attr3_rmt_stale(
0035 struct xfs_inode *dp,
0036 xfs_dablk_t blkno,
0037 int blkcnt)
0038 {
0039 struct xfs_bmbt_irec map;
0040 int nmap;
0041 int error;
0042
0043
0044
0045
0046
0047 while (blkcnt > 0) {
0048
0049
0050
0051 nmap = 1;
0052 error = xfs_bmapi_read(dp, (xfs_fileoff_t)blkno, blkcnt,
0053 &map, &nmap, XFS_BMAPI_ATTRFORK);
0054 if (error)
0055 return error;
0056 if (XFS_IS_CORRUPT(dp->i_mount, nmap != 1))
0057 return -EFSCORRUPTED;
0058
0059
0060
0061
0062
0063
0064 error = xfs_attr_rmtval_stale(dp, &map, 0);
0065 if (error)
0066 return error;
0067
0068 blkno += map.br_blockcount;
0069 blkcnt -= map.br_blockcount;
0070 }
0071
0072 return 0;
0073 }
0074
0075
0076
0077
0078
0079
0080
0081 STATIC int
0082 xfs_attr3_leaf_inactive(
0083 struct xfs_trans **trans,
0084 struct xfs_inode *dp,
0085 struct xfs_buf *bp)
0086 {
0087 struct xfs_attr3_icleaf_hdr ichdr;
0088 struct xfs_mount *mp = bp->b_mount;
0089 struct xfs_attr_leafblock *leaf = bp->b_addr;
0090 struct xfs_attr_leaf_entry *entry;
0091 struct xfs_attr_leaf_name_remote *name_rmt;
0092 int error = 0;
0093 int i;
0094
0095 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
0096
0097
0098
0099
0100
0101 entry = xfs_attr3_leaf_entryp(leaf);
0102 for (i = 0; i < ichdr.count; entry++, i++) {
0103 int blkcnt;
0104
0105 if (!entry->nameidx || (entry->flags & XFS_ATTR_LOCAL))
0106 continue;
0107
0108 name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
0109 if (!name_rmt->valueblk)
0110 continue;
0111
0112 blkcnt = xfs_attr3_rmt_blocks(dp->i_mount,
0113 be32_to_cpu(name_rmt->valuelen));
0114 error = xfs_attr3_rmt_stale(dp,
0115 be32_to_cpu(name_rmt->valueblk), blkcnt);
0116 if (error)
0117 goto err;
0118 }
0119
0120 xfs_trans_brelse(*trans, bp);
0121 err:
0122 return error;
0123 }
0124
0125
0126
0127
0128
0129 STATIC int
0130 xfs_attr3_node_inactive(
0131 struct xfs_trans **trans,
0132 struct xfs_inode *dp,
0133 struct xfs_buf *bp,
0134 int level)
0135 {
0136 struct xfs_mount *mp = dp->i_mount;
0137 struct xfs_da_blkinfo *info;
0138 xfs_dablk_t child_fsb;
0139 xfs_daddr_t parent_blkno, child_blkno;
0140 struct xfs_buf *child_bp;
0141 struct xfs_da3_icnode_hdr ichdr;
0142 int error, i;
0143
0144
0145
0146
0147 if (level > XFS_DA_NODE_MAXDEPTH) {
0148 xfs_buf_mark_corrupt(bp);
0149 xfs_trans_brelse(*trans, bp);
0150 return -EFSCORRUPTED;
0151 }
0152
0153 xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, bp->b_addr);
0154 parent_blkno = xfs_buf_daddr(bp);
0155 if (!ichdr.count) {
0156 xfs_trans_brelse(*trans, bp);
0157 return 0;
0158 }
0159 child_fsb = be32_to_cpu(ichdr.btree[0].before);
0160 xfs_trans_brelse(*trans, bp);
0161 bp = NULL;
0162
0163
0164
0165
0166
0167
0168 for (i = 0; i < ichdr.count; i++) {
0169
0170
0171
0172
0173
0174
0175 error = xfs_da3_node_read(*trans, dp, child_fsb, &child_bp,
0176 XFS_ATTR_FORK);
0177 if (error)
0178 return error;
0179
0180
0181 child_blkno = xfs_buf_daddr(child_bp);
0182
0183
0184
0185
0186 info = child_bp->b_addr;
0187 switch (info->magic) {
0188 case cpu_to_be16(XFS_DA_NODE_MAGIC):
0189 case cpu_to_be16(XFS_DA3_NODE_MAGIC):
0190 error = xfs_attr3_node_inactive(trans, dp, child_bp,
0191 level + 1);
0192 break;
0193 case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
0194 case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
0195 error = xfs_attr3_leaf_inactive(trans, dp, child_bp);
0196 break;
0197 default:
0198 xfs_buf_mark_corrupt(child_bp);
0199 xfs_trans_brelse(*trans, child_bp);
0200 error = -EFSCORRUPTED;
0201 break;
0202 }
0203 if (error)
0204 return error;
0205
0206
0207
0208
0209 error = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
0210 child_blkno,
0211 XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0,
0212 &child_bp);
0213 if (error)
0214 return error;
0215 xfs_trans_binval(*trans, child_bp);
0216 child_bp = NULL;
0217
0218
0219
0220
0221
0222 if (i + 1 < ichdr.count) {
0223 struct xfs_da3_icnode_hdr phdr;
0224
0225 error = xfs_da3_node_read_mapped(*trans, dp,
0226 parent_blkno, &bp, XFS_ATTR_FORK);
0227 if (error)
0228 return error;
0229 xfs_da3_node_hdr_from_disk(dp->i_mount, &phdr,
0230 bp->b_addr);
0231 child_fsb = be32_to_cpu(phdr.btree[i + 1].before);
0232 xfs_trans_brelse(*trans, bp);
0233 bp = NULL;
0234 }
0235
0236
0237
0238 error = xfs_trans_roll_inode(trans, dp);
0239 if (error)
0240 return error;
0241 }
0242
0243 return 0;
0244 }
0245
0246
0247
0248
0249
0250
0251
0252 static int
0253 xfs_attr3_root_inactive(
0254 struct xfs_trans **trans,
0255 struct xfs_inode *dp)
0256 {
0257 struct xfs_mount *mp = dp->i_mount;
0258 struct xfs_da_blkinfo *info;
0259 struct xfs_buf *bp;
0260 xfs_daddr_t blkno;
0261 int error;
0262
0263
0264
0265
0266
0267
0268
0269 error = xfs_da3_node_read(*trans, dp, 0, &bp, XFS_ATTR_FORK);
0270 if (error)
0271 return error;
0272 blkno = xfs_buf_daddr(bp);
0273
0274
0275
0276
0277
0278 info = bp->b_addr;
0279 switch (info->magic) {
0280 case cpu_to_be16(XFS_DA_NODE_MAGIC):
0281 case cpu_to_be16(XFS_DA3_NODE_MAGIC):
0282 error = xfs_attr3_node_inactive(trans, dp, bp, 1);
0283 break;
0284 case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
0285 case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
0286 error = xfs_attr3_leaf_inactive(trans, dp, bp);
0287 break;
0288 default:
0289 error = -EFSCORRUPTED;
0290 xfs_buf_mark_corrupt(bp);
0291 xfs_trans_brelse(*trans, bp);
0292 break;
0293 }
0294 if (error)
0295 return error;
0296
0297
0298
0299
0300 error = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno,
0301 XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0, &bp);
0302 if (error)
0303 return error;
0304 error = bp->b_error;
0305 if (error) {
0306 xfs_trans_brelse(*trans, bp);
0307 return error;
0308 }
0309 xfs_trans_binval(*trans, bp);
0310
0311
0312
0313 error = xfs_trans_roll_inode(trans, dp);
0314
0315 return error;
0316 }
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326 int
0327 xfs_attr_inactive(
0328 struct xfs_inode *dp)
0329 {
0330 struct xfs_trans *trans;
0331 struct xfs_mount *mp;
0332 int lock_mode = XFS_ILOCK_SHARED;
0333 int error = 0;
0334
0335 mp = dp->i_mount;
0336 ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
0337
0338 xfs_ilock(dp, lock_mode);
0339 if (!xfs_inode_has_attr_fork(dp))
0340 goto out_destroy_fork;
0341 xfs_iunlock(dp, lock_mode);
0342
0343 lock_mode = 0;
0344
0345 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrinval, 0, 0, 0, &trans);
0346 if (error)
0347 goto out_destroy_fork;
0348
0349 lock_mode = XFS_ILOCK_EXCL;
0350 xfs_ilock(dp, lock_mode);
0351
0352 if (!xfs_inode_has_attr_fork(dp))
0353 goto out_cancel;
0354
0355
0356
0357
0358
0359 xfs_trans_ijoin(trans, dp, 0);
0360
0361
0362
0363
0364
0365
0366
0367 if (dp->i_af.if_nextents > 0) {
0368 error = xfs_attr3_root_inactive(&trans, dp);
0369 if (error)
0370 goto out_cancel;
0371
0372 error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
0373 if (error)
0374 goto out_cancel;
0375 }
0376
0377
0378 xfs_attr_fork_remove(dp, trans);
0379
0380 error = xfs_trans_commit(trans);
0381 xfs_iunlock(dp, lock_mode);
0382 return error;
0383
0384 out_cancel:
0385 xfs_trans_cancel(trans);
0386 out_destroy_fork:
0387
0388 xfs_ifork_zap_attr(dp);
0389 if (lock_mode)
0390 xfs_iunlock(dp, lock_mode);
0391 return error;
0392 }