Changeset d3b2ffa in mainline for uspace/srv


Ignore:
Timestamp:
2018-06-29T15:40:10Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5e904dd
Parents:
1e472ee (diff), 1a9174e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge volume management improvements (still WIP).

Location:
uspace/srv/volsrv
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/volsrv/part.c

    r1e472ee rd3b2ffa  
    5151
    5252static errno_t vol_part_add_locked(service_id_t);
     53static void vol_part_remove_locked(vol_part_t *);
     54static errno_t vol_part_find_by_id_ref_locked(service_id_t, vol_part_t **);
     55
    5356static LIST_INITIALIZE(vol_parts); /* of vol_part_t */
    5457static FIBRIL_MUTEX_INITIALIZE(vol_parts_lock);
     
    6871};
    6972
    70 /** Check for new partitions */
     73static const char *fstype_str(vol_fstype_t fstype)
     74{
     75        struct fsname_type *fst;
     76
     77        fst = &fstab[0];
     78        while (fst->name != NULL) {
     79                if (fst->fstype == fstype)
     80                        return fst->name;
     81                ++fst;
     82        }
     83
     84        assert(false);
     85        return NULL;
     86}
     87
     88/** Check for new and removed partitions */
    7189static errno_t vol_part_check_new(void)
    7290{
    7391        bool already_known;
     92        bool still_exists;
    7493        category_id_t part_cat;
    7594        service_id_t *svcs;
    7695        size_t count, i;
     96        link_t *cur, *next;
     97        vol_part_t *part;
    7798        errno_t rc;
    7899
     
    94115        }
    95116
     117        /* Check for new partitions */
    96118        for (i = 0; i < count; i++) {
    97119                already_known = false;
    98120
     121                // XXX Make this faster
    99122                list_foreach(vol_parts, lparts, vol_part_t, part) {
    100123                        if (part->svc_id == svcs[i]) {
     
    115138        }
    116139
     140        /* Check for removed partitions */
     141        cur = list_first(&vol_parts);
     142        while (cur != NULL) {
     143                next = list_next(cur, &vol_parts);
     144                part = list_get_instance(cur, vol_part_t, lparts);
     145
     146                still_exists = false;
     147                // XXX Make this faster
     148                for (i = 0; i < count; i++) {
     149                        if (part->svc_id == svcs[i]) {
     150                                still_exists = true;
     151                                break;
     152                        }
     153                }
     154
     155                if (!still_exists) {
     156                        log_msg(LOG_DEFAULT, LVL_NOTE, "Partition '%zu' is gone",
     157                            part->svc_id);
     158                        vol_part_remove_locked(part);
     159                }
     160
     161                cur = next;
     162        }
     163
     164        free(svcs);
     165
    117166        fibril_mutex_unlock(&vol_parts_lock);
    118167        return EOK;
     
    129178        }
    130179
     180        atomic_set(&part->refcnt, 1);
    131181        link_initialize(&part->lparts);
    132182        part->pcnt = vpc_empty;
     
    137187static void vol_part_delete(vol_part_t *part)
    138188{
     189        log_msg(LOG_DEFAULT, LVL_ERROR, "Freeing partition %p", part);
    139190        if (part == NULL)
    140191                return;
    141192
     193        free(part->cur_mp);
    142194        free(part->svc_name);
    143195        free(part);
     
    204256}
    205257
     258static errno_t vol_part_mount(vol_part_t *part)
     259{
     260        char *mp;
     261        int err;
     262        errno_t rc;
     263
     264        if (str_size(part->label) < 1) {
     265                /* Don't mount nameless volumes */
     266                log_msg(LOG_DEFAULT, LVL_NOTE, "Not mounting nameless partition.");
     267                return EOK;
     268        }
     269
     270        log_msg(LOG_DEFAULT, LVL_NOTE, "Determine MP label='%s'", part->label);
     271        err = asprintf(&mp, "/vol/%s", part->label);
     272        if (err < 0) {
     273                log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory");
     274                return ENOMEM;
     275        }
     276
     277        log_msg(LOG_DEFAULT, LVL_NOTE, "Create mount point '%s'", mp);
     278        rc = vfs_link_path(mp, KIND_DIRECTORY, NULL);
     279        if (rc != EOK) {
     280                log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating mount point '%s'",
     281                    mp);
     282                free(mp);
     283                return EIO;
     284        }
     285
     286        log_msg(LOG_DEFAULT, LVL_NOTE, "Call vfs_mount_path mp='%s' fstype='%s' svc_name='%s'",
     287            mp, fstype_str(part->fstype), part->svc_name);
     288        rc = vfs_mount_path(mp, fstype_str(part->fstype),
     289            part->svc_name, "", 0, 0);
     290        if (rc != EOK) {
     291                log_msg(LOG_DEFAULT, LVL_NOTE, "Failed mounting to %s", mp);
     292        }
     293        log_msg(LOG_DEFAULT, LVL_NOTE, "Mount to %s -> %d\n", mp, rc);
     294
     295        part->cur_mp = mp;
     296        part->cur_mp_auto = true;
     297
     298        return rc;
     299}
     300
    206301static errno_t vol_part_add_locked(service_id_t sid)
    207302{
     
    210305
    211306        assert(fibril_mutex_is_locked(&vol_parts_lock));
     307        log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_add_locked(%zu)", sid);
    212308
    213309        /* Check for duplicates */
    214         rc = vol_part_find_by_id(sid, &part);
    215         if (rc == EOK)
     310        rc = vol_part_find_by_id_ref_locked(sid, &part);
     311        if (rc == EOK) {
     312                vol_part_del_ref(part);
    216313                return EEXIST;
    217 
    218         log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_add_locked()");
     314        }
     315
     316        log_msg(LOG_DEFAULT, LVL_NOTE, "partition %zu is new", sid);
     317
    219318        part = vol_part_new();
    220319        if (part == NULL)
     
    233332                goto error;
    234333
     334        rc = vol_part_mount(part);
     335        if (rc != EOK)
     336                goto error;
     337
    235338        list_append(&part->lparts, &vol_parts);
    236339
     
    242345        vol_part_delete(part);
    243346        return rc;
     347}
     348
     349static void vol_part_remove_locked(vol_part_t *part)
     350{
     351        assert(fibril_mutex_is_locked(&vol_parts_lock));
     352        log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_remove_locked(%zu)", part->svc_id);
     353
     354        list_remove(&part->lparts);
     355
     356        log_msg(LOG_DEFAULT, LVL_NOTE, "Removed partition.");
     357        vol_part_del_ref(part);
    244358}
    245359
     
    308422}
    309423
    310 errno_t vol_part_find_by_id(service_id_t sid, vol_part_t **rpart)
    311 {
     424static errno_t vol_part_find_by_id_ref_locked(service_id_t sid,
     425    vol_part_t **rpart)
     426{
     427        assert(fibril_mutex_is_locked(&vol_parts_lock));
     428
    312429        list_foreach(vol_parts, lparts, vol_part_t, part) {
    313430                if (part->svc_id == sid) {
     431                        /* Add reference */
     432                        atomic_inc(&part->refcnt);
    314433                        *rpart = part;
    315                         /* XXX Add reference */
    316434                        return EOK;
    317435                }
     
    319437
    320438        return ENOENT;
     439}
     440
     441errno_t vol_part_find_by_id_ref(service_id_t sid, vol_part_t **rpart)
     442{
     443        errno_t rc;
     444
     445        fibril_mutex_lock(&vol_parts_lock);
     446        rc = vol_part_find_by_id_ref_locked(sid, rpart);
     447        fibril_mutex_unlock(&vol_parts_lock);
     448
     449        return rc;
     450}
     451
     452void vol_part_del_ref(vol_part_t *part)
     453{
     454        if (atomic_predec(&part->refcnt) == 0)
     455                vol_part_delete(part);
     456}
     457
     458errno_t vol_part_eject_part(vol_part_t *part)
     459{
     460        int rc;
     461
     462        log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_part()");
     463
     464        if (part->cur_mp == NULL) {
     465                log_msg(LOG_DEFAULT, LVL_DEBUG, "Attempt to mount unmounted "
     466                    "partition.");
     467                return EINVAL;
     468        }
     469
     470        rc = vfs_unmount_path(part->cur_mp);
     471        if (rc != EOK) {
     472                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed unmounting partition "
     473                    "from %s", part->cur_mp);
     474                return rc;
     475        }
     476
     477        if (part->cur_mp_auto) {
     478                rc = vfs_unlink_path(part->cur_mp);
     479                if (rc != EOK) {
     480                        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed deleting "
     481                            "mount directory %s.", part->cur_mp);
     482                }
     483        }
     484
     485        free(part->cur_mp);
     486        part->cur_mp = NULL;
     487        part->cur_mp_auto = false;
     488
     489        return EOK;
    321490}
    322491
     
    366535        }
    367536
     537        rc = vol_part_mount(part);
     538        if (rc != EOK) {
     539                fibril_mutex_unlock(&vol_parts_lock);
     540                return rc;
     541        }
     542
    368543        fibril_mutex_unlock(&vol_parts_lock);
    369544        return EOK;
     
    372547errno_t vol_part_get_info(vol_part_t *part, vol_part_info_t *pinfo)
    373548{
     549        memset(pinfo, 0, sizeof(*pinfo));
     550
    374551        pinfo->pcnt = part->pcnt;
    375552        pinfo->fstype = part->fstype;
    376553        str_cpy(pinfo->label, sizeof(pinfo->label), part->label);
     554        if (part->cur_mp != NULL)
     555                str_cpy(pinfo->cur_mp, sizeof(pinfo->cur_mp), part->cur_mp);
     556        pinfo->cur_mp_auto = part->cur_mp_auto;
    377557        return EOK;
    378558}
  • uspace/srv/volsrv/part.h

    r1e472ee rd3b2ffa  
    4747extern errno_t vol_part_add(service_id_t);
    4848extern errno_t vol_part_get_ids(service_id_t *, size_t, size_t *);
    49 extern errno_t vol_part_find_by_id(service_id_t, vol_part_t **);
     49extern errno_t vol_part_find_by_id_ref(service_id_t, vol_part_t **);
     50extern void vol_part_del_ref(vol_part_t *);
     51extern errno_t vol_part_eject_part(vol_part_t *);
    5052extern errno_t vol_part_empty_part(vol_part_t *);
    5153extern errno_t vol_part_mkfs_part(vol_part_t *, vol_fstype_t, const char *);
  • uspace/srv/volsrv/types/part.h

    r1e472ee rd3b2ffa  
    3939
    4040#include <adt/list.h>
     41#include <atomic.h>
     42#include <stdbool.h>
    4143#include <types/label.h>
    4244
     
    4547        /** Link to vol_parts */
    4648        link_t lparts;
     49        /** Reference count */
     50        atomic_t refcnt;
    4751        /** Service ID */
    4852        service_id_t svc_id;
     
    5559        /** Volume label */
    5660        char *label;
     61        /** Where volume is currently mounted */
     62        char *cur_mp;
     63        /** Mounted at automatic mount point */
     64        bool cur_mp_auto;
    5765} vol_part_t;
    5866
  • uspace/srv/volsrv/volsrv.c

    r1e472ee rd3b2ffa  
    144144        log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_info_srv(%zu)",
    145145            sid);
    146         rc = vol_part_find_by_id(sid, &part);
     146        rc = vol_part_find_by_id_ref(sid, &part);
    147147        if (rc != EOK) {
    148148                async_answer_0(icall_handle, ENOENT);
     
    153153        if (rc != EOK) {
    154154                async_answer_0(icall_handle, EIO);
    155                 return;
     155                goto error;
    156156        }
    157157
     
    161161                async_answer_0(chandle, EREFUSED);
    162162                async_answer_0(icall_handle, EREFUSED);
    163                 return;
     163                goto error;
    164164        }
    165165
     
    167167                async_answer_0(chandle, EINVAL);
    168168                async_answer_0(icall_handle, EINVAL);
    169                 return;
     169                goto error;
    170170        }
    171171
     
    175175                async_answer_0(chandle, rc);
    176176                async_answer_0(icall_handle, rc);
    177                 return;
    178         }
    179 
    180         async_answer_0(icall_handle, EOK);
     177                goto error;
     178        }
     179
     180        async_answer_0(icall_handle, EOK);
     181error:
     182        vol_part_del_ref(part);
     183}
     184
     185static void vol_part_eject_srv(cap_call_handle_t icall_handle, ipc_call_t *icall)
     186{
     187        service_id_t sid;
     188        vol_part_t *part;
     189        errno_t rc;
     190
     191        sid = IPC_GET_ARG1(*icall);
     192        log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu)", sid);
     193
     194        rc = vol_part_find_by_id_ref(sid, &part);
     195        if (rc != EOK) {
     196                async_answer_0(icall_handle, ENOENT);
     197                goto error;
     198        }
     199
     200        rc = vol_part_eject_part(part);
     201        if (rc != EOK) {
     202                async_answer_0(icall_handle, EIO);
     203                goto error;
     204        }
     205
     206        async_answer_0(icall_handle, EOK);
     207error:
     208        vol_part_del_ref(part);
    181209}
    182210
     
    190218        log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_empty_srv(%zu)", sid);
    191219
    192         rc = vol_part_find_by_id(sid, &part);
     220        rc = vol_part_find_by_id_ref(sid, &part);
    193221        if (rc != EOK) {
    194222                async_answer_0(icall_handle, ENOENT);
     
    199227        if (rc != EOK) {
    200228                async_answer_0(icall_handle, EIO);
    201                 return;
    202         }
    203 
    204         async_answer_0(icall_handle, EOK);
     229                goto error;
     230        }
     231
     232        async_answer_0(icall_handle, EOK);
     233error:
     234        vol_part_del_ref(part);
    205235}
    206236
     
    251281        errno_t rc;
    252282
     283        log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv()");
     284
    253285        sid = IPC_GET_ARG1(*icall);
    254286        fstype = IPC_GET_ARG2(*icall);
     
    261293        }
    262294
    263         printf("vol_part_mkfs_srv: label=%p\n", label);
    264         if (label != NULL)
    265                 printf("vol_part_mkfs_srv: label='%s'\n", label);
    266 
    267         rc = vol_part_find_by_id(sid, &part);
     295        if (label != NULL) {
     296                log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv: label='%s'",
     297                    label);
     298        }
     299
     300        rc = vol_part_find_by_id_ref(sid, &part);
    268301        if (rc != EOK) {
    269302                free(label);
     
    276309                free(label);
    277310                async_answer_0(icall_handle, rc);
     311                vol_part_del_ref(part);
    278312                return;
    279313        }
     
    311345                        vol_part_info_srv(chandle, &call);
    312346                        break;
     347                case VOL_PART_EJECT:
     348                        vol_part_eject_srv(chandle, &call);
     349                        break;
    313350                case VOL_PART_EMPTY:
    314351                        vol_part_empty_srv(chandle, &call);
Note: See TracChangeset for help on using the changeset viewer.