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

📄 inode.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/fs/fat/inode.c * *  Written 1992,1993 by Werner Almesberger *  VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner */#define ASC_LINUX_VERSION(V, P, S)	(((V) * 65536) + ((P) * 256) + (S))#include <linux/version.h>#define __NO_VERSION__#include <linux/module.h>#include <linux/msdos_fs.h>#include <linux/nls.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/major.h>#include <linux/blkdev.h>#include <linux/fs.h>#include <linux/stat.h>#include <linux/locks.h>#include <linux/malloc.h>#include "msbuffer.h"#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0)#include <asm/uaccess.h>#define FAT_COPY_TO_USER(uaddr, kaddr, len) copy_to_user(uaddr, kaddr, len)#else#include <asm/segment.h>#define FAT_COPY_TO_USER(uaddr, kaddr, len) memcpy_tofs(uaddr, kaddr, len)#endif#include <asm/unaligned.h>#if 0#  define PRINTK(x) printk x#else#  define PRINTK(x)#endifvoid fat_put_inode(struct inode *inode){	struct inode *depend, *linked;	struct super_block *sb;	depend = MSDOS_I(inode)->i_depend;	linked = MSDOS_I(inode)->i_linked;	sb = inode->i_sb;	if (inode->i_nlink) {		if (depend) {			iput(depend);		}		if (linked) {			iput(linked);			MSDOS_I(inode)->i_linked = NULL;		}		if (MSDOS_I(inode)->i_busy) fat_cache_inval_inode(inode);		return;	}	inode->i_size = 0;	fat_truncate(inode);	if (depend) {		if (MSDOS_I(depend)->i_old != inode) {			printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",			    depend, inode, MSDOS_I(depend)->i_old);			fat_fs_panic(sb,"...");			goto done;		}		MSDOS_I(depend)->i_old = NULL;		iput(depend);	}	if (linked) {		if (MSDOS_I(linked)->i_oldlink != inode) {			printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",			    linked, inode, MSDOS_I(linked)->i_oldlink);			fat_fs_panic(sb,"...");			goto done;		}		MSDOS_I(linked)->i_oldlink = NULL;		iput(linked);	}done:	clear_inode(inode);}void fat_put_super(struct super_block *sb){	if (MSDOS_SB(sb)->fat_bits == 32) {		fat_clusters_flush(sb);	}	fat_cache_inval_dev(sb->s_dev);	set_blocksize (sb->s_dev,BLOCK_SIZE);	if (MSDOS_SB(sb)->nls_disk) {		unload_nls(MSDOS_SB(sb)->nls_disk);		MSDOS_SB(sb)->nls_disk = NULL;		MSDOS_SB(sb)->options.codepage = 0;	}	if (MSDOS_SB(sb)->nls_io) {		unload_nls(MSDOS_SB(sb)->nls_io);		MSDOS_SB(sb)->nls_io = NULL;		kfree(MSDOS_SB(sb)->options.iocharset);		MSDOS_SB(sb)->options.iocharset = NULL;	}	lock_super(sb);	sb->s_dev = 0;	unlock_super(sb);	MOD_DEC_USE_COUNT;	return;}static int parse_options(char *options,int *fat, int *blksize, int *debug,			 struct fat_mount_options *opts){	char *this_char,*value,save,*savep;	char *p;	int ret, len;	opts->name_check = 'n';	opts->conversion = 'b';	opts->fs_uid = current->uid;	opts->fs_gid = current->gid;	opts->fs_umask = current->fs->umask;	opts->quiet = opts->sys_immutable = opts->dotsOK = opts->showexec = 0;	opts->codepage = 0;	opts->utf8 = 0;	opts->iocharset = NULL;	*debug = *fat = 0;	if (!options) return 1;	save = 0;	savep = NULL;	ret = 1;	for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {		if ((value = strchr(this_char,'=')) != NULL) {			save = *value;			savep = value;			*value++ = 0;		}		if (!strcmp(this_char,"check") && value) {			if (value[0] && !value[1] && strchr("rns",*value))				opts->name_check = *value;			else if (!strcmp(value,"relaxed")) opts->name_check = 'r';			else if (!strcmp(value,"normal")) opts->name_check = 'n';			else if (!strcmp(value,"strict")) opts->name_check = 's';			else ret = 0;		}		else if (!strcmp(this_char,"conv") && value) {			if (value[0] && !value[1] && strchr("bta",*value))				opts->conversion = *value;			else if (!strcmp(value,"binary")) opts->conversion = 'b';			else if (!strcmp(value,"text")) opts->conversion = 't';			else if (!strcmp(value,"auto")) opts->conversion = 'a';			else ret = 0;		}		else if (!strcmp(this_char,"dots")) {			opts->dotsOK = 1;		}		else if (!strcmp(this_char,"nodots")) {			opts->dotsOK = 0;		}		else if (!strcmp(this_char,"showexec")) {			opts->showexec = 1;		}		else if (!strcmp(this_char,"dotsOK") && value) {			if (!strcmp(value,"yes")) opts->dotsOK = 1;			else if (!strcmp(value,"no")) opts->dotsOK = 0;			else ret = 0;		}		else if (!strcmp(this_char,"uid")) {			if (!value || !*value) ret = 0;			else {				opts->fs_uid = simple_strtoul(value,&value,0);				if (*value) ret = 0;			}		}		else if (!strcmp(this_char,"gid")) {			if (!value || !*value) ret= 0;			else {				opts->fs_gid = simple_strtoul(value,&value,0);				if (*value) ret = 0;			}		}		else if (!strcmp(this_char,"umask")) {			if (!value || !*value) ret = 0;			else {				opts->fs_umask = simple_strtoul(value,&value,8);				if (*value) ret = 0;			}		}		else if (!strcmp(this_char,"debug")) {			if (value) ret = 0;			else *debug = 1;		}		else if (!strcmp(this_char,"fat")) {			if (!value || !*value) ret = 0;			else {				*fat = simple_strtoul(value,&value,0);				if (*value || (*fat != 12 && *fat != 16 &&					       *fat != 32)) 					ret = 0;			}		}		else if (!strcmp(this_char,"quiet")) {			if (value) ret = 0;			else opts->quiet = 1;		}		else if (!strcmp(this_char,"blocksize")) {			*blksize = simple_strtoul(value,&value,0);			if (*value) ret = 0;			else if (*blksize != 512 && *blksize != 1024){				printk ("MSDOS FS: Invalid blocksize (512 or 1024)\n");			}		}		else if (!strcmp(this_char,"sys_immutable")) {			if (value) ret = 0;			else opts->sys_immutable = 1;		}		else if (!strcmp(this_char,"codepage")) {			opts->codepage = simple_strtoul(value,&value,0);			if (*value) ret = 0;			else printk ("MSDOS FS: Using codepage %d\n", opts->codepage);		}		else if (!strcmp(this_char,"iocharset")) {			p = value;			while (*value && *value != ',') value++;			len = value - p;			if (len) {				opts->iocharset = kmalloc(len+1, GFP_KERNEL);				memcpy(opts->iocharset, p, len);				opts->iocharset[len] = 0;				printk ("MSDOS FS: Using IO charset %s\n",					opts->iocharset);			} else {				opts->iocharset = NULL;				ret = 0;			}		}		if (this_char != options) *(this_char-1) = ',';		if (value) *savep = save;		if (ret == 0) return 0;	}	return 1;}/* Read the super block of an MS-DOS FS. *//* XXX: Make sure we handle the case of no codepage (unable to load) */struct super_block *fat_read_super(struct super_block *sb,void *data, int silent){	struct buffer_head *bh;	struct fat_boot_sector *b;	int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;	int debug,error,fat,cp;	int blksize = 512;	int fat32;	struct fat_mount_options opts;	char buf[50];	char *p;	MOD_INC_USE_COUNT;	if (hardsect_size[MAJOR(sb->s_dev)] != NULL){		blksize = hardsect_size[MAJOR(sb->s_dev)][MINOR(sb->s_dev)];		if (blksize != 512){			printk ("MSDOS: Hardware sector size is %d\n",blksize);		}	}	opts.isvfat = MSDOS_SB(sb)->options.isvfat;	if (!parse_options((char *) data, &fat, &blksize, &debug, &opts)		|| (blksize != 512 && blksize != 1024)) {		sb->s_dev = 0;		MOD_DEC_USE_COUNT;		return NULL;	}	cache_init();	lock_super(sb);	/* The first read is always 1024 bytes */	sb->s_blocksize = 1024;	set_blocksize(sb->s_dev, 1024);	bh = fat_bread(sb, 0);	unlock_super(sb);	if (bh == NULL || !fat_is_uptodate(sb,bh)) {		fat_brelse (sb, bh);		sb->s_dev = 0;		printk("FAT bread failed\n");		MOD_DEC_USE_COUNT;		return NULL;	}	set_blocksize(sb->s_dev, blksize);/* * The DOS3 partition size limit is *not* 32M as many people think.   * Instead, it is 64K sectors (with the usual sector size being * 512 bytes, leading to a 32M limit). *  * DOS 3 partition managers got around this problem by faking a  * larger sector size, ie treating multiple physical sectors as  * a single logical sector. *  * We can accommodate this scheme by adjusting our cluster size, * fat_start, and data_start by an appropriate value. * * (by Drew Eckhardt) */#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)    /* don't divide by zero */	b = (struct fat_boot_sector *) bh->b_data;	logical_sector_size =		CF_LE_W(get_unaligned((unsigned short *) &b->sector_size));	sector_mult = logical_sector_size >> SECTOR_BITS;	MSDOS_SB(sb)->cluster_size = b->cluster_size*sector_mult;	MSDOS_SB(sb)->fats = b->fats;	MSDOS_SB(sb)->fat_start = CF_LE_W(b->reserved)*sector_mult;	if (!b->fat_length && b->fat32_length) {		struct fat_boot_fsinfo *fsinfo;		/* Must be FAT32 */		fat32 = 1;		MSDOS_SB(sb)->fat_length= CF_LE_W(b->fat32_length)*sector_mult;		MSDOS_SB(sb)->root_cluster = CF_LE_L(b->root_cluster);		MSDOS_SB(sb)->fsinfo_offset =			CF_LE_W(b->info_sector) * logical_sector_size + 0x1e0;		fsinfo = (struct fat_boot_fsinfo *)			&bh->b_data[MSDOS_SB(sb)->fsinfo_offset];		if (CF_LE_L(fsinfo->signature) != 0x61417272) {			printk("fat_read_super: Did not find valid FSINFO signature. Found 0x%x\n", CF_LE_L(fsinfo->signature));		} else {			MSDOS_SB(sb)->free_clusters = CF_LE_L(fsinfo->free_clusters);		}	} else {		fat32 = 0;		MSDOS_SB(sb)->fat_length = CF_LE_W(b->fat_length)*sector_mult;		MSDOS_SB(sb)->root_cluster = 0;		MSDOS_SB(sb)->free_clusters = -1; /* Don't know yet */	}	MSDOS_SB(sb)->dir_start= CF_LE_W(b->reserved)*sector_mult+	    b->fats*MSDOS_SB(sb)->fat_length;	MSDOS_SB(sb)->dir_entries =		CF_LE_W(get_unaligned((unsigned short *) &b->dir_entries));	MSDOS_SB(sb)->data_start = MSDOS_SB(sb)->dir_start+ROUND_TO_MULTIPLE((	    MSDOS_SB(sb)->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,	    sector_mult);	data_sectors = CF_LE_W(get_unaligned((unsigned short *) &b->sectors));	if (!data_sectors) {		data_sectors = CF_LE_L(b->total_sect);	}	data_sectors = data_sectors * sector_mult - MSDOS_SB(sb)->data_start;	error = !b->cluster_size || !sector_mult;	if (!error) {		MSDOS_SB(sb)->clusters = b->cluster_size ? data_sectors/		    b->cluster_size/sector_mult : 0;		MSDOS_SB(sb)->fat_bits = fat32 ? 32 :			(fat ? fat :			 (MSDOS_SB(sb)->clusters > MSDOS_FAT12 ? 16 : 12));		fat_clusters = MSDOS_SB(sb)->fat_length*SECTOR_SIZE*8/		    MSDOS_SB(sb)->fat_bits;		error = !MSDOS_SB(sb)->fats || (MSDOS_SB(sb)->dir_entries &		    (MSDOS_DPS-1)) || MSDOS_SB(sb)->clusters+2 > fat_clusters+		    MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1))		    || !b->secs_track || !b->heads;	}	fat_brelse(sb, bh);	/*		This must be done after the brelse because the bh is a dummy		allocated by fat_bread (see buffer.c)	*/	sb->s_blocksize = blksize;    /* Using this small block size solves */				/* the misfit with buffer cache and cluster */

⌨️ 快捷键说明

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