struct super_block *capifs_read_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; struct dentry * root; struct capifs_sb_info *sbi; /* Super block already completed? */ if (s->s_root) goto out; sbi = (struct capifs_sb_info *) kmalloc(sizeof(struct capifs_sb_info), GFP_KERNEL); if ( !sbi ) goto fail; memset(sbi, 0, sizeof(struct capifs_sb_info)); sbi->magic = CAPIFS_SBI_MAGIC; if ( capifs_parse_options(data,sbi) ) { kfree(sbi); printk("capifs: called with bogus options\n"); goto fail; } sbi->nccis = kmalloc(sizeof(struct capifs_ncci) * sbi->max_ncci, GFP_KERNEL); if ( !sbi->nccis ) { kfree(sbi); goto fail; } memset(sbi->nccis, 0, sizeof(struct capifs_ncci) * sbi->max_ncci); s->u.generic_sbp = (void *) sbi; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = CAPIFS_SUPER_MAGIC; s->s_op = &capifs_sops; s->s_root = NULL; /* * Get the root inode and dentry, but defer checking for errors. */ root_inode = capifs_new_inode(s); if (root_inode) { root_inode->i_ino = 1; root_inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; root_inode->i_op = &capifs_root_inode_operations; root_inode->i_fop = &capifs_root_operations; root_inode->i_nlink = 2; } root = d_alloc_root(root_inode); /* * Check whether somebody else completed the super block. */ if (s->s_root) { if (root) dput(root); else iput(root_inode); goto out; } if (!root) { printk("capifs: get root dentry failed\n"); /* * iput() can block, so we clear the super block first. */ iput(root_inode); kfree(sbi->nccis); kfree(sbi); goto fail; } /* * Check whether somebody else completed the super block. */ if (s->s_root) goto out; /* * Success! Install the root dentry now to indicate completion. */ s->s_root = root; sbi->next = mounts; if ( sbi->next ) SBI(sbi->next)->back = &(sbi->next); sbi->back = &mounts; mounts = s; out: /* Success ... somebody else completed the super block for us. */ return s; fail: return NULL; }
struct super_block *capifs_read_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; struct dentry * root; struct capifs_sb_info *sbi; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51) MOD_INC_USE_COUNT; lock_super(s); #endif /* Super block already completed? */ if (s->s_root) goto out; sbi = (struct capifs_sb_info *) kmalloc(sizeof(struct capifs_sb_info), GFP_KERNEL); if ( !sbi ) goto fail; memset(sbi, 0, sizeof(struct capifs_sb_info)); sbi->magic = CAPIFS_SBI_MAGIC; if ( capifs_parse_options(data,sbi) ) { kfree(sbi); printk("capifs: called with bogus options\n"); goto fail; } sbi->nccis = kmalloc(sizeof(struct capifs_ncci) * sbi->max_ncci, GFP_KERNEL); if ( !sbi->nccis ) { kfree(sbi); goto fail; } memset(sbi->nccis, 0, sizeof(struct capifs_ncci) * sbi->max_ncci); s->u.generic_sbp = (void *) sbi; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = CAPIFS_SUPER_MAGIC; s->s_op = &capifs_sops; s->s_root = NULL; /* * Get the root inode and dentry, but defer checking for errors. */ root_inode = iget(s, 1); /* inode 1 == root directory */ root = d_alloc_root(root_inode); /* * Check whether somebody else completed the super block. */ if (s->s_root) { if (root) dput(root); else iput(root_inode); goto out; } if (!root) { printk("capifs: get root dentry failed\n"); /* * iput() can block, so we clear the super block first. */ iput(root_inode); kfree(sbi->nccis); kfree(sbi); goto fail; } /* * Check whether somebody else completed the super block. */ if (s->s_root) goto out; /* * Success! Install the root dentry now to indicate completion. */ s->s_root = root; sbi->next = mounts; if ( sbi->next ) SBI(sbi->next)->back = &(sbi->next); sbi->back = &mounts; mounts = s; out: /* Success ... somebody else completed the super block for us. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51) unlock_super(s); #endif return s; fail: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51) unlock_super(s); MOD_DEC_USE_COUNT; #endif return NULL; }