Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 2e07f62c in mainline for uspace/srv/fs/fat/fat_ops.c


Ignore:
Timestamp:
2010-01-31T18:11:24Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
1735f3e, 7d6f7d2b
Parents:
ab4bace (diff), 430de97 (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 progress from the file system branch allowing FAT to be unmounted.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_ops.c

    rab4bace r2e07f62c  
    137137        rc = block_put(b);
    138138        return rc;
     139}
     140
     141static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle)
     142{
     143        link_t *lnk;
     144        fat_node_t *nodep;
     145        int rc;
     146
     147        /*
     148         * We are called from fat_unmounted() and assume that there are already
     149         * no nodes belonging to this instance with non-zero refcount. Therefore
     150         * it is sufficient to clean up only the FAT free node list.
     151         */
     152
     153restart:
     154        fibril_mutex_lock(&ffn_mutex);
     155        for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
     156                nodep = list_get_instance(lnk, fat_node_t, ffn_link);
     157                if (!fibril_mutex_trylock(&nodep->lock)) {
     158                        fibril_mutex_unlock(&ffn_mutex);
     159                        goto restart;
     160                }
     161                if (!fibril_mutex_trylock(&nodep->idx->lock)) {
     162                        fibril_mutex_unlock(&nodep->lock);
     163                        fibril_mutex_unlock(&ffn_mutex);
     164                        goto restart;
     165                }
     166                if (nodep->idx->dev_handle != dev_handle) {
     167                        fibril_mutex_unlock(&nodep->idx->lock);
     168                        fibril_mutex_unlock(&nodep->lock);
     169                        continue;
     170                }
     171
     172                list_remove(&nodep->ffn_link);
     173                fibril_mutex_unlock(&ffn_mutex);
     174
     175                /*
     176                 * We can unlock the node and its index structure because we are
     177                 * the last player on this playground and VFS is preventing new
     178                 * players from entering.
     179                 */
     180                fibril_mutex_unlock(&nodep->idx->lock);
     181                fibril_mutex_unlock(&nodep->lock);
     182
     183                if (nodep->dirty) {
     184                        rc = fat_node_sync(nodep);
     185                        if (rc != EOK)
     186                                return rc;
     187                }
     188                nodep->idx->nodep = NULL;
     189                free(nodep->bp);
     190                free(nodep);
     191
     192                /* Need to restart because we changed the ffn_head list. */
     193                goto restart;
     194        }
     195        fibril_mutex_unlock(&ffn_mutex);
     196
     197        return EOK;
    139198}
    140199
     
    9861045        rc = fat_sanity_check(bs, dev_handle);
    9871046        if (rc != EOK) {
     1047                (void) block_cache_fini(dev_handle);
    9881048                block_fini(dev_handle);
    9891049                ipc_answer_0(rid, rc);
     
    9931053        rc = fat_idx_init_by_dev_handle(dev_handle);
    9941054        if (rc != EOK) {
     1055                (void) block_cache_fini(dev_handle);
    9951056                block_fini(dev_handle);
    9961057                ipc_answer_0(rid, rc);
     
    10011062        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    10021063        if (!rfn) {
     1064                (void) block_cache_fini(dev_handle);
    10031065                block_fini(dev_handle);
    10041066                fat_idx_fini_by_dev_handle(dev_handle);
     
    10101072        if (!rootp) {
    10111073                free(rfn);
     1074                (void) block_cache_fini(dev_handle);
    10121075                block_fini(dev_handle);
    10131076                fat_idx_fini_by_dev_handle(dev_handle);
     
    10211084                free(rfn);
    10221085                free(rootp);
     1086                (void) block_cache_fini(dev_handle);
    10231087                block_fini(dev_handle);
    10241088                fat_idx_fini_by_dev_handle(dev_handle);
     
    10511115void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
    10521116{
    1053         ipc_answer_0(rid, ENOTSUP);
     1117        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1118        fs_node_t *fn;
     1119        fat_node_t *nodep;
     1120        int rc;
     1121
     1122        rc = fat_root_get(&fn, dev_handle);
     1123        if (rc != EOK) {
     1124                ipc_answer_0(rid, rc);
     1125                return;
     1126        }
     1127        nodep = FAT_NODE(fn);
     1128
     1129        /*
     1130         * We expect exactly two references on the root node. One for the
     1131         * fat_root_get() above and one created in fat_mounted().
     1132         */
     1133        if (nodep->refcnt != 2) {
     1134                (void) fat_node_put(fn);
     1135                ipc_answer_0(rid, EBUSY);
     1136                return;
     1137        }
     1138       
     1139        /*
     1140         * Put the root node and force it to the FAT free node list.
     1141         */
     1142        (void) fat_node_put(fn);
     1143        (void) fat_node_put(fn);
     1144
     1145        /*
     1146         * Perform cleanup of the node structures, index structures and
     1147         * associated data. Write back this file system's dirty blocks and
     1148         * stop using libblock for this instance.
     1149         */
     1150        (void) fat_node_fini_by_dev_handle(dev_handle);
     1151        fat_idx_fini_by_dev_handle(dev_handle);
     1152        (void) block_cache_fini(dev_handle);
     1153        block_fini(dev_handle);
     1154
     1155        ipc_answer_0(rid, EOK);
    10541156}
    10551157
Note: See TracChangeset for help on using the changeset viewer.