]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/attr_repair.c
xfs_repair: ignore "repaired" flag after we decide to clear xattr block
[thirdparty/xfsprogs-dev.git] / repair / attr_repair.c
1 /*
2 * Copyright (c) 2000-2002,2004-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "libxfs.h"
20 #include "globals.h"
21 #include "err_protos.h"
22 #include "attr_repair.h"
23 #include "dinode.h"
24 #include "bmap.h"
25 #include "protos.h"
26 #include "dir2.h"
27
28 static int xfs_acl_valid(struct xfs_mount *mp, struct xfs_acl *daclp);
29 static int xfs_mac_valid(xfs_mac_label_t *lp);
30
31 /*
32 * da node check/verify functions that the attribute tree relies on are first in
33 * the file before the actual attribute code. This used to be shared with the
34 * dir v1 code, but that format is no longer supported yb the userspace
35 * utilities and hence is now specific to the attribute tree implementation.
36 */
37 #define XR_DA_LEAF_MAPSIZE XFS_ATTR_LEAF_MAPSIZE
38
39 typedef unsigned char da_freemap_t;
40
41 /*
42 * the cursor gets passed up and down the da btree processing
43 * routines. The interior block processing routines use the
44 * cursor to determine if the pointers to and from the preceding
45 * and succeeding sibling blocks are ok and whether the values in
46 * the current block are consistent with the entries in the parent
47 * nodes. When a block is traversed, a parent-verification routine
48 * is called to verify if the next logical entry in the next level up
49 * is consistent with the greatest hashval in the next block of the
50 * current level. The verification routine is itself recursive and
51 * calls itself if it has to traverse an interior block to get
52 * the next logical entry. The routine recurses upwards through
53 * the tree until it finds a block where it can simply step to
54 * the next entry. The hashval in that entry should be equal to
55 * the hashval being passed to it (the greatest hashval in the block
56 * that the entry points to). If that isn't true, then the tree
57 * is blown and we need to trash it, salvage and trash it, or fix it.
58 * Currently, we just trash it.
59 */
60 typedef struct da_level_state {
61 xfs_buf_t *bp; /* block bp */
62 #ifdef XR_DIR_TRACE
63 xfs_da_intnode_t *n; /* bp data */
64 #endif
65 xfs_dablk_t bno; /* file block number */
66 xfs_dahash_t hashval; /* last verified hashval */
67 int index; /* current index in block */
68 int dirty; /* is buffer dirty ? (1 == yes) */
69 } da_level_state_t;
70
71 typedef struct da_bt_cursor {
72 int active; /* highest level in tree (# levels-1) */
73 int type; /* 0 if dir, 1 if attr */
74 xfs_ino_t ino;
75 xfs_dablk_t greatest_bno;
76 xfs_dinode_t *dip;
77 da_level_state_t level[XFS_DA_NODE_MAXDEPTH];
78 struct blkmap *blkmap;
79 } da_bt_cursor_t;
80
81
82 /*
83 * Allocate a freespace map for directory or attr leaf blocks (1 bit per byte)
84 * 1 == used, 0 == free.
85 */
86 static da_freemap_t *
87 alloc_da_freemap(struct xfs_mount *mp)
88 {
89 return calloc(1, mp->m_sb.sb_blocksize / NBBY);
90 }
91
92 /*
93 * Set the he range [start, stop) in the directory freemap.
94 *
95 * Returns 1 if there is a conflict or 0 if everything's good.
96 *
97 * Within a char, the lowest bit of the char represents the byte with
98 * the smallest address
99 */
100 static int
101 set_da_freemap(xfs_mount_t *mp, da_freemap_t *map, int start, int stop)
102 {
103 const da_freemap_t mask = 0x1;
104 int i;
105
106 if (start > stop) {
107 /*
108 * allow == relation since [x, x) claims 1 byte
109 */
110 do_warn(_("bad range claimed [%d, %d) in da block\n"),
111 start, stop);
112 return(1);
113 }
114
115 if (stop > mp->m_sb.sb_blocksize) {
116 do_warn(
117 _("byte range end [%d %d) in da block larger than blocksize %d\n"),
118 start, stop, mp->m_sb.sb_blocksize);
119 return(1);
120 }
121
122 for (i = start; i < stop; i ++) {
123 if (map[i / NBBY] & (mask << i % NBBY)) {
124 do_warn(_("multiply claimed byte %d in da block\n"), i);
125 return(1);
126 }
127 map[i / NBBY] |= (mask << i % NBBY);
128 }
129
130 return(0);
131 }
132
133 /*
134 * walk tree from root to the left-most leaf block reading in
135 * blocks and setting up cursor. passes back file block number of the
136 * left-most leaf block if successful (bno). returns 1 if successful,
137 * 0 if unsuccessful.
138 */
139 static int
140 traverse_int_dablock(xfs_mount_t *mp,
141 da_bt_cursor_t *da_cursor,
142 xfs_dablk_t *rbno,
143 int whichfork)
144 {
145 xfs_dablk_t bno;
146 int i;
147 xfs_da_intnode_t *node;
148 xfs_fsblock_t fsbno;
149 xfs_buf_t *bp;
150 struct xfs_da_node_entry *btree;
151 struct xfs_da3_icnode_hdr nodehdr;
152
153 /*
154 * traverse down left-side of tree until we hit the
155 * left-most leaf block setting up the btree cursor along
156 * the way.
157 */
158 bno = 0;
159 i = -1;
160 node = NULL;
161 da_cursor->active = 0;
162
163 do {
164 /*
165 * read in each block along the way and set up cursor
166 */
167 fsbno = blkmap_get(da_cursor->blkmap, bno);
168
169 if (fsbno == NULLFSBLOCK)
170 goto error_out;
171
172 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
173 XFS_FSB_TO_BB(mp, 1), 0, &xfs_da3_node_buf_ops);
174 if (!bp) {
175 if (whichfork == XFS_DATA_FORK)
176 do_warn(
177 _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"),
178 bno, fsbno, da_cursor->ino);
179 else
180 do_warn(
181 _("can't read block %u (fsbno %" PRIu64 ") for attrbute fork of inode %" PRIu64 "\n"),
182 bno, fsbno, da_cursor->ino);
183 goto error_out;
184 }
185
186 node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp);
187 btree = M_DIROPS(mp)->node_tree_p(node);
188 M_DIROPS(mp)->node_hdr_from_disk(&nodehdr, node);
189
190 if (nodehdr.magic != XFS_DA_NODE_MAGIC &&
191 nodehdr.magic != XFS_DA3_NODE_MAGIC) {
192 do_warn(_("bad dir/attr magic number in inode %" PRIu64 ", "
193 "file bno = %u, fsbno = %" PRIu64 "\n"),
194 da_cursor->ino, bno, fsbno);
195 libxfs_putbuf(bp);
196 goto error_out;
197 }
198
199 if (nodehdr.count > mp->m_attr_geo->node_ents) {
200 do_warn(_("bad record count in inode %" PRIu64 ", "
201 "count = %d, max = %d\n"),
202 da_cursor->ino,
203 nodehdr.count,
204 mp->m_attr_geo->node_ents);
205 libxfs_putbuf(bp);
206 goto error_out;
207 }
208
209 /*
210 * maintain level counter
211 */
212 if (i == -1)
213 i = da_cursor->active = nodehdr.level;
214 else {
215 if (nodehdr.level == i - 1) {
216 i--;
217 } else {
218 if (whichfork == XFS_DATA_FORK)
219 do_warn(_("bad directory btree for "
220 "directory inode %" PRIu64 "\n"),
221 da_cursor->ino);
222 else
223 do_warn(_("bad attribute fork btree "
224 "for inode %" PRIu64 "\n"),
225 da_cursor->ino);
226 libxfs_putbuf(bp);
227 goto error_out;
228 }
229 }
230
231 da_cursor->level[i].hashval = be32_to_cpu(btree[0].hashval);
232 da_cursor->level[i].bp = bp;
233 da_cursor->level[i].bno = bno;
234 da_cursor->level[i].index = 0;
235 #ifdef XR_DIR_TRACE
236 da_cursor->level[i].n = XFS_BUF_TO_DA_INTNODE(bp);
237 #endif
238
239 /*
240 * set up new bno for next level down
241 */
242 bno = be32_to_cpu(btree[0].before);
243 } while (node != NULL && i > 1);
244
245 /*
246 * now return block number and get out
247 */
248 *rbno = da_cursor->level[0].bno = bno;
249 return(1);
250
251 error_out:
252 while (i > 1 && i <= da_cursor->active) {
253 libxfs_putbuf(da_cursor->level[i].bp);
254 i++;
255 }
256
257 return(0);
258 }
259
260 /*
261 * blow out buffer for this level and all the rest above as well
262 * if error == 0, we are not expecting to encounter any unreleased
263 * buffers (e.g. if we do, it's a mistake). if error == 1, we're
264 * in an error-handling case so unreleased buffers may exist.
265 */
266 static void
267 release_da_cursor_int(xfs_mount_t *mp,
268 da_bt_cursor_t *cursor,
269 int prev_level,
270 int error)
271 {
272 int level = prev_level + 1;
273
274 if (cursor->level[level].bp != NULL) {
275 if (!error) {
276 do_warn(_("release_da_cursor_int got unexpected "
277 "non-null bp, dabno = %u\n"),
278 cursor->level[level].bno);
279 }
280 ASSERT(error != 0);
281
282 libxfs_putbuf(cursor->level[level].bp);
283 cursor->level[level].bp = NULL;
284 }
285
286 if (level < cursor->active)
287 release_da_cursor_int(mp, cursor, level, error);
288
289 return;
290 }
291
292 static void
293 release_da_cursor(xfs_mount_t *mp,
294 da_bt_cursor_t *cursor,
295 int prev_level)
296 {
297 release_da_cursor_int(mp, cursor, prev_level, 0);
298 }
299
300 static void
301 err_release_da_cursor(xfs_mount_t *mp,
302 da_bt_cursor_t *cursor,
303 int prev_level)
304 {
305 release_da_cursor_int(mp, cursor, prev_level, 1);
306 }
307
308 /*
309 * make sure that all entries in all blocks along the right side of
310 * of the tree are used and hashval's are consistent. level is the
311 * level of the descendent block. returns 0 if good (even if it had
312 * to be fixed up), and 1 if bad. The right edge of the tree is
313 * technically a block boundary. this routine should be used then
314 * instead of verify_da_path().
315 */
316 static int
317 verify_final_da_path(xfs_mount_t *mp,
318 da_bt_cursor_t *cursor,
319 const int p_level)
320 {
321 xfs_da_intnode_t *node;
322 xfs_dahash_t hashval;
323 int bad = 0;
324 int entry;
325 int this_level = p_level + 1;
326 struct xfs_da_node_entry *btree;
327 struct xfs_da3_icnode_hdr nodehdr;
328
329 #ifdef XR_DIR_TRACE
330 fprintf(stderr, "in verify_final_da_path, this_level = %d\n",
331 this_level);
332 #endif
333 /*
334 * the index should point to the next "unprocessed" entry
335 * in the block which should be the final (rightmost) entry
336 */
337 entry = cursor->level[this_level].index;
338 node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp);
339 btree = M_DIROPS(mp)->node_tree_p(node);
340 M_DIROPS(mp)->node_hdr_from_disk(&nodehdr, node);
341
342 /*
343 * check internal block consistency on this level -- ensure
344 * that all entries are used, encountered and expected hashvals
345 * match, etc.
346 */
347 if (entry != nodehdr.count - 1) {
348 do_warn(_("directory/attribute block used/count "
349 "inconsistency - %d/%hu\n"),
350 entry, nodehdr.count);
351 bad++;
352 }
353 /*
354 * hash values monotonically increasing ???
355 */
356 if (cursor->level[this_level].hashval >=
357 be32_to_cpu(btree[entry].hashval)) {
358 do_warn(_("directory/attribute block hashvalue inconsistency, "
359 "expected > %u / saw %u\n"),
360 cursor->level[this_level].hashval,
361 be32_to_cpu(btree[entry].hashval));
362 bad++;
363 }
364 if (nodehdr.forw != 0) {
365 do_warn(_("bad directory/attribute forward block pointer, "
366 "expected 0, saw %u\n"),
367 nodehdr.forw);
368 bad++;
369 }
370 if (bad) {
371 do_warn(_("bad directory block in dir ino %" PRIu64 "\n"),
372 cursor->ino);
373 return(1);
374 }
375 /*
376 * keep track of greatest block # -- that gets
377 * us the length of the directory
378 */
379 if (cursor->level[this_level].bno > cursor->greatest_bno)
380 cursor->greatest_bno = cursor->level[this_level].bno;
381
382 /*
383 * ok, now check descendant block number against this level
384 */
385 if (cursor->level[p_level].bno != be32_to_cpu(btree[entry].before)) {
386 #ifdef XR_DIR_TRACE
387 fprintf(stderr, "bad directory btree pointer, child bno should "
388 "be %d, block bno is %d, hashval is %u\n",
389 be16_to_cpu(btree[entry].before),
390 cursor->level[p_level].bno,
391 cursor->level[p_level].hashval);
392 fprintf(stderr, "verify_final_da_path returns 1 (bad) #1a\n");
393 #endif
394 return(1);
395 }
396
397 if (cursor->level[p_level].hashval != be32_to_cpu(btree[entry].hashval)) {
398 if (!no_modify) {
399 do_warn(_("correcting bad hashval in non-leaf "
400 "dir/attr block\n\tin (level %d) in "
401 "inode %" PRIu64 ".\n"),
402 this_level, cursor->ino);
403 btree[entry].hashval = cpu_to_be32(
404 cursor->level[p_level].hashval);
405 cursor->level[this_level].dirty++;
406 } else {
407 do_warn(_("would correct bad hashval in non-leaf "
408 "dir/attr block\n\tin (level %d) in "
409 "inode %" PRIu64 ".\n"),
410 this_level, cursor->ino);
411 }
412 }
413
414 /*
415 * Note: squirrel hashval away _before_ releasing the
416 * buffer, preventing a use-after-free problem.
417 */
418 hashval = be32_to_cpu(btree[entry].hashval);
419
420 /*
421 * release/write buffer
422 */
423 ASSERT(cursor->level[this_level].dirty == 0 ||
424 (cursor->level[this_level].dirty && !no_modify));
425
426 if (cursor->level[this_level].dirty && !no_modify)
427 libxfs_writebuf(cursor->level[this_level].bp, 0);
428 else
429 libxfs_putbuf(cursor->level[this_level].bp);
430
431 cursor->level[this_level].bp = NULL;
432
433 /*
434 * bail out if this is the root block (top of tree)
435 */
436 if (this_level >= cursor->active) {
437 #ifdef XR_DIR_TRACE
438 fprintf(stderr, "verify_final_da_path returns 0 (ok)\n");
439 #endif
440 return(0);
441 }
442 /*
443 * set hashvalue to correctly reflect the now-validated
444 * last entry in this block and continue upwards validation
445 */
446 cursor->level[this_level].hashval = hashval;
447 return(verify_final_da_path(mp, cursor, this_level));
448 }
449
450 /*
451 * Verifies the path from a descendant block up to the root.
452 * Should be called when the descendant level traversal hits
453 * a block boundary before crossing the boundary (reading in a new
454 * block).
455 *
456 * the directory/attr btrees work differently to the other fs btrees.
457 * each interior block contains records that are <hashval, bno>
458 * pairs. The bno is a file bno, not a filesystem bno. The last
459 * hashvalue in the block <bno> will be <hashval>. BUT unlike
460 * the freespace btrees, the *last* value in each block gets
461 * propagated up the tree instead of the first value in each block.
462 * that is, the interior records point to child blocks and the *greatest*
463 * hash value contained by the child block is the one the block above
464 * uses as the key for the child block.
465 *
466 * level is the level of the descendent block. returns 0 if good,
467 * and 1 if bad. The descendant block may be a leaf block.
468 *
469 * the invariant here is that the values in the cursor for the
470 * levels beneath this level (this_level) and the cursor index
471 * for this level *must* be valid.
472 *
473 * that is, the hashval/bno info is accurate for all
474 * DESCENDANTS and match what the node[index] information
475 * for the current index in the cursor for this level.
476 *
477 * the index values in the cursor for the descendant level
478 * are allowed to be off by one as they will reflect the
479 * next entry at those levels to be processed.
480 *
481 * the hashvalue for the current level can't be set until
482 * we hit the last entry in the block so, it's garbage
483 * until set by this routine.
484 *
485 * bno and bp for the current block/level are always valid
486 * since they have to be set so we can get a buffer for the
487 * block.
488 */
489 static int
490 verify_da_path(xfs_mount_t *mp,
491 da_bt_cursor_t *cursor,
492 const int p_level)
493 {
494 xfs_da_intnode_t *node;
495 xfs_da_intnode_t *newnode;
496 xfs_fsblock_t fsbno;
497 xfs_dablk_t dabno;
498 xfs_buf_t *bp;
499 int bad;
500 int entry;
501 int this_level = p_level + 1;
502 struct xfs_da_node_entry *btree;
503 struct xfs_da3_icnode_hdr nodehdr;
504
505 /*
506 * index is currently set to point to the entry that
507 * should be processed now in this level.
508 */
509 entry = cursor->level[this_level].index;
510 node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp);
511 btree = M_DIROPS(mp)->node_tree_p(node);
512 M_DIROPS(mp)->node_hdr_from_disk(&nodehdr, node);
513
514 /*
515 * if this block is out of entries, validate this
516 * block and move on to the next block.
517 * and update cursor value for said level
518 */
519 if (entry >= nodehdr.count) {
520 /*
521 * update the hash value for this level before
522 * validating it. bno value should be ok since
523 * it was set when the block was first read in.
524 */
525 cursor->level[this_level].hashval =
526 be32_to_cpu(btree[entry - 1].hashval);
527
528 /*
529 * keep track of greatest block # -- that gets
530 * us the length of the directory
531 */
532 if (cursor->level[this_level].bno > cursor->greatest_bno)
533 cursor->greatest_bno = cursor->level[this_level].bno;
534
535 /*
536 * validate the path for the current used-up block
537 * before we trash it
538 */
539 if (verify_da_path(mp, cursor, this_level))
540 return(1);
541 /*
542 * ok, now get the next buffer and check sibling pointers
543 */
544 dabno = nodehdr.forw;
545 ASSERT(dabno != 0);
546 fsbno = blkmap_get(cursor->blkmap, dabno);
547
548 if (fsbno == NULLFSBLOCK) {
549 do_warn(_("can't get map info for block %u "
550 "of directory inode %" PRIu64 "\n"),
551 dabno, cursor->ino);
552 return(1);
553 }
554
555 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
556 XFS_FSB_TO_BB(mp, 1), 0, &xfs_da3_node_buf_ops);
557 if (!bp) {
558 do_warn(
559 _("can't read block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"),
560 dabno, fsbno, cursor->ino);
561 return(1);
562 }
563
564 newnode = (xfs_da_intnode_t *)XFS_BUF_PTR(bp);
565 btree = M_DIROPS(mp)->node_tree_p(node);
566 M_DIROPS(mp)->node_hdr_from_disk(&nodehdr, newnode);
567
568 /*
569 * verify magic number and back pointer, sanity-check
570 * entry count, verify level
571 */
572 bad = 0;
573 if (nodehdr.magic != XFS_DA_NODE_MAGIC &&
574 nodehdr.magic != XFS_DA3_NODE_MAGIC) {
575 do_warn(
576 _("bad magic number %x in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"),
577 nodehdr.magic,
578 dabno, fsbno, cursor->ino);
579 bad++;
580 }
581 if (nodehdr.back != cursor->level[this_level].bno) {
582 do_warn(
583 _("bad back pointer in block %u (%"PRIu64 ") for directory inode %" PRIu64 "\n"),
584 dabno, fsbno, cursor->ino);
585 bad++;
586 }
587 if (nodehdr.count > mp->m_attr_geo->node_ents) {
588 do_warn(
589 _("entry count %d too large in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"),
590 nodehdr.count,
591 dabno, fsbno, cursor->ino);
592 bad++;
593 }
594 if (nodehdr.level != this_level) {
595 do_warn(
596 _("bad level %d in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"),
597 nodehdr.level,
598 dabno, fsbno, cursor->ino);
599 bad++;
600 }
601 if (bad) {
602 #ifdef XR_DIR_TRACE
603 fprintf(stderr, "verify_da_path returns 1 (bad) #4\n");
604 #endif
605 libxfs_putbuf(bp);
606 return(1);
607 }
608
609 /*
610 * update cursor, write out the *current* level if
611 * required. don't write out the descendant level
612 */
613 ASSERT(cursor->level[this_level].dirty == 0 ||
614 (cursor->level[this_level].dirty && !no_modify));
615
616 if (cursor->level[this_level].dirty && !no_modify)
617 libxfs_writebuf(cursor->level[this_level].bp, 0);
618 else
619 libxfs_putbuf(cursor->level[this_level].bp);
620
621 /* switch cursor to point at the new buffer we just read */
622 cursor->level[this_level].bp = bp;
623 cursor->level[this_level].dirty = 0;
624 cursor->level[this_level].bno = dabno;
625 cursor->level[this_level].hashval =
626 be32_to_cpu(btree[0].hashval);
627 #ifdef XR_DIR_TRACE
628 cursor->level[this_level].n = newnode;
629 #endif
630 entry = cursor->level[this_level].index = 0;
631
632 /*
633 * We want to rewrite the buffer on a CRC error seeing as it
634 * contains what appears to be a valid node block, but only if
635 * we are fixing errors.
636 */
637 if (bp->b_error == -EFSBADCRC && !no_modify)
638 cursor->level[this_level].dirty++;
639 }
640 /*
641 * ditto for block numbers
642 */
643 if (cursor->level[p_level].bno != be32_to_cpu(btree[entry].before)) {
644 #ifdef XR_DIR_TRACE
645 fprintf(stderr, "bad directory btree pointer, child bno "
646 "should be %d, block bno is %d, hashval is %u\n",
647 be32_to_cpu(btree[entry].before),
648 cursor->level[p_level].bno,
649 cursor->level[p_level].hashval);
650 fprintf(stderr, "verify_da_path returns 1 (bad) #1a\n");
651 #endif
652 return(1);
653 }
654 /*
655 * ok, now validate last hashvalue in the descendant
656 * block against the hashval in the current entry
657 */
658 if (cursor->level[p_level].hashval !=
659 be32_to_cpu(btree[entry].hashval)) {
660 if (!no_modify) {
661 do_warn(_("correcting bad hashval in interior "
662 "dir/attr block\n\tin (level %d) in "
663 "inode %" PRIu64 ".\n"),
664 this_level, cursor->ino);
665 btree[entry].hashval = cpu_to_be32(
666 cursor->level[p_level].hashval);
667 cursor->level[this_level].dirty++;
668 } else {
669 do_warn(_("would correct bad hashval in interior "
670 "dir/attr block\n\tin (level %d) in "
671 "inode %" PRIu64 ".\n"),
672 this_level, cursor->ino);
673 }
674 }
675 /*
676 * increment index for this level to point to next entry
677 * (which should point to the next descendant block)
678 */
679 cursor->level[this_level].index++;
680 #ifdef XR_DIR_TRACE
681 fprintf(stderr, "verify_da_path returns 0 (ok)\n");
682 #endif
683 return(0);
684 }
685
686 /*
687 * For attribute repair, there are 3 formats to worry about. First, is
688 * shortform attributes which reside in the inode. Second is the leaf
689 * form, and lastly the btree. Much of this models after the directory
690 * structure so code resembles the directory repair cases.
691 * For shortform case, if an attribute looks corrupt, it is removed.
692 * If that leaves the shortform down to 0 attributes, it's okay and
693 * will appear to just have a null attribute fork. Some checks are done
694 * for validity of the value field based on what the security needs are.
695 * Calls will be made to xfs_mac_valid or xfs_acl_valid routines if the
696 * security attributes exist. They will be cleared if invalid.
697 * No other values will be checked. The DMF folks do not have current
698 * requirements, but may in the future.
699 *
700 * For leaf block attributes, it requires more processing. One sticky
701 * point is that the attributes can be local (within the leaf) or
702 * remote (outside the leaf in other blocks). Thinking of local only
703 * if you get a bad attribute, and want to delete just one, it's a-okay
704 * if it remains large enough to still be a leaf block attribute. Otherwise,
705 * it may have to be converted to shortform. How to convert this and when
706 * is an issue. This call is happening in Phase3. Phase5 will capture empty
707 * blocks, but Phase6 allows you to use the libxfs library which knows
708 * how to handle attributes in the kernel for converting formats. What we
709 * could do is mark an attribute to be cleared now, but in phase6 somehow
710 * have it cleared for real and then the format changed to shortform if
711 * applicable. Since this requires more work than I anticipate can be
712 * accomplished for the next release, we will instead just say any bad
713 * attribute in the leaf block will make the entire attribute fork be
714 * cleared. The simplest way to do that is to ignore the leaf format, and
715 * call clear_dinode_attr to just make a shortform attribute fork with
716 * zero entries.
717 *
718 * Another issue with handling repair on leaf attributes is the remote
719 * blocks. To make sure that they look good and are not used multiple times
720 * by the attribute fork, some mechanism to keep track of all them is necessary.
721 * Do this in the future, time permitting. For now, note that there is no
722 * check for remote blocks and their allocations.
723 *
724 * For btree formatted attributes, the model can follow directories. That
725 * would mean go down the tree to the leftmost leaf. From there moving down
726 * the links and processing each. They would call back up the tree, to verify
727 * that the tree structure is okay. Any problems will result in the attribute
728 * fork being emptied and put in shortform format.
729 */
730
731 /*
732 * This routine just checks what security needs are for attribute values
733 * only called when root flag is set, otherwise these names could exist in
734 * in user attribute land without a conflict.
735 * If value is non-zero, then a remote attribute is being passed in
736 */
737 static int
738 valuecheck(
739 struct xfs_mount *mp,
740 char *namevalue,
741 char *value,
742 int namelen,
743 int valuelen)
744 {
745 /* for proper alignment issues, get the structs and memmove the values */
746 xfs_mac_label_t macl;
747 void *valuep;
748 int clearit = 0;
749
750 if ((namelen == SGI_ACL_FILE_SIZE &&
751 strncmp(namevalue, SGI_ACL_FILE, SGI_ACL_FILE_SIZE) == 0) ||
752 (namelen == SGI_ACL_DEFAULT_SIZE &&
753 strncmp(namevalue, SGI_ACL_DEFAULT, SGI_ACL_DEFAULT_SIZE) == 0)) {
754 if (value == NULL) {
755 valuep = malloc(valuelen);
756 if (!valuep)
757 do_error(_("No memory for ACL check!\n"));
758 memcpy(valuep, namevalue + namelen, valuelen);
759 } else
760 valuep = value;
761
762 if (xfs_acl_valid(mp, valuep) != 0) {
763 clearit = 1;
764 do_warn(
765 _("entry contains illegal value in attribute named SGI_ACL_FILE "
766 "or SGI_ACL_DEFAULT\n"));
767 }
768
769 if (valuep != value)
770 free(valuep);
771
772 } else if (strncmp(namevalue, SGI_MAC_FILE, SGI_MAC_FILE_SIZE) == 0) {
773 if (value == NULL) {
774 memset(&macl, 0, sizeof(xfs_mac_label_t));
775 memmove(&macl, namevalue+namelen, valuelen);
776 valuep = &macl;
777 } else
778 valuep = value;
779
780 if (xfs_mac_valid((xfs_mac_label_t *)valuep) != 1) { /* 1 is valid */
781 /*
782 * if sysconf says MAC enabled,
783 * temp = mac_from_text("msenhigh/mintlow", NULL)
784 * copy it to value, update valuelen, totsize
785 * This causes pushing up or down of all following
786 * attributes, forcing a attribute format change!!
787 * else clearit = 1;
788 */
789 clearit = 1;
790 do_warn(
791 _("entry contains illegal value in attribute named SGI_MAC_LABEL\n"));
792 }
793 } else if (strncmp(namevalue, SGI_CAP_FILE, SGI_CAP_FILE_SIZE) == 0) {
794 if ( valuelen != sizeof(xfs_cap_set_t)) {
795 clearit = 1;
796 do_warn(
797 _("entry contains illegal value in attribute named SGI_CAP_FILE\n"));
798 }
799 }
800
801 return(clearit);
802 }
803
804
805 /*
806 * this routine validates the attributes in shortform format.
807 * a non-zero return repair value means certain attributes are bogus
808 * and were cleared if possible. Warnings do not generate error conditions
809 * if you cannot modify the structures. repair is set to 1, if anything
810 * was fixed.
811 */
812 static int
813 process_shortform_attr(
814 struct xfs_mount *mp,
815 xfs_ino_t ino,
816 xfs_dinode_t *dip,
817 int *repair)
818 {
819 xfs_attr_shortform_t *asf;
820 xfs_attr_sf_entry_t *currententry, *nextentry, *tempentry;
821 int i, junkit;
822 int currentsize, remainingspace;
823
824 *repair = 0;
825
826 asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip);
827
828 /* Assumption: hdr.totsize is less than a leaf block and was checked
829 * by lclinode for valid sizes. Check the count though.
830 */
831 if (asf->hdr.count == 0)
832 /* then the total size should just be the header length */
833 if (be16_to_cpu(asf->hdr.totsize) != sizeof(xfs_attr_sf_hdr_t)) {
834 /* whoops there's a discrepancy. Clear the hdr */
835 if (!no_modify) {
836 do_warn(
837 _("there are no attributes in the fork for inode %" PRIu64 "\n"),
838 ino);
839 asf->hdr.totsize =
840 cpu_to_be16(sizeof(xfs_attr_sf_hdr_t));
841 *repair = 1;
842 return(1);
843 } else {
844 do_warn(
845 _("would junk the attribute fork since count is 0 for inode %" PRIu64 "\n"),
846 ino);
847 return(1);
848 }
849 }
850
851 currentsize = sizeof(xfs_attr_sf_hdr_t);
852 remainingspace = be16_to_cpu(asf->hdr.totsize) - currentsize;
853 nextentry = &asf->list[0];
854 for (i = 0; i < asf->hdr.count; i++) {
855 currententry = nextentry;
856 junkit = 0;
857
858 /* don't go off the end if the hdr.count was off */
859 if ((currentsize + (sizeof(xfs_attr_sf_entry_t) - 1)) >
860 be16_to_cpu(asf->hdr.totsize))
861 break; /* get out and reset count and totSize */
862
863 /* if the namelen is 0, can't get to the rest of the entries */
864 if (currententry->namelen == 0) {
865 do_warn(_("zero length name entry in attribute fork,"));
866 if (!no_modify) {
867 do_warn(
868 _(" truncating attributes for inode %" PRIu64 " to %d\n"), ino, i);
869 *repair = 1;
870 break; /* and then update hdr fields */
871 } else {
872 do_warn(
873 _(" would truncate attributes for inode %" PRIu64 " to %d\n"), ino, i);
874 break;
875 }
876 } else {
877 /* It's okay to have a 0 length valuelen, but do a
878 * rough check to make sure we haven't gone outside of
879 * totsize.
880 */
881 if (remainingspace < currententry->namelen ||
882 ((remainingspace - currententry->
883 namelen) < currententry->valuelen)) {
884 do_warn(
885 _("name or value attribute lengths are too large,\n"));
886 if (!no_modify) {
887 do_warn(
888 _(" truncating attributes for inode %" PRIu64 " to %d\n"),
889 ino, i);
890 *repair = 1;
891 break; /* and then update hdr fields */
892 } else {
893 do_warn(
894 _(" would truncate attributes for inode %" PRIu64 " to %d\n"),
895 ino, i);
896 break;
897 }
898 }
899 }
900
901 /* namecheck checks for / and null terminated for file names.
902 * attributes names currently follow the same rules.
903 */
904 if (namecheck((char *)&currententry->nameval[0],
905 currententry->namelen)) {
906 do_warn(
907 _("entry contains illegal character in shortform attribute name\n"));
908 junkit = 1;
909 }
910
911 if (currententry->flags & XFS_ATTR_INCOMPLETE) {
912 do_warn(
913 _("entry has INCOMPLETE flag on in shortform attribute\n"));
914 junkit = 1;
915 }
916
917 /* Only check values for root security attributes */
918 if (currententry->flags & XFS_ATTR_ROOT)
919 junkit |= valuecheck(mp,
920 (char *)&currententry->nameval[0],
921 NULL, currententry->namelen,
922 currententry->valuelen);
923
924 remainingspace = remainingspace -
925 XFS_ATTR_SF_ENTSIZE(currententry);
926
927 if (junkit) {
928 if (!no_modify) {
929 /* get rid of only this entry */
930 do_warn(
931 _("removing attribute entry %d for inode %" PRIu64 "\n"),
932 i, ino);
933 tempentry = (xfs_attr_sf_entry_t *)
934 ((intptr_t) currententry +
935 XFS_ATTR_SF_ENTSIZE(currententry));
936 memmove(currententry,tempentry,remainingspace);
937 asf->hdr.count -= 1;
938 i--; /* no worries, it will wrap back to 0 */
939 *repair = 1;
940 continue; /* go back up now */
941 } else {
942 do_warn(
943 _("would remove attribute entry %d for inode %" PRIu64 "\n"),
944 i, ino);
945 }
946 }
947
948 /* Let's get ready for the next entry... */
949 nextentry = (xfs_attr_sf_entry_t *)((intptr_t) nextentry +
950 XFS_ATTR_SF_ENTSIZE(currententry));
951 currentsize = currentsize + XFS_ATTR_SF_ENTSIZE(currententry);
952
953 } /* end the loop */
954
955 if (asf->hdr.count != i) {
956 if (no_modify) {
957 do_warn(
958 _("would have corrected attribute entry count in inode %" PRIu64 " from %d to %d\n"),
959 ino, asf->hdr.count, i);
960 } else {
961 do_warn(
962 _("corrected attribute entry count in inode %" PRIu64 ", was %d, now %d\n"),
963 ino, asf->hdr.count, i);
964 asf->hdr.count = i;
965 *repair = 1;
966 }
967 }
968
969 /* ASSUMPTION: currentsize <= totsize */
970 if (be16_to_cpu(asf->hdr.totsize) != currentsize) {
971 if (no_modify) {
972 do_warn(
973 _("would have corrected attribute totsize in inode %" PRIu64 " from %d to %d\n"),
974 ino, be16_to_cpu(asf->hdr.totsize),
975 currentsize);
976 } else {
977 do_warn(
978 _("corrected attribute entry totsize in inode %" PRIu64 ", was %d, now %d\n"),
979 ino, be16_to_cpu(asf->hdr.totsize),
980 currentsize);
981 asf->hdr.totsize = cpu_to_be16(currentsize);
982 *repair = 1;
983 }
984 }
985
986 return(*repair);
987 }
988
989 /* This routine brings in blocks from disk one by one and assembles them
990 * in the value buffer. If get_bmapi gets smarter later to return an extent
991 * or list of extents, that would be great. For now, we don't expect too
992 * many blocks per remote value, so one by one is sufficient.
993 */
994 static int
995 rmtval_get(xfs_mount_t *mp, xfs_ino_t ino, blkmap_t *blkmap,
996 xfs_dablk_t blocknum, int valuelen, char* value)
997 {
998 xfs_fsblock_t bno;
999 xfs_buf_t *bp;
1000 int clearit = 0, i = 0, length = 0, amountdone = 0;
1001 int hdrsize = 0;
1002
1003 if (xfs_sb_version_hascrc(&mp->m_sb))
1004 hdrsize = sizeof(struct xfs_attr3_rmt_hdr);
1005
1006 /* ASSUMPTION: valuelen is a valid number, so use it for looping */
1007 /* Note that valuelen is not a multiple of blocksize */
1008 while (amountdone < valuelen) {
1009 bno = blkmap_get(blkmap, blocknum + i);
1010 if (bno == NULLFSBLOCK) {
1011 do_warn(
1012 _("remote block for attributes of inode %" PRIu64 " is missing\n"), ino);
1013 clearit = 1;
1014 break;
1015 }
1016 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
1017 XFS_FSB_TO_BB(mp, 1), 0,
1018 &xfs_attr3_rmt_buf_ops);
1019 if (!bp) {
1020 do_warn(
1021 _("can't read remote block for attributes of inode %" PRIu64 "\n"), ino);
1022 clearit = 1;
1023 break;
1024 }
1025
1026 if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) {
1027 do_warn(
1028 _("Corrupt remote block for attributes of inode %" PRIu64 "\n"), ino);
1029 clearit = 1;
1030 break;
1031 }
1032
1033 ASSERT(mp->m_sb.sb_blocksize == XFS_BUF_COUNT(bp));
1034
1035 length = MIN(XFS_BUF_COUNT(bp) - hdrsize, valuelen - amountdone);
1036 memmove(value, XFS_BUF_PTR(bp) + hdrsize, length);
1037 amountdone += length;
1038 value += length;
1039 i++;
1040 libxfs_putbuf(bp);
1041 }
1042 return (clearit);
1043 }
1044
1045 /* The block is read in. The magic number and forward / backward
1046 * links are checked by the caller process_leaf_attr.
1047 * If any problems occur the routine returns with non-zero. In
1048 * this case the next step is to clear the attribute fork, by
1049 * changing it to shortform and zeroing it out. Forkoff need not
1050 * be changed.
1051 */
1052
1053 static int
1054 process_leaf_attr_local(
1055 struct xfs_mount *mp,
1056 xfs_attr_leafblock_t *leaf,
1057 int i,
1058 xfs_attr_leaf_entry_t *entry,
1059 xfs_dahash_t last_hashval,
1060 xfs_dablk_t da_bno,
1061 xfs_ino_t ino)
1062 {
1063 xfs_attr_leaf_name_local_t *local;
1064
1065 local = xfs_attr3_leaf_name_local(leaf, i);
1066 if (local->namelen == 0 || namecheck((char *)&local->nameval[0],
1067 local->namelen)) {
1068 do_warn(
1069 _("attribute entry %d in attr block %u, inode %" PRIu64 " has bad name (namelen = %d)\n"),
1070 i, da_bno, ino, local->namelen);
1071 return -1;
1072 }
1073
1074 /* Check on the hash value. Checking order of values
1075 * is not necessary, since one wrong clears the whole
1076 * fork. If the ordering's wrong, it's caught here or
1077 * the kernel code has a bug with transaction logging
1078 * or attributes itself. Being paranoid, let's check
1079 * ordering anyway in case both the name value and the
1080 * hashvalue were wrong but matched. Unlikely, however.
1081 */
1082 if (be32_to_cpu(entry->hashval) != libxfs_da_hashname(
1083 &local->nameval[0], local->namelen) ||
1084 be32_to_cpu(entry->hashval) < last_hashval) {
1085 do_warn(
1086 _("bad hashvalue for attribute entry %d in attr block %u, inode %" PRIu64 "\n"),
1087 i, da_bno, ino);
1088 return -1;
1089 }
1090
1091 /* Only check values for root security attributes */
1092 if (entry->flags & XFS_ATTR_ROOT) {
1093 if (valuecheck(mp, (char *)&local->nameval[0], NULL,
1094 local->namelen, be16_to_cpu(local->valuelen))) {
1095 do_warn(
1096 _("bad security value for attribute entry %d in attr block %u, inode %" PRIu64 "\n"),
1097 i, da_bno, ino);
1098 return -1;
1099 }
1100 }
1101 return xfs_attr_leaf_entsize_local(local->namelen,
1102 be16_to_cpu(local->valuelen));
1103 }
1104
1105 static int
1106 process_leaf_attr_remote(
1107 xfs_attr_leafblock_t *leaf,
1108 int i,
1109 xfs_attr_leaf_entry_t *entry,
1110 xfs_dahash_t last_hashval,
1111 xfs_dablk_t da_bno,
1112 xfs_ino_t ino,
1113 xfs_mount_t *mp,
1114 blkmap_t *blkmap)
1115 {
1116 xfs_attr_leaf_name_remote_t *remotep;
1117 char* value;
1118
1119 remotep = xfs_attr3_leaf_name_remote(leaf, i);
1120
1121 if (remotep->namelen == 0 || namecheck((char *)&remotep->name[0],
1122 remotep->namelen) ||
1123 be32_to_cpu(entry->hashval) !=
1124 libxfs_da_hashname((unsigned char *)&remotep->name[0],
1125 remotep->namelen) ||
1126 be32_to_cpu(entry->hashval) < last_hashval ||
1127 be32_to_cpu(remotep->valueblk) == 0) {
1128 do_warn(
1129 _("inconsistent remote attribute entry %d in attr block %u, ino %" PRIu64 "\n"), i, da_bno, ino);
1130 return -1;
1131 }
1132
1133 if (!(entry->flags & XFS_ATTR_ROOT))
1134 goto out;
1135
1136 value = malloc(be32_to_cpu(remotep->valuelen));
1137 if (value == NULL) {
1138 do_warn(
1139 _("cannot malloc enough for remotevalue attribute for inode %" PRIu64 "\n"),
1140 ino);
1141 do_warn(_("SKIPPING this remote attribute\n"));
1142 goto out;
1143 }
1144 if (rmtval_get(mp, ino, blkmap, be32_to_cpu(remotep->valueblk),
1145 be32_to_cpu(remotep->valuelen), value)) {
1146 do_warn(
1147 _("remote attribute get failed for entry %d, inode %" PRIu64 "\n"),
1148 i, ino);
1149 goto bad_free_out;
1150 }
1151 if (valuecheck(mp, (char *)&remotep->name[0], value, remotep->namelen,
1152 be32_to_cpu(remotep->valuelen))) {
1153 do_warn(
1154 _("remote attribute value check failed for entry %d, inode %" PRIu64 "\n"),
1155 i, ino);
1156 goto bad_free_out;
1157 }
1158 free(value);
1159 out:
1160 return xfs_attr_leaf_entsize_remote(remotep->namelen);
1161
1162 bad_free_out:
1163 free(value);
1164 return -1;
1165 }
1166
1167 static int
1168 process_leaf_attr_block(
1169 xfs_mount_t *mp,
1170 xfs_attr_leafblock_t *leaf,
1171 xfs_dablk_t da_bno,
1172 xfs_ino_t ino,
1173 blkmap_t *blkmap,
1174 xfs_dahash_t last_hashval,
1175 xfs_dahash_t *current_hashval,
1176 int *repair)
1177 {
1178 xfs_attr_leaf_entry_t *entry;
1179 int i, start, stop, clearit, usedbs, firstb, thissize;
1180 da_freemap_t *attr_freemap;
1181 struct xfs_attr3_icleaf_hdr leafhdr;
1182
1183 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
1184 clearit = usedbs = 0;
1185 firstb = mp->m_sb.sb_blocksize;
1186 stop = xfs_attr3_leaf_hdr_size(leaf);
1187
1188 /* does the count look sorta valid? */
1189 if (leafhdr.count * sizeof(xfs_attr_leaf_entry_t) + stop >
1190 mp->m_sb.sb_blocksize) {
1191 do_warn(
1192 _("bad attribute count %d in attr block %u, inode %" PRIu64 "\n"),
1193 leafhdr.count, da_bno, ino);
1194 return 1;
1195 }
1196
1197 attr_freemap = alloc_da_freemap(mp);
1198 (void) set_da_freemap(mp, attr_freemap, 0, stop);
1199
1200 /* go thru each entry checking for problems */
1201 for (i = 0, entry = xfs_attr3_leaf_entryp(leaf);
1202 i < leafhdr.count; i++, entry++) {
1203
1204 /* check if index is within some boundary. */
1205 if (be16_to_cpu(entry->nameidx) > mp->m_sb.sb_blocksize) {
1206 do_warn(
1207 _("bad attribute nameidx %d in attr block %u, inode %" PRIu64 "\n"),
1208 be16_to_cpu(entry->nameidx), da_bno, ino);
1209 clearit = 1;
1210 break;
1211 }
1212
1213 if (entry->flags & XFS_ATTR_INCOMPLETE) {
1214 /* we are inconsistent state. get rid of us */
1215 do_warn(
1216 _("attribute entry #%d in attr block %u, inode %" PRIu64 " is INCOMPLETE\n"),
1217 i, da_bno, ino);
1218 clearit = 1;
1219 break;
1220 }
1221
1222 /* mark the entry used */
1223 start = (intptr_t)entry - (intptr_t)leaf;
1224 stop = start + sizeof(xfs_attr_leaf_entry_t);
1225 if (set_da_freemap(mp, attr_freemap, start, stop)) {
1226 do_warn(
1227 _("attribute entry %d in attr block %u, inode %" PRIu64 " claims already used space\n"),
1228 i, da_bno, ino);
1229 clearit = 1;
1230 break; /* got an overlap */
1231 }
1232
1233 if (entry->flags & XFS_ATTR_LOCAL)
1234 thissize = process_leaf_attr_local(mp, leaf, i, entry,
1235 last_hashval, da_bno, ino);
1236 else
1237 thissize = process_leaf_attr_remote(leaf, i, entry,
1238 last_hashval, da_bno, ino,
1239 mp, blkmap);
1240 if (thissize < 0) {
1241 clearit = 1;
1242 break;
1243 }
1244
1245 *current_hashval = last_hashval = be32_to_cpu(entry->hashval);
1246
1247 if (set_da_freemap(mp, attr_freemap, be16_to_cpu(entry->nameidx),
1248 be16_to_cpu(entry->nameidx) + thissize)) {
1249 do_warn(
1250 _("attribute entry %d in attr block %u, inode %" PRIu64 " claims used space\n"),
1251 i, da_bno, ino);
1252 clearit = 1;
1253 break; /* got an overlap */
1254 }
1255 usedbs += thissize;
1256 if (be16_to_cpu(entry->nameidx) < firstb)
1257 firstb = be16_to_cpu(entry->nameidx);
1258
1259 } /* end the loop */
1260
1261 if (!clearit) {
1262 /* verify the header information is correct */
1263
1264 /* if the holes flag is set, don't reset first_used unless it's
1265 * pointing to used bytes. we're being conservative here
1266 * since the block will get compacted anyhow by the kernel.
1267 */
1268
1269 if ((leafhdr.holes == 0 &&
1270 firstb != leafhdr.firstused) ||
1271 leafhdr.firstused > firstb) {
1272 if (!no_modify) {
1273 do_warn(
1274 _("- resetting first used heap value from %d to %d in "
1275 "block %u of attribute fork of inode %" PRIu64 "\n"),
1276 leafhdr.firstused,
1277 firstb, da_bno, ino);
1278 leafhdr.firstused = firstb;
1279 *repair = 1;
1280 } else {
1281 do_warn(
1282 _("- would reset first used value from %d to %d in "
1283 "block %u of attribute fork of inode %" PRIu64 "\n"),
1284 leafhdr.firstused,
1285 firstb, da_bno, ino);
1286 }
1287 }
1288
1289 if (usedbs != leafhdr.usedbytes) {
1290 if (!no_modify) {
1291 do_warn(
1292 _("- resetting usedbytes cnt from %d to %d in "
1293 "block %u of attribute fork of inode %" PRIu64 "\n"),
1294 leafhdr.usedbytes,
1295 usedbs, da_bno, ino);
1296 leafhdr.usedbytes = usedbs;
1297 *repair = 1;
1298 } else {
1299 do_warn(
1300 _("- would reset usedbytes cnt from %d to %d in "
1301 "block %u of attribute fork of %" PRIu64 "\n"),
1302 leafhdr.usedbytes,
1303 usedbs, da_bno, ino);
1304 }
1305 }
1306
1307 /* there's a lot of work in process_leaf_dir_block to go thru
1308 * checking for holes and compacting if appropiate. I don't think
1309 * attributes need all that, so let's just leave the holes. If
1310 * we discover later that this is a good place to do compaction
1311 * we can add it then.
1312 */
1313 }
1314 /*
1315 * If we're just going to zap the block, don't pretend like we
1316 * repaired it, because repairing the block stops the clear
1317 * operation.
1318 */
1319 if (clearit)
1320 *repair = 0;
1321 if (*repair)
1322 xfs_attr3_leaf_hdr_to_disk(mp->m_attr_geo, leaf, &leafhdr);
1323
1324 free(attr_freemap);
1325 return (clearit); /* and repair */
1326 }
1327
1328
1329 /*
1330 * returns 0 if the attribute fork is ok, 1 if it has to be junked.
1331 */
1332 static int
1333 process_leaf_attr_level(xfs_mount_t *mp,
1334 da_bt_cursor_t *da_cursor)
1335 {
1336 int repair;
1337 xfs_attr_leafblock_t *leaf;
1338 xfs_buf_t *bp;
1339 xfs_ino_t ino;
1340 xfs_fsblock_t dev_bno;
1341 xfs_dablk_t da_bno;
1342 xfs_dablk_t prev_bno;
1343 xfs_dahash_t current_hashval = 0;
1344 xfs_dahash_t greatest_hashval;
1345 struct xfs_attr3_icleaf_hdr leafhdr;
1346
1347 da_bno = da_cursor->level[0].bno;
1348 ino = da_cursor->ino;
1349 prev_bno = 0;
1350
1351 do {
1352 repair = 0;
1353 dev_bno = blkmap_get(da_cursor->blkmap, da_bno);
1354 /*
1355 * 0 is the root block and no block
1356 * pointer can point to the root block of the btree
1357 */
1358 ASSERT(da_bno != 0);
1359
1360 if (dev_bno == NULLFSBLOCK) {
1361 do_warn(
1362 _("can't map block %u for attribute fork for inode %" PRIu64 "\n"),
1363 da_bno, ino);
1364 goto error_out;
1365 }
1366
1367 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dev_bno),
1368 XFS_FSB_TO_BB(mp, 1), 0,
1369 &xfs_attr3_leaf_buf_ops);
1370 if (!bp) {
1371 do_warn(
1372 _("can't read file block %u (fsbno %" PRIu64 ") for attribute fork of inode %" PRIu64 "\n"),
1373 da_bno, dev_bno, ino);
1374 goto error_out;
1375 }
1376 if (bp->b_error == -EFSBADCRC)
1377 repair++;
1378
1379 leaf = bp->b_addr;
1380 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
1381
1382 /* check magic number for leaf directory btree block */
1383 if (!(leafhdr.magic == XFS_ATTR_LEAF_MAGIC ||
1384 leafhdr.magic == XFS_ATTR3_LEAF_MAGIC)) {
1385 do_warn(
1386 _("bad attribute leaf magic %#x for inode %" PRIu64 "\n"),
1387 leafhdr.magic, ino);
1388 libxfs_putbuf(bp);
1389 goto error_out;
1390 }
1391
1392 /*
1393 * for each block, process the block, verify its path,
1394 * then get next block. update cursor values along the way
1395 */
1396 if (process_leaf_attr_block(mp, leaf, da_bno, ino,
1397 da_cursor->blkmap, current_hashval,
1398 &greatest_hashval, &repair)) {
1399 libxfs_putbuf(bp);
1400 goto error_out;
1401 }
1402
1403 /*
1404 * index can be set to hdr.count so match the
1405 * indexes of the interior blocks -- which at the
1406 * end of the block will point to 1 after the final
1407 * real entry in the block
1408 */
1409 da_cursor->level[0].hashval = greatest_hashval;
1410 da_cursor->level[0].bp = bp;
1411 da_cursor->level[0].bno = da_bno;
1412 da_cursor->level[0].index = leafhdr.count;
1413 da_cursor->level[0].dirty = repair;
1414
1415 if (leafhdr.back != prev_bno) {
1416 do_warn(
1417 _("bad sibling back pointer for block %u in attribute fork for inode %" PRIu64 "\n"),
1418 da_bno, ino);
1419 libxfs_putbuf(bp);
1420 goto error_out;
1421 }
1422
1423 prev_bno = da_bno;
1424 da_bno = leafhdr.forw;
1425
1426 if (da_bno != 0 && verify_da_path(mp, da_cursor, 0)) {
1427 libxfs_putbuf(bp);
1428 goto error_out;
1429 }
1430
1431 current_hashval = greatest_hashval;
1432
1433 if (repair && !no_modify)
1434 libxfs_writebuf(bp, 0);
1435 else
1436 libxfs_putbuf(bp);
1437 } while (da_bno != 0);
1438
1439 if (verify_final_da_path(mp, da_cursor, 0)) {
1440 /*
1441 * verify the final path up (right-hand-side) if still ok
1442 */
1443 do_warn(
1444 _("bad hash path in attribute fork for inode %" PRIu64 "\n"),
1445 da_cursor->ino);
1446 goto error_out;
1447 }
1448
1449 /* releases all buffers holding interior btree blocks */
1450 release_da_cursor(mp, da_cursor, 0);
1451 return(0);
1452
1453 error_out:
1454 /* release all buffers holding interior btree blocks */
1455 err_release_da_cursor(mp, da_cursor, 0);
1456 return(1);
1457 }
1458
1459
1460 /*
1461 * a node directory is a true btree -- where the attribute fork
1462 * has gotten big enough that it is represented as a non-trivial (e.g.
1463 * has more than just a block) btree.
1464 *
1465 * Note that if we run into any problems, we will trash the attribute fork.
1466 *
1467 * returns 0 if things are ok, 1 if bad
1468 * Note this code has been based off process_node_dir.
1469 */
1470 static int
1471 process_node_attr(
1472 xfs_mount_t *mp,
1473 xfs_ino_t ino,
1474 xfs_dinode_t *dip,
1475 blkmap_t *blkmap)
1476 {
1477 xfs_dablk_t bno;
1478 int error = 0;
1479 da_bt_cursor_t da_cursor;
1480
1481 /*
1482 * try again -- traverse down left-side of tree until we hit
1483 * the left-most leaf block setting up the btree cursor along
1484 * the way. Then walk the leaf blocks left-to-right, calling
1485 * a parent-verification routine each time we traverse a block.
1486 */
1487 memset(&da_cursor, 0, sizeof(da_bt_cursor_t));
1488 da_cursor.active = 0;
1489 da_cursor.type = 0;
1490 da_cursor.ino = ino;
1491 da_cursor.dip = dip;
1492 da_cursor.greatest_bno = 0;
1493 da_cursor.blkmap = blkmap;
1494
1495 /*
1496 * now process interior node. don't have any buffers held in this path.
1497 */
1498 error = traverse_int_dablock(mp, &da_cursor, &bno, XFS_ATTR_FORK);
1499 if (error == 0)
1500 return(1); /* 0 means unsuccessful */
1501
1502 /*
1503 * now pass cursor and bno into leaf-block processing routine
1504 * the leaf dir level routine checks the interior paths
1505 * up to the root including the final right-most path.
1506 */
1507
1508 return (process_leaf_attr_level(mp, &da_cursor));
1509 }
1510
1511 /*
1512 * Start processing for a leaf or fuller btree.
1513 * A leaf directory is one where the attribute fork is too big for
1514 * the inode but is small enough to fit into one btree block
1515 * outside the inode. This code is modelled after process_leaf_dir_block.
1516 *
1517 * returns 0 if things are ok, 1 if bad (attributes needs to be junked)
1518 * repair is set, if anything was changed, but attributes can live thru it
1519 */
1520 static int
1521 process_longform_attr(
1522 xfs_mount_t *mp,
1523 xfs_ino_t ino,
1524 xfs_dinode_t *dip,
1525 blkmap_t *blkmap,
1526 int *repair) /* out - 1 if something was fixed */
1527 {
1528 xfs_attr_leafblock_t *leaf;
1529 xfs_fsblock_t bno;
1530 xfs_buf_t *bp;
1531 xfs_dahash_t next_hashval;
1532 int repairlinks = 0;
1533 struct xfs_attr3_icleaf_hdr leafhdr;
1534 int error;
1535
1536 *repair = 0;
1537
1538 bno = blkmap_get(blkmap, 0);
1539
1540 if ( bno == NULLFSBLOCK ) {
1541 if (dip->di_aformat == XFS_DINODE_FMT_EXTENTS &&
1542 be16_to_cpu(dip->di_anextents) == 0)
1543 return(0); /* the kernel can handle this state */
1544 do_warn(
1545 _("block 0 of inode %" PRIu64 " attribute fork is missing\n"),
1546 ino);
1547 return(1);
1548 }
1549 /* FIX FOR bug 653709 -- EKN */
1550 if (mp->m_sb.sb_agcount < XFS_FSB_TO_AGNO(mp, bno)) {
1551 do_warn(
1552 _("agno of attribute fork of inode %" PRIu64 " out of regular partition\n"), ino);
1553 return(1);
1554 }
1555
1556 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
1557 XFS_FSB_TO_BB(mp, 1), 0, &xfs_da3_node_buf_ops);
1558 if (!bp) {
1559 do_warn(
1560 _("can't read block 0 of inode %" PRIu64 " attribute fork\n"),
1561 ino);
1562 return(1);
1563 }
1564 if (bp->b_error == -EFSBADCRC)
1565 (*repair)++;
1566
1567 /* verify leaf block */
1568 leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp);
1569 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
1570
1571 /* check sibling pointers in leaf block or root block 0 before
1572 * we have to release the btree block
1573 */
1574 if (leafhdr.forw != 0 || leafhdr.back != 0) {
1575 if (!no_modify) {
1576 do_warn(
1577 _("clearing forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"),
1578 ino);
1579 repairlinks = 1;
1580 leafhdr.forw = 0;
1581 leafhdr.back = 0;
1582 xfs_attr3_leaf_hdr_to_disk(mp->m_attr_geo,
1583 leaf, &leafhdr);
1584 } else {
1585 do_warn(
1586 _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino);
1587 }
1588 }
1589
1590 /*
1591 * use magic number to tell us what type of attribute this is.
1592 * it's possible to have a node or leaf attribute in either an
1593 * extent format or btree format attribute fork.
1594 */
1595 switch (leafhdr.magic) {
1596 case XFS_ATTR_LEAF_MAGIC: /* leaf-form attribute */
1597 case XFS_ATTR3_LEAF_MAGIC:
1598 if (process_leaf_attr_block(mp, leaf, 0, ino, blkmap,
1599 0, &next_hashval, repair)) {
1600 *repair = 0;
1601 /* the block is bad. lose the attribute fork. */
1602 libxfs_putbuf(bp);
1603 return(1);
1604 }
1605 *repair = *repair || repairlinks;
1606 break;
1607
1608 case XFS_DA_NODE_MAGIC: /* btree-form attribute */
1609 case XFS_DA3_NODE_MAGIC:
1610 /* must do this now, to release block 0 before the traversal */
1611 if ((*repair || repairlinks) && !no_modify) {
1612 *repair = 1;
1613 libxfs_writebuf(bp, 0);
1614 } else
1615 libxfs_putbuf(bp);
1616 error = process_node_attr(mp, ino, dip, blkmap); /* + repair */
1617 if (error)
1618 *repair = 0;
1619 return error;
1620 default:
1621 do_warn(
1622 _("bad attribute leaf magic # %#x for dir ino %" PRIu64 "\n"),
1623 be16_to_cpu(leaf->hdr.info.magic), ino);
1624 libxfs_putbuf(bp);
1625 *repair = 0;
1626 return(1);
1627 }
1628
1629 if (*repair && !no_modify)
1630 libxfs_writebuf(bp, 0);
1631 else
1632 libxfs_putbuf(bp);
1633
1634 return(0); /* repair may be set */
1635 }
1636
1637
1638 static int
1639 xfs_acl_from_disk(
1640 struct xfs_mount *mp,
1641 struct xfs_icacl **aclp,
1642 struct xfs_acl *dacl)
1643 {
1644 struct xfs_icacl *acl;
1645 struct xfs_icacl_entry *ace;
1646 struct xfs_acl_entry *dace;
1647 int count;
1648 int i;
1649
1650 count = be32_to_cpu(dacl->acl_cnt);
1651 if (count > XFS_ACL_MAX_ENTRIES(mp)) {
1652 do_warn(_("Too many ACL entries, count %d\n"), count);
1653 *aclp = NULL;
1654 return EINVAL;
1655 }
1656
1657
1658 acl = malloc(sizeof(struct xfs_icacl) +
1659 count * sizeof(struct xfs_icacl_entry));
1660 if (!acl) {
1661 do_warn(_("cannot malloc enough for ACL attribute\n"));
1662 do_warn(_("SKIPPING this ACL\n"));
1663 *aclp = NULL;
1664 return ENOMEM;
1665 }
1666
1667 acl->acl_cnt = count;
1668 for (i = 0; i < count; i++) {
1669 ace = &acl->acl_entry[i];
1670 dace = &dacl->acl_entry[i];
1671
1672 ace->ae_tag = be32_to_cpu(dace->ae_tag);
1673 ace->ae_id = be32_to_cpu(dace->ae_id);
1674 ace->ae_perm = be16_to_cpu(dace->ae_perm);
1675 }
1676
1677 *aclp = acl;
1678 return 0;
1679 }
1680
1681 /*
1682 * returns 1 if attributes got cleared
1683 * and 0 if things are ok.
1684 */
1685 int
1686 process_attributes(
1687 xfs_mount_t *mp,
1688 xfs_ino_t ino,
1689 xfs_dinode_t *dip,
1690 blkmap_t *blkmap,
1691 int *repair) /* returned if we did repair */
1692 {
1693 int err;
1694 __u8 aformat = dip->di_aformat;
1695 #ifdef DEBUG
1696 xfs_attr_shortform_t *asf;
1697
1698 asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip);
1699 #endif
1700
1701 if (aformat == XFS_DINODE_FMT_LOCAL) {
1702 ASSERT(be16_to_cpu(asf->hdr.totsize) <=
1703 XFS_DFORK_ASIZE(dip, mp));
1704 err = process_shortform_attr(mp, ino, dip, repair);
1705 } else if (aformat == XFS_DINODE_FMT_EXTENTS ||
1706 aformat == XFS_DINODE_FMT_BTREE) {
1707 err = process_longform_attr(mp, ino, dip, blkmap,
1708 repair);
1709 /* if err, convert this to shortform and clear it */
1710 /* if repair and no error, it's taken care of */
1711 } else {
1712 do_warn(_("illegal attribute format %d, ino %" PRIu64 "\n"),
1713 aformat, ino);
1714 err = 1;
1715 }
1716 return (err); /* and repair */
1717 }
1718
1719 /*
1720 * Validate an ACL
1721 */
1722 static int
1723 xfs_acl_valid(
1724 struct xfs_mount *mp,
1725 struct xfs_acl *daclp)
1726 {
1727 struct xfs_icacl *aclp = NULL;
1728 struct xfs_icacl_entry *entry, *e;
1729 int user = 0, group = 0, other = 0, mask = 0, mask_required = 0;
1730 int i, j;
1731
1732 if (daclp == NULL)
1733 goto acl_invalid;
1734
1735 switch (xfs_acl_from_disk(mp, &aclp, daclp)) {
1736 case ENOMEM:
1737 return 0;
1738 case EINVAL:
1739 goto acl_invalid;
1740 default:
1741 break;
1742 }
1743
1744 for (i = 0; i < aclp->acl_cnt; i++) {
1745 entry = &aclp->acl_entry[i];
1746 if (entry->ae_perm & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
1747 goto acl_invalid;
1748 switch (entry->ae_tag) {
1749 case ACL_USER_OBJ:
1750 if (user++)
1751 goto acl_invalid;
1752 break;
1753 case ACL_GROUP_OBJ:
1754 if (group++)
1755 goto acl_invalid;
1756 break;
1757 case ACL_OTHER:
1758 if (other++)
1759 goto acl_invalid;
1760 break;
1761 case ACL_USER:
1762 case ACL_GROUP:
1763 for (j = i + 1; j < aclp->acl_cnt; j++) {
1764 e = &aclp->acl_entry[j];
1765 if (e->ae_id == entry->ae_id &&
1766 e->ae_tag == entry->ae_tag)
1767 goto acl_invalid;
1768 }
1769 mask_required++;
1770 break;
1771 case ACL_MASK:
1772 if (mask++)
1773 goto acl_invalid;
1774 break;
1775 default:
1776 goto acl_invalid;
1777 }
1778 }
1779 if (!user || !group || !other || (mask_required && !mask))
1780 goto acl_invalid;
1781 free(aclp);
1782 return 0;
1783 acl_invalid:
1784 free(aclp);
1785 errno = EINVAL;
1786 return (-1);
1787 }
1788
1789 /*
1790 * Check a category or division set to ensure that all values are in
1791 * ascending order and each division or category appears only once.
1792 */
1793 static int
1794 __check_setvalue(const unsigned short *list, unsigned short count)
1795 {
1796 unsigned short i;
1797
1798 for (i = 1; i < count ; i++)
1799 if (list[i] <= list[i-1])
1800 return -1;
1801 return 0;
1802 }
1803
1804 /*
1805 * xfs_mac_valid(lp)
1806 * Check the validity of a MAC label.
1807 */
1808 static int
1809 xfs_mac_valid(xfs_mac_label_t *lp)
1810 {
1811 if (lp == NULL)
1812 return (0);
1813
1814 /*
1815 * if the total category set and division set is greater than 250
1816 * report error
1817 */
1818 if ((lp->ml_catcount + lp->ml_divcount) > XFS_MAC_MAX_SETS)
1819 return(0);
1820
1821 /*
1822 * check whether the msentype value is valid, and do they have
1823 * appropriate level, category association.
1824 */
1825 switch (lp->ml_msen_type) {
1826 case XFS_MSEN_ADMIN_LABEL:
1827 case XFS_MSEN_EQUAL_LABEL:
1828 case XFS_MSEN_HIGH_LABEL:
1829 case XFS_MSEN_MLD_HIGH_LABEL:
1830 case XFS_MSEN_LOW_LABEL:
1831 case XFS_MSEN_MLD_LOW_LABEL:
1832 if (lp->ml_level != 0 || lp->ml_catcount > 0 )
1833 return (0);
1834 break;
1835 case XFS_MSEN_TCSEC_LABEL:
1836 case XFS_MSEN_MLD_LABEL:
1837 if (lp->ml_catcount > 0 &&
1838 __check_setvalue(lp->ml_list,
1839 lp->ml_catcount) == -1)
1840 return (0);
1841 break;
1842 case XFS_MSEN_UNKNOWN_LABEL:
1843 default:
1844 return (0);
1845 }
1846
1847 /*
1848 * check whether the minttype value is valid, and do they have
1849 * appropriate grade, division association.
1850 */
1851 switch (lp->ml_mint_type) {
1852 case XFS_MINT_BIBA_LABEL:
1853 if (lp->ml_divcount > 0 &&
1854 __check_setvalue(lp->ml_list + lp->ml_catcount,
1855 lp->ml_divcount) == -1)
1856 return(0);
1857 break;
1858 case XFS_MINT_EQUAL_LABEL:
1859 case XFS_MINT_HIGH_LABEL:
1860 case XFS_MINT_LOW_LABEL:
1861 if (lp->ml_grade != 0 || lp->ml_divcount > 0 )
1862 return(0);
1863 break;
1864 default:
1865 return(0);
1866 }
1867
1868 return (1);
1869 }