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

📄 inode.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  linux/fs/isofs/inode.c * *  (C) 1991  Linus Torvalds - minix filesystem *      1992, 1993, 1994  Eric Youngdale Modified for ISO 9660 filesystem. *      1994  Eberhard Mönkeberg - multi session handling. *      1995  Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs. *	1997  Gordon Chaffee - Joliet CDs *	1998  Eric Lammerts - ISO 9660 Level 3 *	2004  Paul Serice - Inode Support pushed out from 4GB to 128GB *	2004  Paul Serice - NFS Export Operations */#include <linux/init.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/nls.h>#include <linux/ctype.h>#include <linux/smp_lock.h>#include <linux/statfs.h>#include <linux/cdrom.h>#include <linux/parser.h>#include "isofs.h"#include "zisofs.h"#define BEQUIETstatic int isofs_hashi(struct dentry *parent, struct qstr *qstr);static int isofs_hash(struct dentry *parent, struct qstr *qstr);static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);#ifdef CONFIG_JOLIETstatic int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);#endifstatic void isofs_put_super(struct super_block *sb){	struct isofs_sb_info *sbi = ISOFS_SB(sb);#ifdef CONFIG_JOLIET	if (sbi->s_nls_iocharset) {		unload_nls(sbi->s_nls_iocharset);		sbi->s_nls_iocharset = NULL;	}#endif	kfree(sbi);	sb->s_fs_info = NULL;	return;}static void isofs_read_inode(struct inode *);static int isofs_statfs (struct dentry *, struct kstatfs *);static struct kmem_cache *isofs_inode_cachep;static struct inode *isofs_alloc_inode(struct super_block *sb){	struct iso_inode_info *ei;	ei = kmem_cache_alloc(isofs_inode_cachep, GFP_KERNEL);	if (!ei)		return NULL;	return &ei->vfs_inode;}static void isofs_destroy_inode(struct inode *inode){	kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));}static void init_once(struct kmem_cache *cachep, void *foo){	struct iso_inode_info *ei = foo;	inode_init_once(&ei->vfs_inode);}static int init_inodecache(void){	isofs_inode_cachep = kmem_cache_create("isofs_inode_cache",					sizeof(struct iso_inode_info),					0, (SLAB_RECLAIM_ACCOUNT|					SLAB_MEM_SPREAD),					init_once);	if (isofs_inode_cachep == NULL)		return -ENOMEM;	return 0;}static void destroy_inodecache(void){	kmem_cache_destroy(isofs_inode_cachep);}static int isofs_remount(struct super_block *sb, int *flags, char *data){	/* we probably want a lot more here */	*flags |= MS_RDONLY;	return 0;}static const struct super_operations isofs_sops = {	.alloc_inode	= isofs_alloc_inode,	.destroy_inode	= isofs_destroy_inode,	.read_inode	= isofs_read_inode,	.put_super	= isofs_put_super,	.statfs		= isofs_statfs,	.remount_fs	= isofs_remount,};static struct dentry_operations isofs_dentry_ops[] = {	{		.d_hash		= isofs_hash,		.d_compare	= isofs_dentry_cmp,	},	{		.d_hash		= isofs_hashi,		.d_compare	= isofs_dentry_cmpi,	},#ifdef CONFIG_JOLIET	{		.d_hash		= isofs_hash_ms,		.d_compare	= isofs_dentry_cmp_ms,	},	{		.d_hash		= isofs_hashi_ms,		.d_compare	= isofs_dentry_cmpi_ms,	},#endif};struct iso9660_options{	char map;	char rock;	char joliet;	char cruft;	char hide;	char showassoc;	char nocompress;	unsigned char check;	unsigned int blocksize;	mode_t mode;	gid_t gid;	uid_t uid;	char *iocharset;	unsigned char utf8;	/* LVE */	s32 session;	s32 sbsector;};/* * Compute the hash for the isofs name corresponding to the dentry. */static intisofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms){	const char *name;	int len;	len = qstr->len;	name = qstr->name;	if (ms) {		while (len && name[len-1] == '.')			len--;	}	qstr->hash = full_name_hash(name, len);	return 0;}/* * Compute the hash for the isofs name corresponding to the dentry. */static intisofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms){	const char *name;	int len;	char c;	unsigned long hash;	len = qstr->len;	name = qstr->name;	if (ms) {		while (len && name[len-1] == '.')			len--;	}	hash = init_name_hash();	while (len--) {		c = tolower(*name++);		hash = partial_name_hash(c, hash);	}	qstr->hash = end_name_hash(hash);	return 0;}/* * Case insensitive compare of two isofs names. */static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a,				struct qstr *b, int ms){	int alen, blen;	/* A filename cannot end in '.' or we treat it like it has none */	alen = a->len;	blen = b->len;	if (ms) {		while (alen && a->name[alen-1] == '.')			alen--;		while (blen && b->name[blen-1] == '.')			blen--;	}	if (alen == blen) {		if (strnicmp(a->name, b->name, alen) == 0)			return 0;	}	return 1;}/* * Case sensitive compare of two isofs names. */static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a,					struct qstr *b, int ms){	int alen, blen;	/* A filename cannot end in '.' or we treat it like it has none */	alen = a->len;	blen = b->len;	if (ms) {		while (alen && a->name[alen-1] == '.')			alen--;		while (blen && b->name[blen-1] == '.')			blen--;	}	if (alen == blen) {		if (strncmp(a->name, b->name, alen) == 0)			return 0;	}	return 1;}static intisofs_hash(struct dentry *dentry, struct qstr *qstr){	return isofs_hash_common(dentry, qstr, 0);}static intisofs_hashi(struct dentry *dentry, struct qstr *qstr){	return isofs_hashi_common(dentry, qstr, 0);}static intisofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b){	return isofs_dentry_cmp_common(dentry, a, b, 0);}static intisofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b){	return isofs_dentry_cmpi_common(dentry, a, b, 0);}#ifdef CONFIG_JOLIETstatic intisofs_hash_ms(struct dentry *dentry, struct qstr *qstr){	return isofs_hash_common(dentry, qstr, 1);}static intisofs_hashi_ms(struct dentry *dentry, struct qstr *qstr){	return isofs_hashi_common(dentry, qstr, 1);}static intisofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b){	return isofs_dentry_cmp_common(dentry, a, b, 1);}static intisofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b){	return isofs_dentry_cmpi_common(dentry, a, b, 1);}#endifenum {	Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,	Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,	Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,	Opt_nocompress, Opt_hide, Opt_showassoc,};static match_table_t tokens = {	{Opt_norock, "norock"},	{Opt_nojoliet, "nojoliet"},	{Opt_unhide, "unhide"},	{Opt_hide, "hide"},	{Opt_showassoc, "showassoc"},	{Opt_cruft, "cruft"},	{Opt_utf8, "utf8"},	{Opt_iocharset, "iocharset=%s"},	{Opt_map_a, "map=acorn"},	{Opt_map_a, "map=a"},	{Opt_map_n, "map=normal"},	{Opt_map_n, "map=n"},	{Opt_map_o, "map=off"},	{Opt_map_o, "map=o"},	{Opt_session, "session=%u"},	{Opt_sb, "sbsector=%u"},	{Opt_check_r, "check=relaxed"},	{Opt_check_r, "check=r"},	{Opt_check_s, "check=strict"},	{Opt_check_s, "check=s"},	{Opt_uid, "uid=%u"},	{Opt_gid, "gid=%u"},	{Opt_mode, "mode=%u"},	{Opt_block, "block=%u"},	{Opt_ignore, "conv=binary"},	{Opt_ignore, "conv=b"},	{Opt_ignore, "conv=text"},	{Opt_ignore, "conv=t"},	{Opt_ignore, "conv=mtext"},	{Opt_ignore, "conv=m"},	{Opt_ignore, "conv=auto"},	{Opt_ignore, "conv=a"},	{Opt_nocompress, "nocompress"},	{Opt_err, NULL}};static int parse_options(char *options, struct iso9660_options *popt){	char *p;	int option;	popt->map = 'n';	popt->rock = 'y';	popt->joliet = 'y';	popt->cruft = 'n';	popt->hide = 'n';	popt->showassoc = 'n';	popt->check = 'u';		/* unset */	popt->nocompress = 0;	popt->blocksize = 1024;	popt->mode = S_IRUGO | S_IXUGO; /*					 * r-x for all.  The disc could					 * be shared with DOS machines so					 * virtually anything could be					 * a valid executable.					 */	popt->gid = 0;	popt->uid = 0;	popt->iocharset = NULL;	popt->utf8 = 0;	popt->session=-1;	popt->sbsector=-1;	if (!options)		return 1;	while ((p = strsep(&options, ",")) != NULL) {		int token;		substring_t args[MAX_OPT_ARGS];		unsigned n;		if (!*p)			continue;		token = match_token(p, tokens, args);		switch (token) {		case Opt_norock:			popt->rock = 'n';			break;		case Opt_nojoliet:			popt->joliet = 'n';			break;		case Opt_hide:			popt->hide = 'y';			break;		case Opt_unhide:		case Opt_showassoc:			popt->showassoc = 'y';			break;		case Opt_cruft:			popt->cruft = 'y';			break;		case Opt_utf8:			popt->utf8 = 1;			break;#ifdef CONFIG_JOLIET		case Opt_iocharset:			popt->iocharset = match_strdup(&args[0]);			break;#endif		case Opt_map_a:			popt->map = 'a';			break;		case Opt_map_o:			popt->map = 'o';			break;		case Opt_map_n:			popt->map = 'n';			break;		case Opt_session:			if (match_int(&args[0], &option))				return 0;			n = option;			if (n > 99)				return 0;			popt->session = n + 1;			break;		case Opt_sb:			if (match_int(&args[0], &option))				return 0;			popt->sbsector = option;			break;		case Opt_check_r:			popt->check = 'r';			break;		case Opt_check_s:			popt->check = 's';			break;		case Opt_ignore:			break;		case Opt_uid:			if (match_int(&args[0], &option))				return 0;			popt->uid = option;			break;		case Opt_gid:			if (match_int(&args[0], &option))				return 0;			popt->gid = option;			break;		case Opt_mode:			if (match_int(&args[0], &option))				return 0;			popt->mode = option;			break;		case Opt_block:			if (match_int(&args[0], &option))				return 0;			n = option;			if (n != 512 && n != 1024 && n != 2048)				return 0;			popt->blocksize = n;			break;		case Opt_nocompress:			popt->nocompress = 1;			break;		default:			return 0;		}	}	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 */

⌨️ 快捷键说明

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