⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xfs_inode.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	case S_IFIFO:	case S_IFCHR:	case S_IFBLK:	case S_IFSOCK:		if (unlikely(dip->di_core.di_format != XFS_DINODE_FMT_DEV)) {			XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,					      ip->i_mount, dip);			return XFS_ERROR(EFSCORRUPTED);		}		ip->i_d.di_size = 0;		ip->i_size = 0;		ip->i_df.if_u2.if_rdev = be32_to_cpu(dip->di_u.di_dev);		break;	case S_IFREG:	case S_IFLNK:	case S_IFDIR:		switch (dip->di_core.di_format) {		case XFS_DINODE_FMT_LOCAL:			/*			 * no local regular files yet			 */			if (unlikely((be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG)) {				xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,					"corrupt inode %Lu "					"(local format for regular file).",					(unsigned long long) ip->i_ino);				XFS_CORRUPTION_ERROR("xfs_iformat(4)",						     XFS_ERRLEVEL_LOW,						     ip->i_mount, dip);				return XFS_ERROR(EFSCORRUPTED);			}			di_size = be64_to_cpu(dip->di_core.di_size);			if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {				xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,					"corrupt inode %Lu "					"(bad size %Ld for local inode).",					(unsigned long long) ip->i_ino,					(long long) di_size);				XFS_CORRUPTION_ERROR("xfs_iformat(5)",						     XFS_ERRLEVEL_LOW,						     ip->i_mount, dip);				return XFS_ERROR(EFSCORRUPTED);			}			size = (int)di_size;			error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size);			break;		case XFS_DINODE_FMT_EXTENTS:			error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK);			break;		case XFS_DINODE_FMT_BTREE:			error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);			break;		default:			XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW,					 ip->i_mount);			return XFS_ERROR(EFSCORRUPTED);		}		break;	default:		XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount);		return XFS_ERROR(EFSCORRUPTED);	}	if (error) {		return error;	}	if (!XFS_DFORK_Q(dip))		return 0;	ASSERT(ip->i_afp == NULL);	ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);	ip->i_afp->if_ext_max =		XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);	switch (dip->di_core.di_aformat) {	case XFS_DINODE_FMT_LOCAL:		atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);		size = be16_to_cpu(atp->hdr.totsize);		error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);		break;	case XFS_DINODE_FMT_EXTENTS:		error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);		break;	case XFS_DINODE_FMT_BTREE:		error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);		break;	default:		error = XFS_ERROR(EFSCORRUPTED);		break;	}	if (error) {		kmem_zone_free(xfs_ifork_zone, ip->i_afp);		ip->i_afp = NULL;		xfs_idestroy_fork(ip, XFS_DATA_FORK);	}	return error;}/* * The file is in-lined in the on-disk inode. * If it fits into if_inline_data, then copy * it there, otherwise allocate a buffer for it * and copy the data there.  Either way, set * if_data to point at the data. * If we allocate a buffer for the data, make * sure that its size is a multiple of 4 and * record the real size in i_real_bytes. */STATIC intxfs_iformat_local(	xfs_inode_t	*ip,	xfs_dinode_t	*dip,	int		whichfork,	int		size){	xfs_ifork_t	*ifp;	int		real_size;	/*	 * If the size is unreasonable, then something	 * is wrong and we just bail out rather than crash in	 * kmem_alloc() or memcpy() below.	 */	if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,			"corrupt inode %Lu "			"(bad size %d for local fork, size = %d).",			(unsigned long long) ip->i_ino, size,			XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));		XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,				     ip->i_mount, dip);		return XFS_ERROR(EFSCORRUPTED);	}	ifp = XFS_IFORK_PTR(ip, whichfork);	real_size = 0;	if (size == 0)		ifp->if_u1.if_data = NULL;	else if (size <= sizeof(ifp->if_u2.if_inline_data))		ifp->if_u1.if_data = ifp->if_u2.if_inline_data;	else {		real_size = roundup(size, 4);		ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP);	}	ifp->if_bytes = size;	ifp->if_real_bytes = real_size;	if (size)		memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);	ifp->if_flags &= ~XFS_IFEXTENTS;	ifp->if_flags |= XFS_IFINLINE;	return 0;}/* * The file consists of a set of extents all * of which fit into the on-disk inode. * If there are few enough extents to fit into * the if_inline_ext, then copy them there. * Otherwise allocate a buffer for them and copy * them into it.  Either way, set if_extents * to point at the extents. */STATIC intxfs_iformat_extents(	xfs_inode_t	*ip,	xfs_dinode_t	*dip,	int		whichfork){	xfs_bmbt_rec_t	*dp;	xfs_ifork_t	*ifp;	int		nex;	int		size;	int		i;	ifp = XFS_IFORK_PTR(ip, whichfork);	nex = XFS_DFORK_NEXTENTS(dip, whichfork);	size = nex * (uint)sizeof(xfs_bmbt_rec_t);	/*	 * If the number of extents is unreasonable, then something	 * is wrong and we just bail out rather than crash in	 * kmem_alloc() or memcpy() below.	 */	if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,			"corrupt inode %Lu ((a)extents = %d).",			(unsigned long long) ip->i_ino, nex);		XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,				     ip->i_mount, dip);		return XFS_ERROR(EFSCORRUPTED);	}	ifp->if_real_bytes = 0;	if (nex == 0)		ifp->if_u1.if_extents = NULL;	else if (nex <= XFS_INLINE_EXTS)		ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;	else		xfs_iext_add(ifp, 0, nex);	ifp->if_bytes = size;	if (size) {		dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);		xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip));		for (i = 0; i < nex; i++, dp++) {			xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);			ep->l0 = be64_to_cpu(get_unaligned(&dp->l0));			ep->l1 = be64_to_cpu(get_unaligned(&dp->l1));		}		XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork);		if (whichfork != XFS_DATA_FORK ||			XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)				if (unlikely(xfs_check_nostate_extents(				    ifp, 0, nex))) {					XFS_ERROR_REPORT("xfs_iformat_extents(2)",							 XFS_ERRLEVEL_LOW,							 ip->i_mount);					return XFS_ERROR(EFSCORRUPTED);				}	}	ifp->if_flags |= XFS_IFEXTENTS;	return 0;}/* * The file has too many extents to fit into * the inode, so they are in B-tree format. * Allocate a buffer for the root of the B-tree * and copy the root into it.  The i_extents * field will remain NULL until all of the * extents are read in (when they are needed). */STATIC intxfs_iformat_btree(	xfs_inode_t		*ip,	xfs_dinode_t		*dip,	int			whichfork){	xfs_bmdr_block_t	*dfp;	xfs_ifork_t		*ifp;	/* REFERENCED */	int			nrecs;	int			size;	ifp = XFS_IFORK_PTR(ip, whichfork);	dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);	size = XFS_BMAP_BROOT_SPACE(dfp);	nrecs = XFS_BMAP_BROOT_NUMRECS(dfp);	/*	 * blow out if -- fork has less extents than can fit in	 * fork (fork shouldn't be a btree format), root btree	 * block has more records than can fit into the fork,	 * or the number of extents is greater than the number of	 * blocks.	 */	if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max	    || XFS_BMDR_SPACE_CALC(nrecs) >			XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)	    || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,			"corrupt inode %Lu (btree).",			(unsigned long long) ip->i_ino);		XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW,				 ip->i_mount);		return XFS_ERROR(EFSCORRUPTED);	}	ifp->if_broot_bytes = size;	ifp->if_broot = kmem_alloc(size, KM_SLEEP);	ASSERT(ifp->if_broot != NULL);	/*	 * Copy and convert from the on-disk structure	 * to the in-memory structure.	 */	xfs_bmdr_to_bmbt(dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),		ifp->if_broot, size);	ifp->if_flags &= ~XFS_IFEXTENTS;	ifp->if_flags |= XFS_IFBROOT;	return 0;}voidxfs_dinode_from_disk(	xfs_icdinode_t		*to,	xfs_dinode_core_t	*from){	to->di_magic = be16_to_cpu(from->di_magic);	to->di_mode = be16_to_cpu(from->di_mode);	to->di_version = from ->di_version;	to->di_format = from->di_format;	to->di_onlink = be16_to_cpu(from->di_onlink);	to->di_uid = be32_to_cpu(from->di_uid);	to->di_gid = be32_to_cpu(from->di_gid);	to->di_nlink = be32_to_cpu(from->di_nlink);	to->di_projid = be16_to_cpu(from->di_projid);	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));	to->di_flushiter = be16_to_cpu(from->di_flushiter);	to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);	to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);	to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);	to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);	to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);	to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);	to->di_size = be64_to_cpu(from->di_size);	to->di_nblocks = be64_to_cpu(from->di_nblocks);	to->di_extsize = be32_to_cpu(from->di_extsize);	to->di_nextents = be32_to_cpu(from->di_nextents);	to->di_anextents = be16_to_cpu(from->di_anextents);	to->di_forkoff = from->di_forkoff;	to->di_aformat	= from->di_aformat;	to->di_dmevmask	= be32_to_cpu(from->di_dmevmask);	to->di_dmstate	= be16_to_cpu(from->di_dmstate);	to->di_flags	= be16_to_cpu(from->di_flags);	to->di_gen	= be32_to_cpu(from->di_gen);}voidxfs_dinode_to_disk(	xfs_dinode_core_t	*to,	xfs_icdinode_t		*from){	to->di_magic = cpu_to_be16(from->di_magic);	to->di_mode = cpu_to_be16(from->di_mode);	to->di_version = from ->di_version;	to->di_format = from->di_format;	to->di_onlink = cpu_to_be16(from->di_onlink);	to->di_uid = cpu_to_be32(from->di_uid);	to->di_gid = cpu_to_be32(from->di_gid);	to->di_nlink = cpu_to_be32(from->di_nlink);	to->di_projid = cpu_to_be16(from->di_projid);	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));	to->di_flushiter = cpu_to_be16(from->di_flushiter);	to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);	to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);	to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);	to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);	to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);	to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);	to->di_size = cpu_to_be64(from->di_size);	to->di_nblocks = cpu_to_be64(from->di_nblocks);	to->di_extsize = cpu_to_be32(from->di_extsize);	to->di_nextents = cpu_to_be32(from->di_nextents);	to->di_anextents = cpu_to_be16(from->di_anextents);	to->di_forkoff = from->di_forkoff;	to->di_aformat = from->di_aformat;	to->di_dmevmask = cpu_to_be32(from->di_dmevmask);	to->di_dmstate = cpu_to_be16(from->di_dmstate);	to->di_flags = cpu_to_be16(from->di_flags);	to->di_gen = cpu_to_be32(from->di_gen);}STATIC uint_xfs_dic2xflags(	__uint16_t		di_flags){	uint			flags = 0;	if (di_flags & XFS_DIFLAG_ANY) {		if (di_flags & XFS_DIFLAG_REALTIME)			flags |= XFS_XFLAG_REALTIME;		if (di_flags & XFS_DIFLAG_PREALLOC)			flags |= XFS_XFLAG_PREALLOC;		if (di_flags & XFS_DIFLAG_IMMUTABLE)			flags |= XFS_XFLAG_IMMUTABLE;		if (di_flags & XFS_DIFLAG_APPEND)			flags |= XFS_XFLAG_APPEND;		if (di_flags & XFS_DIFLAG_SYNC)			flags |= XFS_XFLAG_SYNC;		if (di_flags & XFS_DIFLAG_NOATIME)			flags |= XFS_XFLAG_NOATIME;		if (di_flags & XFS_DIFLAG_NODUMP)			flags |= XFS_XFLAG_NODUMP;		if (di_flags & XFS_DIFLAG_RTINHERIT)			flags |= XFS_XFLAG_RTINHERIT;		if (di_flags & XFS_DIFLAG_PROJINHERIT)			flags |= XFS_XFLAG_PROJINHERIT;		if (di_flags & XFS_DIFLAG_NOSYMLINKS)			flags |= XFS_XFLAG_NOSYMLINKS;		if (di_flags & XFS_DIFLAG_EXTSIZE)			flags |= XFS_XFLAG_EXTSIZE;		if (di_flags & XFS_DIFLAG_EXTSZINHERIT)			flags |= XFS_XFLAG_EXTSZINHERIT;		if (di_flags & XFS_DIFLAG_NODEFRAG)			flags |= XFS_XFLAG_NODEFRAG;		if (di_flags & XFS_DIFLAG_FILESTREAM)			flags |= XFS_XFLAG_FILESTREAM;	}	return flags;}uintxfs_ip2xflags(	xfs_inode_t		*ip){	xfs_icdinode_t		*dic = &ip->i_d;	return _xfs_dic2xflags(dic->di_flags) |				(XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);}uintxfs_dic2xflags(	xfs_dinode_core_t	*dic){	return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) |				(XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);}/* * Given a mount structure and an inode number, return a pointer * to a newly allocated in-core inode corresponding to the given * inode number. * * Initialize the inode's attributes and extent pointers if it * already has them (it will not if the inode has no links). */intxfs_iread(	xfs_mount_t	*mp,	xfs_trans_t	*tp,	xfs_ino_t	ino,	xfs_inode_t	**ipp,	xfs_daddr_t	bno,	uint		imap_flags){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -