inode.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 604 行 · 第 1/2 页

C
604
字号
 * of the directory entry. */static const char *qnx4_checkroot(struct super_block *sb){	struct buffer_head *bh;	struct qnx4_inode_entry *rootdir;	int rd, rl;	int i, j;	int found = 0;	if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') {		return "no qnx4 filesystem (no root dir).";	} else {		QNX4DEBUG(("QNX4 filesystem found on dev %s.\n", sb->s_id));		rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;		rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);		for (j = 0; j < rl; j++) {			bh = sb_bread(sb, rd + j);	/* root dir, first block */			if (bh == NULL) {				return "unable to read root entry.";			}			for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) {				rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);				if (rootdir->di_fname != NULL) {					QNX4DEBUG(("Rootdir entry found : [%s]\n", rootdir->di_fname));					if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) {						found = 1;						qnx4_sb(sb)->BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL );						if (!qnx4_sb(sb)->BitMap) {							brelse (bh);							return "not enough memory for bitmap inode";						}						memcpy( qnx4_sb(sb)->BitMap, rootdir, sizeof( struct qnx4_inode_entry ) );	/* keep bitmap inode known */						break;					}				}			}			brelse(bh);			if (found != 0) {				break;			}		}		if (found == 0) {			return "bitmap file not found.";		}	}	return NULL;}static int qnx4_fill_super(struct super_block *s, void *data, int silent){	struct buffer_head *bh;	struct inode *root;	const char *errmsg;	struct qnx4_sb_info *qs;	qs = kmalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);	if (!qs)		return -ENOMEM;	s->s_fs_info = qs;	memset(qs, 0, sizeof(struct qnx4_sb_info));	sb_set_blocksize(s, QNX4_BLOCK_SIZE);	/* Check the superblock signature. Since the qnx4 code is	   dangerous, we should leave as quickly as possible	   if we don't belong here... */	bh = sb_bread(s, 1);	if (!bh) {		printk("qnx4: unable to read the superblock\n");		goto outnobh;	}	if ( le32_to_cpu( *(__u32*)bh->b_data ) != QNX4_SUPER_MAGIC ) {		if (!silent)			printk("qnx4: wrong fsid in superblock.\n");		goto out;	}	s->s_op = &qnx4_sops;	s->s_magic = QNX4_SUPER_MAGIC;#ifndef CONFIG_QNX4FS_RW	s->s_flags |= MS_RDONLY;	/* Yup, read-only yet */#endif	qnx4_sb(s)->sb_buf = bh;	qnx4_sb(s)->sb = (struct qnx4_super_block *) bh->b_data; 	/* check before allocating dentries, inodes, .. */	errmsg = qnx4_checkroot(s);	if (errmsg != NULL) { 		if (!silent) 			printk("qnx4: %s\n", errmsg);		goto out;	} 	/* does root not have inode number QNX4_ROOT_INO ?? */ 	root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); 	if (!root) { 		printk("qnx4: get inode failed\n"); 		goto out; 	} 	s->s_root = d_alloc_root(root); 	if (s->s_root == NULL) 		goto outi;	brelse(bh);	return 0;      outi:	iput(root);      out:	brelse(bh);      outnobh:	kfree(qs);	s->s_fs_info = NULL;	return -EINVAL;}static void qnx4_put_super(struct super_block *sb){	struct qnx4_sb_info *qs = qnx4_sb(sb);	kfree( qs->BitMap );	kfree( qs );	sb->s_fs_info = NULL;	return;}static int qnx4_writepage(struct page *page, struct writeback_control *wbc){	return block_write_full_page(page,qnx4_get_block, wbc);}static int qnx4_readpage(struct file *file, struct page *page){	return block_read_full_page(page,qnx4_get_block);}static int qnx4_prepare_write(struct file *file, struct page *page,			      unsigned from, unsigned to){	struct qnx4_inode_info *qnx4_inode = qnx4_i(page->mapping->host);	return cont_prepare_write(page, from, to, qnx4_get_block,				  &qnx4_inode->mmu_private);}static sector_t qnx4_bmap(struct address_space *mapping, sector_t block){	return generic_block_bmap(mapping,block,qnx4_get_block);}struct address_space_operations qnx4_aops = {	.readpage	= qnx4_readpage,	.writepage	= qnx4_writepage,	.sync_page	= block_sync_page,	.prepare_write	= qnx4_prepare_write,	.commit_write	= generic_commit_write,	.bmap		= qnx4_bmap};static void qnx4_read_inode(struct inode *inode){	struct buffer_head *bh;	struct qnx4_inode_entry *raw_inode;	int block, ino;	struct super_block *sb = inode->i_sb;	struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);	ino = inode->i_ino;	inode->i_mode = 0;	QNX4DEBUG(("Reading inode : [%d]\n", ino));	if (!ino) {		printk("qnx4: bad inode number on dev %s: %d is out of range\n",		       sb->s_id, ino);		return;	}	block = ino / QNX4_INODES_PER_BLOCK;	if (!(bh = sb_bread(sb, block))) {		printk("qnx4: major problem: unable to read inode from dev "		       "%s\n", sb->s_id);		return;	}	raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +	    (ino % QNX4_INODES_PER_BLOCK);	inode->i_mode    = le16_to_cpu(raw_inode->di_mode);	inode->i_uid     = (uid_t)le16_to_cpu(raw_inode->di_uid);	inode->i_gid     = (gid_t)le16_to_cpu(raw_inode->di_gid);	inode->i_nlink   = le16_to_cpu(raw_inode->di_nlink);	inode->i_size    = le32_to_cpu(raw_inode->di_size);	inode->i_mtime.tv_sec   = le32_to_cpu(raw_inode->di_mtime);	inode->i_mtime.tv_nsec = 0;	inode->i_atime.tv_sec   = le32_to_cpu(raw_inode->di_atime);	inode->i_atime.tv_nsec = 0;	inode->i_ctime.tv_sec   = le32_to_cpu(raw_inode->di_ctime);	inode->i_ctime.tv_nsec = 0;	inode->i_blocks  = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);	inode->i_blksize = QNX4_DIR_ENTRY_SIZE;	memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE);	if (S_ISREG(inode->i_mode)) {		inode->i_op = &qnx4_file_inode_operations;		inode->i_fop = &qnx4_file_operations;		inode->i_mapping->a_ops = &qnx4_aops;		qnx4_i(inode)->mmu_private = inode->i_size;	} else if (S_ISDIR(inode->i_mode)) {		inode->i_op = &qnx4_dir_inode_operations;		inode->i_fop = &qnx4_dir_operations;	} else if (S_ISLNK(inode->i_mode)) {		inode->i_op = &page_symlink_inode_operations;		inode->i_mapping->a_ops = &qnx4_aops;		qnx4_i(inode)->mmu_private = inode->i_size;	} else		printk("qnx4: bad inode %d on dev %s\n",ino,sb->s_id);	brelse(bh);}static kmem_cache_t *qnx4_inode_cachep;static struct inode *qnx4_alloc_inode(struct super_block *sb){	struct qnx4_inode_info *ei;	ei = kmem_cache_alloc(qnx4_inode_cachep, SLAB_KERNEL);	if (!ei)		return NULL;	return &ei->vfs_inode;}static void qnx4_destroy_inode(struct inode *inode){	kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));}static void init_once(void *foo, kmem_cache_t * cachep,		      unsigned long flags){	struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;	if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==	    SLAB_CTOR_CONSTRUCTOR)		inode_init_once(&ei->vfs_inode);}static int init_inodecache(void){	qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache",					     sizeof(struct qnx4_inode_info),					     0, SLAB_RECLAIM_ACCOUNT,					     init_once, NULL);	if (qnx4_inode_cachep == NULL)		return -ENOMEM;	return 0;}static void destroy_inodecache(void){	if (kmem_cache_destroy(qnx4_inode_cachep))		printk(KERN_INFO		       "qnx4_inode_cache: not all structures were freed\n");}static struct super_block *qnx4_get_sb(struct file_system_type *fs_type,	int flags, const char *dev_name, void *data){	return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super);}static struct file_system_type qnx4_fs_type = {	.owner		= THIS_MODULE,	.name		= "qnx4",	.get_sb		= qnx4_get_sb,	.kill_sb	= kill_block_super,	.fs_flags	= FS_REQUIRES_DEV,};static int __init init_qnx4_fs(void){	int err;	err = init_inodecache();	if (err)		return err;	err = register_filesystem(&qnx4_fs_type);	if (err) {		destroy_inodecache();		return err;	}	printk("QNX4 filesystem 0.2.3 registered.\n");	return 0;}static void __exit exit_qnx4_fs(void){	unregister_filesystem(&qnx4_fs_type);	destroy_inodecache();}module_init(init_qnx4_fs)module_exit(exit_qnx4_fs)MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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