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

📄 inode.c

📁 linux平台下的systv文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	struct super_block *sb;	int ret, err, new;	struct buffer_head *bh;	unsigned long ptr, phys;	if (!create) {		phys = sysv_block_map(inode, iblock);		if (phys) {			bh_result->b_dev = inode->i_dev;			bh_result->b_blocknr = phys;			bh_result->b_state |= (1UL << BH_Mapped);		}		return 0;	}	err = -EIO;	new = 0;	ret = 0;	bh = NULL;	lock_kernel();	sb = inode->i_sb;	if (iblock < 0)		goto abort_negative;	if (iblock > sb->sv_ind_per_block_3)		goto abort_too_big;	err = 0;	ptr = iblock;	/*	 * ok, these macros clean the logic up a bit and make	 * it much more readable:	 */#define GET_INODE_DATABLOCK(x) \		inode_getblk(inode, x, iblock, &err, 0, &phys, &new)#define GET_INODE_PTR(x) \		inode_getblk(inode, x, iblock, &err, 1, NULL, NULL)#define GET_INDIRECT_DATABLOCK(x) \		block_getblk (inode, bh, x, iblock, &err, 0, &phys, &new);#define GET_INDIRECT_PTR(x) \		block_getblk (inode, bh, x, iblock, &err, 1, NULL, NULL);	if (ptr < 10) {		bh = GET_INODE_DATABLOCK(ptr);		goto out;	}	ptr -= 10;	if (ptr < sb->sv_ind_per_block) {		bh = GET_INODE_PTR(10);		goto get_indirect;	}	ptr -= sb->sv_ind_per_block;	if (ptr < sb->sv_ind_per_block_2) {		bh = GET_INODE_PTR(11);		goto get_double;	}	ptr -= sb->sv_ind_per_block_2;	bh = GET_INODE_PTR(12);	bh = GET_INDIRECT_PTR(ptr >> sb->sv_ind_per_block_2_bits);get_double:	bh = GET_INDIRECT_PTR((ptr >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1);get_indirect:	bh = GET_INDIRECT_DATABLOCK(ptr & sb->sv_ind_per_block_1);#undef GET_INODE_DATABLOCK#undef GET_INODE_PTR#undef GET_INDIRECT_DATABLOCK#undef GET_INDIRECT_PTRout:	if (err)		goto abort;	bh_result->b_dev = inode->i_dev;	bh_result->b_blocknr = phys;	bh_result->b_state |= (1UL << BH_Mapped);	if (new)		bh_result->b_state |= (1UL << BH_New);abort:	unlock_kernel();	return err;abort_negative:	printk("sysv_get_block: block < 0\n");	goto abort;abort_too_big:	printk("sysv_get_block: block > big\n");	goto abort;}static struct buffer_head *sysv_getblk(struct inode *inode, unsigned int block, int create){	struct buffer_head dummy;	int error;	dummy.b_state = 0;	dummy.b_blocknr = -1000;	error = sysv_get_block(inode, block, &dummy, create);	if (!error && buffer_mapped(&dummy)) {		struct buffer_head *bh;		bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->sv_block_size);		if (buffer_new(&dummy)) {			memset(bh->b_data, 0, inode->i_sb->sv_block_size);			mark_buffer_uptodate(bh, 1);			mark_buffer_dirty(bh);		}		return bh;	}	return NULL;}struct buffer_head *sysv_file_bread(struct inode *inode, int block, int create){	struct buffer_head *bh;	bh = sysv_getblk(inode, block, create);	if (!bh || buffer_uptodate(bh))		return bh;	ll_rw_block(READ, 1, &bh);	wait_on_buffer(bh);	if (buffer_uptodate(bh))		return bh;	brelse(bh);	return NULL;}static int sysv_writepage(struct page *page){	return block_write_full_page(page,sysv_get_block);}static int sysv_readpage(struct file *file, struct page *page){	return block_read_full_page(page,sysv_get_block);}static int sysv_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to){	return block_prepare_write(page,from,to,sysv_get_block);}static int sysv_bmap(struct address_space *mapping, long block){	return generic_block_bmap(mapping,block,sysv_get_block);}struct address_space_operations sysv_aops = {	readpage: sysv_readpage,	writepage: sysv_writepage,	sync_page: block_sync_page,	prepare_write: sysv_prepare_write,	commit_write: generic_commit_write,	bmap: sysv_bmap};#ifdef __BIG_ENDIANstatic inline unsigned long read3byte (unsigned char * p){	return (p[2] | (p[1]<<8) | (p[0]<<16));}static inline void write3byte (unsigned char *p , unsigned long val){	p[2]=val&0xFF;	p[1]=(val>>8)&0xFF;	p[0]=(val>>16)&0xFF;}#elsestatic inline unsigned long read3byte (unsigned char * p){	return (unsigned long)(*(unsigned short *)p)	     | (unsigned long)(*(unsigned char *)(p+2)) << 16;}static inline void write3byte (unsigned char * p, unsigned long val){	*(unsigned short *)p = (unsigned short) val;	*(unsigned char *)(p+2) = val >> 16;}#endifstatic inline unsigned long coh_read3byte (unsigned char * p){	return (unsigned long)(*(unsigned char *)p) << 16	     | (unsigned long)(*(unsigned short *)(p+1));}static inline void coh_write3byte (unsigned char * p, unsigned long val){	*(unsigned char *)p = val >> 16;	*(unsigned short *)(p+1) = (unsigned short) val;}struct inode_operations sysv_symlink_inode_operations = {	readlink:	page_readlink,	follow_link:	page_follow_link,	setattr:	sysv_notify_change,};static void sysv_read_inode(struct inode *inode){	struct super_block * sb = inode->i_sb;	struct buffer_head * bh;	struct sysv_inode * raw_inode;	unsigned int block, ino;	umode_t mode;	ino = inode->i_ino;	inode->i_mode = 0;	if (!ino || ino > sb->sv_ninodes) {		printk("Bad inode number on dev %s"		       ": %d is out of range\n",		       kdevname(inode->i_dev), ino);		return;	}	block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);	if (!(bh = sv_bread(sb,inode->i_dev,block))) {		printk("Major problem: unable to read inode from dev "		       "%s\n",		       kdevname(inode->i_dev));		return;	}	raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);	mode = raw_inode->i_mode;	if (sb->sv_kludge_symlinks)		mode = from_coh_imode(mode);	/* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */	inode->i_mode = mode;	inode->i_uid = (uid_t)raw_inode->i_uid;	inode->i_gid = (gid_t)raw_inode->i_gid;	inode->i_nlink = raw_inode->i_nlink;	if (sb->sv_convert) {		inode->i_size = from_coh_ulong(raw_inode->i_size);		inode->i_atime = from_coh_ulong(raw_inode->i_atime);		inode->i_mtime = from_coh_ulong(raw_inode->i_mtime);		inode->i_ctime = from_coh_ulong(raw_inode->i_ctime);	} else {		inode->i_size = raw_inode->i_size;		inode->i_atime = raw_inode->i_atime;		inode->i_mtime = raw_inode->i_mtime;		inode->i_ctime = raw_inode->i_ctime;	}	inode->i_blocks = inode->i_blksize = 0;	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))		;	else	if (sb->sv_convert)		for (block = 0; block < 10+1+1+1; block++)			inode->u.sysv_i.i_data[block] =				coh_read3byte(&raw_inode->i_a.i_addb[3*block]);	else		for (block = 0; block < 10+1+1+1; block++)			inode->u.sysv_i.i_data[block] =				read3byte(&raw_inode->i_a.i_addb[3*block]);	if (S_ISREG(inode->i_mode)) {		inode->i_op = &sysv_file_inode_operations;		inode->i_fop = &sysv_file_operations;		inode->i_mapping->a_ops = &sysv_aops;	} else if (S_ISDIR(inode->i_mode)) {		inode->i_op = &sysv_dir_inode_operations;		inode->i_fop = &sysv_dir_operations;	} else if (S_ISLNK(inode->i_mode)) {		inode->i_op = &sysv_symlink_inode_operations;		inode->i_mapping->a_ops = &sysv_aops;	} else		init_special_inode(inode, inode->i_mode,raw_inode->i_a.i_rdev);	brelse(bh);}/* To avoid inconsistencies between inodes in memory and inodes on disk. */int sysv_notify_change(struct dentry *dentry, struct iattr *attr){	struct inode *inode = dentry->d_inode;	int error;	if ((error = inode_change_ok(inode, attr)) != 0)		return error;	if (attr->ia_valid & ATTR_MODE)		if (inode->i_sb->sv_kludge_symlinks)			if (attr->ia_mode == COH_KLUDGE_SYMLINK_MODE)				attr->ia_mode = COH_KLUDGE_NOT_SYMLINK;	inode_setattr(inode, attr);	return 0;}static struct buffer_head * sysv_update_inode(struct inode * inode){	struct super_block * sb = inode->i_sb;	struct buffer_head * bh;	struct sysv_inode * raw_inode;	unsigned int ino, block;	umode_t mode;	ino = inode->i_ino;	if (!ino || ino > sb->sv_ninodes) {		printk("Bad inode number on dev %s"		       ": %d is out of range\n",		       kdevname(inode->i_dev), ino);		return 0;	}	block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);	if (!(bh = sv_bread(sb,inode->i_dev,block))) {		printk("unable to read i-node block\n");		return 0;	}	raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);	mode = inode->i_mode;	if (sb->sv_kludge_symlinks)		mode = to_coh_imode(mode);	raw_inode->i_mode = mode;	raw_inode->i_uid = fs_high2lowuid(inode->i_uid);	raw_inode->i_gid = fs_high2lowgid(inode->i_gid);	raw_inode->i_nlink = inode->i_nlink;	if (sb->sv_convert) {		raw_inode->i_size = to_coh_ulong(inode->i_size);		raw_inode->i_atime = to_coh_ulong(inode->i_atime);		raw_inode->i_mtime = to_coh_ulong(inode->i_mtime);		raw_inode->i_ctime = to_coh_ulong(inode->i_ctime);	} else {		raw_inode->i_size = inode->i_size;		raw_inode->i_atime = inode->i_atime;		raw_inode->i_mtime = inode->i_mtime;		raw_inode->i_ctime = inode->i_ctime;	}	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))		raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev); /* write 2 or 3 bytes ?? */	else	if (sb->sv_convert)		for (block = 0; block < 10+1+1+1; block++)			coh_write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);	else		for (block = 0; block < 10+1+1+1; block++)			write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);	mark_buffer_dirty(bh);	return bh;}void sysv_write_inode(struct inode * inode, int wait){	struct buffer_head *bh;	lock_kernel();	bh = sysv_update_inode(inode);	brelse(bh);	unlock_kernel();}int sysv_sync_inode(struct inode * inode){        int err = 0;        struct buffer_head *bh;        bh = sysv_update_inode(inode);        if (bh && buffer_dirty(bh)) {                ll_rw_block(WRITE, 1, &bh);                wait_on_buffer(bh);                if (buffer_req(bh) && !buffer_uptodate(bh))                {                        printk ("IO error syncing sysv inode ["				"%s:%08lx]\n",                                kdevname(inode->i_dev), inode->i_ino);                        err = -1;                }        }        else if (!bh)                err = -1;        brelse (bh);        return err;}/* Every kernel module contains stuff like this. */static DECLARE_FSTYPE_DEV(sysv_fs_type, "sysv", sysv_read_super);static int __init init_sysv_fs(void){	return register_filesystem(&sysv_fs_type);}static void __exit exit_sysv_fs(void){	unregister_filesystem(&sysv_fs_type);}EXPORT_NO_SYMBOLS;module_init(init_sysv_fs)module_exit(exit_sysv_fs)

⌨️ 快捷键说明

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