struct dentry *wrapfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { void *lower_path_name = (void *) dev_name; struct dentry *sb_dentry; struct wrapfs_mnt_opt mount_options; int retval=0; DEBUG_MESG("Enter"); retval = wrapfs_parse_options(raw_data, &mount_options); if(retval<0) { printk("wrapfs_mount: Error parsing options\n"); goto out; } sb_dentry = mount_nodev(fs_type, flags, lower_path_name, wrapfs_read_super); if(!sb_dentry) printk(KERN_ERR "sb_dentry is null\n"); printk("**********************************************\n"); wrapfs_set_mount_options(sb_dentry->d_sb, mount_options); #ifdef WRAPFS_CRYPTO WRAPFS_SB(sb_dentry->d_sb)->has_key = FALSE; // make sure to set it to FALSE ??? #endif // printk("%d\n", wrapfs_get_debug(sb_dentry->d_sb)); //memset(((struct wrapfs_sb_info *)(sb)->s_fs_info)->key, '0', KEYLEN + 1); //((struct wrapfs_sb_info *)(sb)->s_fs_info)->key[KEYLEN] = '\0'; DEBUG_MESG("Exit"); return sb_dentry; out: return ERR_PTR(retval); }
/* * There is no need to lock the wrapfs_super_info's rwsem as there is no * way anyone can have a reference to the superblock at this point in time. */ static int wrapfs_read_super(struct super_block *sb, void *raw_data, int silent) { int err = 0, i = 0; struct wrapfs_dentry_info *lower_root_info = NULL; struct inode *inode = NULL; if (!raw_data) { printk(KERN_ERR "u2fs: read_super: missing data argument\n"); err = -EINVAL; goto out; } /* allocate superblock private data */ sb->s_fs_info = kzalloc(sizeof(struct wrapfs_sb_info), GFP_KERNEL); if (!WRAPFS_SB(sb)) { printk(KERN_CRIT "u2fs: read_super: out of memory\n"); err = -ENOMEM; goto out_free; } atomic_set(&WRAPFS_SB(sb)->generation, 1); WRAPFS_SB(sb)->high_branch_id = -1; /* Parsing the Inputs */ lower_root_info = wrapfs_parse_options(sb, raw_data); if (IS_ERR(lower_root_info)) { printk(KERN_ERR "u2fs: read_super: error while parsing options" "(err = %ld)\n", PTR_ERR(lower_root_info)); err = PTR_ERR(lower_root_info); lower_root_info = NULL; goto out_free; } /* set the lower superblock field of upper superblock */ for (i = 0; i <= 1; i++) { struct dentry *d = lower_root_info->lower_paths[i].dentry; atomic_inc(&d->d_sb->s_active); wrapfs_set_lower_super_idx(sb, i, d->d_sb); } /* inherit maxbytes from highest priority branch */ sb->s_maxbytes = wrapfs_lower_super_idx(sb, 0)->s_maxbytes; /* * Our c/m/atime granularity is 1 ns because we may stack on file * systems whose granularity is as good. */ sb->s_time_gran = 1; sb->s_op = &wrapfs_sops; /* get a new inode and allocate our root dentry */ inode = wrapfs_new_iget(sb, iunique(sb, 1)); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out_sput; } sb->s_root = d_alloc_root(inode); if (unlikely(!sb->s_root)) { err = -ENOMEM; goto out_iput; } d_set_d_op(sb->s_root, &wrapfs_dops); /* link the upper and lower dentries */ sb->s_root->d_fsdata = NULL; err = new_dentry_private_data(sb->s_root); if (unlikely(err)) goto out_freeroot; /* if get here: cannot have error */ /* set the lower dentries for s_root */ for (i = 0; i <= 1 ; i++) { struct dentry *d; struct vfsmount *m; d = lower_root_info->lower_paths[i].dentry; m = lower_root_info->lower_paths[i].mnt; wrapfs_set_lower_dentry_idx(sb->s_root, i, d); wrapfs_set_lower_mnt_idx(sb->s_root, i, m); } atomic_set(&WRAPFS_D(sb->s_root)->generation, 1); if (atomic_read(&inode->i_count) <= 1) wrapfs_fill_inode(sb->s_root, inode); /* * No need to call interpose because we already have a positive * dentry, which was instantiated by d_alloc_root. Just need to * d_rehash it. */ d_rehash(sb->s_root); if (!silent) printk(KERN_INFO "u2fs: mounted on top of type\n"); goto out; /* all is well */ /* no longer needed: free_dentry_private_data(sb->s_root); */ out_freeroot: if (WRAPFS_D(sb->s_root)) { kfree(WRAPFS_D(sb->s_root)->lower_paths); free_dentry_private_data(sb->s_root); } dput(sb->s_root); out_iput: iput(inode); out_sput: /* drop refs we took earlier */ if (lower_root_info && !IS_ERR(lower_root_info)) { for (i = 0; i <= 1; i++) { struct dentry *d; d = lower_root_info->lower_paths[i].dentry; atomic_dec(&d->d_sb->s_active); path_put(&lower_root_info->lower_paths[i]); } kfree(lower_root_info->lower_paths); kfree(lower_root_info); lower_root_info = NULL; } out_free: kfree(WRAPFS_SB(sb)->data); kfree(WRAPFS_SB(sb)); sb->s_fs_info = NULL; out: if (lower_root_info && !IS_ERR(lower_root_info)) { kfree(lower_root_info->lower_paths); kfree(lower_root_info); } return err; }