VirtualBox

Changeset 87461 in vbox for trunk/src/VBox/Additions/linux


Ignore:
Timestamp:
Jan 28, 2021 2:44:55 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142480
Message:

linux/vboxsf: Add support for parsing string-based mount options for Linux kernel versions < 2.6.0. bugref:9816

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c

    r87095 r87461  
    222222    *sf_gp = NULL; /* (old gcc maybe used initialized) */
    223223
    224 #if RTLNX_VER_MAX(2,6,0)
    225     /*
    226      * Validate info.
    227      */
    228     if (!VBSF_IS_MOUNT_VBOXSF_DATA(info)) {
    229         SFLOGRELBOTH(("vboxsf: Invalid info signature: %#x %#x %#x %#x!\n",
    230                       info->nullchar, info->signature[0], info->signature[1], info->signature[2]));
    231         return -EINVAL;
    232     }
    233 #endif
    234224    name_len = RTStrNLen(info->name, sizeof(info->name));
    235225    if (name_len >= sizeof(info->name)) {
     
    549539
    550540
    551 #if RTLNX_VER_RANGE(2,6,0,  5,1,0)
    552 /**
    553  * The following section of code uses the Linux match_token() function to
    554  * parse string-based mount options.
    555  */
     541#if RTLNX_VER_MAX(5,1,0)
    556542static void vbsf_init_mount_info(struct vbsf_mount_info_new *mount_info,
    557543    const char *sf_name)
     
    561547    mount_info->enmCacheMode = kVbsfCacheMode_Strict;
    562548    mount_info->length = sizeof(struct vbsf_mount_info_new);
    563     if (sf_name)
     549    if (sf_name) {
     550# if RTLNX_VER_MAX(2,5,69)
     551        strncpy(mount_info->name, sf_name, sizeof(mount_info->name));
     552        mount_info->name[sizeof(mount_info->name)-1] = 0;
     553# else
    564554        strlcpy(mount_info->name, sf_name, sizeof(mount_info->name));
    565 }
    566 
     555# endif
     556    }
     557}
     558#endif
     559
     560#if RTLNX_VER_RANGE(2,6,0,  5,1,0)
     561/**
     562 * The following section of code uses the Linux match_token() family of
     563 * routines to parse string-based mount options.
     564 */
    567565enum {
    568566    Opt_iocharset,  /* nls_name[] */
     
    739737
    740738
     739#if RTLNX_VER_MAX(2,6,0)
     740/**
     741 * Linux kernel versions older than 2.6.0 don't have the match_token() routines
     742 * so we parse the string-based mount options manually here.
     743 */
     744static int vbsf_parse_mount_options(char *options,
     745    struct vbsf_mount_info_new *mount_info)
     746{
     747    char *value;
     748    char *option;
     749
     750    if (!options)
     751        return -EINVAL;
     752
     753# if RTLNX_VER_MIN(2,3,9)
     754    while ((option = strsep(&options, ",")) != NULL) {
     755# else
     756    for (option = strtok(options, ","); option; option = strtok(NULL, ",")) {
     757# endif
     758        if (!*option)
     759            continue;
     760
     761        value = strchr(option, '=');
     762        if (value)
     763            *value++ = '\0';
     764
     765        if (!strcmp(option, "iocharset") || !strcmp(option, "nls")) {
     766            if (!value || !*value)
     767                return -EINVAL;
     768            strncpy(mount_info->nls_name, value, sizeof(mount_info->nls_name));
     769            mount_info->nls_name[sizeof(mount_info->nls_name)-1] = 0;
     770        } else if (!strcmp(option, "uid")) {
     771            mount_info->uid = simple_strtoul(value, &value, 0);
     772            if (*value)
     773                return -EINVAL;
     774        } else if (!strcmp(option, "gid")) {
     775            mount_info->gid = simple_strtoul(value, &value, 0);
     776            if (*value)
     777                return -EINVAL;
     778        } else if (!strcmp(option, "ttl")) {
     779            mount_info->ttl = simple_strtoul(value, &value, 0);
     780            if (*value)
     781                return -EINVAL;
     782        } else if (!strcmp(option, "dmode")) {
     783            mount_info->dmode = simple_strtoul(value, &value, 8);
     784            if (*value)
     785                return -EINVAL;
     786        } else if (!strcmp(option, "fmode")) {
     787            mount_info->fmode = simple_strtoul(value, &value, 8);
     788            if (*value)
     789                return -EINVAL;
     790        } else if (!strcmp(option, "dmask")) {
     791            mount_info->dmask = simple_strtoul(value, &value, 8);
     792            if (*value)
     793                return -EINVAL;
     794        } else if (!strcmp(option, "fmask")) {
     795            mount_info->fmask = simple_strtoul(value, &value, 8);
     796            if (*value)
     797                return -EINVAL;
     798        } else if (!strcmp(option, "umask")) {
     799            mount_info->dmask = mount_info->fmask = simple_strtoul(value,
     800                &value, 8);
     801            if (*value)
     802                return -EINVAL;
     803        } else if (!strcmp(option, "maxiopages")) {
     804            mount_info->cMaxIoPages = simple_strtoul(value, &value, 0);
     805            if (*value)
     806                return -EINVAL;
     807        } else if (!strcmp(option, "dirbuf")) {
     808            mount_info->cbDirBuf = simple_strtoul(value, &value, 0);
     809            if (*value)
     810                return -EINVAL;
     811        } else if (!strcmp(option, "dcachettl")) {
     812            mount_info->msDirCacheTTL = simple_strtoul(value, &value, 0);
     813            if (*value)
     814                return -EINVAL;
     815        } else if (!strcmp(option, "inodettl")) {
     816            mount_info->msInodeTTL = simple_strtoul(value, &value, 0);
     817            if (*value)
     818                return -EINVAL;
     819        } else if (!strcmp(option, "cache")) {
     820            if (!value || !*value)
     821                return -EINVAL;
     822            if (!strcmp(value, "default") || !strcmp(value, "strict"))
     823                mount_info->enmCacheMode = kVbsfCacheMode_Strict;
     824            else if (!strcmp(value, "none"))
     825                mount_info->enmCacheMode = kVbsfCacheMode_None;
     826            else if (!strcmp(value, "read"))
     827                mount_info->enmCacheMode = kVbsfCacheMode_Read;
     828            else if (!strcmp(value, "readwrite"))
     829                mount_info->enmCacheMode = kVbsfCacheMode_ReadWrite;
     830            else
     831                printk(KERN_WARNING "vboxsf: cache mode (%s) is out of range, using default instead.\n", value);
     832        } else if (!strcmp(option, "tag")) {
     833            if (!value || !*value)
     834                return -EINVAL;
     835            strncpy(mount_info->szTag, value, sizeof(mount_info->szTag));
     836            mount_info->szTag[sizeof(mount_info->szTag)-1] = 0;
     837        } else if (!strcmp(option, "sf_name")) {
     838            if (!value || !*value)
     839                return -EINVAL;
     840            strncpy(mount_info->name, value, sizeof(mount_info->name));
     841            mount_info->name[sizeof(mount_info->name)-1] = 0;
     842        } else {
     843            printk(KERN_ERR "unrecognised mount option \"%s\"", option);
     844            return -EINVAL;
     845        }
     846    }
     847
     848    return 0;
     849}
     850#endif
     851
     852
    741853/**
    742854 * This is called by vbsf_read_super_24(), vbsf_read_super_26(), and
     
    9671079# if RTLNX_VER_MIN(5,1,0)
    9681080    vbsf_super_info_copy_remount_options(pSuperInfo, info);
    969 # elif RTLNX_VER_MIN(2,6,0)
     1081# else
    9701082    if (VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
    9711083        vbsf_super_info_copy_remount_options(pSuperInfo, (struct vbsf_mount_info_new *)data);
     
    9781090        vbsf_super_info_copy_remount_options(pSuperInfo, &mount_opts);
    9791091    }
    980 # else /* < 2.6.0 */
    981     if (VBSF_IS_MOUNT_VBOXSF_DATA(data))
    982         vbsf_super_info_copy_remount_options(pSuperInfo, (struct vbsf_mount_info_new *)data);
    9831092# endif
    9841093
     
    11421251{
    11431252    TRACE();
    1144 #  if RTLNX_VER_MIN(2,6,0)
     1253
    11451254    if (!VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
    11461255        int rc;
     
    11521261            return ERR_PTR(rc);
    11531262        return get_sb_nodev(fs_type, flags, &mount_opts, vbsf_read_super_26);
    1154     }
    1155 #  endif
    1156     return get_sb_nodev(fs_type, flags, data, vbsf_read_super_26);
     1263    } else {
     1264        return get_sb_nodev(fs_type, flags, data, vbsf_read_super_26);
     1265    }
    11571266}
    11581267# endif
     
    11661275
    11671276    TRACE();
    1168     err = vbsf_read_super_aux(sb, data, flags);
     1277
     1278    if (!VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
     1279        int rc;
     1280        struct vbsf_mount_info_new mount_opts = { '\0' };
     1281
     1282        vbsf_init_mount_info(&mount_opts, NULL);
     1283        rc = vbsf_parse_mount_options(data, &mount_opts);
     1284        if (rc)
     1285            return ERR_PTR(rc);
     1286        err = vbsf_read_super_aux(sb, &mount_opts, flags);
     1287    } else {
     1288        err = vbsf_read_super_aux(sb, data, flags);
     1289    }
    11691290    if (err) {
    11701291        printk(KERN_DEBUG "vbsf_read_super_aux err=%d\n", err);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette