static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp) { xfs_ino_t ino; int namelen_sum; int count; xfs_dir_shortform_t *sf; xfs_dir_sf_entry_t *sfe; int i; if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & IFMT) != IFDIR) { return 0; } if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) { return 0; } if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) { xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p\n", dp); return 1; } sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf); ino = XFS_GET_DIR_INO_ARCH(mp, sf->hdr.parent, ARCH_CONVERT); if (xfs_dir_ino_validate(mp, ino)) return 1; count = sf->hdr.count; if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) { xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform count: dp 0x%p\n", dp); return(1); } if (count == 0) { return 0; } namelen_sum = 0; sfe = &sf->list[0]; for (i = sf->hdr.count - 1; i >= 0; i--) { ino = XFS_GET_DIR_INO_ARCH(mp, sfe->inumber, ARCH_CONVERT); xfs_dir_ino_validate(mp, ino); if (sfe->namelen >= XFS_LITINO(mp)) { xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform namelen: dp 0x%p\n", dp); return 1; } namelen_sum += sfe->namelen; sfe = XFS_DIR_SF_NEXTENTRY(sfe); } if (namelen_sum >= XFS_LITINO(mp)) { xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform namelen: dp 0x%p\n", dp); return 1; } return 0; }
xfs_dir_sf_entry_t * xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep) { return XFS_DIR_SF_NEXTENTRY(sfep); }