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

📄 inode.c

📁 linux平台下的systv文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))						goto bad_shift;					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;					goto ok;				}				if ((found = detect_sysv2(sb,bh)) != NULL) {					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))						goto bad_shift;					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;					goto ok;				}				brelse(bh);			}	}	bad_shift:	if (!silent)		printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "		       "%s\n", kdevname(dev));	failed:	return NULL;	ok:	if (sb->sv_block_size >= BLOCK_SIZE) {		if (sb->sv_block_size != BLOCK_SIZE) {			brelse(bh);			set_blocksize(dev, sb->sv_block_size);			blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;			if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)				goto bad_superblock;		}		switch (sb->sv_type) {			case FSTYPE_XENIX:				if (!detected_xenix(sb,bh,bh))					goto bad_superblock;				break;			case FSTYPE_SYSV4:				if (!detected_sysv4(sb,bh))					goto bad_superblock;				break;			case FSTYPE_SYSV2:				if (!detected_sysv2(sb,bh))					goto bad_superblock;				break;			default: goto bad_superblock;		goto superblock_ok;		bad_superblock:			brelse(bh);			printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);			goto failed;		superblock_ok:		}	} else {		/* Switch to 512 block size. Unfortunately, we have to		   release the block bh and read it again. */		struct buffer_head *bh1, *bh2;		unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;		brelse(bh);		set_blocksize(dev,sb->sv_block_size);		bh1 = NULL; bh2 = NULL;		switch (sb->sv_type) {			case FSTYPE_XENIX:				if ((bh1 = bread(dev, blocknr, sb->sv_block_size)) == NULL)					goto bad_superblock2;				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)					goto bad_superblock2;				if (!detected_xenix(sb,bh1,bh2))					goto bad_superblock2;				break;			case FSTYPE_SYSV4:				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)					goto bad_superblock2;				if (!detected_sysv4(sb,bh2))					goto bad_superblock2;				break;			case FSTYPE_SYSV2:				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)					goto bad_superblock2;				if (!detected_sysv2(sb,bh2))					goto bad_superblock2;				break;			case FSTYPE_COH:				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)					goto bad_superblock2;				if (!detected_coherent(sb,bh2))					goto bad_superblock2;				break;			default:			bad_superblock2:				brelse(bh1);				brelse(bh2);				set_blocksize(sb->s_dev,BLOCK_SIZE);				printk("SysV FS: cannot read superblock in 512 byte mode\n");				goto failed;		}	}	sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;	if (!silent)		printk("VFS: Found a %s FS (block size = %d) on device %s\n",		       found, sb->sv_block_size, kdevname(dev));	sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type;	/* The buffer code now supports block size 512 as well as 1024. */	sb->s_blocksize = sb->sv_block_size;	sb->s_blocksize_bits = sb->sv_block_size_bits;	/* set up enough so that it can read an inode */	sb->s_op = &sysv_sops;	root_inode = iget(sb,SYSV_ROOT_INO);	sb->s_root = d_alloc_root(root_inode);	if (!sb->s_root) {		printk("SysV FS: get root inode failed\n");		sysv_put_super(sb);		return NULL;	}#ifndef CONFIG_SYSV_FS_WRITE	sb->s_flags |= MS_RDONLY;#endif	sb->s_dirt = 1;	/* brelse(bh);  resp.  brelse(bh1); brelse(bh2);	   occurs when the disk is unmounted. */	return sb;}/* This is only called on sync() and umount(), when s_dirt=1. */static void sysv_write_super(struct super_block *sb){	if (buffer_dirty(sb->sv_bh1) || buffer_dirty(sb->sv_bh2)) {		/* If we are going to write out the super block,		   then attach current time stamp.		   But if the filesystem was marked clean, keep it clean. */		unsigned long time = CURRENT_TIME;		unsigned long old_time = *sb->sv_sb_time;		if (sb->sv_convert)			old_time = from_coh_ulong(old_time);		if (sb->sv_type == FSTYPE_SYSV4)			if (*sb->sv_sb_state == 0x7c269d38 - old_time)				*sb->sv_sb_state = 0x7c269d38 - time;		if (sb->sv_convert)			time = to_coh_ulong(time);		*sb->sv_sb_time = time;		mark_buffer_dirty(sb->sv_bh2);	}	sb->s_dirt = 0;}static void sysv_put_super(struct super_block *sb){	/* we can assume sysv_write_super() has already been called,	   and that the superblock is locked */	brelse(sb->sv_bh1);	if (sb->sv_bh1 != sb->sv_bh2) brelse(sb->sv_bh2);	/* switch back to default block size */	if (sb->s_blocksize != BLOCK_SIZE)		set_blocksize(sb->s_dev,BLOCK_SIZE);}static int sysv_statfs(struct super_block *sb, struct statfs *buf){	buf->f_type = sb->s_magic;			/* type of filesystem */	buf->f_bsize = sb->sv_block_size;		/* block size */	buf->f_blocks = sb->sv_ndatazones;		/* total data blocks in file system */	buf->f_bfree = sysv_count_free_blocks(sb);	/* free blocks in fs */	buf->f_bavail = buf->f_bfree;			/* free blocks available to non-superuser */	buf->f_files = sb->sv_ninodes;			/* total file nodes in file system */	buf->f_ffree = sysv_count_free_inodes(sb);	/* free file nodes in fs */	buf->f_namelen = SYSV_NAMELEN;	/* Don't know what value to put in buf->f_fsid */ /* file system id */	return 0;}/* bmap support for running executables and shared libraries. */static inline int inode_bmap(struct super_block * sb, struct inode * inode, int nr){	int tmp = inode->u.sysv_i.i_data[nr];	if (!tmp)		return 0;	return tmp + sb->sv_block_base;}static int block_bmap(struct super_block * sb, struct buffer_head * bh, int nr, int convert){	int tmp;	if (!bh)		return 0;	tmp = ((sysv_zone_t *) bh->b_data) [nr];	if (convert)		tmp = from_coh_ulong(tmp);	brelse(bh);	if (!tmp)		return 0;	return tmp + sb->sv_block_base;}static unsigned int sysv_block_map(struct inode *inode, unsigned int block){	struct super_block *sb;	int i, ret, convert;	ret = 0;	lock_kernel();	sb = inode->i_sb;	if (block < 10) {		ret = inode_bmap(sb, inode, block);		goto out;	}	block -= 10;	convert = sb->sv_convert;	if (block < sb->sv_ind_per_block) {		i = inode_bmap(sb, inode, 10);		if (!i)			goto out;		ret = block_bmap(sb,				 bread(inode->i_dev, i, sb->sv_block_size),				 block, convert);		goto out;	}	block -= sb->sv_ind_per_block;	if (block < sb->sv_ind_per_block_2) {		i = inode_bmap(sb, inode, 11);		if (!i)			goto out;		i = block_bmap(sb,			       bread(inode->i_dev, i, sb->sv_block_size),			       (block >> sb->sv_ind_per_block_bits), convert);		if (!i)			goto out;		ret = block_bmap(sb,				 bread(inode->i_dev, i, sb->sv_block_size),				 (block & sb->sv_ind_per_block_1), convert);		goto out;	}	block -= sb->sv_ind_per_block_2;	if (block < sb->sv_ind_per_block_3) {		i = inode_bmap(sb, inode, 12);		if (!i)			goto out;		i = block_bmap(sb,			       bread(inode->i_dev, i, sb->sv_block_size),			       (block >> sb->sv_ind_per_block_2_bits), convert);		if (!i)			goto out;		ret = block_bmap(sb,				 bread(inode->i_dev, i, sb->sv_block_size),				 ((block >> sb->sv_ind_per_block_bits) &				  sb->sv_ind_per_block_1), convert);		if (!i)			goto out;		ret = block_bmap(sb,				 bread(inode->i_dev, i, sb->sv_block_size),				 (block & sb->sv_ind_per_block_1), convert);		goto out;	}	if ((int)block < 0)		printk("sysv_block_map: block < 0\n");	else		printk("sysv_block_map: block > big\n");out:	unlock_kernel();	return ret;}/* End of bmap support. *//* Access selected blocks of regular files (or directories) */static struct buffer_head *inode_getblk(struct inode *inode, int nr, int new_block,	int *err, int metadata, long *phys, int *new){	struct super_block *sb;	u32 tmp;	u32 *p;	struct buffer_head * result;	sb = inode->i_sb;	p = inode->u.sysv_i.i_data + nr;repeat:	tmp = *p;	if (tmp) {		if (metadata) {			result = sv_getblk(sb, inode->i_dev, tmp);			if (tmp == *p)				return result;			brelse(result);			goto repeat;		} else {			*phys = tmp;			return NULL;		}	}	tmp = sysv_new_block(sb);	if (!tmp) {		*err = -ENOSPC;		return NULL;	}	if (metadata) {		result = sv_getblk(sb, inode->i_dev, tmp);		if (*p) {			sysv_free_block(sb, tmp);			brelse(result);			goto repeat;		}	} else {		if (*p) {			/*			 * Nobody is allowed to change block allocation			 * state from under us:			 */			BUG();			sysv_free_block(sb, tmp);			goto repeat;		}		*phys = tmp;		result = NULL;		*err = 0;		*new = 1;	}	*p = tmp;	inode->i_ctime = CURRENT_TIME;	mark_inode_dirty(inode);	return result;}static struct buffer_head *block_getblk(struct inode *inode,	struct buffer_head *bh, int nr, int new_block, int *err,	int metadata, long *phys, int *new){	struct super_block *sb;	u32 tmp, block;	sysv_zone_t *p;	struct buffer_head * result;	result = NULL;	if (!bh)		goto out;	if (!buffer_uptodate(bh)) {		ll_rw_block(READ, 1, &bh);		wait_on_buffer(bh);		if (!buffer_uptodate(bh))			goto out;	}	sb = inode->i_sb;	p = nr + (sysv_zone_t *) bh->b_data;repeat:	block = tmp = *p;	if (sb->sv_convert)		block = from_coh_ulong(block);	if (tmp) {		if (metadata) {			result = sv_getblk(sb, bh->b_dev, block);			if (tmp == *p)				goto out;			brelse(result);			goto repeat;		} else {			*phys = tmp;			goto out;		}	}	block = sysv_new_block(sb);	if (!block)		goto out;	if (metadata) {		result = sv_getblk(sb, bh->b_dev, block);		if (*p) {			sysv_free_block(sb, block);			brelse(result);			goto repeat;		}		memset(result->b_data, 0, sb->sv_block_size);		mark_buffer_uptodate(result, 1);		mark_buffer_dirty(result);	} else {		*phys = tmp;		*new = 1;	}	if (*p) {		sysv_free_block(sb, block);		brelse(result);		goto repeat;	}	*p = (sb->sv_convert ? to_coh_ulong(block) : block);	mark_buffer_dirty(bh);	*err = 0;out:	brelse(bh);	return result;}static int sysv_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)

⌨️ 快捷键说明

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