Ignore:
File:
1 edited

Legend:

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

    r5a6cc679 r1a9174e  
    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}
Note: See TracChangeset for help on using the changeset viewer.