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

📄 inode.c

📁 介绍LINUX的文件系统,来自网络,是一篇阐述文件系统的好文章
💻 C
📖 第 1 页 / 共 2 页
字号:
	const char *name;		/* got from dentry */	int len;	res = -EACCES;			/* placeholder for "no data here" */	offset = dir->i_ino & ROMFH_MASK;	if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)		goto out;	maxoff = dir->i_sb->u.romfs_sb.s_maxsize;	offset = ntohl(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 = ntohl(ri.next) & ROMFH_MASK;	}	/* Hard link handling */	if ((ntohl(ri.next) & ROMFH_TYPE) == ROMFH_HRD)		offset = ntohl(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:	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;	unsigned long 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->index << PAGE_CACHE_SHIFT;	if (offset < inode->i_size) {		avail = inode->i_size-offset;		readlen = min_t(unsigned long, avail, PAGE_SIZE);		if (romfs_copyfrom(inode, buf, inode->u.romfs_i.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);	UnlockPage(page);	kunmap(page);err_out:	page_cache_release(page);	unlock_kernel();	return result;}/* Mapping from our types to the kernel */static struct address_space_operations romfs_aops = {	readpage: romfs_readpage};static struct file_operations romfs_dir_operations = {	read:		generic_read_dir,	readdir:	romfs_readdir,};static 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 = ntohl(ri.next);		if ((nextfh & ROMFH_TYPE) != ROMFH_HRD)			break;		ino = ntohl(ri.spec) & ROMFH_MASK;	}	i->i_nlink = 1;		/* Hard to decide.. */	i->i_size = ntohl(ri.size);	i->i_mtime = i->i_atime = i->i_ctime = 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;        i->u.romfs_i.i_metasize = ino;        i->u.romfs_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 = i->u.romfs_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 = ntohl(ri.spec);			nextfh = kdev_t_to_nr(MKDEV(nextfh>>16,nextfh&0xffff));			init_special_inode(i, ino, nextfh);	}}static struct super_operations romfs_ops = {	read_inode:	romfs_read_inode,	statfs:		romfs_statfs,};static DECLARE_FSTYPE_DEV(romfs_fs_type, "romfs", romfs_read_super);static int __init init_romfs_fs(void){	return register_filesystem(&romfs_fs_type);}static void __exit exit_romfs_fs(void){	unregister_filesystem(&romfs_fs_type);}/* Yes, works even as a module... :) */EXPORT_NO_SYMBOLS;module_init(init_romfs_fs)module_exit(exit_romfs_fs)MODULE_LICENSE("GPL");inding 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 = ntohl(ri.next);		if ((nextfh & ROMFH_TYPE) != ROMFH_HRD)			break;		ino = ntohl(ri.spec) & ROMFH_MASK;	}	i->i_nlink = 1;		/* Hard to decide.. */	i->i_size = ntohl(ri.size);	i->i_mtime = i->i_atime = i->i_ctime = 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;        i->u.romfs_i.i_metasize = ino;        i->u.romfs_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 = i->u.romfs_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 = ntohl(ri.spec);			nextfh = kdev_t_to_nr(MKDEV(nextfh>>16,nextfh&0xffff));			init_special_inode(i, ino, nextfh);	}}static struct super_operations romfs_ops = {	read_inode:	romfs_read_inode,	statfs:		romfs_statfs,};static DECLARE_FSTYPE_DEV(romfs_fs_type, "romfs", romfs_read_super);static int __init init_romfs_fs(void){	return register_filesystem(&romfs_fs_type);}static void __exit exit_romfs_fs(void){	unregister_filesystem(&romfs_fs_type);}/* Yes, works even as a module... :) */EXPORT_NO_SYMBOLS;module_init(init_romfs_fs)module_exit(exit_romfs_fs)MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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