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 + -
显示快捷键?