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

📄 balloc.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);		unlock_super(sb);		if (newcount < request)			ufs_free_fragments (inode, result + newcount, request - newcount);		ufs_free_fragments (inode, tmp, oldcount);		UFSD("EXIT, result %llu\n", (unsigned long long)result);		return result;	}	unlock_super(sb);	UFSD("EXIT (FAILED)\n");	return 0;}		static u64 ufs_add_fragments(struct inode *inode, u64 fragment,			     unsigned oldcount, unsigned newcount, int *err){	struct super_block * sb;	struct ufs_sb_private_info * uspi;	struct ufs_super_block_first * usb1;	struct ufs_cg_private_info * ucpi;	struct ufs_cylinder_group * ucg;	unsigned cgno, fragno, fragoff, count, fragsize, i;		UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n",	     (unsigned long long)fragment, oldcount, newcount);		sb = inode->i_sb;	uspi = UFS_SB(sb)->s_uspi;	usb1 = ubh_get_usb_first (uspi);	count = newcount - oldcount;		cgno = ufs_dtog(uspi, fragment);	if (fs32_to_cpu(sb, UFS_SB(sb)->fs_cs(cgno).cs_nffree) < count)		return 0;	if ((ufs_fragnum (fragment) + newcount) > uspi->s_fpb)		return 0;	ucpi = ufs_load_cylinder (sb, cgno);	if (!ucpi)		return 0;	ucg = ubh_get_ucg (UCPI_UBH(ucpi));	if (!ufs_cg_chkmagic(sb, ucg)) {		ufs_panic (sb, "ufs_add_fragments",			"internal error, bad magic number on cg %u", cgno);		return 0;	}	fragno = ufs_dtogd(uspi, fragment);	fragoff = ufs_fragnum (fragno);	for (i = oldcount; i < newcount; i++)		if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i))			return 0;	/*	 * Block can be extended	 */	ucg->cg_time = cpu_to_fs32(sb, get_seconds());	for (i = newcount; i < (uspi->s_fpb - fragoff); i++)		if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i))			break;	fragsize = i - oldcount;	if (!fs32_to_cpu(sb, ucg->cg_frsum[fragsize]))		ufs_panic (sb, "ufs_add_fragments",			"internal error or corrupted bitmap on cg %u", cgno);	fs32_sub(sb, &ucg->cg_frsum[fragsize], 1);	if (fragsize != count)		fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1);	for (i = oldcount; i < newcount; i++)		ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i);	if(DQUOT_ALLOC_BLOCK(inode, count)) {		*err = -EDQUOT;		return 0;	}	fs32_sub(sb, &ucg->cg_cs.cs_nffree, count);	fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);	uspi->cs_total.cs_nffree -= count;		ubh_mark_buffer_dirty (USPI_UBH(uspi));	ubh_mark_buffer_dirty (UCPI_UBH(ucpi));	if (sb->s_flags & MS_SYNCHRONOUS) {		ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));		ubh_wait_on_buffer (UCPI_UBH(ucpi));	}	sb->s_dirt = 1;	UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment);		return fragment;}#define UFS_TEST_FREE_SPACE_CG \	ucg = (struct ufs_cylinder_group *) UFS_SB(sb)->s_ucg[cgno]->b_data; \	if (fs32_to_cpu(sb, ucg->cg_cs.cs_nbfree)) \		goto cg_found; \	for (k = count; k < uspi->s_fpb; k++) \		if (fs32_to_cpu(sb, ucg->cg_frsum[k])) \			goto cg_found; static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno,			       u64 goal, unsigned count, int *err){	struct super_block * sb;	struct ufs_sb_private_info * uspi;	struct ufs_super_block_first * usb1;	struct ufs_cg_private_info * ucpi;	struct ufs_cylinder_group * ucg;	unsigned oldcg, i, j, k, allocsize;	u64 result;		UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n",	     inode->i_ino, cgno, (unsigned long long)goal, count);	sb = inode->i_sb;	uspi = UFS_SB(sb)->s_uspi;	usb1 = ubh_get_usb_first(uspi);	oldcg = cgno;		/*	 * 1. searching on preferred cylinder group	 */	UFS_TEST_FREE_SPACE_CG	/*	 * 2. quadratic rehash	 */	for (j = 1; j < uspi->s_ncg; j *= 2) {		cgno += j;		if (cgno >= uspi->s_ncg) 			cgno -= uspi->s_ncg;		UFS_TEST_FREE_SPACE_CG	}	/*	 * 3. brute force search	 * We start at i = 2 ( 0 is checked at 1.step, 1 at 2.step )	 */	cgno = (oldcg + 1) % uspi->s_ncg;	for (j = 2; j < uspi->s_ncg; j++) {		cgno++;		if (cgno >= uspi->s_ncg)			cgno = 0;		UFS_TEST_FREE_SPACE_CG	}		UFSD("EXIT (FAILED)\n");	return 0;cg_found:	ucpi = ufs_load_cylinder (sb, cgno);	if (!ucpi)		return 0;	ucg = ubh_get_ucg (UCPI_UBH(ucpi));	if (!ufs_cg_chkmagic(sb, ucg)) 		ufs_panic (sb, "ufs_alloc_fragments",			"internal error, bad magic number on cg %u", cgno);	ucg->cg_time = cpu_to_fs32(sb, get_seconds());	if (count == uspi->s_fpb) {		result = ufs_alloccg_block (inode, ucpi, goal, err);		if (result == INVBLOCK)			return 0;		goto succed;	}	for (allocsize = count; allocsize < uspi->s_fpb; allocsize++)		if (fs32_to_cpu(sb, ucg->cg_frsum[allocsize]) != 0)			break;		if (allocsize == uspi->s_fpb) {		result = ufs_alloccg_block (inode, ucpi, goal, err);		if (result == INVBLOCK)			return 0;		goal = ufs_dtogd(uspi, result);		for (i = count; i < uspi->s_fpb; i++)			ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i);		i = uspi->s_fpb - count;		DQUOT_FREE_BLOCK(inode, i);		fs32_add(sb, &ucg->cg_cs.cs_nffree, i);		uspi->cs_total.cs_nffree += i;		fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i);		fs32_add(sb, &ucg->cg_frsum[i], 1);		goto succed;	}	result = ufs_bitmap_search (sb, ucpi, goal, allocsize);	if (result == INVBLOCK)		return 0;	if(DQUOT_ALLOC_BLOCK(inode, count)) {		*err = -EDQUOT;		return 0;	}	for (i = 0; i < count; i++)		ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i);		fs32_sub(sb, &ucg->cg_cs.cs_nffree, count);	uspi->cs_total.cs_nffree -= count;	fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);	fs32_sub(sb, &ucg->cg_frsum[allocsize], 1);	if (count != allocsize)		fs32_add(sb, &ucg->cg_frsum[allocsize - count], 1);succed:	ubh_mark_buffer_dirty (USPI_UBH(uspi));	ubh_mark_buffer_dirty (UCPI_UBH(ucpi));	if (sb->s_flags & MS_SYNCHRONOUS) {		ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));		ubh_wait_on_buffer (UCPI_UBH(ucpi));	}	sb->s_dirt = 1;	result += cgno * uspi->s_fpg;	UFSD("EXIT3, result %llu\n", (unsigned long long)result);	return result;}static u64 ufs_alloccg_block(struct inode *inode,			     struct ufs_cg_private_info *ucpi,			     u64 goal, int *err){	struct super_block * sb;	struct ufs_sb_private_info * uspi;	struct ufs_super_block_first * usb1;	struct ufs_cylinder_group * ucg;	u64 result, blkno;	UFSD("ENTER, goal %llu\n", (unsigned long long)goal);	sb = inode->i_sb;	uspi = UFS_SB(sb)->s_uspi;	usb1 = ubh_get_usb_first(uspi);	ucg = ubh_get_ucg(UCPI_UBH(ucpi));	if (goal == 0) {		goal = ucpi->c_rotor;		goto norot;	}	goal = ufs_blknum (goal);	goal = ufs_dtogd(uspi, goal);		/*	 * If the requested block is available, use it.	 */	if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) {		result = goal;		goto gotit;	}	norot:		result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb);	if (result == INVBLOCK)		return INVBLOCK;	ucpi->c_rotor = result;gotit:	blkno = ufs_fragstoblks(result);	ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);	if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)		ufs_clusteracct (sb, ucpi, blkno, -1);	if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) {		*err = -EDQUOT;		return INVBLOCK;	}	fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1);	uspi->cs_total.cs_nbfree--;	fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1);	if (uspi->fs_magic != UFS2_MAGIC) {		unsigned cylno = ufs_cbtocylno((unsigned)result);		fs16_sub(sb, &ubh_cg_blks(ucpi, cylno,					  ufs_cbtorpos((unsigned)result)), 1);		fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1);	}		UFSD("EXIT, result %llu\n", (unsigned long long)result);	return result;}static unsigned ubh_scanc(struct ufs_sb_private_info *uspi,			  struct ufs_buffer_head *ubh,			  unsigned begin, unsigned size,			  unsigned char *table, unsigned char mask){	unsigned rest, offset;	unsigned char *cp;		offset = begin & ~uspi->s_fmask;	begin >>= uspi->s_fshift;	for (;;) {		if ((offset + size) < uspi->s_fsize)			rest = size;		else			rest = uspi->s_fsize - offset;		size -= rest;		cp = ubh->bh[begin]->b_data + offset;		while ((table[*cp++] & mask) == 0 && --rest)			;		if (rest || !size)			break;		begin++;		offset = 0;	}	return (size + rest);}/* * Find a block of the specified size in the specified cylinder group. * @sp: pointer to super block * @ucpi: pointer to cylinder group info * @goal: near which block we want find new one * @count: specified size */static u64 ufs_bitmap_search(struct super_block *sb,			     struct ufs_cg_private_info *ucpi,			     u64 goal, unsigned count){	/*	 * Bit patterns for identifying fragments in the block map	 * used as ((map & mask_arr) == want_arr)	 */	static const int mask_arr[9] = {		0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff	};	static const int want_arr[9] = {		0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe	};	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;	struct ufs_super_block_first *usb1;	struct ufs_cylinder_group *ucg;	unsigned start, length, loc;	unsigned pos, want, blockmap, mask, end;	u64 result;	UFSD("ENTER, cg %u, goal %llu, count %u\n", ucpi->c_cgx,	     (unsigned long long)goal, count);	usb1 = ubh_get_usb_first (uspi);	ucg = ubh_get_ucg(UCPI_UBH(ucpi));	if (goal)		start = ufs_dtogd(uspi, goal) >> 3;	else		start = ucpi->c_frotor >> 3;			length = ((uspi->s_fpg + 7) >> 3) - start;	loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff + start, length,		(uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other,		1 << (count - 1 + (uspi->s_fpb & 7))); 	if (loc == 0) {		length = start + 1;		loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, length,				(uspi->s_fpb == 8) ? ufs_fragtable_8fpb :				ufs_fragtable_other,				1 << (count - 1 + (uspi->s_fpb & 7)));		if (loc == 0) {			ufs_error(sb, "ufs_bitmap_search",				  "bitmap corrupted on cg %u, start %u,"				  " length %u, count %u, freeoff %u\n",				  ucpi->c_cgx, start, length, count,				  ucpi->c_freeoff);			return INVBLOCK;		}		start = 0;	}	result = (start + length - loc) << 3;	ucpi->c_frotor = result;	/*	 * found the byte in the map	 */	for (end = result + 8; result < end; result += uspi->s_fpb) {		blockmap = ubh_blkmap(UCPI_UBH(ucpi), ucpi->c_freeoff, result);		blockmap <<= 1;		mask = mask_arr[count];		want = want_arr[count];		for (pos = 0; pos <= uspi->s_fpb - count; pos++) {			if ((blockmap & mask) == want) {				UFSD("EXIT, result %llu\n",				     (unsigned long long)result);				return result + pos; 			}			mask <<= 1;			want <<= 1; 		} 	}	ufs_error(sb, "ufs_bitmap_search", "block not in map on cg %u\n",		  ucpi->c_cgx);	UFSD("EXIT (FAILED)\n");	return INVBLOCK;}static void ufs_clusteracct(struct super_block * sb,	struct ufs_cg_private_info * ucpi, unsigned blkno, int cnt){	struct ufs_sb_private_info * uspi;	int i, start, end, forw, back;		uspi = UFS_SB(sb)->s_uspi;	if (uspi->s_contigsumsize <= 0)		return;	if (cnt > 0)		ubh_setbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno);	else		ubh_clrbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno);	/*	 * Find the size of the cluster going forward.	 */	start = blkno + 1;	end = start + uspi->s_contigsumsize;	if ( end >= ucpi->c_nclusterblks)		end = ucpi->c_nclusterblks;	i = ubh_find_next_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, end, start);	if (i > end)		i = end;	forw = i - start;		/*	 * Find the size of the cluster going backward.	 */	start = blkno - 1;	end = start - uspi->s_contigsumsize;	if (end < 0 ) 		end = -1;	i = ubh_find_last_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, start, end);	if ( i < end) 		i = end;	back = start - i;		/*	 * Account for old cluster and the possibly new forward and	 * back clusters.	 */	i = back + forw + 1;	if (i > uspi->s_contigsumsize)		i = uspi->s_contigsumsize;	fs32_add(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (i << 2)), cnt);	if (back > 0)		fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (back << 2)), cnt);	if (forw > 0)		fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (forw << 2)), cnt);}static unsigned char ufs_fragtable_8fpb[] = {	0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,		0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0A,	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 0x08, 0x09, 0x09, 0x0A, 0x10, 0x11, 0x20, 0x40,	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0A,	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0A, 0x12,	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0C,	0x08, 0x09, 0x09, 0x0A, 0x09, 0x09, 0x0A, 0x0C, 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,};static unsigned char ufs_fragtable_other[] = {	0x00, 0x16, 0x16, 0x2A, 0x16, 0x16, 0x26, 0x4E, 0x16, 0x16, 0x16, 0x3E, 0x2A, 0x3E, 0x4E, 0x8A,	0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,	0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,	0x2A, 0x3E, 0x3E, 0x2A, 0x3E, 0x3E, 0x2E, 0x6E, 0x3E, 0x3E, 0x3E, 0x3E, 0x2A, 0x3E, 0x6E, 0xAA,	0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,	0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,	0x26, 0x36, 0x36, 0x2E, 0x36, 0x36, 0x26, 0x6E, 0x36, 0x36, 0x36, 0x3E, 0x2E, 0x3E, 0x6E, 0xAE,	0x4E, 0x5E, 0x5E, 0x6E, 0x5E, 0x5E, 0x6E, 0x4E, 0x5E, 0x5E, 0x5E, 0x7E, 0x6E, 0x7E, 0x4E, 0xCE,	0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,	0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,	0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,	0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xBE,	0x2A, 0x3E, 0x3E, 0x2A, 0x3E, 0x3E, 0x2E, 0x6E, 0x3E, 0x3E, 0x3E, 0x3E, 0x2A, 0x3E, 0x6E, 0xAA,	0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E,	0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xBE,	0x4E, 0x5E, 0x5E, 0x6E, 0x5E, 0x5E, 0x6E, 0x4E, 0x5E, 0x5E, 0x5E, 0x7E, 0x6E, 0x7E, 0x4E, 0xCE,	0x8A, 0x9E, 0x9E, 0xAA, 0x9E, 0x9E, 0xAE, 0xCE, 0x9E, 0x9E, 0x9E, 0xBE, 0xAA, 0xBE, 0xCE, 0x8A,};

⌨️ 快捷键说明

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