fs/xfs/xfs_attr_inactive.c

Source file repositories/reference/linux-study-clean/fs/xfs/xfs_attr_inactive.c

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_attr_inactive.c
Extension
.c
Size
10442 bytes
Lines
410
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (info->magic) {
		case cpu_to_be16(XFS_DA_NODE_MAGIC):
		case cpu_to_be16(XFS_DA3_NODE_MAGIC):
			error = xfs_attr3_node_inactive(trans, dp, child_bp,
							level + 1);
			break;
		case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
		case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
			error = xfs_attr3_leaf_inactive(trans, dp, child_bp);
			break;
		default:
			xfs_buf_mark_corrupt(child_bp);
			xfs_trans_brelse(*trans, child_bp);
			xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
			error = -EFSCORRUPTED;
			break;
		}
		if (error)
			return error;

		/*
		 * Remove the subsidiary block from the cache and from the log.
		 */
		error = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
				child_blkno,
				XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0,
				&child_bp);
		if (error)
			return error;
		xfs_trans_binval(*trans, child_bp);
		child_bp = NULL;

		error = xfs_da3_node_read_mapped(*trans, dp,
				parent_blkno, &bp, XFS_ATTR_FORK);
		if (error)
			return error;

		/*
		 * Remove entry from parent node, prevents being indexed to.
		 */
		xfs_attr3_node_entry_remove(*trans, dp, bp, 0);

		xfs_da3_node_hdr_from_disk(mp, &ichdr, bp->b_addr);
		bp = NULL;

		if (ichdr.count > 0) {
			/*
			 * If we're not done, get the next child block number.
			 */
			child_fsb = be32_to_cpu(ichdr.btree[0].before);

			/*
			 * Atomically commit the whole invalidate stuff.
			 */
			error = xfs_trans_roll_inode(trans, dp);
			if (error)
				return error;
		}
	}

	return 0;
}

/*
 * Indiscriminately delete the entire attribute fork
 *
 * Recurse (gasp!) through the attribute nodes until we find leaves.
 * We're doing a depth-first traversal in order to invalidate everything.
 */
static int
xfs_attr3_root_inactive(
	struct xfs_trans	**trans,
	struct xfs_inode	*dp)
{
	struct xfs_da_blkinfo	*info;
	struct xfs_buf		*bp;
	int			error;

	/*
	 * Read block 0 to see what we have to work with.
	 * We only get here if we have extents, since we remove
	 * the extents in reverse order the extent containing
	 * block 0 must still be there.
	 */
	error = xfs_da3_node_read(*trans, dp, 0, &bp, XFS_ATTR_FORK);
	if (error)
		return error;

	/*
	 * Invalidate the tree, even if the "tree" is only a single leaf block.

Annotation

Implementation Notes