VirtualBox

Changeset 87056 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 8, 2020 4:28:25 PM (4 years ago)
Author:
vboxsync
Message:

linux/vboxsf: Add support for parsing string-based mount options using the Linux match_token() API (kernel versions >= 2.6.0) bugref:9816

Location:
trunk/src/VBox/Additions/linux/sharedfolders
Files:
2 edited

Legend:

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

    r87033 r87056  
    6161# include <linux/fs_context.h>
    6262# include <linux/fs_parser.h>
     63#elif RTLNX_VER_MIN(2,6,0)
     64# include <linux/parser.h>
    6365#endif
    6466
     
    220222    *sf_gp = NULL; /* (old gcc maybe used initialized) */
    221223
    222 #if RTLNX_VER_MAX(5,1,0)
     224#if RTLNX_VER_MAX(2,6,0)
    223225    /*
    224226     * Validate info.
    225227     */
    226     if (   info->nullchar != '\0'
    227         || info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0
    228         || info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1
    229         || info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2) {
     228    if (!VBSF_IS_MOUNT_VBOXSF_DATA(info)) {
    230229        SFLOGRELBOTH(("vboxsf: Invalid info signature: %#x %#x %#x %#x!\n",
    231230                      info->nullchar, info->signature[0], info->signature[1], info->signature[2]));
     
    550549
    551550
     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 */
     556static void vbsf_init_mount_info(struct vbsf_mount_info_new *mount_info,
     557    const char *sf_name)
     558{
     559    mount_info->ttl = mount_info->msDirCacheTTL = mount_info->msInodeTTL = -1;
     560    mount_info->dmode = mount_info->fmode = ~0U;
     561    mount_info->enmCacheMode = kVbsfCacheMode_Strict;
     562    mount_info->length = sizeof(struct vbsf_mount_info_new);
     563    if (sf_name)
     564        strlcpy(mount_info->name, sf_name, sizeof(mount_info->name));
     565}
     566
     567enum {
     568    Opt_iocharset,  /* nls_name[] */
     569    Opt_nls,        /* alias for iocharset */
     570    Opt_uid,
     571    Opt_gid,
     572    Opt_ttl,
     573    Opt_dmode,
     574    Opt_fmode,
     575    Opt_dmask,
     576    Opt_fmask,
     577    Opt_umask,
     578    Opt_maxiopages,
     579    Opt_dirbuf,
     580    Opt_dcachettl,
     581    Opt_inodettl,
     582    Opt_cachemode,  /* enum vbsf_cache_mode */
     583    Opt_tag,
     584    Opt_err
     585};
     586
     587# if RTLNX_VER_MAX(2,6,28)
     588static match_table_t vbsf_tokens = {
     589# else
     590static const match_table_t vbsf_tokens = {
     591# endif
     592    { Opt_iocharset,  "iocharset=%s" },
     593    { Opt_nls,        "nls=%s" },
     594    { Opt_uid,        "uid=%u" },
     595    { Opt_gid,        "gid=%u" },
     596    { Opt_ttl,        "ttl=%u" },
     597    { Opt_dmode,      "dmode=%o" },
     598    { Opt_fmode,      "fmode=%o" },
     599    { Opt_dmask,      "dmask=%o" },
     600    { Opt_fmask,      "fmask=%o" },
     601    { Opt_umask,      "umask=%o" },
     602    { Opt_maxiopages, "maxiopages=%u" },
     603    { Opt_dirbuf,     "dirbuf=%u" },
     604    { Opt_dcachettl,  "dcachettl=%u" },
     605    { Opt_inodettl,   "inodettl=%u" },
     606    { Opt_cachemode,  "cache=%s" },
     607    { Opt_tag,        "tag=%s" },  /* private option for automounter */
     608    { Opt_err,        NULL }
     609};
     610
     611static int vbsf_parse_mount_options(char *options,
     612    struct vbsf_mount_info_new *mount_info)
     613{
     614    substring_t args[MAX_OPT_ARGS];
     615    int option;
     616    int token;
     617    char *p;
     618    char *iocharset;
     619    char *cachemode;
     620    char *tag;
     621
     622    if (!options)
     623        return -EINVAL;
     624
     625    while ((p = strsep(&options, ",")) != NULL) {
     626        if (!*p)
     627            continue;
     628
     629        token = match_token(p, vbsf_tokens, args);
     630        switch (token) {
     631        case Opt_iocharset:
     632        case Opt_nls:
     633            iocharset = match_strdup(&args[0]);
     634            if (!iocharset) {
     635                SFLOGRELBOTH(("vboxsf: Could not allocate memory for iocharset!\n"));
     636                return -ENOMEM;
     637            }
     638            strlcpy(mount_info->nls_name, iocharset,
     639                sizeof(mount_info->nls_name));
     640            kfree(iocharset);
     641            break;
     642        case Opt_uid:
     643            if (match_int(&args[0], &option))
     644                return -EINVAL;
     645            mount_info->uid = option;
     646            break;
     647        case Opt_gid:
     648            if (match_int(&args[0], &option))
     649                return -EINVAL;
     650            mount_info->gid = option;
     651            break;
     652        case Opt_ttl:
     653            if (match_int(&args[0], &option))
     654                return -EINVAL;
     655            mount_info->ttl = option;
     656            break;
     657        case Opt_dmode:
     658            if (match_octal(&args[0], &option))
     659                return -EINVAL;
     660            mount_info->dmode = option;
     661            break;
     662        case Opt_fmode:
     663            if (match_octal(&args[0], &option))
     664                return -EINVAL;
     665            mount_info->fmode = option;
     666            break;
     667        case Opt_dmask:
     668            if (match_octal(&args[0], &option))
     669                return -EINVAL;
     670            mount_info->dmask = option;
     671            break;
     672        case Opt_fmask:
     673            if (match_octal(&args[0], &option))
     674                return -EINVAL;
     675            mount_info->fmask = option;
     676            break;
     677        case Opt_umask:
     678            if (match_octal(&args[0], &option))
     679                return -EINVAL;
     680            mount_info->dmask = mount_info->fmask = option;
     681            break;
     682        case Opt_maxiopages:
     683            if (match_int(&args[0], &option))
     684                return -EINVAL;
     685            mount_info->cMaxIoPages = option;
     686            break;
     687        case Opt_dirbuf:
     688            if (match_int(&args[0], &option))
     689                return -EINVAL;
     690            mount_info->cbDirBuf = option;
     691            break;
     692        case Opt_dcachettl:
     693            if (match_int(&args[0], &option))
     694                return -EINVAL;
     695            mount_info->msDirCacheTTL = option;
     696            break;
     697        case Opt_inodettl:
     698            if (match_int(&args[0], &option))
     699                return -EINVAL;
     700            mount_info->msInodeTTL = option;
     701            break;
     702        case Opt_cachemode: {
     703            cachemode = match_strdup(&args[0]);
     704            if (!cachemode) {
     705                SFLOGRELBOTH(("vboxsf: Could not allocate memory for cachemode!\n"));
     706                return -ENOMEM;
     707            }
     708            if (!strcmp(cachemode, "default") || !strcmp(cachemode, "strict"))
     709                mount_info->enmCacheMode = kVbsfCacheMode_Strict;
     710            else if (!strcmp(cachemode, "none"))
     711                mount_info->enmCacheMode = kVbsfCacheMode_None;
     712            else if (!strcmp(cachemode, "read"))
     713                mount_info->enmCacheMode = kVbsfCacheMode_Read;
     714            else if (!strcmp(cachemode, "readwrite"))
     715                mount_info->enmCacheMode = kVbsfCacheMode_ReadWrite;
     716            else
     717                printk(KERN_WARNING "vboxsf: cache mode (%s) is out of range, using default instead.\n", cachemode);
     718            kfree(cachemode);
     719            break;
     720        }
     721        case Opt_tag:
     722            tag = match_strdup(&args[0]);
     723            if (!tag) {
     724                SFLOGRELBOTH(("vboxsf: Could not allocate memory for automount tag!\n"));
     725                return -ENOMEM;
     726            }
     727            strlcpy(mount_info->szTag, tag, sizeof(mount_info->szTag));
     728            kfree(tag);
     729            break;
     730        default:
     731            printk(KERN_ERR "unrecognised mount option \"%s\"", p);
     732            return -EINVAL;
     733        }
     734    }
     735
     736    return 0;
     737}
     738#endif /* 5.1.0 > version >= 2.6.0 */
     739
     740
    552741/**
    553742 * This is called by vbsf_read_super_24(), vbsf_read_super_26(), and
     
    778967# if RTLNX_VER_MIN(5,1,0)
    779968    vbsf_super_info_copy_remount_options(pSuperInfo, info);
    780 # else
    781     if (data && data[0] != 0) {
    782         struct vbsf_mount_info_new *info = (struct vbsf_mount_info_new *)data;
    783         if (   info->nullchar == '\0'
    784             && info->signature[0] == VBSF_MOUNT_SIGNATURE_BYTE_0
    785             && info->signature[1] == VBSF_MOUNT_SIGNATURE_BYTE_1
    786             && info->signature[2] == VBSF_MOUNT_SIGNATURE_BYTE_2) {
    787             vbsf_super_info_copy_remount_options(pSuperInfo, info);
    788         }
    789     }
     969# elif RTLNX_VER_MIN(2,6,0)
     970    if (VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
     971        vbsf_super_info_copy_remount_options(pSuperInfo, (struct vbsf_mount_info_new *)data);
     972    } else {
     973        struct vbsf_mount_info_new mount_opts = { '\0' };
     974        vbsf_init_mount_info(&mount_opts, NULL);
     975        err = vbsf_parse_mount_options(data, &mount_opts);
     976        if (err)
     977            return err;
     978        vbsf_super_info_copy_remount_options(pSuperInfo, &mount_opts);
     979    }
     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);
    790983# endif
    791984
     
    9121105{
    9131106    TRACE();
    914     return mount_nodev(fs_type, flags, data, vbsf_read_super_26);
     1107
     1108    if (!VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
     1109        int rc;
     1110        struct vbsf_mount_info_new mount_opts = { '\0' };
     1111
     1112        vbsf_init_mount_info(&mount_opts, dev_name);
     1113        rc = vbsf_parse_mount_options(data, &mount_opts);
     1114        if (rc)
     1115            return ERR_PTR(rc);
     1116        return mount_nodev(fs_type, flags, &mount_opts, vbsf_read_super_26);
     1117    } else {
     1118        return mount_nodev(fs_type, flags, data, vbsf_read_super_26);
     1119    }
    9151120}
    9161121# elif RTLNX_VER_MIN(2,6,18)
     
    9181123{
    9191124    TRACE();
    920     return get_sb_nodev(fs_type, flags, data, vbsf_read_super_26, mnt);
     1125
     1126    if (!VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
     1127        int rc;
     1128        struct vbsf_mount_info_new mount_opts = { '\0' };
     1129
     1130        vbsf_init_mount_info(&mount_opts, dev_name);
     1131        rc = vbsf_parse_mount_options(data, &mount_opts);
     1132        if (rc)
     1133            return rc;
     1134        return get_sb_nodev(fs_type, flags, &mount_opts, vbsf_read_super_26,
     1135            mnt);
     1136    } else {
     1137        return get_sb_nodev(fs_type, flags, data, vbsf_read_super_26, mnt);
     1138    }
    9211139}
    9221140# else /* 2.6.18 > version >= 2.5.4 */
     
    9241142{
    9251143    TRACE();
     1144#  if RTLNX_VER_MIN(2,6,0)
     1145    if (!VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
     1146        int rc;
     1147        struct vbsf_mount_info_new mount_opts = { '\0' };
     1148
     1149        vbsf_init_mount_info(&mount_opts, dev_name);
     1150        rc = vbsf_parse_mount_options(data, &mount_opts);
     1151        if (rc)
     1152            return ERR_PTR(rc);
     1153        return get_sb_nodev(fs_type, flags, &mount_opts, vbsf_read_super_26);
     1154    }
     1155#  endif
    9261156    return get_sb_nodev(fs_type, flags, data, vbsf_read_super_26);
    9271157}
     
    11381368
    11391369    if (data) {
    1140         struct vbsf_mount_info_new *mount_opts =
    1141             (struct vbsf_mount_info_new *)data;
    1142         if (mount_opts->nullchar == '\0'
    1143             && mount_opts->signature[0] == VBSF_MOUNT_SIGNATURE_BYTE_0
    1144             && mount_opts->signature[1] == VBSF_MOUNT_SIGNATURE_BYTE_1
    1145             && mount_opts->signature[2] == VBSF_MOUNT_SIGNATURE_BYTE_2) {
    1146             memcpy(info, mount_opts, sizeof(struct vbsf_mount_info_new));
     1370        if (VBSF_IS_MOUNT_VBOXSF_DATA(data)) {
     1371            memcpy(info, data, sizeof(struct vbsf_mount_info_new));
    11471372        } else {
    11481373            /* this will call vbsf_parse_param() */
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h

    r85703 r87056  
    427427#endif
    428428
     429/**
     430 * Macro for checking if the 'data' argument passed in via mount(2) was supplied
     431 * by the mount.vboxsf command line utility as a page of data containing the
     432 * vbsf_mount_info_new structure.
     433 */
     434#define VBSF_IS_MOUNT_VBOXSF_DATA(data)        \
     435    (((struct vbsf_mount_info_new *)data)->nullchar == '\0' && \
     436    ((struct vbsf_mount_info_new *)data)->signature[0] == VBSF_MOUNT_SIGNATURE_BYTE_0 && \
     437    ((struct vbsf_mount_info_new *)data)->signature[1] == VBSF_MOUNT_SIGNATURE_BYTE_1 && \
     438    ((struct vbsf_mount_info_new *)data)->signature[2] == VBSF_MOUNT_SIGNATURE_BYTE_2)
     439
    429440extern int  vbsf_stat(const char *caller, struct vbsf_super_info *pSuperInfo, SHFLSTRING * path, PSHFLFSOBJINFO result,
    430441                      int ok_to_fail);
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