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


Ignore:
Timestamp:
2010-02-09T20:19:23Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fb150d78
Parents:
975e7e9 (diff), eb73a50 (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 mainline changes.

File:
1 edited

Legend:

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

    r975e7e9 re27cf669  
    139139}
    140140
     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;
     198}
     199
    141200static int fat_node_get_new(fat_node_t **nodepp)
    142201{
     
    290349
    291350        *nodepp = nodep;
    292         return EOK;
    293 }
    294 
    295 /** Perform basic sanity checks on the file system.
    296  *
    297  * Verify if values of boot sector fields are sane. Also verify media
    298  * descriptor. This is used to rule out cases when a device obviously
    299  * does not contain a fat file system.
    300  */
    301 static int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
    302 {
    303         fat_cluster_t e0, e1;
    304         unsigned fat_no;
    305         int rc;
    306 
    307         /* Check number of FATs. */
    308         if (bs->fatcnt == 0)
    309                 return ENOTSUP;
    310 
    311         /* Check total number of sectors. */
    312 
    313         if (bs->totsec16 == 0 && bs->totsec32 == 0)
    314                 return ENOTSUP;
    315 
    316         if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
    317             bs->totsec16 != bs->totsec32)
    318                 return ENOTSUP;
    319 
    320         /* Check media descriptor. Must be between 0xf0 and 0xff. */
    321         if ((bs->mdesc & 0xf0) != 0xf0)
    322                 return ENOTSUP;
    323 
    324         /* Check number of sectors per FAT. */
    325         if (bs->sec_per_fat == 0)
    326                 return ENOTSUP;
    327 
    328         /*
    329          * Check that the root directory entries take up whole blocks.
    330          * This check is rather strict, but it allows us to treat the root
    331          * directory and non-root directories uniformly in some places.
    332          * It can be removed provided that functions such as fat_read() are
    333          * sanitized to support file systems with this property.
    334          */
    335         if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
    336             uint16_t_le2host(bs->bps) != 0)
    337                 return ENOTSUP;
    338 
    339         /* Check signature of each FAT. */
    340 
    341         for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
    342                 rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
    343                 if (rc != EOK)
    344                         return EIO;
    345 
    346                 rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
    347                 if (rc != EOK)
    348                         return EIO;
    349 
    350                 /* Check that first byte of FAT contains the media descriptor. */
    351                 if ((e0 & 0xff) != bs->mdesc)
    352                         return ENOTSUP;
    353 
    354                 /*
    355                  * Check that remaining bits of the first two entries are
    356                  * set to one.
    357                  */
    358                 if ((e0 >> 8) != 0xff || e1 != 0xffff)
    359                         return ENOTSUP;
    360         }
    361 
    362351        return EOK;
    363352}
     
    985974        uint16_t bps;
    986975        uint16_t rde;
    987         int rc;
    988 
    989         /* accept the mount options */
    990         ipc_callid_t callid;
    991         size_t size;
    992         if (!async_data_write_receive(&callid, &size)) {
    993                 ipc_answer_0(callid, EINVAL);
    994                 ipc_answer_0(rid, EINVAL);
    995                 return;
    996         }
    997         char *opts = malloc(size + 1);
    998         if (!opts) {
    999                 ipc_answer_0(callid, ENOMEM);
    1000                 ipc_answer_0(rid, ENOMEM);
    1001                 return;
    1002         }
    1003         ipcarg_t retval = async_data_write_finalize(callid, opts, size);
    1004         if (retval != EOK) {
    1005                 ipc_answer_0(rid, retval);
    1006                 free(opts);
    1007                 return;
    1008         }
    1009         opts[size] = '\0';
     976       
     977        /* Accept the mount options */
     978        char *opts;
     979        int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     980       
     981        if (rc != EOK) {
     982                ipc_answer_0(rid, rc);
     983                return;
     984        }
    1010985
    1011986        /* Check for option enabling write through. */
     
    1015990                cmode = CACHE_MODE_WB;
    1016991
     992        free(opts);
     993
    1017994        /* initialize libblock */
    1018995        rc = block_init(dev_handle, BS_SIZE);
     
    10541031        rc = fat_sanity_check(bs, dev_handle);
    10551032        if (rc != EOK) {
     1033                (void) block_cache_fini(dev_handle);
    10561034                block_fini(dev_handle);
    10571035                ipc_answer_0(rid, rc);
     
    10611039        rc = fat_idx_init_by_dev_handle(dev_handle);
    10621040        if (rc != EOK) {
     1041                (void) block_cache_fini(dev_handle);
    10631042                block_fini(dev_handle);
    10641043                ipc_answer_0(rid, rc);
     
    10691048        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    10701049        if (!rfn) {
     1050                (void) block_cache_fini(dev_handle);
    10711051                block_fini(dev_handle);
    10721052                fat_idx_fini_by_dev_handle(dev_handle);
     
    10781058        if (!rootp) {
    10791059                free(rfn);
     1060                (void) block_cache_fini(dev_handle);
    10801061                block_fini(dev_handle);
    10811062                fat_idx_fini_by_dev_handle(dev_handle);
     
    10891070                free(rfn);
    10901071                free(rootp);
     1072                (void) block_cache_fini(dev_handle);
    10911073                block_fini(dev_handle);
    10921074                fat_idx_fini_by_dev_handle(dev_handle);
     
    11151097{
    11161098        libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
     1099}
     1100
     1101void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
     1102{
     1103        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1104        fs_node_t *fn;
     1105        fat_node_t *nodep;
     1106        int rc;
     1107
     1108        rc = fat_root_get(&fn, dev_handle);
     1109        if (rc != EOK) {
     1110                ipc_answer_0(rid, rc);
     1111                return;
     1112        }
     1113        nodep = FAT_NODE(fn);
     1114
     1115        /*
     1116         * We expect exactly two references on the root node. One for the
     1117         * fat_root_get() above and one created in fat_mounted().
     1118         */
     1119        if (nodep->refcnt != 2) {
     1120                (void) fat_node_put(fn);
     1121                ipc_answer_0(rid, EBUSY);
     1122                return;
     1123        }
     1124       
     1125        /*
     1126         * Put the root node and force it to the FAT free node list.
     1127         */
     1128        (void) fat_node_put(fn);
     1129        (void) fat_node_put(fn);
     1130
     1131        /*
     1132         * Perform cleanup of the node structures, index structures and
     1133         * associated data. Write back this file system's dirty blocks and
     1134         * stop using libblock for this instance.
     1135         */
     1136        (void) fat_node_fini_by_dev_handle(dev_handle);
     1137        fat_idx_fini_by_dev_handle(dev_handle);
     1138        (void) block_cache_fini(dev_handle);
     1139        block_fini(dev_handle);
     1140
     1141        ipc_answer_0(rid, EOK);
     1142}
     1143
     1144void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
     1145{
     1146        libfs_unmount(&fat_libfs_ops, rid, request);
    11171147}
    11181148
Note: See TracChangeset for help on using the changeset viewer.