Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "xfs_bmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "xfs_dir2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "xfs_dir2_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "xfs_errortag.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "xfs_error.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "xfs_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Convert inode mode to directory entry filetype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) xfs_mode_to_ftype(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	int		mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	switch (mode & S_IFMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		return XFS_DIR3_FT_REG_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	case S_IFDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		return XFS_DIR3_FT_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	case S_IFCHR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		return XFS_DIR3_FT_CHRDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	case S_IFBLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		return XFS_DIR3_FT_BLKDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	case S_IFIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return XFS_DIR3_FT_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	case S_IFSOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		return XFS_DIR3_FT_SOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	case S_IFLNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		return XFS_DIR3_FT_SYMLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		return XFS_DIR3_FT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * ASCII case-insensitive (ie. A-Z) support for directories that was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * used in IRIX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) xfs_dahash_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) xfs_ascii_ci_hashname(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct xfs_name	*name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	xfs_dahash_t	hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	int		i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	for (i = 0, hash = 0; i < name->len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		hash = tolower(name->name[i]) ^ rol32(hash, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	return hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) enum xfs_dacmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) xfs_ascii_ci_compname(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct xfs_da_args	*args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	const unsigned char	*name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	int			len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	enum xfs_dacmp		result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	int			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	if (args->namelen != len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		return XFS_CMP_DIFFERENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	result = XFS_CMP_EXACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		if (args->name[i] == name[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		if (tolower(args->name[i]) != tolower(name[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			return XFS_CMP_DIFFERENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		result = XFS_CMP_CASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) xfs_da_mount(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	struct xfs_mount	*mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	struct xfs_da_geometry	*dageo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 				    KM_MAYFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				     KM_MAYFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (!mp->m_dir_geo || !mp->m_attr_geo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		kmem_free(mp->m_dir_geo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		kmem_free(mp->m_attr_geo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/* set up directory geometry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	dageo = mp->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	dageo->fsblog = mp->m_sb.sb_blocklog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (xfs_sb_version_hascrc(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		dageo->data_entry_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 				sizeof(struct xfs_dir3_data_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		dageo->data_entry_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 				sizeof(struct xfs_dir2_data_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			sizeof(struct xfs_dir2_leaf_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			sizeof(xfs_dir2_data_off_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	dageo->data_first_offset = dageo->data_entry_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			xfs_dir2_data_entsize(mp, 1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			xfs_dir2_data_entsize(mp, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * Now we've set up the block conversion variables, we can calculate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * segment block constants using the geometry structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				(uint)sizeof(xfs_da_node_entry_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	dageo->magicpct = (dageo->blksize * 37) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	/* set up attribute geometry - single fsb only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	dageo = mp->m_attr_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	dageo->blklog = mp->m_sb.sb_blocklog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	dageo->fsblog = mp->m_sb.sb_blocklog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	dageo->blksize = 1 << dageo->blklog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	dageo->fsbcount = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	dageo->node_hdr_size = mp->m_dir_geo->node_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				(uint)sizeof(xfs_da_node_entry_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	dageo->magicpct = (dageo->blksize * 37) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) xfs_da_unmount(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	struct xfs_mount	*mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	kmem_free(mp->m_dir_geo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	kmem_free(mp->m_attr_geo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * Return 1 if directory contains only "." and "..".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) xfs_dir_isempty(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	xfs_inode_t	*dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	xfs_dir2_sf_hdr_t	*sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (dp->i_d.di_size == 0)	/* might happen during shutdown. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return !sfp->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * Validate a given inode number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) xfs_dir_ino_validate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	xfs_mount_t	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	xfs_ino_t	ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	bool		ino_ok = xfs_verify_dir_ino(mp, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (XFS_IS_CORRUPT(mp, !ino_ok) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	    XFS_TEST_ERROR(false, mp, XFS_ERRTAG_DIR_INO_VALIDATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		xfs_warn(mp, "Invalid inode number 0x%Lx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				(unsigned long long) ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * Initialize a directory with its "." and ".." entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) xfs_dir_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	xfs_trans_t	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	xfs_inode_t	*dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	xfs_inode_t	*pdp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct xfs_da_args *args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	int		error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	args = kmem_zalloc(sizeof(*args), KM_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (!args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	args->geo = dp->i_mount->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	args->dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	args->trans = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	error = xfs_dir2_sf_create(args, pdp->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	kmem_free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  * Enter a name in a directory, or check for available space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  * If inum is 0, only the available space test is performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) xfs_dir_createname(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	struct xfs_trans	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	struct xfs_inode	*dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	struct xfs_name		*name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	xfs_ino_t		inum,		/* new entry inode number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	xfs_extlen_t		total)		/* bmap's total block count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	struct xfs_da_args	*args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	int			rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	int			v;		/* type-checking value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (inum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		rval = xfs_dir_ino_validate(tp->t_mountp, inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		XFS_STATS_INC(dp->i_mount, xs_dir_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	args = kmem_zalloc(sizeof(*args), KM_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (!args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	args->geo = dp->i_mount->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	args->name = name->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	args->namelen = name->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	args->filetype = name->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	args->hashval = xfs_dir2_hashname(dp->i_mount, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	args->inumber = inum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	args->dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	args->total = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	args->whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	args->trans = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (!inum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		args->op_flags |= XFS_DA_OP_JUSTCHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		rval = xfs_dir2_sf_addname(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	rval = xfs_dir2_isblock(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		rval = xfs_dir2_block_addname(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	rval = xfs_dir2_isleaf(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		rval = xfs_dir2_leaf_addname(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		rval = xfs_dir2_node_addname(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	kmem_free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  * If doing a CI lookup and case-insensitive match, dup actual name into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  * args.value. Return EEXIST for success (ie. name found) or an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) xfs_dir_cilookup_result(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	struct xfs_da_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	const unsigned char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	int		len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (args->cmpresult == XFS_CMP_DIFFERENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (args->cmpresult != XFS_CMP_CASE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 					!(args->op_flags & XFS_DA_OP_CILOOKUP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (!args->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	memcpy(args->value, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	args->valuelen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)  * Lookup a name in a directory, give back the inode number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  * If ci_name is not NULL, returns the actual name in ci_name if it differs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  * to name, or ci_name->name is set to NULL for an exact match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) xfs_dir_lookup(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	xfs_trans_t	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	xfs_inode_t	*dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	struct xfs_name	*name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	xfs_ino_t	*inum,		/* out: inode number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	struct xfs_name *ci_name)	/* out: actual name if CI match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	struct xfs_da_args *args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	int		v;		/* type-checking value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	int		lock_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	 * We need to use KM_NOFS here so that lockdep will not throw false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	 * positive deadlock warnings on a non-transactional lookup path. It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	 * safe to recurse into inode recalim in that case, but lockdep can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	 * easily be taught about it. Hence KM_NOFS avoids having to add more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	 * lockdep Doing this avoids having to add a bunch of lockdep class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	 * annotations into the reclaim path for the ilock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	args = kmem_zalloc(sizeof(*args), KM_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	args->geo = dp->i_mount->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	args->name = name->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	args->namelen = name->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	args->filetype = name->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	args->hashval = xfs_dir2_hashname(dp->i_mount, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	args->dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	args->whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	args->trans = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	args->op_flags = XFS_DA_OP_OKNOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	if (ci_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		args->op_flags |= XFS_DA_OP_CILOOKUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	lock_mode = xfs_ilock_data_map_shared(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		rval = xfs_dir2_sf_lookup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		goto out_check_rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	rval = xfs_dir2_isblock(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	if (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		rval = xfs_dir2_block_lookup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		goto out_check_rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	rval = xfs_dir2_isleaf(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		rval = xfs_dir2_leaf_lookup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		rval = xfs_dir2_node_lookup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) out_check_rval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	if (rval == -EEXIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (!rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		*inum = args->inumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		if (ci_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			ci_name->name = args->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			ci_name->len = args->valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	xfs_iunlock(dp, lock_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	kmem_free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  * Remove an entry from a directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) xfs_dir_removename(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	struct xfs_trans	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	struct xfs_inode	*dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	struct xfs_name		*name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	xfs_ino_t		ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	xfs_extlen_t		total)		/* bmap's total block count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	struct xfs_da_args	*args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	int			rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	int			v;		/* type-checking value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	XFS_STATS_INC(dp->i_mount, xs_dir_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	args = kmem_zalloc(sizeof(*args), KM_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	if (!args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	args->geo = dp->i_mount->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	args->name = name->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	args->namelen = name->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	args->filetype = name->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	args->hashval = xfs_dir2_hashname(dp->i_mount, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	args->inumber = ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	args->dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	args->total = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	args->whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	args->trans = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		rval = xfs_dir2_sf_removename(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	rval = xfs_dir2_isblock(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	if (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		rval = xfs_dir2_block_removename(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	rval = xfs_dir2_isleaf(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		rval = xfs_dir2_leaf_removename(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		rval = xfs_dir2_node_removename(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	kmem_free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)  * Replace the inode number of a directory entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) xfs_dir_replace(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	struct xfs_trans	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	struct xfs_inode	*dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	struct xfs_name		*name,		/* name of entry to replace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	xfs_ino_t		inum,		/* new inode number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	xfs_extlen_t		total)		/* bmap's total block count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	struct xfs_da_args	*args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	int			rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	int			v;		/* type-checking value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	rval = xfs_dir_ino_validate(tp->t_mountp, inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	args = kmem_zalloc(sizeof(*args), KM_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (!args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	args->geo = dp->i_mount->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	args->name = name->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	args->namelen = name->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	args->filetype = name->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	args->hashval = xfs_dir2_hashname(dp->i_mount, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	args->inumber = inum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	args->dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	args->total = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	args->whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	args->trans = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		rval = xfs_dir2_sf_replace(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	rval = xfs_dir2_isblock(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	if (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		rval = xfs_dir2_block_replace(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	rval = xfs_dir2_isleaf(args, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		rval = xfs_dir2_leaf_replace(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		rval = xfs_dir2_node_replace(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	kmem_free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)  * See if this entry can be added to the directory without allocating space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) xfs_dir_canenter(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	xfs_trans_t	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	xfs_inode_t	*dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	struct xfs_name	*name)		/* name of entry to add */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	return xfs_dir_createname(tp, dp, name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)  * Utility routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)  * Add a block to the directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)  * This routine is for data and free blocks, not leaf/node blocks which are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)  * handled by xfs_da_grow_inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) xfs_dir2_grow_inode(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	struct xfs_da_args	*args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	int			space,	/* v2 dir's space XFS_DIR2_xxx_SPACE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	xfs_dir2_db_t		*dbp)	/* out: block number added */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	struct xfs_inode	*dp = args->dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	struct xfs_mount	*mp = dp->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	xfs_fileoff_t		bno;	/* directory offset of new block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	int			count;	/* count of filesystem blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	trace_xfs_dir2_grow_inode(args, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	 * Set lowest possible block in the space requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	count = args->geo->fsbcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	error = xfs_da_grow_inode_int(args, &bno, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	*dbp = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	 * Update file's size if this is the data space and it grew.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (space == XFS_DIR2_DATA_SPACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		xfs_fsize_t	size;		/* directory file (data) size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		size = XFS_FSB_TO_B(mp, bno + count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		if (size > dp->i_d.di_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 			dp->i_d.di_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 			xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)  * See if the directory is a single-block form directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) xfs_dir2_isblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	struct xfs_da_args	*args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	int			*vp)	/* out: 1 is block, 0 is not block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	xfs_fileoff_t		last;	/* last file offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	int			rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	if (XFS_IS_CORRUPT(args->dp->i_mount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			   rval != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 			   args->dp->i_d.di_size != args->geo->blksize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	*vp = rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  * See if the directory is a single-leaf form directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) xfs_dir2_isleaf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	struct xfs_da_args	*args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	int			*vp)	/* out: 1 is block, 0 is not block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	xfs_fileoff_t		last;	/* last file offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	int			rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	*vp = last == args->geo->leafblk + args->geo->fsbcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)  * Remove the given block from the directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)  * This routine is used for data and free blocks, leaf/node are done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)  * by xfs_da_shrink_inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) xfs_dir2_shrink_inode(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	struct xfs_da_args	*args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	xfs_dir2_db_t		db,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	xfs_fileoff_t		bno;		/* directory file offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	xfs_dablk_t		da;		/* directory file offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	int			done;		/* bunmap is finished */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	struct xfs_inode	*dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	struct xfs_mount	*mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	struct xfs_trans	*tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	trace_xfs_dir2_shrink_inode(args, db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	dp = args->dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	mp = dp->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	tp = args->trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	da = xfs_dir2_db_to_da(args->geo, db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	/* Unmap the fsblock(s). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, &done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		 * ENOSPC actually can happen if we're in a removename with no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		 * space reservation, and the resulting block removal would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		 * cause a bmap btree split or conversion from extents to btree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		 * This can only happen for un-fragmented directory blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		 * since you need to be punching out the middle of an extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		 * In this case we need to leave the block in the file, and not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		 * binval it.  So the block has to be in a consistent empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		 * state and appropriately logged.  We don't free up the buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		 * the caller can tell it hasn't happened since it got an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		 * back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	ASSERT(done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	 * Invalidate the buffer from the transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	xfs_trans_binval(tp, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	 * If it's not a data block, we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	if (db >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	 * If the block isn't the last one in the directory, we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(args->geo, db + 1, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	bno = da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		 * This can't really happen unless there's kernel corruption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	if (db == args->geo->datablk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		ASSERT(bno == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		ASSERT(bno > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	 * Set the size to the new last block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	dp->i_d.di_size = XFS_FSB_TO_B(mp, bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* Returns true if the directory entry name is valid. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) xfs_dir2_namecheck(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	const void	*name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	size_t		length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	 * MAXNAMELEN includes the trailing null, but (name/length) leave it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	 * out, so use >= for the length check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	if (length >= MAXNAMELEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	/* There shouldn't be any slashes or nulls here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	return !memchr(name, '/', length) && !memchr(name, 0, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) xfs_dahash_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) xfs_dir2_hashname(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	struct xfs_name		*name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	if (unlikely(xfs_sb_version_hasasciici(&mp->m_sb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		return xfs_ascii_ci_hashname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	return xfs_da_hashname(name->name, name->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) enum xfs_dacmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) xfs_dir2_compname(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	struct xfs_da_args	*args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	const unsigned char	*name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	int			len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	if (unlikely(xfs_sb_version_hasasciici(&args->dp->i_mount->m_sb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		return xfs_ascii_ci_compname(args, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	return xfs_da_compname(args, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }