Changeset 40257f5 in mainline for uspace/srv/fs/tmpfs/tmpfs_ops.c


Ignore:
Timestamp:
2008-06-05T22:49:54Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e32e092
Parents:
32443b0
Message:

Evict the code which loads the TMPFS file system from a file system dump to a
dedicated source file.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r32443b0 r40257f5  
    5151#include <as.h>
    5252#include <libfs.h>
    53 #include <ipc/services.h>
    54 #include <ipc/devmap.h>
    55 #include <sys/mman.h>
    56 #include <byteorder.h>
    5753
    5854#define min(a, b)               ((a) < (b) ? (a) : (b))
     
    6258
    6359#define NAMES_BUCKETS           4
    64 
    65 #define BLOCK_SIZE                      1024    // FIXME
    66 #define RD_BASE                         1024    // FIXME
    67 #define RD_READ_BLOCK   (RD_BASE + 1)
    6860
    6961/*
     
    149141hash_table_t dentries;
    150142
    151 struct rdentry {
    152         uint8_t type;
    153         uint32_t len;
    154 } __attribute__((packed));
    155 
    156143/* Implementation of hash table interface for the dentries hash table. */
    157144static hash_index_t dentries_hash(unsigned long *key)
     
    249236        root->lnkcnt = 1;
    250237        return true;
    251 }
    252 
    253 static bool tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen, size_t *pos, void *dst, size_t size)
    254 {
    255         size_t offset = 0;
    256         size_t left = size;
    257        
    258         while (left > 0) {
    259                 size_t rd;
    260                
    261                 if (*bufpos + left < *buflen)
    262                         rd = left;
    263                 else
    264                         rd = *buflen - *bufpos;
    265                
    266                 if (rd > 0) {
    267                         memcpy(dst + offset, buffer + *bufpos, rd);
    268                         offset += rd;
    269                         *bufpos += rd;
    270                         *pos += rd;
    271                         left -= rd;
    272                 }
    273                
    274                 if (*bufpos == *buflen) {
    275                         ipcarg_t retval;
    276                         int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK,
    277                             *pos / BLOCK_SIZE, BLOCK_SIZE,
    278                             &retval);
    279                         if ((rc != EOK) || (retval != EOK))
    280                                 return false;
    281                        
    282                         *bufpos = 0;
    283                         *buflen = BLOCK_SIZE;
    284                 }
    285         }
    286        
    287         return true;
    288 }
    289 
    290 static bool tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen, size_t *pos, tmpfs_dentry_t *parent)
    291 {
    292         struct rdentry entry;
    293        
    294         do {
    295                 char *fname;
    296                 tmpfs_dentry_t *node;
    297                 uint32_t size;
    298                
    299                 if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry, sizeof(entry)))
    300                         return false;
    301                
    302                 entry.len = uint32_t_le2host(entry.len);
    303                
    304                 switch (entry.type) {
    305                 case 0:
    306                         break;
    307                 case 1:
    308                         fname = malloc(entry.len + 1);
    309                         if (fname == NULL)
    310                                 return false;
    311                        
    312                         node = (tmpfs_dentry_t *) tmpfs_create_node(L_FILE);
    313                         if (node == NULL) {
    314                                 free(fname);
    315                                 return false;
    316                         }
    317                        
    318                         if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) {
    319                                 tmpfs_destroy_node((void *) node);
    320                                 free(fname);
    321                                 return false;
    322                         }
    323                         fname[entry.len] = 0;
    324                        
    325                         if (!tmpfs_link_node((void *) parent, (void *) node, fname)) {
    326                                 tmpfs_destroy_node((void *) node);
    327                                 free(fname);
    328                                 return false;
    329                         }
    330                         free(fname);
    331                        
    332                         if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &size, sizeof(size)))
    333                                 return false;
    334                        
    335                         size = uint32_t_le2host(size);
    336                        
    337                         node->data = malloc(size);
    338                         if (node->data == NULL)
    339                                 return false;
    340                        
    341                         node->size = size;
    342                         if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, node->data, size))
    343                                 return false;
    344                        
    345                         break;
    346                 case 2:
    347                         fname = malloc(entry.len + 1);
    348                         if (fname == NULL)
    349                                 return false;
    350                        
    351                         node = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
    352                         if (node == NULL) {
    353                                 free(fname);
    354                                 return false;
    355                         }
    356                        
    357                         if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) {
    358                                 tmpfs_destroy_node((void *) node);
    359                                 free(fname);
    360                                 return false;
    361                         }
    362                         fname[entry.len] = 0;
    363                        
    364                         if (!tmpfs_link_node((void *) parent, (void *) node, fname)) {
    365                                 tmpfs_destroy_node((void *) node);
    366                                 free(fname);
    367                                 return false;
    368                         }
    369                         free(fname);
    370                        
    371                         if (!tmpfs_restore_recursion(phone, block, bufpos, buflen, pos, node))
    372                                 return false;
    373                        
    374                         break;
    375                 default:
    376                         return false;
    377                 }
    378         } while (entry.type != 0);
    379        
    380         return true;
    381 }
    382 
    383 static bool tmpfs_restore(dev_handle_t dev)
    384 {
    385         void *block = mmap(NULL, BLOCK_SIZE,
    386             PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    387        
    388         if (block == NULL)
    389                 return false;
    390        
    391         int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, dev);
    392 
    393         if (phone < 0) {
    394                 munmap(block, BLOCK_SIZE);
    395                 return false;
    396         }
    397        
    398         if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) != EOK)
    399                 goto error;
    400        
    401         size_t bufpos = 0;
    402         size_t buflen = 0;
    403         size_t pos = 0;
    404        
    405         char tag[6];
    406         if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5))
    407                 goto error;
    408        
    409         tag[5] = 0;
    410         if (strcmp(tag, "TMPFS") != 0)
    411                 goto error;
    412        
    413         if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos, root))
    414                 goto error;
    415                
    416         ipc_hangup(phone);
    417         munmap(block, BLOCK_SIZE);
    418         return true;
    419        
    420 error:
    421         ipc_hangup(phone);
    422         munmap(block, BLOCK_SIZE);
    423         return false;
    424238}
    425239
Note: See TracChangeset for help on using the changeset viewer.