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; }
static void __exit exit_nls_euc_kr(void) { unregister_nls(&table); unload_nls(p_nls); }
/* 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; }
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; }
static void smb_unload_nls(struct smb_sb_info *server) { unload_nls(server->remote_nls); unload_nls(server->local_nls); }
/* 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; }
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; }
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; }
static void __exit exit_nls_koi8_ru(void) { unregister_nls(&table); unload_nls(p_nls); }
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; }
/* 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; }