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

📄 super.c

📁 嵌入式linux下基于SRAM的内存文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* Read the superblock */	if (pram_calc_checksum((u32*)super, PRAM_SB_SIZE>>2)) {		pram_err("checksum error in super block!\n");		goto out;	}#ifdef CONFIG_PRAMFS_VNVRAM	if (sbi->vnvram && super->s_size > sbi->vnvram->size) {		pram_err("pramfs image size 0x%x too large, vnvram only 0x%x",			 super->s_size, sbi->vnvram->size);		goto out;	}#endif /* CONFIG_PRAMFS_VNVRAM */	/* get feature flags first */	// FIXME: implement fs features?#if 0	if (super->s_features & ~PRAM_SUPPORTED_FLAGS) {		pram_err("unsupported filesystem features\n");		goto out;	}#endif	blocksize = super->s_blocksize;	pram_set_blocksize(sb, blocksize);	maxsize = super->s_size;	pram_info("pramfs image appears to be %lu KB in size\n", maxsize>>10);	pram_info("blocksize %lu\n", blocksize);	/* Read the root inode */	root_i = pram_get_inode(sb, PRAM_ROOT_INO);	if (pram_calc_checksum((u32*)root_i, PRAM_INODE_SIZE>>2)) {		pram_err("checksum error in root inode!\n");		goto out;	}	/* Check that the root inode is in a sane state */	if (root_i->i_d.d_next) {		pram_err("root->next not NULL??!!\n");		goto out;	}	if (!S_ISDIR(root_i->i_mode)) {		pram_err("root is not a directory!\n");		goto out;	}	root_offset = root_i->i_type.dir.head;	if (root_offset == 0)		pram_info("empty filesystem\n");	/* Remap the whole filesystem now */	pram_iounmap(sbi, sbi->virt_addr);	sbi->virt_addr = pram_ioremap(sbi, sbi->phys_addr, maxsize);	if (!sbi->virt_addr) {		pram_err("ioremap of the pramfs image failed\n");		goto out;	}	super = pram_get_super(sb);	root_i = pram_get_inode(sb, PRAM_ROOT_INO);	pram_do_powerfail_restore(sb, super);	*superp = super;	*root_ip = root_i;	retval = 0;out:	return retval;}#ifdef CONFIG_PRAMFS_VNVRAMstatic inline void pram_parse_time_param (struct super_block * sb,					  const char *data){	/* default is not update time */	if (!strstr(data, "notime") && strstr(data, "time")) {		 return;	}	sb->s_flags |= MS_NOTIME;}static inline void pram_parse_data_param (struct super_block * sb,					  const char *data){	/* default is not data failsafe */	if (strstr(data, "data_failsafe"))		sb->s_flags |= MS_DATA_FAILSAFE;}#else#define pram_parse_time_param(sb, data) do {} while (0)#define pram_parse_data_param(sb, data) do {} while (0)#endif /* CONFIG_PRAMFS_VNVRAM */static int pram_fill_super (struct super_block * sb, void * data, int silent){	char *p;	struct pram_super_block * super = NULL;	struct pram_inode * root_i = NULL;	struct pram_sb_info * sbi = NULL;	unsigned long maxsize;	int retval = -EINVAL;	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);	if (!sbi)		return -ENOMEM;	sb->s_fs_info = sbi;	sbi->sb = sb;#ifdef CONFIG_PRAMFS_FAILSAFE	mutex_init(&sbi->failsafe_mutex);#endif	if (!data) {		pram_err("no parameter for mount pramfs\n");		goto out;	}#ifdef CONFIG_PRAMFS_VNVRAM	if (!(strstr((char *)data, "physaddr="))) {		/* no physaddr, assume use vnvram */		int err;		sbi->vnvram = kzalloc(sizeof(struct vnvram_info), GFP_KERNEL);		if (!sbi->vnvram) {			pram_err("alloc vnvram failed\n");			retval = -ENOMEM;			goto out;		}		err = vnvram_get_info_pram(sbi->vnvram);		if (err) {			retval = err;			goto out;		}		sbi->phys_addr = sbi->vnvram->phys_addr;	}	if (!sbi->vnvram)#endif /* CONFIG_PRAMFS_VNVRAM */	{		/*		 * The physical location of the pram image is specified as		 * a mount parameter.  This parameter is mandatory for obvious		 * reasons.  Some validation is made on the phys address but this		 * is not exhaustive and we count on the fact that someone using		 * this feature is supposed to know what he/she's doing.		 */		if (!data || !(p = strstr((char *)data, "physaddr="))) {			pram_err("unknown physical address for pramfs image\n");			goto out;		}		sbi->phys_addr = simple_strtoul(p + 9, NULL, 0);		if (sbi->phys_addr & (PAGE_SIZE-1)) {			pram_err("physical address 0x%lx for pramfs isn't "				 "aligned to a page boundary\n",				 sbi->phys_addr);			goto out;		}		if (sbi->phys_addr == 0) {			pram_err("physical address for pramfs image can't be 0\n");			goto out;		}	}	pram_parse_time_param (sb, data);	pram_parse_data_param (sb, data);	if ((p = strstr((char *)data, "init="))) {		maxsize = simple_strtoul(p + 5, NULL, 0);#ifdef CONFIG_PRAMFS_VNVRAM		if (!maxsize && sbi->vnvram)			maxsize = sbi->vnvram->size; /* init=0, use default */#endif		pram_info("creating an empty pramfs of size %lu\n", maxsize);		retval = init_super(sb, data, maxsize, sbi, &super, &root_i);	} else {		retval = fill_super(sb, data, sbi, &super, &root_i);	}	if (retval)		goto out;	/* Set it all up.. */	sb->s_magic = super->s_magic;	sb->s_op = &pram_sops;	sb->s_root = d_alloc_root(pram_fill_new_inode(sb, root_i));	retval = 0; out:	if (retval) {		if (sbi->virt_addr)			pram_iounmap(sbi, sbi->virt_addr);		kfree(sbi);		sb->s_fs_info = NULL;#ifdef CONFIG_PRAMFS_VNVRAM		kfree(sbi->vnvram);#endif	}	return retval;}//static void pram_write_super (struct super_block * sb)//{//}int pram_statfs (struct dentry * dentry, struct kstatfs * buf){	struct super_block * sb = dentry->d_sb;	struct pram_super_block * ps = pram_get_super(sb);	buf->f_type = PRAM_SUPER_MAGIC;	buf->f_bsize = sb->s_blocksize;	buf->f_blocks = ps->s_blocks_count;	buf->f_bfree = buf->f_bavail = pram_get_free_blocks_count(sb);	buf->f_files = ps->s_inodes_count;	buf->f_ffree = pram_get_free_inodes_count(sb);	buf->f_namelen = PRAM_NAME_LEN;	return 0;}int pram_remount (struct super_block * sb, int * mntflags, char * data){	/* mtime is unused at all, avoid calling pram_sync_super	 * no update super when failsafe is enabled. */#ifndef CONFIG_PRAMFS_FAILSAFE	struct pram_super_block * ps;	if ((*mntflags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {		ps = pram_get_super(sb);		pram_lock_super(sb);		/* no need backup */		ps->s_mtime = get_seconds(); // update mount time		pram_unlock_super(sb);	}#endif	return 0;}static void pram_put_super (struct super_block * sb){	struct pram_sb_info * sbi = (struct pram_sb_info *)sb->s_fs_info;	/* It's unmount time, so unmap the pramfs memory */	if (sbi->virt_addr) {		pram_iounmap(sbi, sbi->virt_addr);		sbi->virt_addr = NULL;	}#ifdef CONFIG_PRAMFS_VNVRAM	if (sbi->vnvram) {		vnvram_sync_range_pram(sbi->vnvram->virt_addr,				       sbi->vnvram->size);		kfree(sbi->vnvram);	}#endif	sb->s_fs_info = NULL;	kfree(sbi);}/* * the super block writes are all done "on the fly", so the * super block is never in a "dirty" state, so there's no need * for write_super. */static struct super_operations pram_sops = {	.read_inode	= pram_read_inode,	.write_inode	= pram_write_inode,	.dirty_inode    = pram_dirty_inode,	.put_inode	= pram_put_inode,	.delete_inode	= pram_delete_inode,	.put_super	= pram_put_super,//	.write_super	= pram_write_super,	.statfs		= pram_statfs,	.remount_fs	= pram_remount,};static int pram_get_sb(struct file_system_type *fs_type,		       int flags, const char *dev_name,		       void *data, struct vfsmount *mnt){	return get_sb_single(fs_type, flags, data, pram_fill_super, mnt);}static struct file_system_type pram_fs_type = {	.owner          = THIS_MODULE,	.name           = "pramfs",	.get_sb         = pram_get_sb,	.kill_sb        = kill_anon_super,};static int __init init_pram_fs(void){	printk(KERN_INFO "PRAMFS"#ifdef CONFIG_PRAMFS_VNVRAM	       " (VNVRAM)"#endif#ifdef CONFIG_PRAMFS_FAILSAFE	       " (FAILSAFE)"#endif	       "\n");        return register_filesystem(&pram_fs_type);}static void __exit exit_pram_fs(void){	unregister_filesystem(&pram_fs_type);}module_init(init_pram_fs)module_exit(exit_pram_fs)

⌨️ 快捷键说明

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