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

📄 xfs_mount.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (size == 1 || xfs_sb_info[f].type == 1) {			memcpy(to_ptr + first, from_ptr + first, size);		} else {			switch (size) {			case 2:				*(__be16 *)(to_ptr + first) =					cpu_to_be16(*(__u16 *)(from_ptr + first));				break;			case 4:				*(__be32 *)(to_ptr + first) =					cpu_to_be32(*(__u32 *)(from_ptr + first));				break;			case 8:				*(__be64 *)(to_ptr + first) =					cpu_to_be64(*(__u64 *)(from_ptr + first));				break;			default:				ASSERT(0);			}		}		fields &= ~(1LL << f);	}}/* * xfs_readsb * * Does the initial read of the superblock. */intxfs_readsb(xfs_mount_t *mp, int flags){	unsigned int	sector_size;	unsigned int	extra_flags;	xfs_buf_t	*bp;	int		error;	ASSERT(mp->m_sb_bp == NULL);	ASSERT(mp->m_ddev_targp != NULL);	/*	 * Allocate a (locked) buffer to hold the superblock.	 * This will be kept around at all times to optimize	 * access to the superblock.	 */	sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);	extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED;	bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,				BTOBB(sector_size), extra_flags);	if (!bp || XFS_BUF_ISERROR(bp)) {		xfs_fs_mount_cmn_err(flags, "SB read failed");		error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;		goto fail;	}	ASSERT(XFS_BUF_ISBUSY(bp));	ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);	/*	 * Initialize the mount structure from the superblock.	 * But first do some basic consistency checking.	 */	xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));	error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags);	if (error) {		xfs_fs_mount_cmn_err(flags, "SB validate failed");		goto fail;	}	/*	 * We must be able to do sector-sized and sector-aligned IO.	 */	if (sector_size > mp->m_sb.sb_sectsize) {		xfs_fs_mount_cmn_err(flags,			"device supports only %u byte sectors (not %u)",			sector_size, mp->m_sb.sb_sectsize);		error = ENOSYS;		goto fail;	}	/*	 * If device sector size is smaller than the superblock size,	 * re-read the superblock so the buffer is correctly sized.	 */	if (sector_size < mp->m_sb.sb_sectsize) {		XFS_BUF_UNMANAGE(bp);		xfs_buf_relse(bp);		sector_size = mp->m_sb.sb_sectsize;		bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,					BTOBB(sector_size), extra_flags);		if (!bp || XFS_BUF_ISERROR(bp)) {			xfs_fs_mount_cmn_err(flags, "SB re-read failed");			error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;			goto fail;		}		ASSERT(XFS_BUF_ISBUSY(bp));		ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);	}	/* Initialize per-cpu counters */	xfs_icsb_reinit_counters(mp);	mp->m_sb_bp = bp;	xfs_buf_relse(bp);	ASSERT(XFS_BUF_VALUSEMA(bp) > 0);	return 0; fail:	if (bp) {		XFS_BUF_UNMANAGE(bp);		xfs_buf_relse(bp);	}	return error;}/* * xfs_mount_common * * Mount initialization code establishing various mount * fields from the superblock associated with the given * mount structure */STATIC voidxfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp){	int	i;	mp->m_agfrotor = mp->m_agirotor = 0;	spinlock_init(&mp->m_agirotor_lock, "m_agirotor_lock");	mp->m_maxagi = mp->m_sb.sb_agcount;	mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;	mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;	mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;	mp->m_litino = sbp->sb_inodesize -		((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));	mp->m_blockmask = sbp->sb_blocksize - 1;	mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;	mp->m_blockwmask = mp->m_blockwsize - 1;	INIT_LIST_HEAD(&mp->m_del_inodes);	/*	 * Setup for attributes, in case they get created.	 * This value is for inodes getting attributes for the first time,	 * the per-inode value is for old attribute values.	 */	ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);	switch (sbp->sb_inodesize) {	case 256:		mp->m_attroffset = XFS_LITINO(mp) -				   XFS_BMDR_SPACE_CALC(MINABTPTRS);		break;	case 512:	case 1024:	case 2048:		mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);		break;	default:		ASSERT(0);	}	ASSERT(mp->m_attroffset < XFS_LITINO(mp));	for (i = 0; i < 2; i++) {		mp->m_alloc_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,			xfs_alloc, i == 0);		mp->m_alloc_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,			xfs_alloc, i == 0);	}	for (i = 0; i < 2; i++) {		mp->m_bmap_dmxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,			xfs_bmbt, i == 0);		mp->m_bmap_dmnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,			xfs_bmbt, i == 0);	}	for (i = 0; i < 2; i++) {		mp->m_inobt_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,			xfs_inobt, i == 0);		mp->m_inobt_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,			xfs_inobt, i == 0);	}	mp->m_bsize = XFS_FSB_TO_BB(mp, 1);	mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,					sbp->sb_inopblock);	mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;}/* * xfs_initialize_perag_data * * Read in each per-ag structure so we can count up the number of * allocated inodes, free inodes and used filesystem blocks as this * information is no longer persistent in the superblock. Once we have * this information, write it into the in-core superblock structure. */STATIC intxfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount){	xfs_agnumber_t	index;	xfs_perag_t	*pag;	xfs_sb_t	*sbp = &mp->m_sb;	uint64_t	ifree = 0;	uint64_t	ialloc = 0;	uint64_t	bfree = 0;	uint64_t	bfreelst = 0;	uint64_t	btree = 0;	int		error;	int		s;	for (index = 0; index < agcount; index++) {		/*		 * read the agf, then the agi. This gets us		 * all the inforamtion we need and populates the		 * per-ag structures for us.		 */		error = xfs_alloc_pagf_init(mp, NULL, index, 0);		if (error)			return error;		error = xfs_ialloc_pagi_init(mp, NULL, index);		if (error)			return error;		pag = &mp->m_perag[index];		ifree += pag->pagi_freecount;		ialloc += pag->pagi_count;		bfree += pag->pagf_freeblks;		bfreelst += pag->pagf_flcount;		btree += pag->pagf_btreeblks;	}	/*	 * Overwrite incore superblock counters with just-read data	 */	s = XFS_SB_LOCK(mp);	sbp->sb_ifree = ifree;	sbp->sb_icount = ialloc;	sbp->sb_fdblocks = bfree + bfreelst + btree;	XFS_SB_UNLOCK(mp, s);	/* Fixup the per-cpu counters as well. */	xfs_icsb_reinit_counters(mp);	return 0;}/* * xfs_mountfs * * This function does the following on an initial mount of a file system: *	- reads the superblock from disk and init the mount struct *	- if we're a 32-bit kernel, do a size check on the superblock *		so we don't mount terabyte filesystems *	- init mount struct realtime fields *	- allocate inode hash table for fs *	- init directory manager *	- perform recovery and init the log manager */intxfs_mountfs(	xfs_mount_t	*mp,	int		mfsi_flags){	xfs_buf_t	*bp;	xfs_sb_t	*sbp = &(mp->m_sb);	xfs_inode_t	*rip;	bhv_vnode_t	*rvp = NULL;	int		readio_log, writeio_log;	xfs_daddr_t	d;	__uint64_t	resblks;	__int64_t	update_flags;	uint		quotamount, quotaflags;	int		agno;	int		uuid_mounted = 0;	int		error = 0;	if (mp->m_sb_bp == NULL) {		if ((error = xfs_readsb(mp, mfsi_flags))) {			return error;		}	}	xfs_mount_common(mp, sbp);	/*	 * Check if sb_agblocks is aligned at stripe boundary	 * If sb_agblocks is NOT aligned turn off m_dalign since	 * allocator alignment is within an ag, therefore ag has	 * to be aligned at stripe boundary.	 */	update_flags = 0LL;	if (mp->m_dalign && !(mfsi_flags & XFS_MFSI_SECOND)) {		/*		 * If stripe unit and stripe width are not multiples		 * of the fs blocksize turn off alignment.		 */		if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||		    (BBTOB(mp->m_swidth) & mp->m_blockmask)) {			if (mp->m_flags & XFS_MOUNT_RETERR) {				cmn_err(CE_WARN,					"XFS: alignment check 1 failed");				error = XFS_ERROR(EINVAL);				goto error1;			}			mp->m_dalign = mp->m_swidth = 0;		} else {			/*			 * Convert the stripe unit and width to FSBs.			 */			mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);			if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {				if (mp->m_flags & XFS_MOUNT_RETERR) {					error = XFS_ERROR(EINVAL);					goto error1;				}				xfs_fs_cmn_err(CE_WARN, mp,"stripe alignment turned off: sunit(%d)/swidth(%d) incompatible with agsize(%d)",					mp->m_dalign, mp->m_swidth,					sbp->sb_agblocks);				mp->m_dalign = 0;				mp->m_swidth = 0;			} else if (mp->m_dalign) {				mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);			} else {				if (mp->m_flags & XFS_MOUNT_RETERR) {					xfs_fs_cmn_err(CE_WARN, mp,"stripe alignment turned off: sunit(%d) less than bsize(%d)",                                        	mp->m_dalign,						mp->m_blockmask +1);					error = XFS_ERROR(EINVAL);					goto error1;				}				mp->m_swidth = 0;			}		}		/*		 * Update superblock with new values		 * and log changes		 */		if (XFS_SB_VERSION_HASDALIGN(sbp)) {			if (sbp->sb_unit != mp->m_dalign) {				sbp->sb_unit = mp->m_dalign;				update_flags |= XFS_SB_UNIT;			}			if (sbp->sb_width != mp->m_swidth) {				sbp->sb_width = mp->m_swidth;				update_flags |= XFS_SB_WIDTH;			}		}	} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&		    XFS_SB_VERSION_HASDALIGN(&mp->m_sb)) {			mp->m_dalign = sbp->sb_unit;			mp->m_swidth = sbp->sb_width;	}	xfs_alloc_compute_maxlevels(mp);	xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);	xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);	xfs_ialloc_compute_maxlevels(mp);	if (sbp->sb_imax_pct) {		__uint64_t	icount;		/* Make sure the maximum inode count is a multiple of the		 * units we allocate inodes in.		 */		icount = sbp->sb_dblocks * sbp->sb_imax_pct;		do_div(icount, 100);		do_div(icount, mp->m_ialloc_blks);		mp->m_maxicount = (icount * mp->m_ialloc_blks)  <<				   sbp->sb_inopblog;	} else		mp->m_maxicount = 0;	mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);	/*	 * XFS uses the uuid from the superblock as the unique	 * identifier for fsid.  We can not use the uuid from the volume	 * since a single partition filesystem is identical to a single	 * partition volume/filesystem.	 */	if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&	    (mp->m_flags & XFS_MOUNT_NOUUID) == 0) {		if (xfs_uuid_mount(mp)) {			error = XFS_ERROR(EINVAL);			goto error1;		}		uuid_mounted=1;	}	/*	 * Set the default minimum read and write sizes unless	 * already specified in a mount option.	 * We use smaller I/O sizes when the file system	 * is being used for NFS service (wsync mount option).	 */	if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) {		if (mp->m_flags & XFS_MOUNT_WSYNC) {			readio_log = XFS_WSYNC_READIO_LOG;			writeio_log = XFS_WSYNC_WRITEIO_LOG;		} else {			readio_log = XFS_READIO_LOG_LARGE;			writeio_log = XFS_WRITEIO_LOG_LARGE;		}	} else {		readio_log = mp->m_readio_log;		writeio_log = mp->m_writeio_log;	}	if (sbp->sb_blocklog > readio_log) {		mp->m_readio_log = sbp->sb_blocklog;	} else {		mp->m_readio_log = readio_log;	}	mp->m_readio_blocks = 1 << (mp->m_readio_log - sbp->sb_blocklog);	if (sbp->sb_blocklog > writeio_log) {		mp->m_writeio_log = sbp->sb_blocklog;	} else {		mp->m_writeio_log = writeio_log;	}	mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog);	/*	 * Set the inode cluster size.	 * This may still be overridden by the file system	 * block size if it is larger than the chosen cluster size.	 */	mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;	/*	 * Set whether we're using inode alignment.	 */	if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&	    mp->m_sb.sb_inoalignmt >=	    XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))		mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;	else		mp->m_inoalign_mask = 0;	/*	 * If we are using stripe alignment, check whether	 * the stripe unit is a multiple of the inode alignment	 */	if (mp->m_dalign && mp->m_inoalign_mask &&	    !(mp->m_dalign & mp->m_inoalign_mask))		mp->m_sinoalign = mp->m_dalign;	else		mp->m_sinoalign = 0;	/*	 * Check that the data (and log if separate) are an ok size.	 */	d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);	if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {		cmn_err(CE_WARN, "XFS: size check 1 failed");		error = XFS_ERROR(E2BIG);		goto error1;	}	error = xfs_read_buf(mp, mp->m_ddev_targp,			     d - XFS_FSS_TO_BB(mp, 1),			     XFS_FSS_TO_BB(mp, 1), 0, &bp);	if (!error) {		xfs_buf_relse(bp);	} else {		cmn_err(CE_WARN, "XFS: size check 2 failed");		if (error == ENOSPC) {			error = XFS_ERROR(E2BIG);		}		goto error1;	}	if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) &&	    mp->m_logdev_targp != mp->m_ddev_targp) {		d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);		if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {			cmn_err(CE_WARN, "XFS: size check 3 failed");			error = XFS_ERROR(E2BIG);			goto error1;		}		error = xfs_read_buf(mp, mp->m_logdev_targp,				     d - XFS_FSB_TO_BB(mp, 1),				     XFS_FSB_TO_BB(mp, 1), 0, &bp);

⌨️ 快捷键说明

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