Subversion Repositories HelenOS

Rev

Rev 3424 | Rev 3536 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3424 Rev 3425
Line 37... Line 37...
37
 */
37
 */
38
 
38
 
39
#include "tmpfs.h"
39
#include "tmpfs.h"
40
#include "../../vfs/vfs.h"
40
#include "../../vfs/vfs.h"
41
#include <ipc/ipc.h>
41
#include <ipc/ipc.h>
-
 
42
#include <async.h>
42
#include <errno.h>
43
#include <errno.h>
43
#include <stdlib.h>
44
#include <stdlib.h>
44
#include <string.h>
45
#include <string.h>
45
#include <sys/types.h>
46
#include <sys/types.h>
46
#include <as.h>
47
#include <as.h>
Line 48... Line 49...
48
#include <ipc/services.h>
49
#include <ipc/services.h>
49
#include <ipc/devmap.h>
50
#include <ipc/devmap.h>
50
#include <sys/mman.h>
51
#include <sys/mman.h>
51
#include <byteorder.h>
52
#include <byteorder.h>
52
 
53
 
53
#define BLOCK_SIZE          1024    // FIXME
54
#define TMPFS_BLOCK_SIZE    1024
54
#define RD_BASE             1024    // FIXME
-
 
55
#define RD_READ_BLOCK   (RD_BASE + 1)
-
 
56
 
55
 
57
struct rdentry {
56
struct rdentry {
58
    uint8_t type;
57
    uint8_t type;
59
    uint32_t len;
58
    uint32_t len;
60
} __attribute__((packed));
59
} __attribute__((packed));
61
 
60
 
62
static bool
-
 
63
tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen,
-
 
64
    size_t *pos, void *dst, size_t size)
-
 
65
{
-
 
66
    size_t offset = 0;
-
 
67
    size_t left = size;
-
 
68
   
-
 
69
    while (left > 0) {
-
 
70
        size_t rd;
-
 
71
       
-
 
72
        if (*bufpos + left < *buflen)
-
 
73
            rd = left;
-
 
74
        else
-
 
75
            rd = *buflen - *bufpos;
-
 
76
       
-
 
77
        if (rd > 0) {
-
 
78
            memcpy(dst + offset, buffer + *bufpos, rd);
-
 
79
            offset += rd;
-
 
80
            *bufpos += rd;
-
 
81
            *pos += rd;
-
 
82
            left -= rd;
-
 
83
        }
-
 
84
       
-
 
85
        if (*bufpos == *buflen) {
-
 
86
            ipcarg_t retval;
-
 
87
            int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK,
-
 
88
                *pos / BLOCK_SIZE, BLOCK_SIZE,
-
 
89
                &retval);
-
 
90
            if ((rc != EOK) || (retval != EOK))
-
 
91
                return false;
-
 
92
           
-
 
93
            *bufpos = 0;
-
 
94
            *buflen = BLOCK_SIZE;
-
 
95
        }
-
 
96
    }
-
 
97
   
-
 
98
    return true;
-
 
99
}
-
 
100
 
-
 
101
static bool
61
static bool
102
tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen,
62
tmpfs_restore_recursion(int phone, void *block, off_t *bufpos, size_t *buflen,
103
    size_t *pos, tmpfs_dentry_t *parent)
63
    off_t *pos, tmpfs_dentry_t *parent)
104
{
64
{
105
    struct rdentry entry;
65
    struct rdentry entry;
106
    libfs_ops_t *ops = &tmpfs_libfs_ops;
66
    libfs_ops_t *ops = &tmpfs_libfs_ops;
107
   
67
   
108
    do {
68
    do {
109
        char *fname;
69
        char *fname;
110
        tmpfs_dentry_t *node;
70
        tmpfs_dentry_t *node;
111
        uint32_t size;
71
        uint32_t size;
112
       
72
       
113
        if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry,
73
        if (!libfs_blockread(phone, block, bufpos, buflen, pos, &entry,
114
            sizeof(entry)))
74
            sizeof(entry), TMPFS_BLOCK_SIZE))
115
            return false;
75
            return false;
116
       
76
       
117
        entry.len = uint32_t_le2host(entry.len);
77
        entry.len = uint32_t_le2host(entry.len);
118
       
78
       
119
        switch (entry.type) {
79
        switch (entry.type) {
120
        case 0:
80
        case TMPFS_NONE:
121
            break;
81
            break;
122
        case 1:
82
        case TMPFS_FILE:
123
            fname = malloc(entry.len + 1);
83
            fname = malloc(entry.len + 1);
124
            if (fname == NULL)
84
            if (fname == NULL)
125
                return false;
85
                return false;
126
           
86
           
127
            node = (tmpfs_dentry_t *) ops->create(L_FILE);
87
            node = (tmpfs_dentry_t *) ops->create(L_FILE);
128
            if (node == NULL) {
88
            if (node == NULL) {
129
                free(fname);
89
                free(fname);
130
                return false;
90
                return false;
131
            }
91
            }
132
           
92
           
133
            if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
93
            if (!libfs_blockread(phone, block, bufpos, buflen, pos,
134
                fname, entry.len)) {
94
                fname, entry.len, TMPFS_BLOCK_SIZE)) {
135
                ops->destroy((void *) node);
95
                ops->destroy((void *) node);
136
                free(fname);
96
                free(fname);
137
                return false;
97
                return false;
138
            }
98
            }
139
            fname[entry.len] = 0;
99
            fname[entry.len] = 0;
Line 143... Line 103...
143
                free(fname);
103
                free(fname);
144
                return false;
104
                return false;
145
            }
105
            }
146
            free(fname);
106
            free(fname);
147
           
107
           
148
            if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
108
            if (!libfs_blockread(phone, block, bufpos, buflen, pos,
149
                &size, sizeof(size)))
109
                &size, sizeof(size), TMPFS_BLOCK_SIZE))
150
                return false;
110
                return false;
151
           
111
           
152
            size = uint32_t_le2host(size);
112
            size = uint32_t_le2host(size);
153
           
113
           
154
            node->data = malloc(size);
114
            node->data = malloc(size);
155
            if (node->data == NULL)
115
            if (node->data == NULL)
156
                return false;
116
                return false;
157
           
117
           
158
            node->size = size;
118
            node->size = size;
159
            if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
119
            if (!libfs_blockread(phone, block, bufpos, buflen, pos,
160
                node->data, size))
120
                node->data, size, TMPFS_BLOCK_SIZE))
161
                return false;
121
                return false;
162
           
122
           
163
            break;
123
            break;
164
        case 2:
124
        case TMPFS_DIRECTORY:
165
            fname = malloc(entry.len + 1);
125
            fname = malloc(entry.len + 1);
166
            if (fname == NULL)
126
            if (fname == NULL)
167
                return false;
127
                return false;
168
           
128
           
169
            node = (tmpfs_dentry_t *) ops->create(L_DIRECTORY);
129
            node = (tmpfs_dentry_t *) ops->create(L_DIRECTORY);
170
            if (node == NULL) {
130
            if (node == NULL) {
171
                free(fname);
131
                free(fname);
172
                return false;
132
                return false;
173
            }
133
            }
174
           
134
           
175
            if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
135
            if (!libfs_blockread(phone, block, bufpos, buflen, pos,
176
                fname, entry.len)) {
136
                fname, entry.len, TMPFS_BLOCK_SIZE)) {
177
                ops->destroy((void *) node);
137
                ops->destroy((void *) node);
178
                free(fname);
138
                free(fname);
179
                return false;
139
                return false;
180
            }
140
            }
181
            fname[entry.len] = 0;
141
            fname[entry.len] = 0;
Line 193... Line 153...
193
           
153
           
194
            break;
154
            break;
195
        default:
155
        default:
196
            return false;
156
            return false;
197
        }
157
        }
198
    } while (entry.type != 0);
158
    } while (entry.type != TMPFS_NONE);
199
   
159
   
200
    return true;
160
    return true;
201
}
161
}
202
 
162
 
203
bool tmpfs_restore(dev_handle_t dev)
163
bool tmpfs_restore(dev_handle_t dev)
204
{
164
{
205
    libfs_ops_t *ops = &tmpfs_libfs_ops;
165
    libfs_ops_t *ops = &tmpfs_libfs_ops;
206
 
166
 
207
    void *block = mmap(NULL, BLOCK_SIZE,
167
    void *block = mmap(NULL, TMPFS_BLOCK_SIZE,
208
        PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
168
        PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
209
   
169
   
210
    if (block == NULL)
170
    if (block == NULL)
211
        return false;
171
        return false;
212
   
172
   
213
    int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
173
    int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
214
        DEVMAP_CONNECT_TO_DEVICE, dev);
174
        DEVMAP_CONNECT_TO_DEVICE, dev);
215
 
175
 
216
    if (phone < 0) {
176
    if (phone < 0) {
217
        munmap(block, BLOCK_SIZE);
177
        munmap(block, TMPFS_BLOCK_SIZE);
218
        return false;
178
        return false;
219
    }
179
    }
220
   
180
   
221
    if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) !=
181
    if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) !=
222
        EOK)
182
        EOK)
223
        goto error;
183
        goto error;
224
   
184
   
225
    size_t bufpos = 0;
185
    off_t bufpos = 0;
226
    size_t buflen = 0;
186
    size_t buflen = 0;
227
    size_t pos = 0;
187
    off_t pos = 0;
228
   
188
   
229
    char tag[6];
189
    char tag[6];
230
    if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5))
190
    if (!libfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5,
-
 
191
        TMPFS_BLOCK_SIZE))
231
        goto error;
192
        goto error;
232
   
193
   
233
    tag[5] = 0;
194
    tag[5] = 0;
234
    if (strcmp(tag, "TMPFS") != 0)
195
    if (strcmp(tag, "TMPFS") != 0)
235
        goto error;
196
        goto error;
Line 237... Line 198...
237
    if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos,
198
    if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos,
238
        ops->root_get(dev)))
199
        ops->root_get(dev)))
239
        goto error;
200
        goto error;
240
       
201
       
241
    ipc_hangup(phone);
202
    ipc_hangup(phone);
242
    munmap(block, BLOCK_SIZE);
203
    munmap(block, TMPFS_BLOCK_SIZE);
243
    return true;
204
    return true;
244
   
205
   
245
error:
206
error:
246
    ipc_hangup(phone);
207
    ipc_hangup(phone);
247
    munmap(block, BLOCK_SIZE);
208
    munmap(block, TMPFS_BLOCK_SIZE);
248
    return false;
209
    return false;
249
}
210
}
250
 
211
 
251
/**
212
/**
252
 * @}
213
 * @}