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


Ignore:
Timestamp:
2011-08-24T20:10:43Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
eb660787
Parents:
7fadb65 (diff), 842a2d2 (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 from lp:~romanenko-oleg/helenos/fat.

File:
1 edited

Legend:

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

    r7fadb65 r375ab5e  
    11/*
    22 * Copyright (c) 2008 Jakub Jermar
     3 * Copyright (c) 2011 Oleg Romanenko
    34 * All rights reserved.
    45 *
     
    2930/** @addtogroup fs
    3031 * @{
    31  */ 
     32 */
    3233
    3334/**
     
    3940#include "fat_dentry.h"
    4041#include "fat_fat.h"
     42#include "fat_directory.h"
    4143#include "../../vfs/vfs.h"
    4244#include <libfs.h>
     
    5658#include <align.h>
    5759#include <malloc.h>
     60#include <str.h>
    5861
    5962#define FAT_NODE(node)  ((node) ? (fat_node_t *) (node)->data : NULL)
     
    104107        node->dirty = false;
    105108        node->lastc_cached_valid = false;
    106         node->lastc_cached_value = FAT_CLST_LAST1;
     109        node->lastc_cached_value = 0;
    107110        node->currc_cached_valid = false;
    108111        node->currc_cached_bn = 0;
    109         node->currc_cached_value = FAT_CLST_LAST1;
     112        node->currc_cached_value = 0;
    110113}
    111114
     
    116119        fat_dentry_t *d;
    117120        int rc;
    118        
     121
    119122        assert(node->dirty);
    120123
    121124        bs = block_bb_get(node->idx->service_id);
    122        
     125
    123126        /* Read the block that contains the dentry of interest. */
    124127        rc = _fat_block_get(&b, bs, node->idx->service_id, node->idx->pfc,
     
    136139                d->attr = FAT_ATTR_SUBDIR;
    137140        }
    138        
     141
    139142        /* TODO: update other fields? (e.g time fields) */
    140        
     143
    141144        b->dirty = true;                /* need to sync block */
    142145        rc = block_put(b);
     
    255258        fn->data = nodep;
    256259        nodep->bp = fn;
    257        
     260
    258261        *nodepp = nodep;
    259262        return EOK;
     
    291294         * We must instantiate the node from the file system.
    292295         */
    293        
     296
    294297        assert(idxp->pfc);
    295298
     
    309312
    310313        d = ((fat_dentry_t *)b->data) + (idxp->pdi % DPS(bs));
     314        if (FAT_IS_FAT32(bs)) {
     315                nodep->firstc = uint16_t_le2host(d->firstc_lo) |
     316                    (uint16_t_le2host(d->firstc_hi) << 16);
     317        }
     318        else
     319                nodep->firstc = uint16_t_le2host(d->firstc);
     320
    311321        if (d->attr & FAT_ATTR_SUBDIR) {
    312                 /* 
     322                /*
    313323                 * The only directory which does not have this bit set is the
    314324                 * root directory itself. The root directory node is handled
     
    316326                 */
    317327                nodep->type = FAT_DIRECTORY;
     328
    318329                /*
    319330                 * Unfortunately, the 'size' field of the FAT dentry is not
     
    321332                 * size of the directory by walking the FAT.
    322333                 */
    323                 uint16_t clusters;
    324                 rc = fat_clusters_get(&clusters, bs, idxp->service_id,
    325                     uint16_t_le2host(d->firstc));
     334                uint32_t clusters;
     335                rc = fat_clusters_get(&clusters, bs, idxp->service_id, nodep->firstc);
    326336                if (rc != EOK) {
    327337                        (void) block_put(b);
     
    334344                nodep->size = uint32_t_le2host(d->size);
    335345        }
    336         nodep->firstc = uint16_t_le2host(d->firstc);
     346
    337347        nodep->lnkcnt = 1;
    338348        nodep->refcnt = 1;
     
    363373int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    364374{
    365         fat_bs_t *bs;
    366375        fat_node_t *parentp = FAT_NODE(pfn);
    367         char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
    368         unsigned i, j;
    369         unsigned blocks;
     376        char name[FAT_LFN_NAME_SIZE];
    370377        fat_dentry_t *d;
    371378        service_id_t service_id;
    372         block_t *b;
    373379        int rc;
    374380
     
    376382        service_id = parentp->idx->service_id;
    377383        fibril_mutex_unlock(&parentp->idx->lock);
    378 
    379         bs = block_bb_get(service_id);
    380         blocks = parentp->size / BPS(bs);
    381         for (i = 0; i < blocks; i++) {
    382                 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
    383                 if (rc != EOK)
    384                         return rc;
    385                 for (j = 0; j < DPS(bs); j++) {
    386                         d = ((fat_dentry_t *)b->data) + j;
    387                         switch (fat_classify_dentry(d)) {
    388                         case FAT_DENTRY_SKIP:
    389                         case FAT_DENTRY_FREE:
    390                                 continue;
    391                         case FAT_DENTRY_LAST:
    392                                 /* miss */
    393                                 rc = block_put(b);
    394                                 *rfn = NULL;
    395                                 return rc;
    396                         default:
    397                         case FAT_DENTRY_VALID:
    398                                 fat_dentry_name_get(d, name);
    399                                 break;
     384       
     385        fat_directory_t di;
     386        rc = fat_directory_open(parentp, &di);
     387        if (rc != EOK)
     388                return rc;
     389
     390        while (fat_directory_read(&di, name, &d) == EOK) {
     391                if (fat_dentry_namecmp(name, component) == 0) {
     392                        /* hit */
     393                        fat_node_t *nodep;
     394                        aoff64_t o = di.pos % (BPS(di.bs) / sizeof(fat_dentry_t));
     395                        fat_idx_t *idx = fat_idx_get_by_pos(service_id,
     396                                parentp->firstc, di.bnum * DPS(di.bs) + o);
     397                        if (!idx) {
     398                                /*
     399                                 * Can happen if memory is low or if we
     400                                 * run out of 32-bit indices.
     401                                 */
     402                                rc = fat_directory_close(&di);
     403                                return (rc == EOK) ? ENOMEM : rc;
    400404                        }
    401                         if (fat_dentry_namecmp(name, component) == 0) {
    402                                 /* hit */
    403                                 fat_node_t *nodep;
    404                                 fat_idx_t *idx = fat_idx_get_by_pos(service_id,
    405                                     parentp->firstc, i * DPS(bs) + j);
    406                                 if (!idx) {
    407                                         /*
    408                                          * Can happen if memory is low or if we
    409                                          * run out of 32-bit indices.
    410                                          */
    411                                         rc = block_put(b);
    412                                         return (rc == EOK) ? ENOMEM : rc;
    413                                 }
    414                                 rc = fat_node_get_core(&nodep, idx);
    415                                 fibril_mutex_unlock(&idx->lock);
    416                                 if (rc != EOK) {
    417                                         (void) block_put(b);
    418                                         return rc;
    419                                 }
    420                                 *rfn = FS_NODE(nodep);
    421                                 rc = block_put(b);
    422                                 if (rc != EOK)
    423                                         (void) fat_node_put(*rfn);
     405                        rc = fat_node_get_core(&nodep, idx);
     406                        fibril_mutex_unlock(&idx->lock);
     407                        if (rc != EOK) {
     408                                (void) fat_directory_close(&di);
    424409                                return rc;
    425410                        }
    426                 }
    427                 rc = block_put(b);
    428                 if (rc != EOK)
     411                        *rfn = FS_NODE(nodep);
     412                        rc = fat_directory_close(&di);
     413                        if (rc != EOK)
     414                                (void) fat_node_put(*rfn);
    429415                        return rc;
    430         }
    431 
     416                } else {
     417                        rc = fat_directory_next(&di);
     418                        if (rc != EOK)
     419                                break;
     420                }
     421        }
     422        (void) fat_directory_close(&di);
    432423        *rfn = NULL;
    433424        return EOK;
     
    591582        fat_bs_t *bs;
    592583        block_t *b;
    593         unsigned i, j;
    594         unsigned blocks;
    595         fat_cluster_t mcl, lcl;
     584        fat_directory_t di;
     585        fat_dentry_t de;
    596586        int rc;
    597587
     
    607597        fibril_mutex_unlock(&childp->lock);
    608598
    609         if (!fat_dentry_name_verify(name)) {
    610                 /*
    611                  * Attempt to create unsupported name.
    612                  */
     599        if (!fat_valid_name(name))
    613600                return ENOTSUP;
    614         }
    615 
    616         /*
    617          * Get us an unused parent node's dentry or grow the parent and allocate
    618          * a new one.
    619          */
    620        
     601
    621602        fibril_mutex_lock(&parentp->idx->lock);
    622603        bs = block_bb_get(parentp->idx->service_id);
    623 
    624         blocks = parentp->size / BPS(bs);
    625 
    626         for (i = 0; i < blocks; i++) {
    627                 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
    628                 if (rc != EOK) {
    629                         fibril_mutex_unlock(&parentp->idx->lock);
    630                         return rc;
    631                 }
    632                 for (j = 0; j < DPS(bs); j++) {
    633                         d = ((fat_dentry_t *)b->data) + j;
    634                         switch (fat_classify_dentry(d)) {
    635                         case FAT_DENTRY_SKIP:
    636                         case FAT_DENTRY_VALID:
    637                                 /* skipping used and meta entries */
    638                                 continue;
    639                         case FAT_DENTRY_FREE:
    640                         case FAT_DENTRY_LAST:
    641                                 /* found an empty slot */
    642                                 goto hit;
    643                         }
    644                 }
    645                 rc = block_put(b);
    646                 if (rc != EOK) {
    647                         fibril_mutex_unlock(&parentp->idx->lock);
    648                         return rc;
    649                 }
    650         }
    651         j = 0;
    652        
    653         /*
    654          * We need to grow the parent in order to create a new unused dentry.
    655          */
    656         if (parentp->firstc == FAT_CLST_ROOT) {
    657                 /* Can't grow the root directory. */
    658                 fibril_mutex_unlock(&parentp->idx->lock);
    659                 return ENOSPC;
    660         }
    661         rc = fat_alloc_clusters(bs, parentp->idx->service_id, 1, &mcl, &lcl);
    662         if (rc != EOK) {
    663                 fibril_mutex_unlock(&parentp->idx->lock);
    664                 return rc;
    665         }
    666         rc = fat_zero_cluster(bs, parentp->idx->service_id, mcl);
    667         if (rc != EOK) {
    668                 (void) fat_free_clusters(bs, parentp->idx->service_id, mcl);
    669                 fibril_mutex_unlock(&parentp->idx->lock);
    670                 return rc;
    671         }
    672         rc = fat_append_clusters(bs, parentp, mcl, lcl);
    673         if (rc != EOK) {
    674                 (void) fat_free_clusters(bs, parentp->idx->service_id, mcl);
    675                 fibril_mutex_unlock(&parentp->idx->lock);
    676                 return rc;
    677         }
    678         parentp->size += BPS(bs) * SPC(bs);
    679         parentp->dirty = true;          /* need to sync node */
    680         rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
    681         if (rc != EOK) {
    682                 fibril_mutex_unlock(&parentp->idx->lock);
    683                 return rc;
    684         }
    685         d = (fat_dentry_t *)b->data;
    686 
    687 hit:
     604        rc = fat_directory_open(parentp, &di);
     605        if (rc != EOK)
     606                return rc;
     607
    688608        /*
    689609         * At this point we only establish the link between the parent and the
     
    692612         * dentry data is kept in the child node structure.
    693613         */
    694         memset(d, 0, sizeof(fat_dentry_t));
    695         fat_dentry_name_set(d, name);
    696         b->dirty = true;                /* need to sync block */
    697         rc = block_put(b);
     614        memset(&de, 0, sizeof(fat_dentry_t));
     615
     616        rc = fat_directory_write(&di, name, &de);
     617        if (rc!=EOK)
     618                return rc;
     619        rc = fat_directory_close(&di);
     620        if (rc!=EOK)
     621                return rc;
     622
    698623        fibril_mutex_unlock(&parentp->idx->lock);
    699         if (rc != EOK) 
     624        if (rc != EOK)
    700625                return rc;
    701626
    702627        fibril_mutex_lock(&childp->idx->lock);
    703        
     628
    704629        if (childp->type == FAT_DIRECTORY) {
    705630                /*
     
    720645                d = (fat_dentry_t *) b->data;
    721646                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    722                     (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
     647                    (bcmp(d->name, FAT_NAME_DOT, FAT_NAME_LEN)) == 0) {
    723648                        memset(d, 0, sizeof(fat_dentry_t));
    724649                        memcpy(d->name, FAT_NAME_DOT, FAT_NAME_LEN);
     
    730655                d++;
    731656                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    732                     (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
     657                    (bcmp(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN) == 0)) {
    733658                        memset(d, 0, sizeof(fat_dentry_t));
    734659                        memcpy(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN);
    735660                        memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
    736661                        d->attr = FAT_ATTR_SUBDIR;
    737                         d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
    738                             host2uint16_t_le(FAT_CLST_RES0) :
     662                        d->firstc = (parentp->firstc == FAT_ROOT_CLST(bs)) ?
     663                            host2uint16_t_le(FAT_CLST_ROOTPAR) :
    739664                            host2uint16_t_le(parentp->firstc);
    740665                        /* TODO: initialize also the date/time members. */
     
    750675
    751676        childp->idx->pfc = parentp->firstc;
    752         childp->idx->pdi = i * DPS(bs) + j;
     677        childp->idx->pdi = di.pos;      /* di.pos holds absolute position of SFN entry */
    753678        fibril_mutex_unlock(&childp->idx->lock);
    754679
     
    770695        fat_node_t *parentp = FAT_NODE(pfn);
    771696        fat_node_t *childp = FAT_NODE(cfn);
    772         fat_bs_t *bs;
    773         fat_dentry_t *d;
    774         block_t *b;
    775697        bool has_children;
    776698        int rc;
     
    778700        if (!parentp)
    779701                return EBUSY;
    780        
     702
    781703        rc = fat_has_children(&has_children, cfn);
    782704        if (rc != EOK)
     
    789711        assert(childp->lnkcnt == 1);
    790712        fibril_mutex_lock(&childp->idx->lock);
    791         bs = block_bb_get(childp->idx->service_id);
    792 
    793         rc = _fat_block_get(&b, bs, childp->idx->service_id, childp->idx->pfc,
    794             NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    795             BLOCK_FLAGS_NONE);
    796         if (rc != EOK)
     713       
     714        fat_directory_t di;
     715        rc = fat_directory_open(parentp,&di);
     716        if (rc != EOK)
    797717                goto error;
    798         d = (fat_dentry_t *)b->data +
    799             (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
    800         /* mark the dentry as not-currently-used */
    801         d->name[0] = FAT_DENTRY_ERASED;
    802         b->dirty = true;                /* need to sync block */
    803         rc = block_put(b);
     718        rc = fat_directory_seek(&di, childp->idx->pdi);
     719        if (rc != EOK)
     720                goto error;
     721        rc = fat_directory_erase(&di);
     722        if (rc != EOK)
     723                goto error;
     724        rc = fat_directory_close(&di);
    804725        if (rc != EOK)
    805726                goto error;
     
    820741
    821742error:
    822         fibril_mutex_unlock(&parentp->idx->lock);
     743        (void) fat_directory_close(&di);
     744        fibril_mutex_unlock(&childp->idx->lock);
    823745        fibril_mutex_unlock(&childp->lock);
    824         fibril_mutex_unlock(&childp->idx->lock);
     746        fibril_mutex_unlock(&parentp->lock);
    825747        return rc;
    826748}
     
    839761                return EOK;
    840762        }
    841        
     763
    842764        fibril_mutex_lock(&nodep->idx->lock);
    843765        bs = block_bb_get(nodep->idx->service_id);
     
    847769        for (i = 0; i < blocks; i++) {
    848770                fat_dentry_t *d;
    849        
     771
    850772                rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE);
    851773                if (rc != EOK) {
     
    875797                if (rc != EOK) {
    876798                        fibril_mutex_unlock(&nodep->idx->lock);
    877                         return rc;     
     799                        return rc;
    878800                }
    879801        }
     
    946868        fat_bs_t *bs;
    947869        int rc;
    948        
     870
    949871        /* Check for option enabling write through. */
    950872        if (str_cmp(opts, "wtcache") == 0)
     
    1003925                return ENOMEM;
    1004926        }
     927
    1005928        fs_node_initialize(rfn);
    1006929        fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
     
    1027950
    1028951        rootp->type = FAT_DIRECTORY;
    1029         rootp->firstc = FAT_CLST_ROOT;
     952        rootp->firstc = FAT_ROOT_CLST(bs);
    1030953        rootp->refcnt = 1;
    1031954        rootp->lnkcnt = 0;      /* FS root is not linked */
    1032         rootp->size = RDE(bs) * sizeof(fat_dentry_t);
     955
     956        if (FAT_IS_FAT32(bs)) {
     957                uint32_t clusters;
     958                rc = fat_clusters_get(&clusters, bs, service_id, rootp->firstc);
     959                if (rc != EOK) {
     960                        free(rfn);
     961                        free(rootp);
     962                        (void) block_cache_fini(service_id);
     963                        block_fini(service_id);
     964                        fat_idx_fini_by_service_id(service_id);
     965                        return ENOTSUP;
     966                }
     967                rootp->size = BPS(bs) * SPC(bs) * clusters;
     968        } else
     969                rootp->size = RDE(bs) * sizeof(fat_dentry_t);
     970
    1033971        rootp->idx = ridxp;
    1034972        ridxp->nodep = rootp;
    1035973        rootp->bp = rfn;
    1036974        rfn->data = rootp;
    1037        
     975
    1038976        fibril_mutex_unlock(&ridxp->lock);
    1039977
     
    10641002                return EBUSY;
    10651003        }
    1066        
     1004
    10671005        /*
    10681006         * Put the root node and force it to the FAT free node list.
     
    11411079                }
    11421080        } else {
    1143                 unsigned bnum;
    11441081                aoff64_t spos = pos;
    1145                 char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
     1082                char name[FAT_LFN_NAME_SIZE];
    11461083                fat_dentry_t *d;
    11471084
     
    11501087                assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
    11511088
    1152                 /*
    1153                  * Our strategy for readdir() is to use the position pointer as
    1154                  * an index into the array of all dentries. On entry, it points
    1155                  * to the first unread dentry. If we skip any dentries, we bump
    1156                  * the position pointer accordingly.
    1157                  */
    1158                 bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
    1159                 while (bnum < nodep->size / BPS(bs)) {
    1160                         aoff64_t o;
    1161 
    1162                         rc = fat_block_get(&b, bs, nodep, bnum,
    1163                             BLOCK_FLAGS_NONE);
    1164                         if (rc != EOK)
    1165                                 goto err;
    1166                         for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
    1167                             o < BPS(bs) / sizeof(fat_dentry_t);
    1168                             o++, pos++) {
    1169                                 d = ((fat_dentry_t *)b->data) + o;
    1170                                 switch (fat_classify_dentry(d)) {
    1171                                 case FAT_DENTRY_SKIP:
    1172                                 case FAT_DENTRY_FREE:
    1173                                         continue;
    1174                                 case FAT_DENTRY_LAST:
    1175                                         rc = block_put(b);
    1176                                         if (rc != EOK)
    1177                                                 goto err;
    1178                                         goto miss;
    1179                                 default:
    1180                                 case FAT_DENTRY_VALID:
    1181                                         fat_dentry_name_get(d, name);
    1182                                         rc = block_put(b);
    1183                                         if (rc != EOK)
    1184                                                 goto err;
    1185                                         goto hit;
    1186                                 }
    1187                         }
    1188                         rc = block_put(b);
    1189                         if (rc != EOK)
    1190                                 goto err;
    1191                         bnum++;
    1192                 }
     1089                fat_directory_t di;
     1090                rc = fat_directory_open(nodep, &di);
     1091                if (rc != EOK) goto err;
     1092                rc = fat_directory_seek(&di, pos);
     1093                if (rc != EOK) {
     1094                        (void) fat_directory_close(&di);
     1095                        goto err;
     1096                }
     1097
     1098                rc = fat_directory_read(&di, name, &d);
     1099                if (rc == EOK) goto hit;
     1100                if (rc == ENOENT) goto miss;
     1101
     1102err:
     1103                (void) fat_node_put(fn);
     1104                async_answer_0(callid, rc);
     1105                return rc;
     1106
    11931107miss:
     1108                rc = fat_directory_close(&di);
     1109                if (rc!=EOK)
     1110                        goto err;
    11941111                rc = fat_node_put(fn);
    11951112                async_answer_0(callid, rc != EOK ? rc : ENOENT);
     
    11971114                return rc != EOK ? rc : ENOENT;
    11981115
    1199 err:
    1200                 (void) fat_node_put(fn);
    1201                 async_answer_0(callid, rc);
    1202                 return rc;
    1203 
    12041116hit:
     1117                pos = di.pos;
     1118                rc = fat_directory_close(&di);
     1119                if (rc!=EOK)
     1120                        goto err;
    12051121                (void) async_data_read_finalize(callid, name, str_size(name) + 1);
    1206                 bytes = (pos - spos) + 1;
     1122                bytes = (pos - spos)+1;
    12071123        }
    12081124
     
    12311147                return ENOENT;
    12321148        nodep = FAT_NODE(fn);
    1233        
     1149
    12341150        ipc_callid_t callid;
    12351151        size_t len;
     
    12471163         * but this one greatly simplifies fat_write(). Note that we can afford
    12481164         * to do this because the client must be ready to handle the return
    1249          * value signalizing a smaller number of bytes written. 
    1250          */ 
     1165         * value signalizing a smaller number of bytes written.
     1166         */
    12511167        bytes = min(len, BPS(bs) - pos % BPS(bs));
    12521168        if (bytes == BPS(bs))
    12531169                flags |= BLOCK_FLAGS_NOREAD;
    1254        
     1170
    12551171        boundary = ROUND_UP(nodep->size, BPC(bs));
    12561172        if (pos < boundary) {
     
    12951211                 */
    12961212                unsigned nclsts;
    1297                 fat_cluster_t mcl, lcl; 
    1298  
     1213                fat_cluster_t mcl, lcl;
     1214
    12991215                nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
    13001216                /* create an independent chain of nclsts clusters in all FATs */
     
    13801296                nodep->size = size;
    13811297                nodep->dirty = true;            /* need to sync node */
    1382                 rc = EOK;       
     1298                rc = EOK;
    13831299        } else {
    13841300                /*
     
    14011317                nodep->size = size;
    14021318                nodep->dirty = true;            /* need to sync node */
    1403                 rc = EOK;       
     1319                rc = EOK;
    14041320        }
    14051321out:
     
    14441360        if (!fn)
    14451361                return ENOENT;
    1446        
     1362
    14471363        fat_node_t *nodep = FAT_NODE(fn);
    1448        
     1364
    14491365        nodep->dirty = true;
    14501366        rc = fat_node_sync(nodep);
    1451        
     1367
    14521368        fat_node_put(fn);
    14531369        return rc;
Note: See TracChangeset for help on using the changeset viewer.