super.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,666 行 · 第 1/4 页

C
1,666
字号
	struct reiserfs_inode_info *ei;	ei = (struct reiserfs_inode_info *)kmem_cache_alloc(reiserfs_inode_cachep, SLAB_KERNEL);	if (!ei)		return NULL;	return &ei->vfs_inode;}static void reiserfs_destroy_inode(struct inode *inode){	kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));}static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags){	struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *) foo;	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==	    SLAB_CTOR_CONSTRUCTOR) {		INIT_LIST_HEAD(&ei->i_prealloc_list) ;		inode_init_once(&ei->vfs_inode);		ei->i_acl_access = NULL;		ei->i_acl_default = NULL;	}} static int init_inodecache(void){	reiserfs_inode_cachep = kmem_cache_create("reiser_inode_cache",					     sizeof(struct reiserfs_inode_info),					     0, SLAB_RECLAIM_ACCOUNT,					     init_once, NULL);	if (reiserfs_inode_cachep == NULL)		return -ENOMEM;	return 0;}static void destroy_inodecache(void){	if (kmem_cache_destroy(reiserfs_inode_cachep))		reiserfs_warning (NULL, "reiserfs_inode_cache: not all structures were freed");}/* we don't mark inodes dirty, we just log them */static void reiserfs_dirty_inode (struct inode * inode) {    struct reiserfs_transaction_handle th ;    if (inode->i_sb->s_flags & MS_RDONLY) {        reiserfs_warning(inode->i_sb, "clm-6006: writing inode %lu on readonly FS",	                  inode->i_ino) ;        return ;    }    reiserfs_write_lock(inode->i_sb);    /* this is really only used for atime updates, so they don't have    ** to be included in O_SYNC or fsync    */    journal_begin(&th, inode->i_sb, 1) ;    reiserfs_update_sd (&th, inode);    journal_end(&th, inode->i_sb, 1) ;    reiserfs_write_unlock(inode->i_sb);}static void reiserfs_clear_inode (struct inode *inode){    struct posix_acl *acl;    acl = REISERFS_I(inode)->i_acl_access;    if (acl && !IS_ERR (acl))        posix_acl_release (acl);    REISERFS_I(inode)->i_acl_access = NULL;    acl = REISERFS_I(inode)->i_acl_default;    if (acl && !IS_ERR (acl))        posix_acl_release (acl);    REISERFS_I(inode)->i_acl_default = NULL;}struct super_operations reiserfs_sops = {  .alloc_inode = reiserfs_alloc_inode,  .destroy_inode = reiserfs_destroy_inode,  .write_inode = reiserfs_write_inode,  .dirty_inode = reiserfs_dirty_inode,  .delete_inode = reiserfs_delete_inode,  .clear_inode  = reiserfs_clear_inode,  .put_super = reiserfs_put_super,  .write_super = reiserfs_write_super,  .write_super_lockfs = reiserfs_write_super_lockfs,  .unlockfs = reiserfs_unlockfs,  .statfs = reiserfs_statfs,  .remount_fs = reiserfs_remount,};static struct export_operations reiserfs_export_ops = {  .encode_fh = reiserfs_encode_fh,  .decode_fh = reiserfs_decode_fh,  .get_parent = reiserfs_get_parent,  .get_dentry = reiserfs_get_dentry,} ;/* this struct is used in reiserfs_getopt () for containing the value for those   mount options that have values rather than being toggles. */typedef struct {    char * value;    int setmask; /* bitmask which is to set on mount_options bitmask when this                    value is found, 0 is no bits are to be changed. */    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this		    value is found, 0 is no bits are to be changed. This is		    applied BEFORE setmask */} arg_desc_t;/* this struct is used in reiserfs_getopt() for describing the set of reiserfs   mount options */typedef struct {    char * option_name;    int arg_required; /* 0 if argument is not required, not 0 otherwise */    const arg_desc_t * values; /* list of values accepted by an option */    int setmask; /* bitmask which is to set on mount_options bitmask when this                    value is found, 0 is no bits are to be changed. */    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this		    value is found, 0 is no bits are to be changed. This is		    applied BEFORE setmask */} opt_desc_t;/* possible values for -o data= */static const arg_desc_t logging_mode[] = {    {"ordered", 1<<REISERFS_DATA_ORDERED, (1<<REISERFS_DATA_LOG|1<<REISERFS_DATA_WRITEBACK)},    {"journal", 1<<REISERFS_DATA_LOG, (1<<REISERFS_DATA_ORDERED|1<<REISERFS_DATA_WRITEBACK)},    {"writeback", 1<<REISERFS_DATA_WRITEBACK, (1<<REISERFS_DATA_ORDERED|1<<REISERFS_DATA_LOG)},    {NULL, 0}};/* possible values for -o barrier= */static const arg_desc_t barrier_mode[] = {    {"none", 1<<REISERFS_BARRIER_NONE, 1<<REISERFS_BARRIER_FLUSH},    {"flush", 1<<REISERFS_BARRIER_FLUSH, 1<<REISERFS_BARRIER_NONE},    {NULL, 0}};/* possible values for "-o block-allocator=" and bits which are to be set in   s_mount_opt of reiserfs specific part of in-core super block */static const arg_desc_t balloc[] = {    {"noborder", 1<<REISERFS_NO_BORDER, 0},    {"border", 0, 1<<REISERFS_NO_BORDER},    {"no_unhashed_relocation", 1<<REISERFS_NO_UNHASHED_RELOCATION, 0},    {"hashed_relocation", 1<<REISERFS_HASHED_RELOCATION, 0},    {"test4", 1<<REISERFS_TEST4, 0},    {"notest4", 0, 1<<REISERFS_TEST4},    {NULL, 0, 0}};static const arg_desc_t tails[] = {    {"on", 1<<REISERFS_LARGETAIL, 1<<REISERFS_SMALLTAIL},    {"off", 0, (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},    {"small", 1<<REISERFS_SMALLTAIL, 1<<REISERFS_LARGETAIL},    {NULL, 0, 0}};int reiserfs_default_io_size = 128 * 1024; /* Default recommended I/O size is 128k.					      There might be broken applications that are					      confused by this. Use nolargeio mount option					      to get usual i/o size = PAGE_SIZE.					    *//* proceed only one option from a list *cur - string containing of mount options   opts - array of options which are accepted   opt_arg - if option is found and requires an argument and if it is specifed   in the input - pointer to the argument is stored here   bit_flags - if option requires to set a certain bit - it is set here   return -1 if unknown option is found, opt->arg_required otherwise */static int reiserfs_getopt ( struct super_block * s, char ** cur, opt_desc_t * opts, char ** opt_arg,			    unsigned long * bit_flags){    char * p;    /* foo=bar,        ^   ^  ^       |   |  +-- option_end       |   +-- arg_start       +-- option_start    */    const opt_desc_t * opt;    const arg_desc_t * arg;            p = *cur;        /* assume argument cannot contain commas */    *cur = strchr (p, ',');    if (*cur) {	*(*cur) = '\0';	(*cur) ++;    }    if ( !strncmp (p, "alloc=", 6) ) {	/* Ugly special case, probably we should redo options parser so that	   it can understand several arguments for some options, also so that	   it can fill several bitfields with option values. */	if ( reiserfs_parse_alloc_options( s, p + 6) ) {	    return -1;	} else {	    return 0;	}    }     /* for every option in the list */    for (opt = opts; opt->option_name; opt ++) {	if (!strncmp (p, opt->option_name, strlen (opt->option_name))) {	    if (bit_flags) {		*bit_flags &= ~opt->clrmask;		*bit_flags |= opt->setmask;	    }	    break;	}    }    if (!opt->option_name) {	reiserfs_warning (s, "unknown mount option \"%s\"", p);	return -1;    }        p += strlen (opt->option_name);    switch (*p) {    case '=':	if (!opt->arg_required) {	    reiserfs_warning (s, "the option \"%s\" does not require an argument",		    opt->option_name);	    return -1;	}	break;	    case 0:	if (opt->arg_required) {	    reiserfs_warning (s, "the option \"%s\" requires an argument", opt->option_name);	    return -1;	}	break;    default:	reiserfs_warning (s, "head of option \"%s\" is only correct", opt->option_name);	return -1;    }    /* move to the argument, or to next option if argument is not required */    p ++;        if ( opt->arg_required && !strlen (p) ) {	/* this catches "option=," */	reiserfs_warning (s, "empty argument for \"%s\"", opt->option_name);	return -1;    }        if (!opt->values) {	/* *=NULLopt_arg contains pointer to argument */	*opt_arg = p;	return opt->arg_required;    }        /* values possible for this option are listed in opt->values */    for (arg = opt->values; arg->value; arg ++) {	if (!strcmp (p, arg->value)) {	    if (bit_flags) {		*bit_flags &= ~arg->clrmask;		*bit_flags |= arg->setmask;	    }	    return opt->arg_required;	}    }        reiserfs_warning (s, "bad value \"%s\" for option \"%s\"", p, opt->option_name);    return -1;}/* returns 0 if something is wrong in option string, 1 - otherwise */static int reiserfs_parse_options (struct super_block * s, char * options, /* string given via mount's -o */				   unsigned long * mount_options,				   /* after the parsing phase, contains the				      collection of bitflags defining what				      mount options were selected. */				   unsigned long * blocks, /* strtol-ed from NNN of resize=NNN */				   char ** jdev_name,				   unsigned int * commit_max_age){    int c;    char * arg = NULL;    char * pos;    opt_desc_t opts[] = {	/* Compatibility stuff, so that -o notail for old setups still work */	{"tails",	.arg_required = 't', .values = tails},	{"notail",	.clrmask = (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},	{"conv",	.setmask = 1<<REISERFS_CONVERT},	{"attrs",	.setmask = 1<<REISERFS_ATTRS},	{"noattrs",	.clrmask = 1<<REISERFS_ATTRS},	{"user_xattr",	.setmask = 1<<REISERFS_XATTRS_USER},	{"nouser_xattr",.clrmask = 1<<REISERFS_XATTRS_USER},#ifdef CONFIG_REISERFS_FS_POSIX_ACL	{"acl",		.setmask = 1<<REISERFS_POSIXACL},	{"noacl",	.clrmask = 1<<REISERFS_POSIXACL},#endif	{"nolog",},	 /* This is unsupported */	{"replayonly",	.setmask = 1<<REPLAYONLY},	{"block-allocator", .arg_required = 'a', .values = balloc},	{"data",	.arg_required = 'd', .values = logging_mode},	{"barrier",	.arg_required = 'b', .values = barrier_mode},	{"resize",	.arg_required = 'r', .values = NULL},	{"jdev",	.arg_required = 'j', .values = NULL},	{"nolargeio",	.arg_required = 'w', .values = NULL},	{"commit",	.arg_required = 'c', .values = NULL},	{"usrquota",},	{"grpquota",},	{NULL,}    };	    *blocks = 0;    if (!options || !*options)	/* use default configuration: create tails, journaling on, no	   conversion to newest format */	return 1;        for (pos = options; pos; ) {	c = reiserfs_getopt (s, &pos, opts, &arg, mount_options);	if (c == -1)	    /* wrong option is given */	    return 0;		if (c == 'r') {	    char * p;	    	    p = NULL;	    /* "resize=NNN" */	    *blocks = simple_strtoul (arg, &p, 0);	    if (*p != '\0') {		/* NNN does not look like a number */		reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg);		return 0;	    }	}	if ( c == 'c' ) {		char *p = NULL;		unsigned long val = simple_strtoul (arg, &p, 0);		/* commit=NNN (time in seconds) */		if ( *p != '\0' || val >= (unsigned int)-1) {			reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg);			return 0;		}		*commit_max_age = (unsigned int)val;	}	if ( c == 'w' ) {		char *p=NULL;		int val = simple_strtoul (arg, &p, 0);		if ( *p != '\0') {		    reiserfs_warning (s, "reiserfs_parse_options: non-numeric value %s for nolargeio option", arg);		    return 0;		}		if ( val ) 		    reiserfs_default_io_size = PAGE_SIZE;		else		    reiserfs_default_io_size = 128 * 1024;	}	if (c == 'j') {	    if (arg && *arg && jdev_name) {		if ( *jdev_name ) { //Hm, already assigned?		    reiserfs_warning (s, "reiserfs_parse_options: journal device was already  specified to be %s", *jdev_name);		    return 0;		}		*jdev_name = arg;	    }	}    }        return 1;}static void switch_data_mode(struct super_block *s, unsigned long mode) {    REISERFS_SB(s)->s_mount_opt &= ~((1 << REISERFS_DATA_LOG) |                                       (1 << REISERFS_DATA_ORDERED) |				       (1 << REISERFS_DATA_WRITEBACK));    REISERFS_SB(s)->s_mount_opt |= (1 << mode);}static void handle_data_mode(struct super_block *s, unsigned long mount_options){    if (mount_options & (1 << REISERFS_DATA_LOG)) {        if (!reiserfs_data_log(s)) {	    switch_data_mode(s, REISERFS_DATA_LOG);	    reiserfs_info (s, "switching to journaled data mode\n");	}    } else if (mount_options & (1 << REISERFS_DATA_ORDERED)) {        if (!reiserfs_data_ordered(s)) {	    switch_data_mode(s, REISERFS_DATA_ORDERED);	    reiserfs_info (s, "switching to ordered data mode\n");	}    } else if (mount_options & (1 << REISERFS_DATA_WRITEBACK)) {        if (!reiserfs_data_writeback(s)) {	    switch_data_mode(s, REISERFS_DATA_WRITEBACK);	    reiserfs_info (s, "switching to writeback data mode\n");	}    }}static void handle_barrier_mode(struct super_block *s, unsigned long bits) {    int flush = (1 << REISERFS_BARRIER_FLUSH);    int none = (1 << REISERFS_BARRIER_NONE);    int all_barrier = flush | none;    if (bits & all_barrier) {        REISERFS_SB(s)->s_mount_opt &= ~all_barrier;	if (bits & flush) {	    REISERFS_SB(s)->s_mount_opt |= flush;	    printk("reiserfs: enabling write barrier flush mode\n");	} else if (bits & none) {	    REISERFS_SB(s)->s_mount_opt |= none;	    printk("reiserfs: write barriers turned off\n");	}

⌨️ 快捷键说明

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