tmpfs_dump.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Jakub Jermar 
00003  * Copyright (c) 2008 Martin Decky 
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * - Redistributions of source code must retain the above copyright
00011  *   notice, this list of conditions and the following disclaimer.
00012  * - Redistributions in binary form must reproduce the above copyright
00013  *   notice, this list of conditions and the following disclaimer in the
00014  *   documentation and/or other materials provided with the distribution.
00015  * - The name of the author may not be used to endorse or promote products
00016  *   derived from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00019  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00020  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00021  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00023  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00024  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00025  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00027  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00039 #include "tmpfs.h"
00040 #include "../../vfs/vfs.h"
00041 #include <errno.h>
00042 #include <stdlib.h>
00043 #include <str.h>
00044 #include <sys/types.h>
00045 #include <as.h>
00046 #include <libblock.h>
00047 #include <byteorder.h>
00048 
00049 #define TMPFS_COMM_SIZE         1024
00050 
00051 struct rdentry {
00052         uint8_t type;
00053         uint32_t len;
00054 } __attribute__((packed));
00055 
00056 static bool
00057 tmpfs_restore_recursion(devmap_handle_t dev, size_t *bufpos, size_t *buflen,
00058     aoff64_t *pos, fs_node_t *pfn)
00059 {
00060         struct rdentry entry;
00061         libfs_ops_t *ops = &tmpfs_libfs_ops;
00062         int rc;
00063         
00064         do {
00065                 char *fname;
00066                 fs_node_t *fn;
00067                 tmpfs_node_t *nodep;
00068                 uint32_t size;
00069                 
00070                 if (block_seqread(dev, bufpos, buflen, pos, &entry,
00071                     sizeof(entry)) != EOK)
00072                         return false;
00073                 
00074                 entry.len = uint32_t_le2host(entry.len);
00075                 
00076                 switch (entry.type) {
00077                 case TMPFS_NONE:
00078                         break;
00079                 case TMPFS_FILE:
00080                         fname = malloc(entry.len + 1);
00081                         if (fname == NULL)
00082                                 return false;
00083                         
00084                         rc = ops->create(&fn, dev, L_FILE);
00085                         if (rc != EOK || fn == NULL) {
00086                                 free(fname);
00087                                 return false;
00088                         }
00089                         
00090                         if (block_seqread(dev, bufpos, buflen, pos, fname,
00091                             entry.len) != EOK) {
00092                                 (void) ops->destroy(fn);
00093                                 free(fname);
00094                                 return false;
00095                         }
00096                         fname[entry.len] = 0;
00097                         
00098                         rc = ops->link(pfn, fn, fname);
00099                         if (rc != EOK) {
00100                                 (void) ops->destroy(fn);
00101                                 free(fname);
00102                                 return false;
00103                         }
00104                         free(fname);
00105                         
00106                         if (block_seqread(dev, bufpos, buflen, pos, &size,
00107                             sizeof(size)) != EOK)
00108                                 return false;
00109                         
00110                         size = uint32_t_le2host(size);
00111                         
00112                         nodep = TMPFS_NODE(fn);
00113                         nodep->data = malloc(size);
00114                         if (nodep->data == NULL)
00115                                 return false;
00116                         
00117                         nodep->size = size;
00118                         if (block_seqread(dev, bufpos, buflen, pos, nodep->data,
00119                             size) != EOK)
00120                                 return false;
00121                         
00122                         break;
00123                 case TMPFS_DIRECTORY:
00124                         fname = malloc(entry.len + 1);
00125                         if (fname == NULL)
00126                                 return false;
00127                         
00128                         rc = ops->create(&fn, dev, L_DIRECTORY);
00129                         if (rc != EOK || fn == NULL) {
00130                                 free(fname);
00131                                 return false;
00132                         }
00133                         
00134                         if (block_seqread(dev, bufpos, buflen, pos, fname,
00135                             entry.len) != EOK) {
00136                                 (void) ops->destroy(fn);
00137                                 free(fname);
00138                                 return false;
00139                         }
00140                         fname[entry.len] = 0;
00141 
00142                         rc = ops->link(pfn, fn, fname);
00143                         if (rc != EOK) {
00144                                 (void) ops->destroy(fn);
00145                                 free(fname);
00146                                 return false;
00147                         }
00148                         free(fname);
00149                         
00150                         if (!tmpfs_restore_recursion(dev, bufpos, buflen, pos,
00151                             fn))
00152                                 return false;
00153                         
00154                         break;
00155                 default:
00156                         return false;
00157                 }
00158         } while (entry.type != TMPFS_NONE);
00159         
00160         return true;
00161 }
00162 
00163 bool tmpfs_restore(devmap_handle_t dev)
00164 {
00165         libfs_ops_t *ops = &tmpfs_libfs_ops;
00166         fs_node_t *fn;
00167         int rc;
00168 
00169         rc = block_init(dev, TMPFS_COMM_SIZE);
00170         if (rc != EOK)
00171                 return false; 
00172         
00173         size_t bufpos = 0;
00174         size_t buflen = 0;
00175         aoff64_t pos = 0;
00176         
00177         char tag[6];
00178         if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5) != EOK)
00179                 goto error;
00180         
00181         tag[5] = 0;
00182         if (str_cmp(tag, "TMPFS") != 0)
00183                 goto error;
00184         
00185         rc = ops->root_get(&fn, dev);
00186         if (rc != EOK)
00187                 goto error;
00188 
00189         if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos, fn))
00190                 goto error;
00191                 
00192         block_fini(dev);
00193         return true;
00194         
00195 error:
00196         block_fini(dev);
00197         return false;
00198 }
00199 

Generated on Thu Jun 2 07:45:49 2011 for HelenOS/USB by  doxygen 1.4.7