示例#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);

	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))
			cERROR(1, "cifs_mount failed w/return code = %d", rc);
		root = ERR_PTR(rc);
		goto out_mountdata;
	}

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

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

	if (sb->s_root) {
		cFYI(1, "Use existing superblock");
		cifs_umount(cifs_sb);
	} else {
		sb->s_flags = flags;
		/* BB should we make this contingent on mount parm? */
		sb->s_flags |= MS_NODIRATIME | MS_NOATIME;

		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;

	cFYI(1, "dentry root is: %p", 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;
}
示例#2
0
static void __exit exit_nls_euc_kr(void)
{
	unregister_nls(&table);
	unload_nls(p_nls);
}
示例#3
0
/* Parse the (re)mount options. */
static int parse_options(ntfs_volume *vol, char *opt)
{
	char *value;		/* Defaults if not specified and !remount. */
	ntfs_uid_t uid = -1;	/* 0, root user only */
	ntfs_gid_t gid = -1;	/* 0, root user only */
	int umask = -1;		/* 0077, owner access only */
	unsigned int ngt = -1;	/* ngt_nt */
	void *nls_map = NULL;	/* Try to load the default NLS. */
	int use_utf8 = -1;	/* If no NLS specified and loading the default
				   NLS failed use utf8. */
	int mft_zone_mul = -1;	/* 1 */

	if (!opt)
		goto done;
	for (opt = strtok(opt, ","); opt; opt = strtok(NULL, ",")) {
		if ((value = strchr(opt, '=')) != NULL)
			*value ++= '\0';
		if (strcmp(opt, "uid") == 0) {
			if (!value || !*value)
				goto needs_arg;
			uid = simple_strtoul(value, &value, 0);
			if (*value) {
				printk(KERN_ERR "NTFS: uid invalid argument\n");
				return 0;
			}
		} else if (strcmp(opt, "gid") == 0) {
			if (!value || !*value)
				goto needs_arg;
			gid = simple_strtoul(value, &value, 0);
			if (*value) {
				printk(KERN_ERR "NTFS: gid invalid argument\n");
				return 0;
			}
		} else if (strcmp(opt, "umask") == 0) {
			if (!value || !*value)
				goto needs_arg;
			umask = simple_strtoul(value, &value, 0);
			if (*value) {
				printk(KERN_ERR "NTFS: umask invalid "
						"argument\n");
				return 0;
			}
		} else if (strcmp(opt, "mft_zone_multiplier") == 0) {
			unsigned long ul;

			if (!value || !*value)
				goto needs_arg;
			ul = simple_strtoul(value, &value, 0);
			if (*value) {
				printk(KERN_ERR "NTFS: mft_zone_multiplier "
						"invalid argument\n");
				return 0;
			}
			if (ul >= 1 && ul <= 4)
				mft_zone_mul = ul;
			else {
				mft_zone_mul = 1;
				printk(KERN_WARNING "NTFS: mft_zone_multiplier "
					      "out of range. Setting to 1.\n");
			}
		} else if (strcmp(opt, "posix") == 0) {
			int val;
			if (!value || !*value)
				goto needs_arg;
			if (!simple_getbool(value, &val))
				goto needs_bool;
			ngt = val ? ngt_posix : ngt_nt;
		} else if (strcmp(opt, "show_sys_files") == 0) {
			int val = 0;
			if (!value || !*value)
				val = 1;
			else if (!simple_getbool(value, &val))
				goto needs_bool;
			ngt = val ? ngt_full : ngt_nt;
		} else if (strcmp(opt, "iocharset") == 0) {
			if (!value || !*value)
				goto needs_arg;
			nls_map = load_nls(value);
			if (!nls_map) {
				printk(KERN_ERR "NTFS: charset not found");
				return 0;
			}
		} else if (strcmp(opt, "utf8") == 0) {
			int val = 0;
			if (!value || !*value)
				val = 1;
			else if (!simple_getbool(value, &val))
				goto needs_bool;
			use_utf8 = val;
		} else {
			printk(KERN_ERR "NTFS: unkown option '%s'\n", opt);
			return 0;
		}
	}
done:
	if (use_utf8 == -1) {
		/* utf8 was not specified at all. */
		if (!nls_map) {
			/*
			 * No NLS was specified. If first mount, load the
			 * default NLS, otherwise don't change the NLS setting.
			 */
			if (vol->nls_map == (void*)-1)
				vol->nls_map = load_nls_default();
		} else {
			/* If an NLS was already loaded, unload it first. */
			if (vol->nls_map && vol->nls_map != (void*)-1)
				unload_nls(vol->nls_map);
			/* Use the specified NLS. */
			vol->nls_map = nls_map;
		}
	} else {
		/* utf8 was specified. */
		if (use_utf8 && nls_map) {
			unload_nls(nls_map);
			printk(KERN_ERR "NTFS: utf8 cannot be combined with "
					"iocharset.\n");
			return 0;
		}
		/* If an NLS was already loaded, unload it first. */
		if (vol->nls_map && vol->nls_map != (void*)-1)
			unload_nls(vol->nls_map);
		if (!use_utf8) {
			/* utf8 was specified as false. */
			if (!nls_map)
				/* No NLS was specified, load the default. */
				vol->nls_map = load_nls_default();
			else
				/* Use the specified NLS. */
				vol->nls_map = nls_map;
		} else
			/* utf8 was specified as true. */
			vol->nls_map = NULL;
	}
	if (uid != -1)
		vol->uid = uid;
	if (gid != -1)
		vol->gid = gid;
	if (umask != -1)
		vol->umask = (ntmode_t)umask;
	if (ngt != -1)
		vol->ngt = ngt;
	if (mft_zone_mul != -1) {
		/* mft_zone_multiplier was specified. */
		if (vol->mft_zone_multiplier != -1) {
			/* This is a remount, ignore a change and warn user. */
			if (vol->mft_zone_multiplier != mft_zone_mul)
				printk(KERN_WARNING "NTFS: Ignoring changes in "
						"mft_zone_multiplier on "
						"remount. If you want to "
						"change this you need to "
						"umount and mount again.\n");
		} else
			/* Use the specified multiplier. */
			vol->mft_zone_multiplier = mft_zone_mul;
	} else if (vol->mft_zone_multiplier == -1)
		/* No multiplier specified and first mount, so set default. */
		vol->mft_zone_multiplier = 1;
	return 1;
needs_arg:
	printk(KERN_ERR "NTFS: %s needs an argument", opt);
	return 0;
needs_bool:
	printk(KERN_ERR "NTFS: %s needs boolean argument", opt);
	return 0;
}
示例#4
0
static int
cifs_read_super(struct super_block *sb, void *data,
                const char *devname, int silent)
{
    struct inode *inode;
    struct cifs_sb_info *cifs_sb;
    int rc = 0;

    /* BB should we make this contingent on mount parm? */
    sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
    sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
    cifs_sb = CIFS_SB(sb);
    if (cifs_sb == NULL)
        return -ENOMEM;

#ifdef CONFIG_CIFS_DFS_UPCALL
    /* copy mount params to sb for use in submounts */
    /* BB: should we move this after the mount so we
     * do not have to do the copy on failed mounts?
     * BB: May be it is better to do simple copy before
     * complex operation (mount), and in case of fail
     * just exit instead of doing mount and attempting
     * undo it if this copy fails?*/
    if (data) {
        int len = strlen(data);
        cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
        if (cifs_sb->mountdata == NULL) {
            kfree(sb->s_fs_info);
            sb->s_fs_info = NULL;
            return -ENOMEM;
        }
        strncpy(cifs_sb->mountdata, data, len + 1);
        cifs_sb->mountdata[len] = '\0';
    }
#endif

    rc = cifs_mount(sb, cifs_sb, data, devname);

    if (rc) {
        if (!silent)
            cERROR(1,
                   ("cifs_mount failed w/return code = %d", rc));
        goto out_mount_failed;
    }

    sb->s_magic = CIFS_MAGIC_NUMBER;
    sb->s_op = &cifs_super_ops;
    /*	if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
    	    sb->s_blocksize =
    		cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
#ifdef CONFIG_CIFS_QUOTA
    sb->s_qcop = &cifs_quotactl_ops;
#endif
    sb->s_blocksize = CIFS_MAX_MSGSIZE;
    sb->s_blocksize_bits = 14;	/* default 2**14 = CIFS_MAX_MSGSIZE */
    inode = cifs_root_iget(sb, ROOT_I);

    if (IS_ERR(inode)) {
        rc = PTR_ERR(inode);
        inode = NULL;
        goto out_no_root;
    }

    sb->s_root = d_alloc_root(inode);

    if (!sb->s_root) {
        rc = -ENOMEM;
        goto out_no_root;
    }

#ifdef CONFIG_CIFS_EXPERIMENTAL
    if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
        cFYI(1, ("export ops supported"));
        sb->s_export_op = &cifs_export_ops;
    }
#endif /* EXPERIMENTAL */

    return 0;

out_no_root:
    cERROR(1, ("cifs_read_super: get root inode failed"));
    if (inode)
        iput(inode);

    cifs_umount(sb, cifs_sb);

out_mount_failed:
    if (cifs_sb) {
#ifdef CONFIG_CIFS_DFS_UPCALL
        if (cifs_sb->mountdata) {
            kfree(cifs_sb->mountdata);
            cifs_sb->mountdata = NULL;
        }
#endif
        if (cifs_sb->local_nls)
            unload_nls(cifs_sb->local_nls);
        kfree(cifs_sb);
    }
    return rc;
}
示例#5
0
static void
smb_unload_nls(struct smb_sb_info *server)
{
	unload_nls(server->remote_nls);
	unload_nls(server->local_nls);
}
示例#6
0
/* allocate global info, try to map host share */
static int sf_glob_alloc(struct vbsf_mount_info_new *info, struct sf_glob_info **sf_gp)
{
    int err, rc;
    SHFLSTRING *str_name;
    size_t name_len, str_len;
    struct sf_glob_info *sf_g;

    TRACE();
    sf_g = kmalloc(sizeof(*sf_g), GFP_KERNEL);
    if (!sf_g)
    {
        err = -ENOMEM;
        LogRelFunc(("could not allocate memory for global info\n"));
        goto fail0;
    }

    RT_ZERO(*sf_g);

    if (   info->nullchar     != '\0'
        || info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0
        || info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1
        || info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2)
    {
        /* An old version of mount.vboxsf made the syscall. Translate the
         * old parameters to the new structure. */
        struct vbsf_mount_info_old *info_old = (struct vbsf_mount_info_old *)info;
        static struct vbsf_mount_info_new info_compat;

        info = &info_compat;
        memset(info, 0, sizeof(*info));
        memcpy(&info->name, &info_old->name, MAX_HOST_NAME);
        memcpy(&info->nls_name, &info_old->nls_name, MAX_NLS_NAME);
        info->length = offsetof(struct vbsf_mount_info_new, dmode);
        info->uid    = info_old->uid;
        info->gid    = info_old->gid;
        info->ttl    = info_old->ttl;
    }

    info->name[sizeof(info->name) - 1] = 0;
    info->nls_name[sizeof(info->nls_name) - 1] = 0;

    name_len = strlen(info->name);
    if (name_len > 0xfffe)
    {
        err = -ENAMETOOLONG;
        LogFunc(("map name too big\n"));
        goto fail1;
    }

    str_len = offsetof(SHFLSTRING, String.utf8) + name_len + 1;
    str_name = kmalloc(str_len, GFP_KERNEL);
    if (!str_name)
    {
        err = -ENOMEM;
        LogRelFunc(("could not allocate memory for host name\n"));
        goto fail1;
    }

    str_name->u16Length = name_len;
    str_name->u16Size = name_len + 1;
    memcpy(str_name->String.utf8, info->name, name_len + 1);

    if (info->nls_name[0] && strcmp(info->nls_name, "utf8"))
    {
        sf_g->nls = load_nls(info->nls_name);
        if (!sf_g->nls)
        {
            err = -EINVAL;
            LogFunc(("failed to load nls %s\n", info->nls_name));
            goto fail1;
        }
    }
    else
        sf_g->nls = NULL;

    rc = vboxCallMapFolder(&client_handle, str_name, &sf_g->map);
    kfree(str_name);

    if (RT_FAILURE(rc))
    {
        err = -EPROTO;
        LogFunc(("vboxCallMapFolder failed rc=%d\n", rc));
        goto fail2;
    }

    sf_g->ttl = info->ttl;
    sf_g->uid = info->uid;
    sf_g->gid = info->gid;

    if ((unsigned)info->length >= sizeof(struct vbsf_mount_info_new))
    {
        /* new fields */
        sf_g->dmode = info->dmode;
        sf_g->fmode = info->fmode;
        sf_g->dmask = info->dmask;
        sf_g->fmask = info->fmask;
    }
    else
    {
        sf_g->dmode = ~0;
        sf_g->fmode = ~0;
    }

    *sf_gp = sf_g;
    return 0;

fail2:
    if (sf_g->nls)
        unload_nls(sf_g->nls);

fail1:
    kfree(sf_g);

fail0:
    return err;
}
示例#7
0
static int
cifs_read_super(struct super_block *sb, void *data,
		const char *devname, int silent)
{
	struct inode *inode;
	struct cifs_sb_info *cifs_sb;
	int rc = 0;

	sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
	sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
	cifs_sb = CIFS_SB(sb);
	if(cifs_sb == NULL)
		return -ENOMEM;
	else
		memset(cifs_sb,0,sizeof(struct cifs_sb_info));
	

	rc = cifs_mount(sb, cifs_sb, data, devname);

	if (rc) {
		if (!silent)
			cERROR(1,
			       ("cifs_mount failed w/return code = %d", rc));
		goto out_mount_failed;
	}

	sb->s_magic = CIFS_MAGIC_NUMBER;
	sb->s_op = &cifs_super_ops;
/*	if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
	    sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
#ifdef CONFIG_CIFS_QUOTA
	sb->s_qcop = &cifs_quotactl_ops;
#endif
	sb->s_blocksize = CIFS_MAX_MSGSIZE;
	sb->s_blocksize_bits = 14;	/* default 2**14 = CIFS_MAX_MSGSIZE */
	inode = iget(sb, ROOT_I);

	if (!inode) {
		rc = -ENOMEM;
		goto out_no_root;
	}

	sb->s_root = d_alloc_root(inode);

	if (!sb->s_root) {
		rc = -ENOMEM;
		goto out_no_root;
	}

	return 0;

out_no_root:
	cERROR(1, ("cifs_read_super: get root inode failed"));
	if (inode)
		iput(inode);

out_mount_failed:
	if(cifs_sb) {
		if(cifs_sb->local_nls)
			unload_nls(cifs_sb->local_nls);	
		kfree(cifs_sb);
	}
	return rc;
}
示例#8
0
文件: inode.c 项目: Mr-Aloof/wl500g
static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
{
	struct ncp_mount_data_kernel data;
	struct ncp_server *server;
	struct file *ncp_filp;
	struct inode *root_inode;
	struct inode *sock_inode;
	struct socket *sock;
	int error;
	int default_bufsize;
#ifdef CONFIG_NCPFS_PACKET_SIGNING
	int options;
#endif
	struct ncp_entry_info finfo;

	data.wdog_pid = NULL;
	server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
	if (!server)
		return -ENOMEM;
	sb->s_fs_info = server;

	error = -EFAULT;
	if (raw_data == NULL)
		goto out;
	switch (*(int*)raw_data) {
		case NCP_MOUNT_VERSION:
			{
				struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;

				data.flags = md->flags;
				data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
				data.mounted_uid = md->mounted_uid;
				data.wdog_pid = find_get_pid(md->wdog_pid);
				data.ncp_fd = md->ncp_fd;
				data.time_out = md->time_out;
				data.retry_count = md->retry_count;
				data.uid = md->uid;
				data.gid = md->gid;
				data.file_mode = md->file_mode;
				data.dir_mode = md->dir_mode;
				data.info_fd = -1;
				memcpy(data.mounted_vol, md->mounted_vol,
					NCP_VOLNAME_LEN+1);
			}
			break;
		case NCP_MOUNT_VERSION_V4:
			{
				struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;

				data.flags = md->flags;
				data.int_flags = 0;
				data.mounted_uid = md->mounted_uid;
				data.wdog_pid = find_get_pid(md->wdog_pid);
				data.ncp_fd = md->ncp_fd;
				data.time_out = md->time_out;
				data.retry_count = md->retry_count;
				data.uid = md->uid;
				data.gid = md->gid;
				data.file_mode = md->file_mode;
				data.dir_mode = md->dir_mode;
				data.info_fd = -1;
				data.mounted_vol[0] = 0;
			}
			break;
		default:
			error = -ECHRNG;
			if (memcmp(raw_data, "vers", 4) == 0) {
				error = ncp_parse_options(&data, raw_data);
			}
			if (error)
				goto out;
			break;
	}
	error = -EBADF;
	ncp_filp = fget(data.ncp_fd);
	if (!ncp_filp)
		goto out;
	error = -ENOTSOCK;
	sock_inode = ncp_filp->f_path.dentry->d_inode;
	if (!S_ISSOCK(sock_inode->i_mode))
		goto out_fput;
	sock = SOCKET_I(sock_inode);
	if (!sock)
		goto out_fput;
		
	if (sock->type == SOCK_STREAM)
		default_bufsize = 0xF000;
	else
		default_bufsize = 1024;

	sb->s_flags |= MS_NODIRATIME;	/* probably even noatime */
	sb->s_maxbytes = 0xFFFFFFFFU;
	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
	sb->s_blocksize_bits = 10;
	sb->s_magic = NCP_SUPER_MAGIC;
	sb->s_op = &ncp_sops;

	server = NCP_SBP(sb);
	memset(server, 0, sizeof(*server));

	server->ncp_filp = ncp_filp;
	server->ncp_sock = sock;
	
	if (data.info_fd != -1) {
		struct socket *info_sock;

		error = -EBADF;
		server->info_filp = fget(data.info_fd);
		if (!server->info_filp)
			goto out_fput;
		error = -ENOTSOCK;
		sock_inode = server->info_filp->f_path.dentry->d_inode;
		if (!S_ISSOCK(sock_inode->i_mode))
			goto out_fput2;
		info_sock = SOCKET_I(sock_inode);
		if (!info_sock)
			goto out_fput2;
		error = -EBADFD;
		if (info_sock->type != SOCK_STREAM)
			goto out_fput2;
		server->info_sock = info_sock;
	}

/*	server->lock = 0;	*/
	mutex_init(&server->mutex);
	server->packet = NULL;
/*	server->buffer_size = 0;	*/
/*	server->conn_status = 0;	*/
/*	server->root_dentry = NULL;	*/
/*	server->root_setuped = 0;	*/
#ifdef CONFIG_NCPFS_PACKET_SIGNING
/*	server->sign_wanted = 0;	*/
/*	server->sign_active = 0;	*/
#endif
	server->auth.auth_type = NCP_AUTH_NONE;
/*	server->auth.object_name_len = 0;	*/
/*	server->auth.object_name = NULL;	*/
/*	server->auth.object_type = 0;		*/
/*	server->priv.len = 0;			*/
/*	server->priv.data = NULL;		*/

	server->m = data;
	/* Althought anything producing this is buggy, it happens
	   now because of PATH_MAX changes.. */
	if (server->m.time_out < 1) {
		server->m.time_out = 10;
		printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
	}
	server->m.time_out = server->m.time_out * HZ / 100;
	server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
	server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;

#ifdef CONFIG_NCPFS_NLS
	/* load the default NLS charsets */
	server->nls_vol = load_nls_default();
	server->nls_io = load_nls_default();
#endif /* CONFIG_NCPFS_NLS */

	server->dentry_ttl = 0;	/* no caching */

	INIT_LIST_HEAD(&server->tx.requests);
	mutex_init(&server->rcv.creq_mutex);
	server->tx.creq		= NULL;
	server->rcv.creq	= NULL;
	server->data_ready	= sock->sk->sk_data_ready;
	server->write_space	= sock->sk->sk_write_space;
	server->error_report	= sock->sk->sk_error_report;
	sock->sk->sk_user_data	= server;

	init_timer(&server->timeout_tm);
#undef NCP_PACKET_SIZE
#define NCP_PACKET_SIZE 131072
	error = -ENOMEM;
	server->packet_size = NCP_PACKET_SIZE;
	server->packet = vmalloc(NCP_PACKET_SIZE);
	if (server->packet == NULL)
		goto out_nls;
	server->txbuf = vmalloc(NCP_PACKET_SIZE);
	if (server->txbuf == NULL)
		goto out_packet;
	server->rxbuf = vmalloc(NCP_PACKET_SIZE);
	if (server->rxbuf == NULL)
		goto out_txbuf;

	sock->sk->sk_data_ready	  = ncp_tcp_data_ready;
	sock->sk->sk_error_report = ncp_tcp_error_report;
	if (sock->type == SOCK_STREAM) {
		server->rcv.ptr = (unsigned char*)&server->rcv.buf;
		server->rcv.len = 10;
		server->rcv.state = 0;
		INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
		INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
		sock->sk->sk_write_space = ncp_tcp_write_space;
	} else {
		INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
		INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
		server->timeout_tm.data = (unsigned long)server;
		server->timeout_tm.function = ncpdgram_timeout_call;
	}

	ncp_lock_server(server);
	error = ncp_connect(server);
	ncp_unlock_server(server);
	if (error < 0)
		goto out_rxbuf;
	DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));

	error = -EMSGSIZE;	/* -EREMOTESIDEINCOMPATIBLE */
#ifdef CONFIG_NCPFS_PACKET_SIGNING
	if (ncp_negotiate_size_and_options(server, default_bufsize,
		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
	{
		if (options != NCP_DEFAULT_OPTIONS)
		{
			if (ncp_negotiate_size_and_options(server, 
				default_bufsize,
				options & 2, 
				&(server->buffer_size), &options) != 0)
				
			{
				goto out_disconnect;
			}
		}
		if (options & 2)
			server->sign_wanted = 1;
	}
	else 
#endif	/* CONFIG_NCPFS_PACKET_SIGNING */
	if (ncp_negotiate_buffersize(server, default_bufsize,
  				     &(server->buffer_size)) != 0)
		goto out_disconnect;
	DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);

	memset(&finfo, 0, sizeof(finfo));
	finfo.i.attributes	= aDIR;
	finfo.i.dataStreamSize	= 0;	/* ignored */
	finfo.i.dirEntNum	= 0;
	finfo.i.DosDirNum	= 0;
#ifdef CONFIG_NCPFS_SMALLDOS
	finfo.i.NSCreator	= NW_NS_DOS;
#endif
	finfo.volume		= NCP_NUMBER_OF_VOLUMES;
	/* set dates of mountpoint to Jan 1, 1986; 00:00 */
	finfo.i.creationTime	= finfo.i.modifyTime
				= cpu_to_le16(0x0000);
	finfo.i.creationDate	= finfo.i.modifyDate
				= finfo.i.lastAccessDate
				= cpu_to_le16(0x0C21);
	finfo.i.nameLen		= 0;
	finfo.i.entryName[0]	= '\0';

	finfo.opened		= 0;
	finfo.ino		= 2;	/* tradition */

	server->name_space[finfo.volume] = NW_NS_DOS;

	error = -ENOMEM;
        root_inode = ncp_iget(sb, &finfo);
        if (!root_inode)
		goto out_disconnect;
	DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
	sb->s_root = d_alloc_root(root_inode);
        if (!sb->s_root)
		goto out_no_root;
	sb->s_root->d_op = &ncp_root_dentry_operations;
	return 0;

out_no_root:
	iput(root_inode);
out_disconnect:
	ncp_lock_server(server);
	ncp_disconnect(server);
	ncp_unlock_server(server);
out_rxbuf:
	ncp_stop_tasks(server);
	vfree(server->rxbuf);
out_txbuf:
	vfree(server->txbuf);
out_packet:
	vfree(server->packet);
out_nls:
#ifdef CONFIG_NCPFS_NLS
	unload_nls(server->nls_io);
	unload_nls(server->nls_vol);
#endif
out_fput2:
	if (server->info_filp)
		fput(server->info_filp);
out_fput:
	/* 23/12/1998 Marcin Dalecki <*****@*****.**>:
	 * 
	 * The previously used put_filp(ncp_filp); was bogous, since
	 * it doesn't proper unlocking.
	 */
	fput(ncp_filp);
out:
	put_pid(data.wdog_pid);
	sb->s_fs_info = NULL;
	kfree(server);
	return error;
}
示例#9
0
static void __exit exit_nls_koi8_ru(void)
{
	unregister_nls(&table);
	unload_nls(p_nls);
}
示例#10
0
static APIRET attachVolume(ServerData * pServerData,
   struct attach * pattach)
{
   VolData * pVolData;
   IFS_ATTACH * parms = (IFS_ATTACH *) pServerData->pData;
   int rc;
   struct iso_primary_descriptor jpd;
   struct hs_primary_descriptor *hpd;
   struct iso_directory_record *idr = 0;
   /* For codepage */
   ULONG ulCp[4];
   ULONG ulInfoLen=0;
   char *ptr;

   pattach->pVolData = 0;
   if ((pattach->cbParm != sizeof(IFS_ATTACH)) ||
       VERIFYFIXED(parms->szBasePath)
       )
     return ERROR_INVALID_PARAMETER;

   for (ptr = parms->szBasePath; *ptr; ptr++)
        if (*ptr == '/')
           *ptr = '\\';
   
   logMsg(L_DBG, "attaching drive, isopath=%s, offset: %d, charset: %s",
          parms->szBasePath, parms->iOffset, parms->szCharSet);
   
   if ((strncmp(parms->szBasePath, "\\\\", 2) != 0) && /* UNC */
       (strncmp(parms->szBasePath, "////", 2) != 0) && /* UNC */
       ((strlen(parms->szBasePath) < 3) ||
        (!isalpha((unsigned char) parms->szBasePath[0])) ||
        (parms->szBasePath[1] != ':') ||
        ((parms->szBasePath[2] != '\\') &&
         (parms->szBasePath[2] != '/'))))
     return ERROR_INVALID_PARAMETER;
   
   /* Max sector not tested, yet */
   if(parms->iOffset<0)
     return ERROR_ISOFS_INVALIDOFFSET;
   
   /* Allocate a VolData structure. */
   pVolData = malloc(sizeof(VolData));
   if (!pVolData) {
      logMsg(L_EVIL, "out of memory");
      return ERROR_NOT_ENOUGH_MEMORY;
   }
   memset(pVolData,0,sizeof(VolData));
   pVolData->pServerData = pServerData;
   pVolData->chDrive = toupper(pattach->szDev[0]);
   pVolData->cOpenFiles = 0;
   pVolData->cSearches = 0;
   strncpy(pVolData->fileName,parms->szBasePath,sizeof(pVolData->fileName));
   pVolData->iSectorOffset=parms->iOffset;
   strncpy(pVolData->szCharSet,parms->szCharSet,sizeof(pVolData->szCharSet));

   /* Load translation table */
   if(strlen(pVolData->szCharSet)) {
     pVolData->nls = load_nls(pVolData->szCharSet);
     if(!pVolData->nls)
       logMsg(L_EVIL, "Can't load table for charset %s",pVolData->szCharSet);
   }
   else {
     /* Use default system codepage */
     if(DosQueryCp(sizeof(ulCp),ulCp,&ulInfoLen)==NO_ERROR) {
       /* Check if mkisofs supports our CP */
       if(checkCpSupport((int)ulCp[0])) {
         sprintf(pVolData->szCharSet,"cp%d",(int)ulCp[0]);
         pVolData->nls = load_nls(pVolData->szCharSet);
         if(!pVolData->nls)
           logMsg(L_EVIL, "Can't load table for system codepage %s",pVolData->szCharSet);
       }
     }
   }

   /* ISO file */
   pVolData->isoFile=sysOpenFile(pVolData->fileName, 
        SOF_FAIL_IF_NEW | SOF_OPEN_IF_EXISTS | SOF_DENYWRITE | SOF_READONLY,
        0);
   if(!pVolData->isoFile) {
     logMsg(L_EVIL, "Can't open ISO file");
     /* Unload translation table */
     if(pVolData->nls)
       unload_nls(pVolData->nls);
     free(pVolData);
     return ERROR_ISOFS_FILEOPEN;
   }

   /* Get info from ISO file */
   lseek(pVolData->isoFile->h, ((off_t)(16 + pVolData->iSectorOffset)) <<11, 0);
   rc=read(pVolData->isoFile->h, &pVolData->ipd, sizeof(pVolData->ipd));
   logMsg(L_DBG, "ISO primary descriptor read from ISO file (%d Bytes)",rc);

   /****************************************/
   hpd = (struct hs_primary_descriptor *) &pVolData->ipd;
   if ((hpd->type[0] == ISO_VD_PRIMARY) &&
       (strncmp(hpd->id, HIGH_SIERRA_ID, sizeof(hpd->id)) == 0) &&
       (hpd->version[0] == 1)) {
           pVolData->high_sierra = 1;
           idr = (struct iso_directory_record *) hpd->root_directory_record;
           memcpy(&pVolData->chrCDName,&hpd->volume_id,32);
   }
   else
	if ((pVolData->ipd.type[0] != ISO_VD_PRIMARY) ||
	    (strncmp(pVolData->ipd.id, ISO_STANDARD_ID, sizeof(pVolData->ipd.id)) != 0) ||
	    (pVolData->ipd.version[0] != 1)) {
                logMsg(L_EVIL, "Unable to find PVD");
                /* Unload translation table */
                if(pVolData->nls)
                    unload_nls(pVolData->nls);
                sysCloseFile(pVolData->isoFile);
                free(pVolData);
                return ERROR_ISOFS_NOTISO;
	}

    if (!pVolData->high_sierra)
    {
       int block = 16;
       memcpy(&pVolData->chrCDName,&pVolData->ipd.volume_id,32);
       memcpy(&jpd, &pVolData->ipd, sizeof(pVolData->ipd));
       while (((unsigned char) jpd.type[0] != ISO_VD_END) &&
	    (strncmp(jpd.id, ISO_STANDARD_ID, sizeof(jpd.id)) == 0) &&
	    (jpd.version[0] == 1))
         {
           if( (unsigned char) jpd.type[0] == ISO_VD_SUPPLEMENTARY )
             /*
              * Find the UCS escape sequence.
              */
             if(    jpd.escape_sequences[0] == '%'
                    && jpd.escape_sequences[1] == '/'
                    && (jpd.escape_sequences[3] == '\0'
                        || jpd.escape_sequences[3] == ' ')
                    && (jpd.escape_sequences[2] == '@'
                        || jpd.escape_sequences[2] == 'C'
                        || jpd.escape_sequences[2] == 'E') )
               {
		 pVolData->got_joliet = 1;
                 break;
               }
           
           block++;
           lseek(pVolData->isoFile->h, ((off_t)(block + pVolData->iSectorOffset)) <<11, 0);
           read(pVolData->isoFile->h, &jpd, sizeof(jpd));
         }
       
       if(pVolData->got_joliet)
         switch(jpd.escape_sequences[2])
         {
         case '@':
           pVolData->ucs_level = 1;
           break;
         case 'C':
           pVolData->ucs_level = 2;
           break;
         case 'E':
           pVolData->ucs_level = 3;
           break;
         }
       
	if (pVolData->got_joliet)
            memcpy(&pVolData->ipd, &jpd, sizeof(pVolData->ipd));

        idr = (struct iso_directory_record *) pVolData->ipd.root_directory_record;
     }
   
   /****************************************/
   
   /* Fill in extent of root */
   pVolData->root_directory_record = idr;
   pVolData->idRoot = isonum_733((unsigned char *)idr->extent);/* 733 */
   pVolData->iRootExtent = pVolData->idRoot;
   pVolData->iRootSize=isonum_733((unsigned char *)idr->size);
   
   logMsg(L_DBG, "Extent of root is: %d ",pVolData->idRoot);
   
   pattach->pVolData = pVolData;
   
   pVolData->pNext = pServerData->pFirstVolume;
   pVolData->pPrev = 0;
   if (pVolData->pNext) pVolData->pNext->pPrev = pVolData;
   pServerData->pFirstVolume = pVolData;
   
   return NO_ERROR;
}
示例#11
0
/* allocate global info, try to map host share */
static int sf_glob_alloc(struct vbsf_mount_info_new *info, struct sf_glob_info **sf_gp)
{
    int err, rc;
    SHFLSTRING *str_name;
    size_t name_len, str_len;
    struct sf_glob_info *sf_g;

    TRACE();
    sf_g = kmalloc(sizeof(*sf_g), GFP_KERNEL);
    if (!sf_g)
    {
        err = -ENOMEM;
        LogRelFunc(("could not allocate memory for global info\n"));
        goto fail0;
    }

    RT_ZERO(*sf_g);

    if (   info->nullchar     != '\0'
        || info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0
        || info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1
        || info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2)
    {
        /* An old version of mount.vboxsf made the syscall. Translate the
         * old parameters to the new structure. */
        struct vbsf_mount_info_old *info_old = (struct vbsf_mount_info_old *)info;
        static struct vbsf_mount_info_new info_compat;

        info = &info_compat;
        memset(info, 0, sizeof(*info));
        memcpy(&info->name, &info_old->name, MAX_HOST_NAME);
        memcpy(&info->nls_name, &info_old->nls_name, MAX_NLS_NAME);
        info->length = offsetof(struct vbsf_mount_info_new, dmode);
        info->uid    = info_old->uid;
        info->gid    = info_old->gid;
        info->ttl    = info_old->ttl;
    }

    info->name[sizeof(info->name) - 1] = 0;
    info->nls_name[sizeof(info->nls_name) - 1] = 0;

    name_len = strlen(info->name);
    if (name_len > 0xfffe)
    {
        err = -ENAMETOOLONG;
        LogFunc(("map name too big\n"));
        goto fail1;
    }

    str_len = offsetof(SHFLSTRING, String.utf8) + name_len + 1;
    str_name = kmalloc(str_len, GFP_KERNEL);
    if (!str_name)
    {
        err = -ENOMEM;
        LogRelFunc(("could not allocate memory for host name\n"));
        goto fail1;
    }

    str_name->u16Length = name_len;
    str_name->u16Size = name_len + 1;
    memcpy(str_name->String.utf8, info->name, name_len + 1);

#define _IS_UTF8(_str) \
    (strcmp(_str, "utf8") == 0)
#define _IS_EMPTY(_str) \
    (strcmp(_str, "") == 0)

    /* Check if NLS charset is valid and not points to UTF8 table */
    if (info->nls_name[0])
    {
        if (_IS_UTF8(info->nls_name))
            sf_g->nls = NULL;
        else
        {
            sf_g->nls = load_nls(info->nls_name);
            if (!sf_g->nls)
            {
                err = -EINVAL;
                LogFunc(("failed to load nls %s\n", info->nls_name));
                goto fail1;
            }
        }
    }
    else
    {
#ifdef CONFIG_NLS_DEFAULT
        /* If no NLS charset specified, try to load the default
         * one if it's not points to UTF8. */
        if (!_IS_UTF8(CONFIG_NLS_DEFAULT) && !_IS_EMPTY(CONFIG_NLS_DEFAULT))
            sf_g->nls = load_nls_default();
        else
            sf_g->nls = NULL;
#else
        sf_g->nls = NULL;
#endif

#undef _IS_UTF8
#undef _IS_EMPTY
    }

    rc = VbglR0SfMapFolder(&client_handle, str_name, &sf_g->map);
    kfree(str_name);

    if (RT_FAILURE(rc))
    {
        err = -EPROTO;
        LogFunc(("VbglR0SfMapFolder failed rc=%d\n", rc));
        goto fail2;
    }

    sf_g->ttl = info->ttl;
    sf_g->uid = info->uid;
    sf_g->gid = info->gid;

    if ((unsigned)info->length >= sizeof(struct vbsf_mount_info_new))
    {
        /* new fields */
        sf_g->dmode = info->dmode;
        sf_g->fmode = info->fmode;
        sf_g->dmask = info->dmask;
        sf_g->fmask = info->fmask;
    }
    else
    {
        sf_g->dmode = ~0;
        sf_g->fmode = ~0;
    }

    *sf_gp = sf_g;
    return 0;

fail2:
    if (sf_g->nls)
        unload_nls(sf_g->nls);

fail1:
    kfree(sf_g);

fail0:
    return err;
}