static void cifs_show_nls(struct seq_file *s, struct nls_table *cur) { struct nls_table *def; /* Display iocharset= option if it's not default charset */ def = load_nls_default(); if (def != cur) seq_printf(s, ",iocharset=%s", cur->charset); unload_nls(def); }
static int samplefs_fill_super(struct super_block * sb, void * data, int silent) { struct inode * inode; struct samplefs_sb_info * sfs_sb; sb->s_maxbytes = MAX_LFS_FILESIZE; /* NB: may be too large for mem */ sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = SAMPLEFS_MAGIC; sb->s_op = &samplefs_super_ops; sb->s_time_gran = 1; /* 1 nanosecond time granularity */ printk(KERN_INFO "samplefs: fill super\n"); inode = samplefs_get_inode(sb, S_IFDIR | 0755, 0); /* inode = iget(sb, SAMPLEFS_ROOT_I); was oopsing here */ if (!inode) return -ENOMEM; #ifdef CONFIG_SAMPLEFS_DEBUG printk(KERN_INFO "samplefs: about to alloc s_fs_info\n"); #endif sb->s_fs_info = kzalloc(sizeof(struct samplefs_sb_info), GFP_KERNEL); sfs_sb = SFS_SB(sb); if (!sfs_sb) { iput(inode); return -ENOMEM; } printk(KERN_INFO "samplefs: about to alloc root inode\n"); sb->s_root = d_make_root(inode); if (!sb->s_root) { iput(inode); kfree(sfs_sb); return -ENOMEM; } /* below not needed for many fs - but an example of per fs sb data */ sfs_sb->local_nls = load_nls_default(); samplefs_parse_mount_options(data, sfs_sb); /* FS-FILLIN your filesystem specific mount logic/checks here */ return 0; }
static int samplefs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; struct samplefs_sb_info *sfs_sb; sb->s_maxbytes = MAX_LFS_FILESIZE; /* NB: may be too large for mem */ sb->s_blocksize = PAGE_SIZE; sb->s_blocksize_bits = PAGE_SHIFT; sb->s_magic = SAMPLEFS_MAGIC; sb->s_op = &samplefs_super_ops; sb->s_time_gran = 1; /* 1 nanosecond time granularity */ /* Eventually replace iget with: inode = samplefs_get_inode(sb, S_IFDIR | 0755, 0); */ inode = iget_locked(sb, SAMPLEFS_ROOT_I); if (!inode) return -ENOMEM; unlock_new_inode(inode); sb->s_fs_info = kzalloc(sizeof(struct samplefs_sb_info), GFP_KERNEL); sfs_sb = SFS_SB(sb); if (!sfs_sb) { iput(inode); return -ENOMEM; } sb->s_root = d_make_root(inode); if (!sb->s_root) { iput(inode); kfree(sfs_sb); return -ENOMEM; } /* below not needed for many fs - but an example of per fs sb data */ sfs_sb->local_nls = load_nls_default(); samplefs_parse_mount_options(data, sfs_sb); /* FS-FILLIN your filesystem specific mount logic/checks here */ return 0; }
static void test_nls_base(void) { wchar_t p=0x20; __u8 s=0x01; int n=2; struct nls_table nls; char charset[20]="David"; load_nls_default(); register_nls(&nls); unload_nls(&nls); load_nls(charset); unregister_nls(&nls); utf8_mbtowc(&p, &s, n); utf8_mbstowcs(&p, &s, n); n=20; utf8_wctomb(&s, p, n); utf8_wcstombs(&s, &p, n); }
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; }
/* 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; }
/* Allocate private field of the superblock, fill it. * * Finish filling the public superblock fields * Make the root directory * Load a set of NLS translations if needed. */ static int befs_fill_super(struct super_block *sb, void *data, int silent) { struct buffer_head *bh; befs_sb_info *befs_sb; befs_super_block *disk_sb; struct inode *root; long ret = -EINVAL; const unsigned long sb_block = 0; const off_t x86_sb_off = 512; save_mount_options(sb, data); sb->s_fs_info = kmalloc(sizeof (*befs_sb), GFP_KERNEL); if (sb->s_fs_info == NULL) { printk(KERN_ERR "BeFS(%s): Unable to allocate memory for private " "portion of superblock. Bailing.\n", sb->s_id); goto unacquire_none; } befs_sb = BEFS_SB(sb); memset(befs_sb, 0, sizeof(befs_sb_info)); if (!parse_options((char *) data, &befs_sb->mount_opts)) { befs_error(sb, "cannot parse mount options"); goto unacquire_priv_sbp; } befs_debug(sb, "---> befs_fill_super()"); #ifndef CONFIG_BEFS_RW if (!(sb->s_flags & MS_RDONLY)) { befs_warning(sb, "No write support. Marking filesystem read-only"); sb->s_flags |= MS_RDONLY; } #endif /* CONFIG_BEFS_RW */ /* * Set dummy blocksize to read super block. * Will be set to real fs blocksize later. * * Linux 2.4.10 and later refuse to read blocks smaller than * the hardsect size for the device. But we also need to read at * least 1k to get the second 512 bytes of the volume. * -WD 10-26-01 */ sb_min_blocksize(sb, 1024); if (!(bh = sb_bread(sb, sb_block))) { befs_error(sb, "unable to read superblock"); goto unacquire_priv_sbp; } /* account for offset of super block on x86 */ disk_sb = (befs_super_block *) bh->b_data; if ((disk_sb->magic1 == BEFS_SUPER_MAGIC1_LE) || (disk_sb->magic1 == BEFS_SUPER_MAGIC1_BE)) { befs_debug(sb, "Using PPC superblock location"); } else { befs_debug(sb, "Using x86 superblock location"); disk_sb = (befs_super_block *) ((void *) bh->b_data + x86_sb_off); } if (befs_load_sb(sb, disk_sb) != BEFS_OK) goto unacquire_bh; befs_dump_super_block(sb, disk_sb); brelse(bh); if (befs_check_sb(sb) != BEFS_OK) goto unacquire_priv_sbp; if( befs_sb->num_blocks > ~((sector_t)0) ) { befs_error(sb, "blocks count: %Lu " "is larger than the host can use", befs_sb->num_blocks); goto unacquire_priv_sbp; } /* * set up enough so that it can read an inode * Fill in kernel superblock fields from private sb */ sb->s_magic = BEFS_SUPER_MAGIC; /* Set real blocksize of fs */ sb_set_blocksize(sb, (ulong) befs_sb->block_size); sb->s_op = &befs_sops; root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); if (IS_ERR(root)) { ret = PTR_ERR(root); goto unacquire_priv_sbp; } sb->s_root = d_make_root(root); if (!sb->s_root) { befs_error(sb, "get root inode failed"); goto unacquire_priv_sbp; } /* load nls library */ if (befs_sb->mount_opts.iocharset) { befs_debug(sb, "Loading nls: %s", befs_sb->mount_opts.iocharset); befs_sb->nls = load_nls(befs_sb->mount_opts.iocharset); if (!befs_sb->nls) { befs_warning(sb, "Cannot load nls %s" " loading default nls", befs_sb->mount_opts.iocharset); befs_sb->nls = load_nls_default(); } /* load default nls if none is specified in mount options */ } else { befs_debug(sb, "Loading default nls"); befs_sb->nls = load_nls_default(); } return 0; /*****************/ unacquire_bh: brelse(bh); unacquire_priv_sbp: kfree(befs_sb->mount_opts.iocharset); kfree(sb->s_fs_info); unacquire_none: sb->s_fs_info = NULL; return ret; }
/* * parse_options() * * adapted from linux/fs/msdos/inode.c written 1992,93 by Werner Almesberger * This function is called by hfs_read_super() to parse the mount options. */ static int parse_options(char *options, struct hfs_sb_info *hsb) { char *p; substring_t args[MAX_OPT_ARGS]; int tmp, token; /* initialize the sb with defaults */ hsb->s_uid = current_uid(); hsb->s_gid = current_gid(); hsb->s_file_umask = 0133; hsb->s_dir_umask = 0022; hsb->s_type = hsb->s_creator = cpu_to_be32(0x3f3f3f3f); /* == '????' */ hsb->s_quiet = 0; hsb->part = -1; hsb->session = -1; if (!options) return 1; while ((p = strsep(&options, ",")) != NULL) { if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case opt_uid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: uid requires an argument\n"); return 0; } hsb->s_uid = (uid_t)tmp; break; case opt_gid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: gid requires an argument\n"); return 0; } hsb->s_gid = (gid_t)tmp; break; case opt_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: umask requires a value\n"); return 0; } hsb->s_file_umask = (umode_t)tmp; hsb->s_dir_umask = (umode_t)tmp; break; case opt_file_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: file_umask requires a value\n"); return 0; } hsb->s_file_umask = (umode_t)tmp; break; case opt_dir_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: dir_umask requires a value\n"); return 0; } hsb->s_dir_umask = (umode_t)tmp; break; case opt_part: if (match_int(&args[0], &hsb->part)) { printk(KERN_ERR "hfs: part requires an argument\n"); return 0; } break; case opt_session: if (match_int(&args[0], &hsb->session)) { printk(KERN_ERR "hfs: session requires an argument\n"); return 0; } break; case opt_type: if (match_fourchar(&args[0], &hsb->s_type)) { printk(KERN_ERR "hfs: type requires a 4 character value\n"); return 0; } break; case opt_creator: if (match_fourchar(&args[0], &hsb->s_creator)) { printk(KERN_ERR "hfs: creator requires a 4 character value\n"); return 0; } break; case opt_quiet: hsb->s_quiet = 1; break; case opt_codepage: if (hsb->nls_disk) { printk(KERN_ERR "hfs: unable to change codepage\n"); return 0; } p = match_strdup(&args[0]); if (p) hsb->nls_disk = load_nls(p); if (!hsb->nls_disk) { printk(KERN_ERR "hfs: unable to load codepage \"%s\"\n", p); kfree(p); return 0; } kfree(p); break; case opt_iocharset: if (hsb->nls_io) { printk(KERN_ERR "hfs: unable to change iocharset\n"); return 0; } p = match_strdup(&args[0]); if (p) hsb->nls_io = load_nls(p); if (!hsb->nls_io) { printk(KERN_ERR "hfs: unable to load iocharset \"%s\"\n", p); kfree(p); return 0; } kfree(p); break; default: return 0; } } if (hsb->nls_disk && !hsb->nls_io) { hsb->nls_io = load_nls_default(); if (!hsb->nls_io) { printk(KERN_ERR "hfs: unable to load default iocharset\n"); return 0; } } hsb->s_dir_umask &= 0777; hsb->s_file_umask &= 0577; return 1; }
/* input is the options passed to mount() as a string */ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) { char *p; substring_t args[MAX_OPT_ARGS]; int tmp, token; if (!input) goto done; while ((p = strsep(&input, ",")) != NULL) { if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case opt_creator: if (match_fourchar(&args[0], &sbi->creator)) { printk(KERN_ERR "hfs: creator requires a 4 character value\n"); return 0; } break; case opt_type: if (match_fourchar(&args[0], &sbi->type)) { printk(KERN_ERR "hfs: type requires a 4 character value\n"); return 0; } break; case opt_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: umask requires a value\n"); return 0; } sbi->umask = (umode_t)tmp; break; case opt_uid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: uid requires an argument\n"); return 0; } sbi->uid = (uid_t)tmp; break; case opt_gid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: gid requires an argument\n"); return 0; } sbi->gid = (gid_t)tmp; break; case opt_part: if (match_int(&args[0], &sbi->part)) { printk(KERN_ERR "hfs: part requires an argument\n"); return 0; } break; case opt_session: if (match_int(&args[0], &sbi->session)) { printk(KERN_ERR "hfs: session requires an argument\n"); return 0; } break; case opt_nls: if (sbi->nls) { printk(KERN_ERR "hfs: unable to change nls mapping\n"); return 0; } p = match_strdup(&args[0]); if (p) sbi->nls = load_nls(p); if (!sbi->nls) { printk(KERN_ERR "hfs: unable to load " "nls mapping \"%s\"\n", p); kfree(p); return 0; } kfree(p); break; case opt_decompose: clear_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags); break; case opt_nodecompose: set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags); break; case opt_barrier: clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags); break; case opt_nobarrier: set_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags); break; case opt_force: set_bit(HFSPLUS_SB_FORCE, &sbi->flags); break; default: return 0; } } done: if (!sbi->nls) { /* try utf8 first, as this is the old default behaviour */ sbi->nls = load_nls("utf8"); if (!sbi->nls) sbi->nls = load_nls_default(); if (!sbi->nls) return 0; } return 1; }
/* Parse the (re)mount options */ static int parse_options(ntfs_volume* vol,char *opt) { char *value; vol->uid=vol->gid=0; vol->umask=0077; vol->ngt=ngt_nt; vol->nls_map=0; vol->nct=0; 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; vol->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; vol->gid=simple_strtoul(value,&value,0); if(*value){ printk(KERN_ERR "gid invalid argument\n"); return 0; } }else if(strcmp(opt, "umask") == 0) { if(!value || !*value)goto needs_arg; vol->umask=simple_strtoul(value,&value,0); if(*value){ printk(KERN_ERR "umask invalid argument\n"); return 0; } }else if(strcmp(opt, "iocharset") == 0){ if(!value || !*value)goto needs_arg; vol->nls_map=load_nls(value); vol->nct |= nct_map; if(!vol->nls_map){ printk(KERN_ERR "NTFS: charset not found"); return 0; } }else if(strcmp(opt, "posix") == 0){ int val; if(!value || !*value)goto needs_arg; if(!simple_getbool(value,&val)) goto needs_bool; vol->ngt=val?ngt_posix:ngt_nt; }else if(strcmp(opt,"utf8") == 0){ int val=0; if(!value || !*value) val=1; else if(!simple_getbool(value,&val)) goto needs_bool; if(val) vol->nct|=nct_utf8; }else if(strcmp(opt,"uni_xlate") == 0){ int val=0; /* no argument: uni_vfat. boolean argument: uni_vfat. "2": uni. */ if(!value || !*value) val=1; else if(strcmp(value,"2")==0) vol->nct |= nct_uni_xlate; else if(!simple_getbool(value,&val)) goto needs_bool; if(val) vol->nct |= nct_uni_xlate_vfat | nct_uni_xlate; }else{ printk(KERN_ERR "NTFS: unkown option '%s'\n", opt); return 0; } } if(vol->nct & nct_utf8 & (nct_map | nct_uni_xlate)){ printk(KERN_ERR "utf8 cannot be combined with iocharset or uni_xlate\n"); return 0; } done: if((vol->nct & (nct_uni_xlate | nct_map | nct_utf8))==0) /* default to UTF-8 */ vol->nct=nct_utf8; if(!vol->nls_map){ vol->nls_map=load_nls_default(); if (vol->nls_map) vol->nct=nct_map | (vol->nct&nct_uni_xlate); } 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; }
/* 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 = 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; }