Subversion Repositories HelenOS

Rev

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

Rev 3250 Rev 3251
Line 49... Line 49...
49
#include <ipc/services.h>
49
#include <ipc/services.h>
50
#include <ipc/devmap.h>
50
#include <ipc/devmap.h>
51
#include <sys/mman.h>
51
#include <sys/mman.h>
52
#include <byteorder.h>
52
#include <byteorder.h>
53
 
53
 
54
#define BLOCK_SIZE          1024    // FIXME
54
#define TMPFS_BLOCK_SIZE    1024
55
#define RD_BASE             1024    // FIXME
-
 
56
#define RD_READ_BLOCK   (RD_BASE + 1)
-
 
57
 
55
 
58
struct rdentry {
56
struct rdentry {
59
    uint8_t type;
57
    uint8_t type;
60
    uint32_t len;
58
    uint32_t len;
61
} __attribute__((packed));
59
} __attribute__((packed));
62
 
60
 
63
static bool
-
 
64
tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen,
-
 
65
    size_t *pos, void *dst, size_t size)
-
 
66
{
-
 
67
    size_t offset = 0;
-
 
68
    size_t left = size;
-
 
69
   
-
 
70
    while (left > 0) {
-
 
71
        size_t rd;
-
 
72
       
-
 
73
        if (*bufpos + left < *buflen)
-
 
74
            rd = left;
-
 
75
        else
-
 
76
            rd = *buflen - *bufpos;
-
 
77
       
-
 
78
        if (rd > 0) {
-
 
79
            memcpy(dst + offset, buffer + *bufpos, rd);
-
 
80
            offset += rd;
-
 
81
            *bufpos += rd;
-
 
82
            *pos += rd;
-
 
83
            left -= rd;
-
 
84
        }
-
 
85
       
-
 
86
        if (*bufpos == *buflen) {
-
 
87
            ipcarg_t retval;
-
 
88
            int rc = async_req_2_1(phone, RD_READ_BLOCK,
-
 
89
                *pos / BLOCK_SIZE, BLOCK_SIZE, &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, size_t *bufpos, size_t *buflen,
103
    size_t *pos, tmpfs_dentry_t *parent)
63
    size_t *pos, tmpfs_dentry_t *parent)
104
{
64
{
105
    struct rdentry entry;
65
    struct rdentry entry;
Line 108... Line 68...
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) {
Line 128... Line 88...
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 TMPFS_DIRECTORY:
124
        case TMPFS_DIRECTORY:
165
            fname = malloc(entry.len + 1);
125
            fname = malloc(entry.len + 1);
Line 170... Line 130...
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 202... Line 162...
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)
Line 225... Line 185...
225
    size_t bufpos = 0;
185
    size_t bufpos = 0;
226
    size_t buflen = 0;
186
    size_t buflen = 0;
227
    size_t pos = 0;
187
    size_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
 * @}