Пример #1
0
static struct dentry *
cifs_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data)
{
	int rc;
	struct super_block *sb;
	struct cifs_sb_info *cifs_sb;
	struct smb_vol *volume_info;
	struct cifs_mnt_data mnt_data;
	struct dentry *root;

	cFYI(1, "Devname: %s flags: %d ", dev_name, flags);

	rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name);
	if (rc)
		return ERR_PTR(rc);

	cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
	if (cifs_sb == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out;
	}

	cifs_setup_cifs_sb(volume_info, cifs_sb);

	mnt_data.vol = volume_info;
	mnt_data.cifs_sb = cifs_sb;
	mnt_data.flags = flags;

	sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
	if (IS_ERR(sb)) {
		root = ERR_CAST(sb);
		goto out_cifs_sb;
	}

	if (sb->s_fs_info) {
		cFYI(1, "Use existing superblock");
		goto out_shared;
	}

	/*
	 * Copy mount params for use in submounts. Better to do
	 * the copy here and deal with the error before cleanup gets
	 * complicated post-mount.
	 */
	cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
	if (cifs_sb->mountdata == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out_super;
	}

	sb->s_flags = flags;
	/* BB should we make this contingent on mount parm? */
	sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
	sb->s_fs_info = cifs_sb;

	rc = cifs_read_super(sb, volume_info, dev_name,
			     flags & MS_SILENT ? 1 : 0);
	if (rc) {
		root = ERR_PTR(rc);
		goto out_super;
	}

	sb->s_flags |= MS_ACTIVE;

	root = cifs_get_root(volume_info, sb);
	if (root == NULL)
		goto out_super;

	cFYI(1, "dentry root is: %p", root);
	goto out;

out_shared:
	root = cifs_get_root(volume_info, sb);
	if (root)
		cFYI(1, "dentry root is: %p", root);
	goto out;

out_super:
	kfree(cifs_sb->mountdata);
	deactivate_locked_super(sb);

out_cifs_sb:
	unload_nls(cifs_sb->local_nls);
	kfree(cifs_sb);

out:
	cifs_cleanup_volume_info(&volume_info);
	return root;
}
Пример #2
0
static struct dentry *
cifs_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data)
{
	int rc;
	struct super_block *sb;
	struct cifs_sb_info *cifs_sb;
	struct smb_vol *volume_info;
	struct cifs_mnt_data mnt_data;
	struct dentry *root;

	cifs_dbg(FYI, "Devname: %s flags: %d\n", dev_name, flags);

	volume_info = cifs_get_volume_info((char *)data, dev_name);
	if (IS_ERR(volume_info))
		return ERR_CAST(volume_info);

	cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
	if (cifs_sb == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out_nls;
	}

	cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
	if (cifs_sb->mountdata == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out_cifs_sb;
	}

	cifs_setup_cifs_sb(volume_info, cifs_sb);

	rc = cifs_mount(cifs_sb, volume_info);
	if (rc) {
		if (!(flags & MS_SILENT))
			cifs_dbg(VFS, "cifs_mount failed w/return code = %d\n",
				 rc);
		root = ERR_PTR(rc);
		goto out_mountdata;
	}

	mnt_data.vol = volume_info;
	mnt_data.cifs_sb = cifs_sb;
	mnt_data.flags = flags;

	/* BB should we make this contingent on mount parm? */
	flags |= MS_NODIRATIME | MS_NOATIME;

	sb = sget(fs_type, cifs_match_super, cifs_set_super, flags, &mnt_data);
	if (IS_ERR(sb)) {
		root = ERR_CAST(sb);
		cifs_umount(cifs_sb);
		goto out;
	}

	if (sb->s_root) {
		cifs_dbg(FYI, "Use existing superblock\n");
		cifs_umount(cifs_sb);
	} else {
		rc = cifs_read_super(sb);
		if (rc) {
			root = ERR_PTR(rc);
			goto out_super;
		}

		sb->s_flags |= MS_ACTIVE;
	}

	root = cifs_get_root(volume_info, sb);
	if (IS_ERR(root))
		goto out_super;

	cifs_dbg(FYI, "dentry root is: %p\n", root);
	goto out;

out_super:
	deactivate_locked_super(sb);
out:
	cifs_cleanup_volume_info(volume_info);
	return root;

out_mountdata:
	kfree(cifs_sb->mountdata);
out_cifs_sb:
	kfree(cifs_sb);
out_nls:
	unload_nls(volume_info->local_nls);
	goto out;
}