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

📄 inode.c

📁 linux平台下的systv文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  linux/fs/sysv/inode.c * *  minix/inode.c *  Copyright (C) 1991, 1992  Linus Torvalds * *  xenix/inode.c *  Copyright (C) 1992  Doug Evans * *  coh/inode.c *  Copyright (C) 1993  Pascal Haible, Bruno Haible * *  sysv/inode.c *  Copyright (C) 1993  Paul B. Monday * *  sysv/inode.c *  Copyright (C) 1993  Bruno Haible *  Copyright (C) 1997, 1998  Krzysztof G. Baranowski * *  This file contains code for allocating/freeing inodes and for read/writing *  the superblock. */#include <linux/config.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/sysv_fs.h>#include <linux/stat.h>#include <linux/string.h>#include <linux/locks.h>#include <linux/init.h>#include <linux/smp_lock.h>#include <linux/highuid.h>#include <asm/byteorder.h>#include <asm/uaccess.h>#if 0void sysv_print_inode(struct inode * inode){        printk("ino %lu  mode 0%6.6o  lk %d  uid %d  gid %d"               "  sz %lu  blks %lu  cnt %u\n",               inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid,               inode->i_gid, inode->i_size, inode->i_blocks,               atomic_read(&inode->i_count));        printk("  db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx"               " 0x%lx 0x%lx>\n",                inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1],                inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3],                inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5],                inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7],                inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]);        printk("  ib <0x%lx 0x%lx 0x%lx>\n",                inode->u.sysv_i.i_data[10],                inode->u.sysv_i.i_data[11],                inode->u.sysv_i.i_data[12]);}#endifstatic void sysv_delete_inode(struct inode *inode){	lock_kernel();	inode->i_size = 0;	sysv_truncate(inode);	sysv_free_inode(inode);	unlock_kernel();}static void sysv_put_super(struct super_block *);static void sysv_write_super(struct super_block *);static void sysv_read_inode(struct inode *);static int sysv_statfs(struct super_block *, struct statfs *);static struct super_operations sysv_sops = {	read_inode:	sysv_read_inode,	write_inode:	sysv_write_inode,	delete_inode:	sysv_delete_inode,	put_super:	sysv_put_super,	write_super:	sysv_write_super,	statfs:		sysv_statfs,};/* The following functions try to recognize specific filesystems. * We recognize: * - Xenix FS by its magic number. * - SystemV FS by its magic number. * - Coherent FS by its funny fname/fpack field. * We discriminate among SystemV4 and SystemV2 FS by the assumption that * the time stamp is not < 01-01-1980. */static void detected_bs (u_char type, struct super_block *sb){	u_char n_bits = type+8;	int bsize = 1 << n_bits;	int bsize_4 = bsize >> 2;		sb->sv_block_size = bsize;	sb->sv_block_size_1 = bsize-1;	sb->sv_block_size_bits = n_bits;	sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;	sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;	sb->sv_inodes_per_block = bsize >> 6;	sb->sv_inodes_per_block_1 = (bsize >> 6)-1;	sb->sv_inodes_per_block_bits = n_bits-6;	sb->sv_toobig_block = 10 +	  (sb->sv_ind_per_block = bsize_4) +	  (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +	  (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);	sb->sv_ind_per_block_1 = bsize_4-1;	sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;	sb->sv_ind_per_block_2_bits = 2 *	  (sb->sv_ind_per_block_bits = n_bits-2);	sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;	sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;	sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;	sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;	sb->sv_ind0_size = 10 * bsize;	sb->sv_ind1_size = (10 + bsize_4)* bsize;	sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;}static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh){	struct xenix_super_block * sbd;	sbd = (struct xenix_super_block *) bh->b_data;	if (sbd->s_magic != 0x2b5544)		return NULL;	if (sbd->s_type > 2 || sbd->s_type < 1)		return NULL;	detected_bs(sbd->s_type, sb);	sb->sv_type = FSTYPE_XENIX;	return "Xenix";}static struct super_block * detected_xenix (struct super_block *sb, struct buffer_head *bh1, struct buffer_head *bh2){	struct xenix_super_block * sbd1;	struct xenix_super_block * sbd2;	if (sb->sv_block_size >= BLOCK_SIZE)		/* block size >= 1024, so bh1 = bh2 */		sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;	else {		/* block size = 512, so bh1 != bh2 */		sbd1 = (struct xenix_super_block *) bh1->b_data;		sbd2 = (struct xenix_super_block *) (bh2->b_data - BLOCK_SIZE/2);		/* sanity check */		if (sbd2->s_magic != 0x2b5544)			return NULL;	}	sb->sv_convert = 0;	sb->sv_kludge_symlinks = 1;	sb->sv_truncate = 1;	sb->sv_link_max = XENIX_LINK_MAX;	sb->sv_fic_size = XENIX_NICINOD;	sb->sv_flc_size = XENIX_NICFREE;	sb->sv_bh1 = bh1;	sb->sv_bh2 = bh2;	sb->sv_sbd1 = (char *) sbd1;	sb->sv_sbd2 = (char *) sbd2;	sb->sv_sb_fic_count = &sbd1->s_ninode;	sb->sv_sb_fic_inodes = &sbd1->s_inode[0];	sb->sv_sb_total_free_inodes = &sbd2->s_tinode;	sb->sv_sb_flc_count = &sbd1->s_nfree;	sb->sv_sb_flc_blocks = &sbd1->s_free[0];	sb->sv_sb_total_free_blocks = &sbd2->s_tfree;	sb->sv_sb_time = &sbd2->s_time;	sb->sv_firstinodezone = 2;	sb->sv_firstdatazone = sbd1->s_isize;	sb->sv_nzones = sbd1->s_fsize;	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;	return sb;}static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh){	struct sysv4_super_block * sbd;	sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);	if (sbd->s_magic != 0xfd187e20)		return NULL;	if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */		return NULL;	if ((sbd->s_type > 3 || sbd->s_type < 1) && (sbd->s_type > 0x30 || sbd->s_type < 0x10))		return NULL;	/* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,	   0x20 or 0x30 indicates that symbolic links and the 14-character	   filename limit is gone. Due to lack of information about this           feature read-only mode seems to be a reasonable approach... -KGB */	if (sbd->s_type >= 0x10) {		printk("SysV FS: can't handle long file names on %s, "		       "forcing read-only mode.\n", kdevname(sb->s_dev));		sb->s_flags |= MS_RDONLY;	}	detected_bs(sbd->s_type >= 0x10 ? (sbd->s_type >> 4) : sbd->s_type, sb);	sb->sv_type = FSTYPE_SYSV4;	return "SystemV";}static struct super_block * detected_sysv4 (struct super_block *sb, struct buffer_head *bh){	struct sysv4_super_block * sbd;	if (sb->sv_block_size >= BLOCK_SIZE)		sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);	else {		sbd = (struct sysv4_super_block *) bh->b_data;		/* sanity check */		if (sbd->s_magic != 0xfd187e20)			return NULL;		if (sbd->s_time < 315532800)			return NULL;	}	sb->sv_convert = 0;	sb->sv_kludge_symlinks = 0; /* ?? */	sb->sv_truncate = 1;	sb->sv_link_max = SYSV_LINK_MAX;	sb->sv_fic_size = SYSV_NICINOD;	sb->sv_flc_size = SYSV_NICFREE;	sb->sv_bh1 = bh;	sb->sv_bh2 = bh;	sb->sv_sbd1 = (char *) sbd;	sb->sv_sbd2 = (char *) sbd;	sb->sv_sb_fic_count = &sbd->s_ninode;	sb->sv_sb_fic_inodes = &sbd->s_inode[0];	sb->sv_sb_total_free_inodes = &sbd->s_tinode;	sb->sv_sb_flc_count = &sbd->s_nfree;	sb->sv_sb_flc_blocks = &sbd->s_free[0];	sb->sv_sb_total_free_blocks = &sbd->s_tfree;	sb->sv_sb_time = &sbd->s_time;	sb->sv_sb_state = &sbd->s_state;	sb->sv_firstinodezone = 2;	sb->sv_firstdatazone = sbd->s_isize;	sb->sv_nzones = sbd->s_fsize;	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;	return sb;}static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh){	struct sysv2_super_block * sbd;	sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);	if (sbd->s_magic != 0xfd187e20)		return NULL;	if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */		return NULL;	if (sbd->s_type > 3 || sbd->s_type < 1)		return NULL;	detected_bs(sbd->s_type, sb);	sb->sv_type = FSTYPE_SYSV2;	return "SystemV Release 2";}static struct super_block * detected_sysv2 (struct super_block *sb, struct buffer_head *bh){	struct sysv2_super_block * sbd;	if (sb->sv_block_size >= BLOCK_SIZE)		sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);	else {		sbd = (struct sysv2_super_block *) bh->b_data;		/* sanity check */		if (sbd->s_magic != 0xfd187e20)			return NULL;		if (sbd->s_time < 315532800)			return NULL;	}	sb->sv_convert = 0;	sb->sv_kludge_symlinks = 0; /* ?? */	sb->sv_truncate = 1;	sb->sv_link_max = SYSV_LINK_MAX;	sb->sv_fic_size = SYSV_NICINOD;	sb->sv_flc_size = SYSV_NICFREE;	sb->sv_bh1 = bh;	sb->sv_bh2 = bh;	sb->sv_sbd1 = (char *) sbd;	sb->sv_sbd2 = (char *) sbd;	sb->sv_sb_fic_count = &sbd->s_ninode;	sb->sv_sb_fic_inodes = &sbd->s_inode[0];	sb->sv_sb_total_free_inodes = &sbd->s_tinode;	sb->sv_sb_flc_count = &sbd->s_nfree;	sb->sv_sb_flc_blocks = &sbd->s_free[0];	sb->sv_sb_total_free_blocks = &sbd->s_tfree;	sb->sv_sb_time = &sbd->s_time;	sb->sv_sb_state = &sbd->s_state;	sb->sv_firstinodezone = 2;	sb->sv_firstdatazone = sbd->s_isize;	sb->sv_nzones = sbd->s_fsize;	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;	return sb;}static const char* detect_coherent (struct super_block *sb, struct buffer_head *bh){	struct coh_super_block * sbd;	sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2);	if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))	    || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))		return NULL;	detected_bs(1, sb);	sb->sv_type = FSTYPE_COH;	return "Coherent";}static struct super_block * detected_coherent (struct super_block *sb, struct buffer_head *bh){	struct coh_super_block * sbd;	sbd = (struct coh_super_block *) bh->b_data;	/* sanity check */	if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))	    || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))		return NULL;	sb->sv_convert = 1;	sb->sv_kludge_symlinks = 1;	sb->sv_truncate = 1;	sb->sv_link_max = COH_LINK_MAX;	sb->sv_fic_size = COH_NICINOD;	sb->sv_flc_size = COH_NICFREE;	sb->sv_bh1 = bh;	sb->sv_bh2 = bh;	sb->sv_sbd1 = (char *) sbd;	sb->sv_sbd2 = (char *) sbd;	sb->sv_sb_fic_count = &sbd->s_ninode;	sb->sv_sb_fic_inodes = &sbd->s_inode[0];	sb->sv_sb_total_free_inodes = &sbd->s_tinode;	sb->sv_sb_flc_count = &sbd->s_nfree;	sb->sv_sb_flc_blocks = &sbd->s_free[0];	sb->sv_sb_total_free_blocks = &sbd->s_tfree;	sb->sv_sb_time = &sbd->s_time;	sb->sv_firstinodezone = 2;	sb->sv_firstdatazone = sbd->s_isize;	sb->sv_nzones = from_coh_ulong(sbd->s_fsize);	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;	return sb;}static struct super_block *sysv_read_super(struct super_block *sb,					   void *data, int silent){	struct buffer_head *bh;	const char *found;	kdev_t dev = sb->s_dev;	struct inode *root_inode;	unsigned long blocknr;		if (1024 != sizeof (struct xenix_super_block))		panic("Xenix FS: bad super-block size");	if ((512 != sizeof (struct sysv4_super_block))            || (512 != sizeof (struct sysv2_super_block)))		panic("SystemV FS: bad super-block size");	if (500 != sizeof (struct coh_super_block))		panic("Coherent FS: bad super-block size");	if (64 != sizeof (struct sysv_inode))		panic("sysv fs: bad i-node size");	set_blocksize(dev,BLOCK_SIZE);	sb->sv_block_base = 0;	/* Try to read Xenix superblock */	if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {		if ((found = detect_xenix(sb,bh)) != NULL)			goto ok;		brelse(bh);	}	if ((bh = bread(dev, 0, BLOCK_SIZE)) != NULL) {		/* Try to recognize SystemV superblock */		if ((found = detect_sysv4(sb,bh)) != NULL)			goto ok;		if ((found = detect_sysv2(sb,bh)) != NULL)			goto ok;		/* Try to recognize Coherent superblock */		if ((found = detect_coherent(sb,bh)) != NULL)			goto ok;		brelse(bh);	}	/* Try to recognize SystemV superblock */	/* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */	/* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */	/* Maybe we should also check the device geometry ? */	{	static int offsets[] = { 9, 15, 18, };		int i;		for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)			if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {				/* Try to recognize SystemV superblock */				if ((found = detect_sysv4(sb,bh)) != NULL) {

⌨️ 快捷键说明

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