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

📄 super.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* N.B. after this point bh must be released */got_root:	root_block = s->u.affs_sb.s_root_block;	s->u.affs_sb.s_partition_size   = size;	s->s_blocksize_bits             = blocksize == 512 ? 9 :					  blocksize == 1024 ? 10 :					  blocksize == 2048 ? 11 : 12;	/* Find out which kind of FS we have */	bb = affs_bread(dev,0,s->s_blocksize);	if (!bb)		goto out_no_root_block;	chksum = be32_to_cpu(*(u32 *)bb->b_data);	affs_brelse(bb);	/* Dircache filesystems are compatible with non-dircache ones	 * when reading. As long as they aren't supported, writing is	 * not recommended.	 */	if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS	     || chksum == MUFS_DCOFS) && !(s->s_flags & MS_RDONLY)) {		printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n",			kdevname(dev));		s->s_flags |= MS_RDONLY;		s->u.affs_sb.s_flags |= SF_READONLY;	}	switch (chksum) {		case MUFS_FS:		case MUFS_INTLFFS:			s->u.affs_sb.s_flags |= SF_MUFS;			/* fall thru */		case FS_INTLFFS:			s->u.affs_sb.s_flags |= SF_INTL;			break;		case MUFS_DCFFS:		case MUFS_FFS:			s->u.affs_sb.s_flags |= SF_MUFS;			break;		case FS_DCFFS:		case FS_FFS:			break;		case MUFS_OFS:			s->u.affs_sb.s_flags |= SF_MUFS;			/* fall thru */		case FS_OFS:			s->u.affs_sb.s_flags |= SF_OFS;			s->s_flags |= MS_NOEXEC;			break;		case MUFS_DCOFS:		case MUFS_INTLOFS:			s->u.affs_sb.s_flags |= SF_MUFS;		case FS_DCOFS:		case FS_INTLOFS:			s->u.affs_sb.s_flags |= SF_INTL | SF_OFS;			s->s_flags |= MS_NOEXEC;			break;		default:			goto out_unknown_fs;	}	if (mount_flags & SF_VERBOSE) {		chksum = cpu_to_be32(chksum);		printk(KERN_NOTICE "AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n",			GET_END_PTR(struct root_end,bh->b_data,blocksize)->disk_name[0],			&GET_END_PTR(struct root_end,bh->b_data,blocksize)->disk_name[1],			(char *)&chksum,((char *)&chksum)[3] + '0',blocksize);	}	s->s_flags |= MS_NODEV | MS_NOSUID;	/* Keep super block in cache */	bb = affs_bread(dev,root_block,s->s_blocksize);	if (!bb)		goto out_no_root_block;	s->u.affs_sb.s_root_bh = bb;	/* N.B. after this point s_root_bh must be released */	/* Allocate space for bitmaps, zones and others */	size   = s->u.affs_sb.s_partition_size - reserved;	num_bm = (size + s->s_blocksize * 8 - 32 - 1) / (s->s_blocksize * 8 - 32);	az_no  = (size + AFFS_ZONE_SIZE - 1) / (AFFS_ZONE_SIZE - 32);	ptype  = num_bm * sizeof(struct affs_bm_info) +		 az_no * sizeof(struct affs_alloc_zone) +		 MAX_ZONES * sizeof(struct affs_zone);	pr_debug("AFFS: num_bm=%d, az_no=%d, sum=%d\n",num_bm,az_no,ptype);	if (!(s->u.affs_sb.s_bitmap = kmalloc(ptype, GFP_KERNEL)))		goto out_no_bitmap;	memset(s->u.affs_sb.s_bitmap,0,ptype);	/* N.B. after the point s_bitmap must be released */	s->u.affs_sb.s_zones   = (struct affs_zone *)&s->u.affs_sb.s_bitmap[num_bm];	s->u.affs_sb.s_alloc   = (struct affs_alloc_zone *)&s->u.affs_sb.s_zones[MAX_ZONES];	s->u.affs_sb.s_num_az  = az_no;	mapidx = 0;	if (ROOT_END_S(bh->b_data,s)->bm_flag == 0) {		if (!(s->s_flags & MS_RDONLY)) {			printk(KERN_NOTICE "AFFS: Bitmap invalid - mounting %s read only\n",				kdevname(dev));			s->s_flags |= MS_RDONLY;		}		affs_brelse(bh);		bh = NULL;		goto nobitmap;	}	/* The following section is ugly, I know. Especially because of the	 * reuse of some variables that are not named properly.	 */	key    = root_block;	ptype  = s->s_blocksize / 4 - 49;	stype  = ptype + 25;	offset = s->u.affs_sb.s_reserved;	az_no  = 0;	while (bh) {		bm = (u32 *)bh->b_data;		for (i = ptype; i < stype && bm[i]; i++, mapidx++) {			if (mapidx >= num_bm) {				printk(KERN_ERR "AFFS: Extraneous bitmap pointer - "					       "mounting %s read only.\n",kdevname(dev));				s->s_flags |= MS_RDONLY;				s->u.affs_sb.s_flags |= SF_READONLY;				continue;			}			bb = affs_bread(dev,be32_to_cpu(bm[i]),s->s_blocksize);			if (!bb)				goto out_no_read_bm;			if (affs_checksum_block(s->s_blocksize,bb->b_data,NULL,NULL) &&			    !(s->s_flags & MS_RDONLY)) {				printk(KERN_WARNING "AFFS: Bitmap (%d,key=%u) invalid - "				       "mounting %s read only.\n",mapidx,be32_to_cpu(bm[i]),					kdevname(dev));				s->s_flags |= MS_RDONLY;				s->u.affs_sb.s_flags |= SF_READONLY;			}			/* Mark unused bits in the last word as allocated */			if (size <= s->s_blocksize * 8 - 32) {	/* last bitmap */				ptype = size / 32 + 1;		/* word number */				key   = size & 0x1F;		/* used bits */				if (key && !(s->s_flags & MS_RDONLY)) {					chksum = cpu_to_be32(0x7FFFFFFF >> (31 - key));					((u32 *)bb->b_data)[ptype] &= chksum;					affs_fix_checksum(s->s_blocksize,bb->b_data,0);					mark_buffer_dirty(bb);					bmalt = 1;				}				ptype = (size + 31) & ~0x1F;				size  = 0;				s->u.affs_sb.s_flags |= SF_BM_VALID;			} else {				ptype = s->s_blocksize * 8 - 32;				size -= ptype;			}			s->u.affs_sb.s_bitmap[mapidx].bm_firstblk = offset;			s->u.affs_sb.s_bitmap[mapidx].bm_bh       = NULL;			s->u.affs_sb.s_bitmap[mapidx].bm_key      = be32_to_cpu(bm[i]);			s->u.affs_sb.s_bitmap[mapidx].bm_count    = 0;			offset += ptype;			for (j = 0; ptype > 0; j++, az_no++, ptype -= key) {				key = MIN(ptype,AFFS_ZONE_SIZE);	/* size in bits */				s->u.affs_sb.s_alloc[az_no].az_size = key / 32;				s->u.affs_sb.s_alloc[az_no].az_free =					affs_count_free_bits(key / 8,bb->b_data +					     j * (AFFS_ZONE_SIZE / 8) + 4);			}			affs_brelse(bb);		}		key   = be32_to_cpu(bm[stype]);		/* Next block of bitmap pointers	*/		ptype = 0;		stype = s->s_blocksize / 4 - 1;		affs_brelse(bh);		bh = NULL;		if (key) {			bh = affs_bread(dev,key,s->s_blocksize);			if (!bh)				goto out_no_bm_ext;		}	}	if (mapidx < num_bm)		goto out_bad_num;nobitmap:	s->u.affs_sb.s_bm_count = num_bm;	/* set up enough so that it can read an inode */	s->s_dirt  = 1;	root_inode = iget(s,root_block);	if (!root_inode)		goto out_no_root;	s->s_root  = d_alloc_root(root_inode);	if (!s->s_root)		goto out_no_root;	s->s_root->d_op = &affs_dentry_operations;	/* Record date of last change if the bitmap was truncated and	 * create data zones if the volume is writable.	 */	if (!(s->s_flags & MS_RDONLY)) {		if (bmalt) {			secs_to_datestamp(CURRENT_TIME,&ROOT_END(				s->u.affs_sb.s_root_bh->b_data,root_inode)->disk_altered);			affs_fix_checksum(s->s_blocksize,s->u.affs_sb.s_root_bh->b_data,5);			mark_buffer_dirty(s->u.affs_sb.s_root_bh);		}		affs_make_zones(s);	}	pr_debug("AFFS: s_flags=%lX\n",s->s_flags);	return s;out_bad_opts:	printk(KERN_ERR "AFFS: Error parsing options\n");	goto out_fail;out_bad_size:	printk(KERN_ERR "AFFS: Could not determine device size\n");	goto out_free_prefix;out_no_valid_block:	if (!silent)		printk(KERN_ERR "AFFS: No valid root block on device %s\n",			kdevname(dev));	goto out_restore;out_unknown_fs:	printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n",		kdevname(dev), chksum);	goto out_free_bh;out_no_root_block:	printk(KERN_ERR "AFFS: Cannot read root block\n");	goto out_free_bh;out_no_bitmap:	printk(KERN_ERR "AFFS: Bitmap allocation failed\n");	goto out_free_root_block;out_no_read_bm:	printk(KERN_ERR "AFFS: Cannot read bitmap\n");	goto out_free_bitmap;out_no_bm_ext:	printk(KERN_ERR "AFFS: Cannot read bitmap extension\n");	goto out_free_bitmap;out_bad_num:	printk(KERN_ERR "AFFS: Got only %d bitmap blocks, expected %d\n",		mapidx, num_bm);	goto out_free_bitmap;out_no_root:	printk(KERN_ERR "AFFS: Get root inode failed\n");	/*	 * Begin the cascaded cleanup ...	 */	iput(root_inode);out_free_bitmap:	kfree(s->u.affs_sb.s_bitmap);out_free_root_block:	affs_brelse(s->u.affs_sb.s_root_bh);out_free_bh:	affs_brelse(bh);out_restore:	set_blocksize(dev, s->u.affs_sb.s_blksize);out_free_prefix:	if (s->u.affs_sb.s_prefix)		kfree(s->u.affs_sb.s_prefix);out_fail:	return NULL;}static intaffs_remount(struct super_block *sb, int *flags, char *data){	int			 blocksize;	uid_t			 uid;	gid_t			 gid;	int			 mode;	int			 reserved;	int			 root_block;	unsigned long		 mount_flags;	unsigned long		 read_only = sb->u.affs_sb.s_flags & SF_READONLY;	pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);	if (!parse_options(data,&uid,&gid,&mode,&reserved,&root_block,	    &blocksize,&sb->u.affs_sb.s_prefix,sb->u.affs_sb.s_volume,&mount_flags))		return -EINVAL;	sb->u.affs_sb.s_flags = mount_flags | read_only;	sb->u.affs_sb.s_mode  = mode;	sb->u.affs_sb.s_uid   = uid;	sb->u.affs_sb.s_gid   = gid;	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))		return 0;	if (*flags & MS_RDONLY) {		sb->s_dirt = 1;		while (sb->s_dirt)			affs_write_super(sb);		sb->s_flags |= MS_RDONLY;	} else if (!(sb->u.affs_sb.s_flags & SF_READONLY)) {		sb->s_flags &= ~MS_RDONLY;		affs_make_zones(sb);	} else {		affs_warning(sb,"remount","Cannot remount fs read/write because of errors");		return -EINVAL;	}	return 0;}static intaffs_statfs(struct super_block *sb, struct statfs *buf){	int		 free;	pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",sb->u.affs_sb.s_partition_size,	     sb->u.affs_sb.s_reserved);	free          = affs_count_free_blocks(sb);	buf->f_type    = AFFS_SUPER_MAGIC;	buf->f_bsize   = sb->s_blocksize;	buf->f_blocks  = sb->u.affs_sb.s_partition_size - sb->u.affs_sb.s_reserved;	buf->f_bfree   = free;	buf->f_bavail  = free;	return 0;}static DECLARE_FSTYPE_DEV(affs_fs_type, "affs", affs_read_super);static int __init init_affs_fs(void){	return register_filesystem(&affs_fs_type);}static void __exit exit_affs_fs(void){	unregister_filesystem(&affs_fs_type);}EXPORT_NO_SYMBOLS;module_init(init_affs_fs)module_exit(exit_affs_fs)

⌨️ 快捷键说明

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