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

📄 inode.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		stored++;		offset = nextfh & ROMFH_MASK;	}out:	unlock_kernel();	return stored;}static struct dentry *romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){	unsigned long offset, maxoff;	int fslen, res;	struct inode *inode;	char fsname[ROMFS_MAXFN];	/* XXX dynamic? */	struct romfs_inode ri;	const char *name;		/* got from dentry */	int len;	res = -EACCES;			/* placeholder for "no data here" */	offset = dir->i_ino & ROMFH_MASK;	lock_kernel();	if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)		goto out;	maxoff = romfs_maxsize(dir->i_sb);	offset = be32_to_cpu(ri.spec) & ROMFH_MASK;	/* OK, now find the file whose name is in "dentry" in the	 * directory specified by "dir".  */	name = dentry->d_name.name;	len = dentry->d_name.len;	for(;;) {		if (!offset || offset >= maxoff)			goto out0;		if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)			goto out;		/* try to match the first 16 bytes of name */		fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE);		if (len < ROMFH_SIZE) {			if (len == fslen) {				/* both are shorter, and same size */				romfs_copyfrom(dir, fsname, offset+ROMFH_SIZE, len+1);				if (strncmp (name, fsname, len) == 0)					break;			}		} else if (fslen >= ROMFH_SIZE) {			/* both are longer; XXX optimize max size */			fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, sizeof(fsname)-1);			if (len == fslen) {				romfs_copyfrom(dir, fsname, offset+ROMFH_SIZE, len+1);				if (strncmp(name, fsname, len) == 0)					break;			}		}		/* next entry */		offset = be32_to_cpu(ri.next) & ROMFH_MASK;	}	/* Hard link handling */	if ((be32_to_cpu(ri.next) & ROMFH_TYPE) == ROMFH_HRD)		offset = be32_to_cpu(ri.spec) & ROMFH_MASK;	if ((inode = iget(dir->i_sb, offset)))		goto outi;	/*	 * it's a bit funky, _lookup needs to return an error code	 * (negative) or a NULL, both as a dentry.  ENOENT should not	 * be returned, instead we need to create a negative dentry by	 * d_add(dentry, NULL); and return 0 as no error.	 * (Although as I see, it only matters on writable file	 * systems).	 */out0:	inode = NULL;outi:	res = 0;	d_add (dentry, inode);out:	unlock_kernel();	return ERR_PTR(res);}/* * Ok, we do readpage, to be able to execute programs.  Unfortunately, * we can't use bmap, since we may have looser alignments. */static intromfs_readpage(struct file *file, struct page * page){	struct inode *inode = page->mapping->host;	loff_t offset, avail, readlen;	void *buf;	int result = -EIO;	page_cache_get(page);	lock_kernel();	buf = kmap(page);	if (!buf)		goto err_out;	/* 32 bit warning -- but not for us :) */	offset = page_offset(page);	if (offset < i_size_read(inode)) {		avail = inode->i_size-offset;		readlen = min_t(unsigned long, avail, PAGE_SIZE);		if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) {			if (readlen < PAGE_SIZE) {				memset(buf + readlen,0,PAGE_SIZE-readlen);			}			SetPageUptodate(page);			result = 0;		}	}	if (result) {		memset(buf, 0, PAGE_SIZE);		SetPageError(page);	}	flush_dcache_page(page);	unlock_page(page);	kunmap(page);err_out:	page_cache_release(page);	unlock_kernel();	return result;}/* Mapping from our types to the kernel */static const struct address_space_operations romfs_aops = {	.readpage = romfs_readpage};static const struct file_operations romfs_dir_operations = {	.read		= generic_read_dir,	.readdir	= romfs_readdir,};static const struct inode_operations romfs_dir_inode_operations = {	.lookup		= romfs_lookup,};static mode_t romfs_modemap[] ={	0, S_IFDIR+0644, S_IFREG+0644, S_IFLNK+0777,	S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644};static voidromfs_read_inode(struct inode *i){	int nextfh, ino;	struct romfs_inode ri;	ino = i->i_ino & ROMFH_MASK;	i->i_mode = 0;	/* Loop for finding the real hard link */	for(;;) {		if (romfs_copyfrom(i, &ri, ino, ROMFH_SIZE) <= 0) {			printk("romfs: read error for inode 0x%x\n", ino);			return;		}		/* XXX: do romfs_checksum here too (with name) */		nextfh = be32_to_cpu(ri.next);		if ((nextfh & ROMFH_TYPE) != ROMFH_HRD)			break;		ino = be32_to_cpu(ri.spec) & ROMFH_MASK;	}	i->i_nlink = 1;		/* Hard to decide.. */	i->i_size = be32_to_cpu(ri.size);	i->i_mtime.tv_sec = i->i_atime.tv_sec = i->i_ctime.tv_sec = 0;	i->i_mtime.tv_nsec = i->i_atime.tv_nsec = i->i_ctime.tv_nsec = 0;	i->i_uid = i->i_gid = 0;        /* Precalculate the data offset */        ino = romfs_strnlen(i, ino+ROMFH_SIZE, ROMFS_MAXFN);        if (ino >= 0)                ino = ((ROMFH_SIZE+ino+1+ROMFH_PAD)&ROMFH_MASK);        else                ino = 0;        ROMFS_I(i)->i_metasize = ino;        ROMFS_I(i)->i_dataoffset = ino+(i->i_ino&ROMFH_MASK);        /* Compute permissions */        ino = romfs_modemap[nextfh & ROMFH_TYPE];	/* only "normal" files have ops */	switch (nextfh & ROMFH_TYPE) {		case 1:			i->i_size = ROMFS_I(i)->i_metasize;			i->i_op = &romfs_dir_inode_operations;			i->i_fop = &romfs_dir_operations;			if (nextfh & ROMFH_EXEC)				ino |= S_IXUGO;			i->i_mode = ino;			break;		case 2:			i->i_fop = &generic_ro_fops;			i->i_data.a_ops = &romfs_aops;			if (nextfh & ROMFH_EXEC)				ino |= S_IXUGO;			i->i_mode = ino;			break;		case 3:			i->i_op = &page_symlink_inode_operations;			i->i_data.a_ops = &romfs_aops;			i->i_mode = ino | S_IRWXUGO;			break;		default:			/* depending on MBZ for sock/fifos */			nextfh = be32_to_cpu(ri.spec);			init_special_inode(i, ino,					MKDEV(nextfh>>16,nextfh&0xffff));	}}static struct kmem_cache * romfs_inode_cachep;static struct inode *romfs_alloc_inode(struct super_block *sb){	struct romfs_inode_info *ei;	ei = kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL);	if (!ei)		return NULL;	return &ei->vfs_inode;}static void romfs_destroy_inode(struct inode *inode){	kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode));}static void init_once(struct kmem_cache *cachep, void *foo){	struct romfs_inode_info *ei = foo;	inode_init_once(&ei->vfs_inode);}static int init_inodecache(void){	romfs_inode_cachep = kmem_cache_create("romfs_inode_cache",					     sizeof(struct romfs_inode_info),					     0, (SLAB_RECLAIM_ACCOUNT|						SLAB_MEM_SPREAD),					     init_once);	if (romfs_inode_cachep == NULL)		return -ENOMEM;	return 0;}static void destroy_inodecache(void){	kmem_cache_destroy(romfs_inode_cachep);}static int romfs_remount(struct super_block *sb, int *flags, char *data){	*flags |= MS_RDONLY;	return 0;}static const struct super_operations romfs_ops = {	.alloc_inode	= romfs_alloc_inode,	.destroy_inode	= romfs_destroy_inode,	.read_inode	= romfs_read_inode,	.statfs		= romfs_statfs,	.remount_fs	= romfs_remount,};static int romfs_get_sb(struct file_system_type *fs_type,	int flags, const char *dev_name, void *data, struct vfsmount *mnt){	return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super,			   mnt);}static struct file_system_type romfs_fs_type = {	.owner		= THIS_MODULE,	.name		= "romfs",	.get_sb		= romfs_get_sb,	.kill_sb	= kill_block_super,	.fs_flags	= FS_REQUIRES_DEV,};static int __init init_romfs_fs(void){	int err = init_inodecache();	if (err)		goto out1;        err = register_filesystem(&romfs_fs_type);	if (err)		goto out;	return 0;out:	destroy_inodecache();out1:	return err;}static void __exit exit_romfs_fs(void){	unregister_filesystem(&romfs_fs_type);	destroy_inodecache();}/* Yes, works even as a module... :) */module_init(init_romfs_fs)module_exit(exit_romfs_fs)MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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