^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) }