2 * Copyright (c) 2000-2002,2004-2005 Silicon Graphics, Inc.
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.
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.
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
21 #include "err_protos.h"
22 #include "attr_repair.h"
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
);
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.
37 #define XR_DA_LEAF_MAPSIZE XFS_ATTR_LEAF_MAPSIZE
39 typedef unsigned char da_freemap_t
;
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.
60 typedef struct da_level_state
{
61 xfs_buf_t
*bp
; /* block bp */
63 xfs_da_intnode_t
*n
; /* bp data */
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) */
71 typedef struct da_bt_cursor
{
72 int active
; /* highest level in tree (# levels-1) */
73 int type
; /* 0 if dir, 1 if attr */
75 xfs_dablk_t greatest_bno
;
77 da_level_state_t level
[XFS_DA_NODE_MAXDEPTH
];
78 struct blkmap
*blkmap
;
83 * Allocate a freespace map for directory or attr leaf blocks (1 bit per byte)
84 * 1 == used, 0 == free.
87 alloc_da_freemap(struct xfs_mount
*mp
)
89 return calloc(1, mp
->m_sb
.sb_blocksize
/ NBBY
);
93 * Set the he range [start, stop) in the directory freemap.
95 * Returns 1 if there is a conflict or 0 if everything's good.
97 * Within a char, the lowest bit of the char represents the byte with
98 * the smallest address
101 set_da_freemap(xfs_mount_t
*mp
, da_freemap_t
*map
, int start
, int stop
)
103 const da_freemap_t mask
= 0x1;
108 * allow == relation since [x, x) claims 1 byte
110 do_warn(_("bad range claimed [%d, %d) in da block\n"),
115 if (stop
> mp
->m_sb
.sb_blocksize
) {
117 _("byte range end [%d %d) in da block larger than blocksize %d\n"),
118 start
, stop
, mp
->m_sb
.sb_blocksize
);
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
);
127 map
[i
/ NBBY
] |= (mask
<< i
% NBBY
);
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,
140 traverse_int_dablock(xfs_mount_t
*mp
,
141 da_bt_cursor_t
*da_cursor
,
147 xfs_da_intnode_t
*node
;
150 struct xfs_da_node_entry
*btree
;
151 struct xfs_da3_icnode_hdr nodehdr
;
154 * traverse down left-side of tree until we hit the
155 * left-most leaf block setting up the btree cursor along
161 da_cursor
->active
= 0;
165 * read in each block along the way and set up cursor
167 fsbno
= blkmap_get(da_cursor
->blkmap
, bno
);
169 if (fsbno
== NULLFSBLOCK
)
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
);
175 if (whichfork
== XFS_DATA_FORK
)
177 _("can't read block %u (fsbno %" PRIu64
") for directory inode %" PRIu64
"\n"),
178 bno
, fsbno
, da_cursor
->ino
);
181 _("can't read block %u (fsbno %" PRIu64
") for attrbute fork of inode %" PRIu64
"\n"),
182 bno
, fsbno
, da_cursor
->ino
);
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
);
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
);
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"),
204 mp
->m_attr_geo
->node_ents
);
210 * maintain level counter
213 i
= da_cursor
->active
= nodehdr
.level
;
215 if (nodehdr
.level
== i
- 1) {
218 if (whichfork
== XFS_DATA_FORK
)
219 do_warn(_("bad directory btree for "
220 "directory inode %" PRIu64
"\n"),
223 do_warn(_("bad attribute fork btree "
224 "for inode %" PRIu64
"\n"),
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;
236 da_cursor
->level
[i
].n
= XFS_BUF_TO_DA_INTNODE(bp
);
240 * set up new bno for next level down
242 bno
= be32_to_cpu(btree
[0].before
);
243 } while (node
!= NULL
&& i
> 1);
246 * now return block number and get out
248 *rbno
= da_cursor
->level
[0].bno
= bno
;
252 while (i
> 1 && i
<= da_cursor
->active
) {
253 libxfs_putbuf(da_cursor
->level
[i
].bp
);
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.
267 release_da_cursor_int(xfs_mount_t
*mp
,
268 da_bt_cursor_t
*cursor
,
272 int level
= prev_level
+ 1;
274 if (cursor
->level
[level
].bp
!= NULL
) {
276 do_warn(_("release_da_cursor_int got unexpected "
277 "non-null bp, dabno = %u\n"),
278 cursor
->level
[level
].bno
);
282 libxfs_putbuf(cursor
->level
[level
].bp
);
283 cursor
->level
[level
].bp
= NULL
;
286 if (level
< cursor
->active
)
287 release_da_cursor_int(mp
, cursor
, level
, error
);
293 release_da_cursor(xfs_mount_t
*mp
,
294 da_bt_cursor_t
*cursor
,
297 release_da_cursor_int(mp
, cursor
, prev_level
, 0);
301 err_release_da_cursor(xfs_mount_t
*mp
,
302 da_bt_cursor_t
*cursor
,
305 release_da_cursor_int(mp
, cursor
, prev_level
, 1);
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().
317 verify_final_da_path(xfs_mount_t
*mp
,
318 da_bt_cursor_t
*cursor
,
321 xfs_da_intnode_t
*node
;
322 xfs_dahash_t hashval
;
325 int this_level
= p_level
+ 1;
326 struct xfs_da_node_entry
*btree
;
327 struct xfs_da3_icnode_hdr nodehdr
;
330 fprintf(stderr
, "in verify_final_da_path, this_level = %d\n",
334 * the index should point to the next "unprocessed" entry
335 * in the block which should be the final (rightmost) entry
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
);
343 * check internal block consistency on this level -- ensure
344 * that all entries are used, encountered and expected hashvals
347 if (entry
!= nodehdr
.count
- 1) {
348 do_warn(_("directory/attribute block used/count "
349 "inconsistency - %d/%hu\n"),
350 entry
, nodehdr
.count
);
354 * hash values monotonically increasing ???
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
));
364 if (nodehdr
.forw
!= 0) {
365 do_warn(_("bad directory/attribute forward block pointer, "
366 "expected 0, saw %u\n"),
371 do_warn(_("bad directory block in dir ino %" PRIu64
"\n"),
376 * keep track of greatest block # -- that gets
377 * us the length of the directory
379 if (cursor
->level
[this_level
].bno
> cursor
->greatest_bno
)
380 cursor
->greatest_bno
= cursor
->level
[this_level
].bno
;
383 * ok, now check descendant block number against this level
385 if (cursor
->level
[p_level
].bno
!= be32_to_cpu(btree
[entry
].before
)) {
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");
397 if (cursor
->level
[p_level
].hashval
!= be32_to_cpu(btree
[entry
].hashval
)) {
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
++;
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
);
415 * Note: squirrel hashval away _before_ releasing the
416 * buffer, preventing a use-after-free problem.
418 hashval
= be32_to_cpu(btree
[entry
].hashval
);
421 * release/write buffer
423 ASSERT(cursor
->level
[this_level
].dirty
== 0 ||
424 (cursor
->level
[this_level
].dirty
&& !no_modify
));
426 if (cursor
->level
[this_level
].dirty
&& !no_modify
)
427 libxfs_writebuf(cursor
->level
[this_level
].bp
, 0);
429 libxfs_putbuf(cursor
->level
[this_level
].bp
);
431 cursor
->level
[this_level
].bp
= NULL
;
434 * bail out if this is the root block (top of tree)
436 if (this_level
>= cursor
->active
) {
438 fprintf(stderr
, "verify_final_da_path returns 0 (ok)\n");
443 * set hashvalue to correctly reflect the now-validated
444 * last entry in this block and continue upwards validation
446 cursor
->level
[this_level
].hashval
= hashval
;
447 return(verify_final_da_path(mp
, cursor
, this_level
));
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
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.
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.
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.
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.
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.
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.
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
490 verify_da_path(xfs_mount_t
*mp
,
491 da_bt_cursor_t
*cursor
,
494 xfs_da_intnode_t
*node
;
495 xfs_da_intnode_t
*newnode
;
501 int this_level
= p_level
+ 1;
502 struct xfs_da_node_entry
*btree
;
503 struct xfs_da3_icnode_hdr nodehdr
;
506 * index is currently set to point to the entry that
507 * should be processed now in this level.
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
);
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
519 if (entry
>= nodehdr
.count
) {
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.
525 cursor
->level
[this_level
].hashval
=
526 be32_to_cpu(btree
[entry
- 1].hashval
);
529 * keep track of greatest block # -- that gets
530 * us the length of the directory
532 if (cursor
->level
[this_level
].bno
> cursor
->greatest_bno
)
533 cursor
->greatest_bno
= cursor
->level
[this_level
].bno
;
536 * validate the path for the current used-up block
539 if (verify_da_path(mp
, cursor
, this_level
))
542 * ok, now get the next buffer and check sibling pointers
544 dabno
= nodehdr
.forw
;
546 fsbno
= blkmap_get(cursor
->blkmap
, dabno
);
548 if (fsbno
== NULLFSBLOCK
) {
549 do_warn(_("can't get map info for block %u "
550 "of directory inode %" PRIu64
"\n"),
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
);
559 _("can't read block %u (%" PRIu64
") for directory inode %" PRIu64
"\n"),
560 dabno
, fsbno
, cursor
->ino
);
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
);
569 * verify magic number and back pointer, sanity-check
570 * entry count, verify level
573 if (nodehdr
.magic
!= XFS_DA_NODE_MAGIC
&&
574 nodehdr
.magic
!= XFS_DA3_NODE_MAGIC
) {
576 _("bad magic number %x in block %u (%" PRIu64
") for directory inode %" PRIu64
"\n"),
578 dabno
, fsbno
, cursor
->ino
);
581 if (nodehdr
.back
!= cursor
->level
[this_level
].bno
) {
583 _("bad back pointer in block %u (%"PRIu64
") for directory inode %" PRIu64
"\n"),
584 dabno
, fsbno
, cursor
->ino
);
587 if (nodehdr
.count
> mp
->m_attr_geo
->node_ents
) {
589 _("entry count %d too large in block %u (%" PRIu64
") for directory inode %" PRIu64
"\n"),
591 dabno
, fsbno
, cursor
->ino
);
594 if (nodehdr
.level
!= this_level
) {
596 _("bad level %d in block %u (%" PRIu64
") for directory inode %" PRIu64
"\n"),
598 dabno
, fsbno
, cursor
->ino
);
603 fprintf(stderr
, "verify_da_path returns 1 (bad) #4\n");
610 * update cursor, write out the *current* level if
611 * required. don't write out the descendant level
613 ASSERT(cursor
->level
[this_level
].dirty
== 0 ||
614 (cursor
->level
[this_level
].dirty
&& !no_modify
));
616 if (cursor
->level
[this_level
].dirty
&& !no_modify
)
617 libxfs_writebuf(cursor
->level
[this_level
].bp
, 0);
619 libxfs_putbuf(cursor
->level
[this_level
].bp
);
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
);
628 cursor
->level
[this_level
].n
= newnode
;
630 entry
= cursor
->level
[this_level
].index
= 0;
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.
637 if (bp
->b_error
== -EFSBADCRC
&& !no_modify
)
638 cursor
->level
[this_level
].dirty
++;
641 * ditto for block numbers
643 if (cursor
->level
[p_level
].bno
!= be32_to_cpu(btree
[entry
].before
)) {
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");
655 * ok, now validate last hashvalue in the descendant
656 * block against the hashval in the current entry
658 if (cursor
->level
[p_level
].hashval
!=
659 be32_to_cpu(btree
[entry
].hashval
)) {
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
++;
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
);
676 * increment index for this level to point to next entry
677 * (which should point to the next descendant block)
679 cursor
->level
[this_level
].index
++;
681 fprintf(stderr
, "verify_da_path returns 0 (ok)\n");
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.
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
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.
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.
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
739 struct xfs_mount
*mp
,
745 /* for proper alignment issues, get the structs and memmove the values */
746 xfs_mac_label_t macl
;
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)) {
755 valuep
= malloc(valuelen
);
757 do_error(_("No memory for ACL check!\n"));
758 memcpy(valuep
, namevalue
+ namelen
, valuelen
);
762 if (xfs_acl_valid(mp
, valuep
) != 0) {
765 _("entry contains illegal value in attribute named SGI_ACL_FILE "
766 "or SGI_ACL_DEFAULT\n"));
772 } else if (strncmp(namevalue
, SGI_MAC_FILE
, SGI_MAC_FILE_SIZE
) == 0) {
774 memset(&macl
, 0, sizeof(xfs_mac_label_t
));
775 memmove(&macl
, namevalue
+namelen
, valuelen
);
780 if (xfs_mac_valid((xfs_mac_label_t
*)valuep
) != 1) { /* 1 is valid */
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!!
791 _("entry contains illegal value in attribute named SGI_MAC_LABEL\n"));
793 } else if (strncmp(namevalue
, SGI_CAP_FILE
, SGI_CAP_FILE_SIZE
) == 0) {
794 if ( valuelen
!= sizeof(xfs_cap_set_t
)) {
797 _("entry contains illegal value in attribute named SGI_CAP_FILE\n"));
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
813 process_shortform_attr(
814 struct xfs_mount
*mp
,
819 xfs_attr_shortform_t
*asf
;
820 xfs_attr_sf_entry_t
*currententry
, *nextentry
, *tempentry
;
822 int currentsize
, remainingspace
;
826 asf
= (xfs_attr_shortform_t
*) XFS_DFORK_APTR(dip
);
828 /* Assumption: hdr.totsize is less than a leaf block and was checked
829 * by lclinode for valid sizes. Check the count though.
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 */
837 _("there are no attributes in the fork for inode %" PRIu64
"\n"),
840 cpu_to_be16(sizeof(xfs_attr_sf_hdr_t
));
845 _("would junk the attribute fork since count is 0 for inode %" PRIu64
"\n"),
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
;
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 */
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,"));
868 _(" truncating attributes for inode %" PRIu64
" to %d\n"), ino
, i
);
870 break; /* and then update hdr fields */
873 _(" would truncate attributes for inode %" PRIu64
" to %d\n"), ino
, i
);
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
881 if (remainingspace
< currententry
->namelen
||
882 ((remainingspace
- currententry
->
883 namelen
) < currententry
->valuelen
)) {
885 _("name or value attribute lengths are too large,\n"));
888 _(" truncating attributes for inode %" PRIu64
" to %d\n"),
891 break; /* and then update hdr fields */
894 _(" would truncate attributes for inode %" PRIu64
" to %d\n"),
901 /* namecheck checks for / and null terminated for file names.
902 * attributes names currently follow the same rules.
904 if (namecheck((char *)¤tentry
->nameval
[0],
905 currententry
->namelen
)) {
907 _("entry contains illegal character in shortform attribute name\n"));
911 if (currententry
->flags
& XFS_ATTR_INCOMPLETE
) {
913 _("entry has INCOMPLETE flag on in shortform attribute\n"));
917 /* Only check values for root security attributes */
918 if (currententry
->flags
& XFS_ATTR_ROOT
)
919 junkit
|= valuecheck(mp
,
920 (char *)¤tentry
->nameval
[0],
921 NULL
, currententry
->namelen
,
922 currententry
->valuelen
);
924 remainingspace
= remainingspace
-
925 XFS_ATTR_SF_ENTSIZE(currententry
);
929 /* get rid of only this entry */
931 _("removing attribute entry %d for inode %" PRIu64
"\n"),
933 tempentry
= (xfs_attr_sf_entry_t
*)
934 ((intptr_t) currententry
+
935 XFS_ATTR_SF_ENTSIZE(currententry
));
936 memmove(currententry
,tempentry
,remainingspace
);
938 i
--; /* no worries, it will wrap back to 0 */
940 continue; /* go back up now */
943 _("would remove attribute entry %d for inode %" PRIu64
"\n"),
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
);
955 if (asf
->hdr
.count
!= i
) {
958 _("would have corrected attribute entry count in inode %" PRIu64
" from %d to %d\n"),
959 ino
, asf
->hdr
.count
, i
);
962 _("corrected attribute entry count in inode %" PRIu64
", was %d, now %d\n"),
963 ino
, asf
->hdr
.count
, i
);
969 /* ASSUMPTION: currentsize <= totsize */
970 if (be16_to_cpu(asf
->hdr
.totsize
) != currentsize
) {
973 _("would have corrected attribute totsize in inode %" PRIu64
" from %d to %d\n"),
974 ino
, be16_to_cpu(asf
->hdr
.totsize
),
978 _("corrected attribute entry totsize in inode %" PRIu64
", was %d, now %d\n"),
979 ino
, be16_to_cpu(asf
->hdr
.totsize
),
981 asf
->hdr
.totsize
= cpu_to_be16(currentsize
);
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.
995 rmtval_get(xfs_mount_t
*mp
, xfs_ino_t ino
, blkmap_t
*blkmap
,
996 xfs_dablk_t blocknum
, int valuelen
, char* value
)
1000 int clearit
= 0, i
= 0, length
= 0, amountdone
= 0;
1003 if (xfs_sb_version_hascrc(&mp
->m_sb
))
1004 hdrsize
= sizeof(struct xfs_attr3_rmt_hdr
);
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
) {
1012 _("remote block for attributes of inode %" PRIu64
" is missing\n"), ino
);
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
);
1021 _("can't read remote block for attributes of inode %" PRIu64
"\n"), ino
);
1026 if (bp
->b_error
== -EFSBADCRC
|| bp
->b_error
== -EFSCORRUPTED
) {
1028 _("Corrupt remote block for attributes of inode %" PRIu64
"\n"), ino
);
1033 ASSERT(mp
->m_sb
.sb_blocksize
== XFS_BUF_COUNT(bp
));
1035 length
= MIN(XFS_BUF_COUNT(bp
) - hdrsize
, valuelen
- amountdone
);
1036 memmove(value
, XFS_BUF_PTR(bp
) + hdrsize
, length
);
1037 amountdone
+= length
;
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
1054 process_leaf_attr_local(
1055 struct xfs_mount
*mp
,
1056 xfs_attr_leafblock_t
*leaf
,
1058 xfs_attr_leaf_entry_t
*entry
,
1059 xfs_dahash_t last_hashval
,
1063 xfs_attr_leaf_name_local_t
*local
;
1065 local
= xfs_attr3_leaf_name_local(leaf
, i
);
1066 if (local
->namelen
== 0 || namecheck((char *)&local
->nameval
[0],
1069 _("attribute entry %d in attr block %u, inode %" PRIu64
" has bad name (namelen = %d)\n"),
1070 i
, da_bno
, ino
, local
->namelen
);
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.
1082 if (be32_to_cpu(entry
->hashval
) != libxfs_da_hashname(
1083 &local
->nameval
[0], local
->namelen
) ||
1084 be32_to_cpu(entry
->hashval
) < last_hashval
) {
1086 _("bad hashvalue for attribute entry %d in attr block %u, inode %" PRIu64
"\n"),
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
))) {
1096 _("bad security value for attribute entry %d in attr block %u, inode %" PRIu64
"\n"),
1101 return xfs_attr_leaf_entsize_local(local
->namelen
,
1102 be16_to_cpu(local
->valuelen
));
1106 process_leaf_attr_remote(
1107 xfs_attr_leafblock_t
*leaf
,
1109 xfs_attr_leaf_entry_t
*entry
,
1110 xfs_dahash_t last_hashval
,
1116 xfs_attr_leaf_name_remote_t
*remotep
;
1119 remotep
= xfs_attr3_leaf_name_remote(leaf
, i
);
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) {
1129 _("inconsistent remote attribute entry %d in attr block %u, ino %" PRIu64
"\n"), i
, da_bno
, ino
);
1133 if (!(entry
->flags
& XFS_ATTR_ROOT
))
1136 value
= malloc(be32_to_cpu(remotep
->valuelen
));
1137 if (value
== NULL
) {
1139 _("cannot malloc enough for remotevalue attribute for inode %" PRIu64
"\n"),
1141 do_warn(_("SKIPPING this remote attribute\n"));
1144 if (rmtval_get(mp
, ino
, blkmap
, be32_to_cpu(remotep
->valueblk
),
1145 be32_to_cpu(remotep
->valuelen
), value
)) {
1147 _("remote attribute get failed for entry %d, inode %" PRIu64
"\n"),
1151 if (valuecheck(mp
, (char *)&remotep
->name
[0], value
, remotep
->namelen
,
1152 be32_to_cpu(remotep
->valuelen
))) {
1154 _("remote attribute value check failed for entry %d, inode %" PRIu64
"\n"),
1160 return xfs_attr_leaf_entsize_remote(remotep
->namelen
);
1168 process_leaf_attr_block(
1170 xfs_attr_leafblock_t
*leaf
,
1174 xfs_dahash_t last_hashval
,
1175 xfs_dahash_t
*current_hashval
,
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
;
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
);
1188 /* does the count look sorta valid? */
1189 if (leafhdr
.count
* sizeof(xfs_attr_leaf_entry_t
) + stop
>
1190 mp
->m_sb
.sb_blocksize
) {
1192 _("bad attribute count %d in attr block %u, inode %" PRIu64
"\n"),
1193 leafhdr
.count
, da_bno
, ino
);
1197 attr_freemap
= alloc_da_freemap(mp
);
1198 (void) set_da_freemap(mp
, attr_freemap
, 0, stop
);
1200 /* go thru each entry checking for problems */
1201 for (i
= 0, entry
= xfs_attr3_leaf_entryp(leaf
);
1202 i
< leafhdr
.count
; i
++, entry
++) {
1204 /* check if index is within some boundary. */
1205 if (be16_to_cpu(entry
->nameidx
) > mp
->m_sb
.sb_blocksize
) {
1207 _("bad attribute nameidx %d in attr block %u, inode %" PRIu64
"\n"),
1208 be16_to_cpu(entry
->nameidx
), da_bno
, ino
);
1213 if (entry
->flags
& XFS_ATTR_INCOMPLETE
) {
1214 /* we are inconsistent state. get rid of us */
1216 _("attribute entry #%d in attr block %u, inode %" PRIu64
" is INCOMPLETE\n"),
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
)) {
1227 _("attribute entry %d in attr block %u, inode %" PRIu64
" claims already used space\n"),
1230 break; /* got an overlap */
1233 if (entry
->flags
& XFS_ATTR_LOCAL
)
1234 thissize
= process_leaf_attr_local(mp
, leaf
, i
, entry
,
1235 last_hashval
, da_bno
, ino
);
1237 thissize
= process_leaf_attr_remote(leaf
, i
, entry
,
1238 last_hashval
, da_bno
, ino
,
1245 *current_hashval
= last_hashval
= be32_to_cpu(entry
->hashval
);
1247 if (set_da_freemap(mp
, attr_freemap
, be16_to_cpu(entry
->nameidx
),
1248 be16_to_cpu(entry
->nameidx
) + thissize
)) {
1250 _("attribute entry %d in attr block %u, inode %" PRIu64
" claims used space\n"),
1253 break; /* got an overlap */
1256 if (be16_to_cpu(entry
->nameidx
) < firstb
)
1257 firstb
= be16_to_cpu(entry
->nameidx
);
1259 } /* end the loop */
1262 /* verify the header information is correct */
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.
1269 if ((leafhdr
.holes
== 0 &&
1270 firstb
!= leafhdr
.firstused
) ||
1271 leafhdr
.firstused
> firstb
) {
1274 _("- resetting first used heap value from %d to %d in "
1275 "block %u of attribute fork of inode %" PRIu64
"\n"),
1277 firstb
, da_bno
, ino
);
1278 leafhdr
.firstused
= firstb
;
1282 _("- would reset first used value from %d to %d in "
1283 "block %u of attribute fork of inode %" PRIu64
"\n"),
1285 firstb
, da_bno
, ino
);
1289 if (usedbs
!= leafhdr
.usedbytes
) {
1292 _("- resetting usedbytes cnt from %d to %d in "
1293 "block %u of attribute fork of inode %" PRIu64
"\n"),
1295 usedbs
, da_bno
, ino
);
1296 leafhdr
.usedbytes
= usedbs
;
1300 _("- would reset usedbytes cnt from %d to %d in "
1301 "block %u of attribute fork of %" PRIu64
"\n"),
1303 usedbs
, da_bno
, ino
);
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.
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
1322 xfs_attr3_leaf_hdr_to_disk(mp
->m_attr_geo
, leaf
, &leafhdr
);
1325 return (clearit
); /* and repair */
1330 * returns 0 if the attribute fork is ok, 1 if it has to be junked.
1333 process_leaf_attr_level(xfs_mount_t
*mp
,
1334 da_bt_cursor_t
*da_cursor
)
1337 xfs_attr_leafblock_t
*leaf
;
1340 xfs_fsblock_t dev_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
;
1347 da_bno
= da_cursor
->level
[0].bno
;
1348 ino
= da_cursor
->ino
;
1353 dev_bno
= blkmap_get(da_cursor
->blkmap
, da_bno
);
1355 * 0 is the root block and no block
1356 * pointer can point to the root block of the btree
1358 ASSERT(da_bno
!= 0);
1360 if (dev_bno
== NULLFSBLOCK
) {
1362 _("can't map block %u for attribute fork for inode %" PRIu64
"\n"),
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
);
1372 _("can't read file block %u (fsbno %" PRIu64
") for attribute fork of inode %" PRIu64
"\n"),
1373 da_bno
, dev_bno
, ino
);
1376 if (bp
->b_error
== -EFSBADCRC
)
1380 xfs_attr3_leaf_hdr_from_disk(mp
->m_attr_geo
, &leafhdr
, leaf
);
1382 /* check magic number for leaf directory btree block */
1383 if (!(leafhdr
.magic
== XFS_ATTR_LEAF_MAGIC
||
1384 leafhdr
.magic
== XFS_ATTR3_LEAF_MAGIC
)) {
1386 _("bad attribute leaf magic %#x for inode %" PRIu64
"\n"),
1387 leafhdr
.magic
, ino
);
1393 * for each block, process the block, verify its path,
1394 * then get next block. update cursor values along the way
1396 if (process_leaf_attr_block(mp
, leaf
, da_bno
, ino
,
1397 da_cursor
->blkmap
, current_hashval
,
1398 &greatest_hashval
, &repair
)) {
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
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
;
1415 if (leafhdr
.back
!= prev_bno
) {
1417 _("bad sibling back pointer for block %u in attribute fork for inode %" PRIu64
"\n"),
1424 da_bno
= leafhdr
.forw
;
1426 if (da_bno
!= 0 && verify_da_path(mp
, da_cursor
, 0)) {
1431 current_hashval
= greatest_hashval
;
1433 if (repair
&& !no_modify
)
1434 libxfs_writebuf(bp
, 0);
1437 } while (da_bno
!= 0);
1439 if (verify_final_da_path(mp
, da_cursor
, 0)) {
1441 * verify the final path up (right-hand-side) if still ok
1444 _("bad hash path in attribute fork for inode %" PRIu64
"\n"),
1449 /* releases all buffers holding interior btree blocks */
1450 release_da_cursor(mp
, da_cursor
, 0);
1454 /* release all buffers holding interior btree blocks */
1455 err_release_da_cursor(mp
, da_cursor
, 0);
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.
1465 * Note that if we run into any problems, we will trash the attribute fork.
1467 * returns 0 if things are ok, 1 if bad
1468 * Note this code has been based off process_node_dir.
1479 da_bt_cursor_t da_cursor
;
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.
1487 memset(&da_cursor
, 0, sizeof(da_bt_cursor_t
));
1488 da_cursor
.active
= 0;
1490 da_cursor
.ino
= ino
;
1491 da_cursor
.dip
= dip
;
1492 da_cursor
.greatest_bno
= 0;
1493 da_cursor
.blkmap
= blkmap
;
1496 * now process interior node. don't have any buffers held in this path.
1498 error
= traverse_int_dablock(mp
, &da_cursor
, &bno
, XFS_ATTR_FORK
);
1500 return(1); /* 0 means unsuccessful */
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.
1508 return (process_leaf_attr_level(mp
, &da_cursor
));
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.
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
1521 process_longform_attr(
1526 int *repair
) /* out - 1 if something was fixed */
1528 xfs_attr_leafblock_t
*leaf
;
1531 xfs_dahash_t next_hashval
;
1532 int repairlinks
= 0;
1533 struct xfs_attr3_icleaf_hdr leafhdr
;
1538 bno
= blkmap_get(blkmap
, 0);
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 */
1545 _("block 0 of inode %" PRIu64
" attribute fork is missing\n"),
1549 /* FIX FOR bug 653709 -- EKN */
1550 if (mp
->m_sb
.sb_agcount
< XFS_FSB_TO_AGNO(mp
, bno
)) {
1552 _("agno of attribute fork of inode %" PRIu64
" out of regular partition\n"), ino
);
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
);
1560 _("can't read block 0 of inode %" PRIu64
" attribute fork\n"),
1564 if (bp
->b_error
== -EFSBADCRC
)
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
);
1571 /* check sibling pointers in leaf block or root block 0 before
1572 * we have to release the btree block
1574 if (leafhdr
.forw
!= 0 || leafhdr
.back
!= 0) {
1577 _("clearing forw/back pointers in block 0 for attributes in inode %" PRIu64
"\n"),
1582 xfs_attr3_leaf_hdr_to_disk(mp
->m_attr_geo
,
1586 _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64
"\n"), ino
);
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.
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
)) {
1601 /* the block is bad. lose the attribute fork. */
1605 *repair
= *repair
|| repairlinks
;
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
) {
1613 libxfs_writebuf(bp
, 0);
1616 error
= process_node_attr(mp
, ino
, dip
, blkmap
); /* + repair */
1622 _("bad attribute leaf magic # %#x for dir ino %" PRIu64
"\n"),
1623 be16_to_cpu(leaf
->hdr
.info
.magic
), ino
);
1629 if (*repair
&& !no_modify
)
1630 libxfs_writebuf(bp
, 0);
1634 return(0); /* repair may be set */
1640 struct xfs_mount
*mp
,
1641 struct xfs_icacl
**aclp
,
1642 struct xfs_acl
*dacl
)
1644 struct xfs_icacl
*acl
;
1645 struct xfs_icacl_entry
*ace
;
1646 struct xfs_acl_entry
*dace
;
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
);
1658 acl
= malloc(sizeof(struct xfs_icacl
) +
1659 count
* sizeof(struct xfs_icacl_entry
));
1661 do_warn(_("cannot malloc enough for ACL attribute\n"));
1662 do_warn(_("SKIPPING this ACL\n"));
1667 acl
->acl_cnt
= count
;
1668 for (i
= 0; i
< count
; i
++) {
1669 ace
= &acl
->acl_entry
[i
];
1670 dace
= &dacl
->acl_entry
[i
];
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
);
1682 * returns 1 if attributes got cleared
1683 * and 0 if things are ok.
1691 int *repair
) /* returned if we did repair */
1694 __u8 aformat
= dip
->di_aformat
;
1696 xfs_attr_shortform_t
*asf
;
1698 asf
= (xfs_attr_shortform_t
*) XFS_DFORK_APTR(dip
);
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
,
1709 /* if err, convert this to shortform and clear it */
1710 /* if repair and no error, it's taken care of */
1712 do_warn(_("illegal attribute format %d, ino %" PRIu64
"\n"),
1716 return (err
); /* and repair */
1724 struct xfs_mount
*mp
,
1725 struct xfs_acl
*daclp
)
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;
1735 switch (xfs_acl_from_disk(mp
, &aclp
, daclp
)) {
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
))
1748 switch (entry
->ae_tag
) {
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
)
1779 if (!user
|| !group
|| !other
|| (mask_required
&& !mask
))
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.
1794 __check_setvalue(const unsigned short *list
, unsigned short count
)
1798 for (i
= 1; i
< count
; i
++)
1799 if (list
[i
] <= list
[i
-1])
1806 * Check the validity of a MAC label.
1809 xfs_mac_valid(xfs_mac_label_t
*lp
)
1815 * if the total category set and division set is greater than 250
1818 if ((lp
->ml_catcount
+ lp
->ml_divcount
) > XFS_MAC_MAX_SETS
)
1822 * check whether the msentype value is valid, and do they have
1823 * appropriate level, category association.
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 )
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)
1842 case XFS_MSEN_UNKNOWN_LABEL
:
1848 * check whether the minttype value is valid, and do they have
1849 * appropriate grade, division association.
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)
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 )