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

📄 inode.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  linux/fs/isofs/inode.c *  *  (C) 1991  Linus Torvalds - minix filesystem *      1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem. *      1994  Eberhard Moenkeberg - multi session handling. *      1995  Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs. * */#include <linux/module.h>#include <linux/stat.h>#include <linux/sched.h>#include <linux/iso_fs.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/mm.h>#include <linux/string.h>#include <linux/locks.h>#include <linux/malloc.h>#include <linux/errno.h>#include <linux/cdrom.h>#include <linux/nls.h>#include <asm/system.h>#include <asm/segment.h>/* * We have no support for "multi volume" CDs, but more and more disks carry * wrong information within the volume descriptors. */#define IGNORE_WRONG_MULTI_VOLUME_SPECS#ifdef LEAK_CHECKstatic int check_malloc = 0;static int check_bread = 0;#endifvoid isofs_put_super(struct super_block *sb){	if (sb->u.isofs_sb.s_nls_iocharset) {		unload_nls(sb->u.isofs_sb.s_nls_iocharset);		sb->u.isofs_sb.s_nls_iocharset = NULL;	}	lock_super(sb);#ifdef LEAK_CHECK	printk("Outstanding mallocs:%d, outstanding buffers: %d\n", 	       check_malloc, check_bread);#endif	sb->s_dev = 0;	unlock_super(sb);	MOD_DEC_USE_COUNT;	return;}static struct super_operations isofs_sops = { 	isofs_read_inode,	NULL,			/* notify_change */	NULL,			/* write_inode */	NULL,			/* put_inode */	isofs_put_super,	NULL,			/* write_super */	isofs_statfs,	NULL};struct iso9660_options{  char map;  char rock;  char joliet;  char cruft;  char unhide;  unsigned char check;  unsigned char conversion;  unsigned int blocksize;  mode_t mode;  gid_t gid;  uid_t uid;  char *iocharset;  unsigned char utf8;};static int parse_options(char *options, struct iso9660_options * popt){	char *this_char,*value,*p;	int len;	popt->map = 'n';	popt->rock = 'y';	popt->joliet = 'y';	popt->cruft = 'n';	popt->unhide = 'n';	popt->check = 's';		/* default: strict */	popt->conversion = 'b';		/* default: no conversion */	popt->blocksize = 1024;	popt->mode = S_IRUGO;	popt->gid = 0;	popt->uid = 0;	popt->iocharset = NULL;	popt->utf8 = 0;	if (!options) return 1;	for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {	        if (strncmp(this_char,"norock",6) == 0) {		  popt->rock = 'n';		  continue;		}	        if (strncmp(this_char,"nojoliet",8) == 0) {		  popt->joliet = 'n';		  continue;		}	        if (strncmp(this_char,"unhide",6) == 0) {		  popt->unhide = 'y';		  continue;		}	        if (strncmp(this_char,"cruft",5) == 0) {		  popt->cruft = 'y';		  continue;		}	        if (strncmp(this_char,"utf8",4) == 0) {		  popt->utf8 = 1;		  continue;		}		if ((value = strchr(this_char,'=')) != NULL)			*value++ = 0;		if (!strcmp(this_char,"iocharset")) {			p = value;			while (*value && *value != ',') value++;			len = value - p;			if (len) {				popt->iocharset = kmalloc(len+1, GFP_KERNEL);				memcpy(popt->iocharset, p, len);				popt->iocharset[len] = 0;			} else {				popt->iocharset = NULL;				return 0;			}		}		else if (!strcmp(this_char,"map") && value) {			if (value[0] && !value[1] && strchr("on",*value))				popt->map = *value;			else if (!strcmp(value,"off")) popt->map = 'o';			else if (!strcmp(value,"normal")) popt->map = 'n';			else return 0;		}		else if (!strcmp(this_char,"check") && value) {			if (value[0] && !value[1] && strchr("rs",*value))				popt->check = *value;			else if (!strcmp(value,"relaxed")) popt->check = 'r';			else if (!strcmp(value,"strict")) popt->check = 's';			else return 0;		}		else if (!strcmp(this_char,"conv") && value) {			if (value[0] && !value[1] && strchr("btma",*value))				popt->conversion = *value;			else if (!strcmp(value,"binary")) popt->conversion = 'b';			else if (!strcmp(value,"text")) popt->conversion = 't';			else if (!strcmp(value,"mtext")) popt->conversion = 'm';			else if (!strcmp(value,"auto")) popt->conversion = 'a';			else return 0;		}		else if (value && 			 (!strcmp(this_char,"block") ||			  !strcmp(this_char,"mode") ||			  !strcmp(this_char,"uid") ||			  !strcmp(this_char,"gid"))) {		  char * vpnt = value;		  unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);		  if (*vpnt) return 0;		  switch(*this_char) {		  case 'b':		    if (   ivalue != 512 			&& ivalue != 1024 			&& ivalue != 2048) return 0;		    popt->blocksize = ivalue;		    break;		  case 'u':		    popt->uid = ivalue;		    break;		  case 'g':		    popt->gid = ivalue;		    break;		  case 'm':		    popt->mode = ivalue;		    break;		  }		}		else return 1;	}	return 1;}/* * look if the driver can tell the multi session redirection value * * don't change this if you don't know what you do, please! * Multisession is legal only with XA disks. * A non-XA disk with more than one volume descriptor may do it right, but * usually is written in a nowhere standardized "multi-partition" manner. * Multisession uses absolute addressing (solely the first frame of the whole * track is #0), multi-partition uses relative addressing (each first frame of * each track is #0), and a track is not a session. * * A broken CDwriter software or drive firmware does not set new standards, * at least not if conflicting with the existing ones. *  * emoenke@gwdg.de */#define WE_OBEY_THE_WRITTEN_STANDARDS 1static unsigned int isofs_get_last_session(kdev_t dev){  struct cdrom_multisession ms_info;  unsigned int vol_desc_start;  struct inode inode_fake;  extern struct file_operations * get_blkfops(unsigned int);  int i;  vol_desc_start=0;  if (get_blkfops(MAJOR(dev))->ioctl!=NULL)    {      /* Whoops.  We must save the old FS, since otherwise       * we would destroy the kernels idea about FS on root       * mount in read_super... [chexum]       */      unsigned long old_fs=get_fs();      inode_fake.i_rdev=dev;      ms_info.addr_format=CDROM_LBA;      set_fs(KERNEL_DS);      i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake,				       NULL,				       CDROMMULTISESSION,				       (unsigned long) &ms_info);      set_fs(old_fs);#if 0       printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);      if (i==0)	{	  printk("isofs.inode: XA disk: %s\n", ms_info.xa_flag ? "yes":"no");	  printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);	}#endif 0      if (i==0)#if WE_OBEY_THE_WRITTEN_STANDARDS        if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */#endif WE_OBEY_THE_WRITTEN_STANDARDS          vol_desc_start=ms_info.addr.lba;    }  return vol_desc_start;}struct super_block *isofs_read_super(struct super_block *s,void *data,				     int silent){	struct buffer_head *bh=NULL;	int iso_blknum;	unsigned int blocksize_bits;	int high_sierra;	kdev_t dev = s->s_dev;	unsigned int vol_desc_start;	int orig_zonesize;	char *p;	int joliet_level = 0;	struct iso_volume_descriptor *vdp;	struct hs_volume_descriptor *hdp;	struct iso_primary_descriptor *pri = NULL;	struct iso_supplementary_descriptor *sec = NULL;	struct hs_primary_descriptor *h_pri = NULL;	struct iso_directory_record *rootp;	struct iso9660_options opt;	MOD_INC_USE_COUNT;	if (!parse_options((char *) data,&opt)) {		s->s_dev = 0;		MOD_DEC_USE_COUNT;		return NULL;	}#if 0	printk("map = %c\n", opt.map);	printk("rock = %c\n", opt.rock);	printk("joliet = %c\n", opt.joliet);	printk("check = %c\n", opt.check);	printk("cruft = %c\n", opt.cruft);	printk("unhide = %c\n", opt.unhide);	printk("conversion = %c\n", opt.conversion);	printk("blocksize = %d\n", opt.blocksize);	printk("gid = %d\n", opt.gid);	printk("uid = %d\n", opt.uid);#endif		blocksize_bits = 0;	{	  int i = opt.blocksize;	  while (i != 1){	    blocksize_bits++;	    i >>=1;	  }	}	set_blocksize(dev, opt.blocksize);	lock_super(s);	s->u.isofs_sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */	vol_desc_start = isofs_get_last_session(dev);		for (iso_blknum = vol_desc_start+16;             iso_blknum < vol_desc_start+100; iso_blknum++)	{	    int b = iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits);	    if (!(bh = bread(dev,b,opt.blocksize))) {		s->s_dev = 0;		printk("isofs_read_super: bread failed, dev "		       "%s iso_blknum %d block %d\n",		       kdevname(dev), iso_blknum, b);		unlock_super(s);		MOD_DEC_USE_COUNT;		return NULL;	    }	    vdp = (struct iso_volume_descriptor *)bh->b_data;	    hdp = (struct hs_volume_descriptor *)bh->b_data;	    	    if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {		if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)		    goto out;		if (isonum_711 (hdp->type) == ISO_VD_END)		    goto out;				s->u.isofs_sb.s_high_sierra = 1;		high_sierra = 1;		opt.rock = 'n';		h_pri = (struct hs_primary_descriptor *)vdp;		break;	    }	    if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {		if (isonum_711 (vdp->type) == ISO_VD_END)		    break;		if (isonum_711 (vdp->type) == ISO_VD_PRIMARY) {		    if (pri == NULL) {			pri = (struct iso_primary_descriptor *)vdp;		    }		} else if (isonum_711 (vdp->type) == ISO_VD_SUPPLEMENTARY) {		    sec = (struct iso_supplementary_descriptor *)vdp;		    if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) {			if (opt.joliet == 'y') {			    if (sec->escape[2] == 0x40) {				joliet_level = 1;			    } else if (sec->escape[2] == 0x43) {				joliet_level = 2;			    } else if (sec->escape[2] == 0x45) {				joliet_level = 3;			    }			    printk("ISO9660 Extensions: Microsoft Joliet Level %d\n",				   joliet_level);			}			break;		    } else {			/* Unknown supplementary volume descriptor */			sec = NULL;		    }		}		/* Just skip any volume descriptors we don't recognize */	    }	    brelse(bh);	}	if ((pri == NULL) && (sec == NULL) && (h_pri == NULL)) {	    if (!silent)		printk("Unable to identify CD-ROM format.\n");	    s->s_dev = 0;	    unlock_super(s);	    MOD_DEC_USE_COUNT;	    return NULL;	}	s->u.isofs_sb.s_joliet_level = joliet_level;	if (joliet_level && opt.rock == 'n') {	    /* This is the case of Joliet with the norock mount flag.	     * A disc with both Joliet and Rock Ridge is handled later	     */	    pri = (struct iso_primary_descriptor *) sec;	}	if(high_sierra){

⌨️ 快捷键说明

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