Changeset d2c8533 in mainline


Ignore:
Timestamp:
2017-05-08T20:38:47Z (8 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f066a87
Parents:
582a0b8
Message:

File system probing groundwork. Only MFS can do it for now.

Location:
uspace
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/init/init.c

    r582a0b8 rd2c8533  
    320320                srv_start("/srv/tmpfs");
    321321       
     322        srv_start("/srv/mfs");
     323       
    322324        srv_start("/srv/klog");
    323325        srv_start("/srv/locfs");
  • uspace/lib/c/generic/vfs/vfs.c

    r582a0b8 rd2c8533  
    347347        return loc_service_connect(stat.service, iface, 0);
    348348}
     349
     350/** Determine if a device contains the specified file system type. If so,
     351 * return identification information.
     352 *
     353 * @param fs_name File system name
     354 * @param serv    Service representing the mountee
     355 * @param info    Place to store volume identification information
     356 *
     357 * @return                      EOK on success or a negative error code
     358 */
     359int vfs_fsprobe(const char *fs_name, service_id_t serv,
     360    vfs_fs_probe_info_t *info)
     361{
     362        sysarg_t rc;
     363       
     364        ipc_call_t answer;
     365        async_exch_t *exch = vfs_exchange_begin();
     366        aid_t req = async_send_1(exch, VFS_IN_FSPROBE, serv, &answer);
     367       
     368        rc = async_data_write_start(exch, (void *) fs_name,
     369            str_size(fs_name));
     370       
     371        async_wait_for(req, &rc);
     372       
     373        if (rc != EOK) {
     374                vfs_exchange_end(exch);
     375                return rc;
     376        }
     377       
     378        rc = async_data_read_start(exch, info, sizeof(*info));
     379        vfs_exchange_end(exch);
     380       
     381        return rc;
     382}
     383
    349384
    350385/** Return a list of currently available file system types
  • uspace/lib/c/include/ipc/vfs.h

    r582a0b8 rd2c8533  
    4141
    4242#define FS_NAME_MAXLEN  20
     43#define FS_LABEL_MAXLEN 256
     44#define FS_VUID_MAXLEN 128
    4345#define MAX_PATH_LEN    (32 * 1024)
    4446#define MAX_MNTOPTS_LEN 256
     
    6264} vfs_info_t;
    6365
     66/** Data returned by filesystem probe regarding a specific volume. */
     67typedef struct {
     68        char label[FS_LABEL_MAXLEN + 1];
     69        char vuid[FS_VUID_MAXLEN + 1];
     70} vfs_fs_probe_info_t;
     71
    6472typedef enum {
    6573        VFS_IN_CLONE = IPC_FIRST_USER_METHOD,
     74        VFS_IN_FSPROBE,
    6675        VFS_IN_FSTYPES,
    6776        VFS_IN_MOUNT,
     
    8594        VFS_OUT_CLOSE = IPC_FIRST_USER_METHOD,
    8695        VFS_OUT_DESTROY,
     96        VFS_OUT_FSPROBE,
    8797        VFS_OUT_IS_EMPTY,
    8898        VFS_OUT_LINK,
  • uspace/lib/c/include/vfs/vfs.h

    r582a0b8 rd2c8533  
    8888extern async_exch_t *vfs_exchange_begin(void);
    8989extern void vfs_exchange_end(async_exch_t *);
     90extern int vfs_fsprobe(const char *, service_id_t, vfs_fs_probe_info_t *);
    9091extern int vfs_fstypes(vfs_fstypes_t *);
    9192extern void vfs_fstypes_free(vfs_fstypes_t *);
  • uspace/lib/fs/libfs.c

    r582a0b8 rd2c8533  
    8181    ipc_call_t *);
    8282
     83static void vfs_out_fsprobe(ipc_callid_t rid, ipc_call_t *req)
     84{
     85        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     86        int rc;
     87        vfs_fs_probe_info_t info;
     88       
     89        ipc_callid_t callid;
     90        size_t size;
     91        if ((!async_data_read_receive(&callid, &size)) ||
     92            (size != sizeof(info))) {
     93                async_answer_0(callid, EIO);
     94                async_answer_0(rid, EIO);
     95                return;
     96        }
     97       
     98        memset(&info, 0, sizeof(info));
     99        rc = vfs_out_ops->fsprobe(service_id, &info);
     100        if (rc != EOK) {
     101                async_answer_0(callid, EIO);
     102                async_answer_0(rid, rc);
     103                return;
     104        }
     105       
     106        async_data_read_finalize(callid, &info, sizeof(info));
     107        async_answer_0(rid, EOK);
     108}
     109
    83110static void vfs_out_mounted(ipc_callid_t rid, ipc_call_t *req)
    84111{
     
    272299               
    273300                switch (IPC_GET_IMETHOD(call)) {
     301                case VFS_OUT_FSPROBE:
     302                        vfs_out_fsprobe(callid, &call);
     303                        break;
    274304                case VFS_OUT_MOUNTED:
    275305                        vfs_out_mounted(callid, &call);
  • uspace/lib/fs/libfs.h

    r582a0b8 rd2c8533  
    4343
    4444typedef struct {
     45        int (* fsprobe)(service_id_t, vfs_fs_probe_info_t *);
    4546        int (* mounted)(service_id_t, const char *, fs_index_t *, aoff64_t *,
    4647            unsigned *);
  • uspace/srv/fs/cdfs/cdfs_ops.c

    r582a0b8 rd2c8533  
    10211021}
    10221022
     1023static int cdfs_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     1024{
     1025        return ENOTSUP;
     1026}
     1027
    10231028static int cdfs_mounted(service_id_t service_id, const char *opts,
    10241029    fs_index_t *index, aoff64_t *size, unsigned int *lnkcnt)
     
    12971302
    12981303vfs_out_ops_t cdfs_ops = {
     1304        .fsprobe = cdfs_fsprobe,
    12991305        .mounted = cdfs_mounted,
    13001306        .unmounted = cdfs_unmounted,
  • uspace/srv/fs/exfat/exfat_ops.c

    r582a0b8 rd2c8533  
    10501050}
    10511051*/
    1052  
     1052
     1053static int exfat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     1054{
     1055        return ENOTSUP;
     1056}
     1057
    10531058static int
    10541059exfat_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
     
    15711576
    15721577vfs_out_ops_t exfat_ops = {
     1578        .fsprobe = exfat_fsprobe,
    15731579        .mounted = exfat_mounted,
    15741580        .unmounted = exfat_unmounted,
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    r582a0b8 rd2c8533  
    915915 * VFS operations.
    916916 */
     917
     918/** Probe operation.
     919 *
     920 * Try to get information about specified filesystem from device.
     921 *
     922 * @param sevice_id Service ID
     923 * @param info Place to store information
     924 *
     925 * @return Error code
     926 */
     927static int ext4fs_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     928{
     929        return ENOTSUP;
     930}
    917931
    918932/** Mount operation.
     
    15201534 */
    15211535vfs_out_ops_t ext4fs_ops = {
     1536        .fsprobe = ext4fs_fsprobe,
    15221537        .mounted = ext4fs_mounted,
    15231538        .unmounted = ext4fs_unmounted,
  • uspace/srv/fs/fat/fat_ops.c

    r582a0b8 rd2c8533  
    912912 * FAT VFS_OUT operations.
    913913 */
     914
     915static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     916{
     917        return ENOTSUP;
     918}
    914919
    915920static int
     
    15081513
    15091514vfs_out_ops_t fat_ops = {
     1515        .fsprobe = fat_fsprobe,
    15101516        .mounted = fat_mounted,
    15111517        .unmounted = fat_unmounted,
  • uspace/srv/fs/locfs/locfs_ops.c

    r582a0b8 rd2c8533  
    455455}
    456456
     457static int locfs_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     458{
     459        return ENOTSUP;
     460}
     461
    457462static int locfs_mounted(service_id_t service_id, const char *opts,
    458463    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     
    763768
    764769vfs_out_ops_t locfs_ops = {
     770        .fsprobe = locfs_fsprobe,
    765771        .mounted = locfs_mounted,
    766772        .unmounted = locfs_unmounted,
  • uspace/srv/fs/mfs/mfs_ops.c

    r582a0b8 rd2c8533  
    140140}
    141141
    142 static int
    143 mfs_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
    144     aoff64_t *size, unsigned *linkcnt)
    145 {
    146         enum cache_mode cmode;
     142/** Read the superblock.
     143 */
     144static int mfs_read_sb(service_id_t service_id, struct mfs_sb_info **rsbi)
     145{
    147146        struct mfs_superblock *sb = NULL;
    148147        struct mfs3_superblock *sb3 = NULL;
    149         struct mfs_sb_info *sbi = NULL;
    150         struct mfs_instance *instance = NULL;
     148        struct mfs_sb_info *sbi;
     149        size_t bsize;
    151150        bool native, longnames;
    152151        mfs_version_t version;
    153152        uint16_t magic;
    154153        int rc;
    155 
    156         /* Check for option enabling write through. */
    157         if (str_cmp(opts, "wtcache") == 0)
    158                 cmode = CACHE_MODE_WT;
    159         else
    160                 cmode = CACHE_MODE_WB;
    161 
    162         /* initialize libblock */
    163         rc = block_init(service_id, 4096);
    164         if (rc != EOK)
    165                 return rc;
    166154
    167155        /* Allocate space for generic MFS superblock */
     
    172160        }
    173161
    174         /* Allocate space for filesystem instance */
    175         instance = malloc(sizeof(*instance));
    176         if (!instance) {
    177                 rc = ENOMEM;
    178                 goto out_error;
    179         }
    180 
    181162        sb = malloc(MFS_SUPERBLOCK_SIZE);
    182163        if (!sb) {
    183164                rc = ENOMEM;
     165                goto out_error;
     166        }
     167
     168        rc = block_get_bsize(service_id, &bsize);
     169        if (rc != EOK) {
     170                rc = EIO;
     171                goto out_error;
     172        }
     173
     174        /* We don't support other block size than 512 */
     175        if (bsize != 512) {
     176                rc = ENOTSUP;
    184177                goto out_error;
    185178        }
     
    269262        }
    270263
     264        mfsdebug("read superblock successful\n");
     265
     266        free(sb);
     267        *rsbi = sbi;
     268        return EOK;
     269
     270out_error:
     271        if (sb)
     272                free(sb);
     273        if (sbi)
     274                free(sbi);
     275        return rc;
     276}
     277
     278
     279static int mfs_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     280{
     281        struct mfs_sb_info *sbi = NULL;
     282        int rc;
     283
     284        /* Initialize libblock */
     285        rc = block_init(service_id, 4096);
     286        if (rc != EOK)
     287                return rc;
     288
     289        /* Read the superblock */
     290        rc = mfs_read_sb(service_id, &sbi);
     291        block_fini(service_id);
     292
     293        return rc;
     294}
     295
     296static int
     297mfs_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
     298    aoff64_t *size, unsigned *linkcnt)
     299{
     300        enum cache_mode cmode;
     301        struct mfs_sb_info *sbi = NULL;
     302        struct mfs_instance *instance = NULL;
     303        int rc;
     304
     305        /* Check for option enabling write through. */
     306        if (str_cmp(opts, "wtcache") == 0)
     307                cmode = CACHE_MODE_WT;
     308        else
     309                cmode = CACHE_MODE_WB;
     310
     311        /* Initialize libblock */
     312        rc = block_init(service_id, 4096);
     313        if (rc != EOK)
     314                return rc;
     315
     316        /* Allocate space for filesystem instance */
     317        instance = malloc(sizeof(*instance));
     318        if (!instance) {
     319                rc = ENOMEM;
     320                goto out_error;
     321        }
     322
     323        /* Read the superblock */
     324        rc = mfs_read_sb(service_id, &sbi);
     325        if (rc != EOK)
     326                goto out_error;
     327
    271328        rc = block_cache_init(service_id, sbi->block_size, 0, cmode);
    272329        if (rc != EOK) {
     
    298355        *linkcnt = 1;
    299356
    300         free(sb);
    301 
    302357        return mfs_node_put(fn);
    303358
    304359out_error:
    305360        block_fini(service_id);
    306         if (sb)
    307                 free(sb);
    308361        if (sbi)
    309362                free(sbi);
     
    12051258
    12061259vfs_out_ops_t mfs_ops = {
     1260        .fsprobe = mfs_fsprobe,
    12071261        .mounted = mfs_mounted,
    12081262        .unmounted = mfs_unmounted,
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r582a0b8 rd2c8533  
    421421 */
    422422
     423static int tmpfs_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     424{
     425        return ENOTSUP;
     426}
     427
    423428static int
    424429tmpfs_mounted(service_id_t service_id, const char *opts,
     
    652657
    653658vfs_out_ops_t tmpfs_ops = {
     659        .fsprobe = tmpfs_fsprobe,
    654660        .mounted = tmpfs_mounted,
    655661        .unmounted = tmpfs_unmounted,
  • uspace/srv/fs/udf/udf_ops.c

    r582a0b8 rd2c8533  
    299299};
    300300
     301static int udf_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     302{
     303        return ENOTSUP;
     304}
     305
    301306static int udf_mounted(service_id_t service_id, const char *opts,
    302307    fs_index_t *index, aoff64_t *size, unsigned *linkcnt)
     
    547552
    548553vfs_out_ops_t udf_ops = {
     554        .fsprobe = udf_fsprobe,
    549555        .mounted = udf_mounted,
    550556        .unmounted = udf_unmounted,
  • uspace/srv/vfs/vfs.h

    r582a0b8 rd2c8533  
    206206
    207207extern int vfs_op_clone(int oldfd, int newfd, bool desc);
     208extern int vfs_op_fsprobe(const char *, service_id_t, vfs_fs_probe_info_t *);
    208209extern int vfs_op_mount(int mpfd, unsigned servid, unsigned flags, unsigned instance, const char *opts, const char *fsname, int *outfd);
    209210extern int vfs_op_mtab_get(void);
  • uspace/srv/vfs/vfs_ipc.c

    r582a0b8 rd2c8533  
    4545}
    4646
     47static void vfs_in_fsprobe(ipc_callid_t rid, ipc_call_t *request)
     48{
     49        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*request);
     50        char *fs_name = NULL;
     51        ipc_callid_t callid;
     52        vfs_fs_probe_info_t info;
     53        size_t len;
     54        int rc;
     55       
     56        /*
     57         * Now we expect the client to send us data with the name of the file
     58         * system.
     59         */
     60        rc = async_data_write_accept((void **) &fs_name, true, 0,
     61            FS_NAME_MAXLEN, 0, NULL);
     62        if (rc != EOK) {
     63                async_answer_0(rid, rc);
     64                return;
     65        }
     66       
     67        rc = vfs_op_fsprobe(fs_name, service_id, &info);
     68        async_answer_0(rid, rc);
     69        if (rc != EOK)
     70                goto out;
     71       
     72        /* Now we should get a read request */
     73        if (!async_data_read_receive(&callid, &len))
     74                goto out;
     75
     76        if (len > sizeof(info))
     77                len = sizeof(info);
     78        (void) async_data_read_finalize(callid, &info, len);
     79
     80out:
     81        free(fs_name);
     82}
     83
    4784static void vfs_in_fstypes(ipc_callid_t rid, ipc_call_t *request)
    4885{
     
    297334                        vfs_in_clone(callid, &call);
    298335                        break;
     336                case VFS_IN_FSPROBE:
     337                        vfs_in_fsprobe(callid, &call);
     338                        break;
    299339                case VFS_IN_FSTYPES:
    300340                        vfs_in_fstypes(callid, &call);
  • uspace/srv/vfs/vfs_ops.c

    r582a0b8 rd2c8533  
    190190}
    191191
     192int vfs_op_fsprobe(const char *fs_name, service_id_t sid,
     193    vfs_fs_probe_info_t *info)
     194{
     195        fs_handle_t fs_handle = 0;
     196        sysarg_t rc;
     197        int retval;
     198       
     199        fibril_mutex_lock(&fs_list_lock);
     200        fs_handle = fs_name_to_handle(0, fs_name, false);
     201        fibril_mutex_unlock(&fs_list_lock);
     202       
     203        if (fs_handle == 0)
     204                return ENOFS;
     205       
     206        /* Send probe request to the file system server */
     207        ipc_call_t answer;
     208        async_exch_t *exch = vfs_exchange_grab(fs_handle);
     209        aid_t msg = async_send_1(exch, VFS_OUT_FSPROBE, (sysarg_t) sid,
     210            &answer);
     211        if (msg == 0)
     212                return EINVAL;
     213       
     214        /* Read probe information */
     215        retval = async_data_read_start(exch, info, sizeof(*info));
     216        if (retval != EOK) {
     217                async_forget(msg);
     218                return retval;
     219        }
     220       
     221        async_wait_for(msg, &rc);
     222        vfs_exchange_release(exch);
     223        return rc;
     224}
     225
    192226int vfs_op_mount(int mpfd, unsigned service_id, unsigned flags,
    193227    unsigned instance, const char *opts, const char *fs_name, int *outfd)
  • uspace/srv/volsrv/part.c

    r582a0b8 rd2c8533  
    4242#include <stdlib.h>
    4343#include <str.h>
     44#include <vfs/vfs.h>
    4445
    4546#include "empty.h"
     
    132133        vol_part_t *part;
    133134        bool empty;
     135        vfs_fs_probe_info_t info;
    134136        int rc;
    135137
     
    154156        }
    155157
    156         log_msg(LOG_DEFAULT, LVL_DEBUG, "Probe partition %s", part->svc_name);
    157         rc = volsrv_part_is_empty(sid, &empty);
    158         if (rc != EOK) {
    159                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed determining if "
    160                     "partition is empty.");
    161                 goto error;
    162         }
    163 
    164         part->pcnt = empty ? vpc_empty : vpc_unknown;
     158        log_msg(LOG_DEFAULT, LVL_NOTE, "Probe partition %s", part->svc_name);
     159        rc = vfs_fsprobe("mfs", sid, &info);
     160        if (rc == EOK) {
     161                part->pcnt = vpc_fs;
     162                part->fstype = fs_minix;
     163        } else {
     164                log_msg(LOG_DEFAULT, LVL_NOTE, "Partition does not contain "
     165                    "a recognized file system.");
     166
     167                rc = volsrv_part_is_empty(sid, &empty);
     168                if (rc != EOK) {
     169                        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed determining if "
     170                            "partition is empty.");
     171                        goto error;
     172                }
     173
     174                part->pcnt = empty ? vpc_empty : vpc_unknown;
     175        }
     176
    165177        list_append(&part->lparts, &vol_parts);
    166178
Note: See TracChangeset for help on using the changeset viewer.