OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [fs/] [jffs/] [inode.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * JFFS -- Journalling Flash File System, Linux implementation.
3
 *
4
 * Copyright (C) 1999, 2000  Finn Hakansson, Axis Communications, Inc.
5
 *
6
 * This is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * $Id: inode.c,v 1.1.1.1 2001-09-10 07:44:39 simons Exp $
12
 *
13
 */
14
 
15
/* inode.c -- Contains the code that is called from the VFS.  */
16
 
17
#include <linux/module.h>
18
#include <linux/types.h>
19
#include <linux/errno.h>
20
#include <linux/malloc.h>
21
#include <linux/jffs.h>
22
#include <linux/fs.h>
23
#include <linux/locks.h>
24
#include <linux/sched.h>
25
#include <linux/ioctl.h>
26
#include <linux/stat.h>
27
#include <linux/blkdev.h>
28
#include <asm/byteorder.h>
29
#include "jffs_fm.h"
30
#include "intrep.h"
31
 
32
#if defined(CONFIG_JFFS_FS_VERBOSE) && CONFIG_JFFS_FS_VERBOSE
33
#define D(x) x
34
#else
35
#define D(x)
36
#endif
37
#define D1(x)
38
#define D2(x)
39
#define D3(x)
40
#define ASSERT(x) x
41
 
42
static int jffs_remove(struct inode *dir, const char *name,
43
                       int len, int type, int must_iput);
44
 
45
static struct super_operations jffs_ops;
46
static struct file_operations jffs_file_operations;
47
static struct inode_operations jffs_file_inode_operations;
48
static struct file_operations jffs_dir_operations;
49
static struct inode_operations jffs_dir_inode_operations;
50
static struct inode_operations jffs_symlink_inode_operations;
51
 
52
 
53
/* Called by the VFS at mount time to initialize the whole file system.  */
54
static struct super_block *
55
jffs_read_super(struct super_block *sb, void *data, int silent)
56
{
57
        kdev_t dev = sb->s_dev;
58
 
59
        printk(KERN_NOTICE "JFFS: Trying to mount device %s.\n",
60
               kdevname(dev));
61
 
62
        MOD_INC_USE_COUNT;
63
        lock_super(sb);
64
        set_blocksize(dev, BLOCK_SIZE);
65
        sb->s_blocksize = BLOCK_SIZE;
66
        sb->s_blocksize_bits = BLOCK_SIZE_BITS;
67
        sb->u.generic_sbp = (void *) 0;
68
 
69
        /* Build the file system.  */
70
        if (jffs_build_fs(sb) < 0) {
71
                goto jffs_sb_err1;
72
        }
73
        sb->s_magic = JFFS_MAGIC_SB_BITMASK;
74
        sb->s_op = &jffs_ops;
75
 
76
        /* Get the root directory of this file system.  */
77
        if (!(sb->s_mounted = iget(sb, JFFS_MIN_INO))) {
78
                goto jffs_sb_err2;
79
        }
80
 
81
#ifdef USE_GC
82
        /* Do a garbage collect every time we mount.  */
83
        jffs_garbage_collect((struct jffs_control *)sb->u.generic_sbp);
84
#endif
85
 
86
        unlock_super(sb);
87
        printk(KERN_NOTICE "JFFS: Successfully mounted device %s.\n",
88
               kdevname(dev));
89
        return sb;
90
 
91
jffs_sb_err2:
92
        jffs_cleanup_control((struct jffs_control *)sb->u.generic_sbp);
93
jffs_sb_err1:
94
        unlock_super(sb);
95
        MOD_DEC_USE_COUNT;
96
        printk(KERN_WARNING "JFFS: Failed to mount device %s.\n",
97
               kdevname(dev));
98
        return 0;
99
}
100
 
101
 
102
/* This function is called when the file system is umounted.  */
103
static void
104
jffs_put_super(struct super_block *sb)
105
{
106
        kdev_t dev = sb->s_dev;
107
        D2(printk("jffs_put_super()\n"));
108
        lock_super(sb);
109
        sb->s_dev = 0;
110
        jffs_cleanup_control((struct jffs_control *)sb->u.generic_sbp);
111
        unlock_super(sb);
112
        MOD_DEC_USE_COUNT;
113
        printk(KERN_NOTICE "JFFS: Successfully unmounted device %s.\n",
114
               kdevname(dev));
115
}
116
 
117
 
118
/* This function is called when user commands like chmod, chgrp and
119
   chown are executed. System calls like trunc() results in a call
120
   to this function.  */
121
static int
122
jffs_notify_change(struct inode *inode, struct iattr *iattr)
123
{
124
        struct jffs_raw_inode raw_inode;
125
        struct jffs_control *c;
126
        struct jffs_fmcontrol *fmc;
127
        struct jffs_file *f;
128
        struct jffs_node *new_node;
129
        char *name = 0;
130
        int update_all;
131
        int res;
132
 
133
        f = (struct jffs_file *)inode->u.generic_ip;
134
        ASSERT(if (!f) {
135
                printk("jffs_notify_change(): Invalid inode number: %lu\n",
136
                       inode->i_ino);
137
                return -1;
138
        });
139
 
140
        D1(printk("***jffs_notify_change(): file: \"%s\", ino: %u\n",
141
                  f->name, f->ino));
142
 
143
        c = f->c;
144
        fmc = c->fmc;
145
        update_all = iattr->ia_valid & ATTR_FORCE;
146
 
147
        if (!JFFS_ENOUGH_SPACE(fmc)) {
148
                if (((update_all || iattr->ia_valid & ATTR_SIZE)
149
                    && (iattr->ia_size < f->size))) {
150
                        /* See this case where someone is trying to
151
                           shrink the size of a file as an exception.
152
                           Accept it.  */
153
                }
154
                else {
155
                        D1(printk("jffs_notify_change(): Free size = %u\n",
156
                                  jffs_free_size1(fmc)
157
                                  + jffs_free_size2(fmc)));
158
                        D(printk(KERN_NOTICE "JFFS: No space left on "
159
                                 "device\n"));
160
                        return -ENOSPC;
161
                }
162
        }
163
 
164
        if (!(new_node = (struct jffs_node *)
165
                         kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
166
                D(printk("jffs_notify_change(): Allocation failed!\n"));
167
                return -ENOMEM;
168
        }
169
        DJM(no_jffs_node++);
170
        new_node->data_offset = 0;
171
        new_node->removed_size = 0;
172
        raw_inode.magic = JFFS_MAGIC_BITMASK;
173
        raw_inode.ino = f->ino;
174
        raw_inode.pino = f->pino;
175
        raw_inode.version = f->highest_version + 1;
176
        raw_inode.mode = f->mode;
177
        raw_inode.uid = f->uid;
178
        raw_inode.gid = f->gid;
179
        raw_inode.atime = f->atime;
180
        raw_inode.mtime = f->mtime;
181
        raw_inode.ctime = f->ctime;
182
        raw_inode.dsize = 0;
183
        raw_inode.offset = 0;
184
        raw_inode.rsize = 0;
185
        raw_inode.dsize = 0;
186
        raw_inode.nsize = 0;
187
        raw_inode.nlink = f->nlink;
188
        raw_inode.spare = 0;
189
        raw_inode.rename = 0;
190
        raw_inode.deleted = 0;
191
 
192
        if (update_all || iattr->ia_valid & ATTR_MODE) {
193
                raw_inode.mode = iattr->ia_mode;
194
                inode->i_mode = iattr->ia_mode;
195
        }
196
        if (update_all || iattr->ia_valid & ATTR_UID) {
197
                raw_inode.uid = iattr->ia_uid;
198
                inode->i_uid = iattr->ia_uid;
199
        }
200
        if (update_all || iattr->ia_valid & ATTR_GID) {
201
                raw_inode.gid = iattr->ia_gid;
202
                inode->i_gid = iattr->ia_gid;
203
        }
204
        if (update_all || iattr->ia_valid & ATTR_SIZE) {
205
                int len;
206
                D1(printk("jffs_notify_change(): Changing size "
207
                          "to %lu bytes!\n", iattr->ia_size));
208
                raw_inode.offset = iattr->ia_size;
209
 
210
                /* Calculate how many bytes need to be removed from
211
                   the end.  */
212
 
213
                if (f->size < iattr->ia_size) {
214
                        len = 0;
215
                }
216
                else {
217
                        len = f->size - iattr->ia_size;
218
                }
219
 
220
                raw_inode.rsize = len;
221
 
222
                /* The updated node will be a removal node, with
223
                   base at the new size and size of the nbr of bytes
224
                   to be removed.  */
225
 
226
                new_node->data_offset = iattr->ia_size;
227
                new_node->removed_size = len;
228
                inode->i_size = iattr->ia_size;
229
 
230
                /* If we truncate a file we want to add the name.  If we
231
                   always do that, we could perhaps free more space on
232
                   the flash (and besides it doesn't hurt).  */
233
                name = f->name;
234
                raw_inode.nsize = f->nsize;
235
                if (len) {
236
                        invalidate_inode_pages(inode);
237
                }
238
                inode->i_ctime = CURRENT_TIME;
239
                inode->i_mtime = inode->i_ctime;
240
        }
241
        if (update_all || iattr->ia_valid & ATTR_ATIME) {
242
                raw_inode.atime = iattr->ia_atime;
243
                inode->i_atime = iattr->ia_atime;
244
        }
245
        if (update_all || iattr->ia_valid & ATTR_MTIME) {
246
                raw_inode.mtime = iattr->ia_mtime;
247
                inode->i_mtime = iattr->ia_mtime;
248
        }
249
        if (update_all || iattr->ia_valid & ATTR_CTIME) {
250
                raw_inode.ctime = iattr->ia_ctime;
251
                inode->i_ctime = iattr->ia_ctime;
252
        }
253
 
254
        /* Write this node to the flash.  */
255
        if ((res = jffs_write_node(c, new_node, &raw_inode, name, 0)) < 0) {
256
                D(printk("jffs_notify_change(): The write failed!\n"));
257
                kfree(new_node);
258
                DJM(no_jffs_node--);
259
                return res;
260
        }
261
 
262
        jffs_insert_node(c, f, &raw_inode, 0, new_node);
263
        inode->i_dirt = 1;
264
        return 0;
265
} /* jffs_notify_change()  */
266
 
267
 
268
/* Get statistics of the file system.  */
269
static void
270
jffs_statfs(struct super_block *sb, struct statfs *buf, int bufsize)
271
{
272
        struct statfs tmp;
273
        struct jffs_control *c = (struct jffs_control *) sb->u.generic_sbp;
274
        struct jffs_fmcontrol *fmc = c->fmc;
275
 
276
        D2(printk("jffs_statfs()\n"));
277
 
278
        c = (struct jffs_control *)sb->u.generic_sbp;
279
        memset(&tmp, 0, sizeof(tmp));
280
        tmp.f_type = JFFS_MAGIC_SB_BITMASK;
281
        tmp.f_bsize = PAGE_SIZE;
282
        tmp.f_blocks = (fmc->flash_size / BLOCK_SIZE)
283
                       - (fmc->min_free_size / BLOCK_SIZE);
284
        tmp.f_bfree = (jffs_free_size1(fmc) / BLOCK_SIZE
285
                       + jffs_free_size2(fmc) / BLOCK_SIZE)
286
                      - (fmc->min_free_size / BLOCK_SIZE);
287
        /* Find out how many files there are in the filesystem.  */
288
        tmp.f_files = jffs_foreach_file(c, jffs_file_count);
289
        tmp.f_ffree = tmp.f_bfree;
290
        /* tmp.f_fsid = 0; */
291
        tmp.f_namelen = JFFS_MAX_NAME_LEN;
292
        memcpy_tofs(buf, &tmp, bufsize);
293
}
294
 
295
 
296
/* Rename a file.  */
297
int
298
jffs_rename(struct inode *old_dir, const char *old_name, int old_len,
299
            struct inode *new_dir, const char *new_name, int new_len,
300
            int must_be_dir)
301
{
302
        struct jffs_raw_inode raw_inode;
303
        struct jffs_control *c;
304
        struct jffs_file *old_dir_f;
305
        struct jffs_file *new_dir_f;
306
        struct jffs_file *del_f;
307
        struct jffs_file *f;
308
        struct jffs_node *node;
309
        struct inode *inode;
310
        int result = 0;
311
        __u32 rename_data = 0;
312
 
313
        D2(printk("***jffs_rename()\n"));
314
 
315
        if (!old_dir || !old_name || !new_dir || !new_name) {
316
                D(printk("jffs_rename(): old_dir: 0x%p, old_name: 0x%p, "
317
                         "new_dir: 0x%p, new_name: 0x%p\n",
318
                         old_dir, old_name, new_dir, new_name));
319
                return -1;
320
        }
321
 
322
        c = (struct jffs_control *)old_dir->i_sb->u.generic_sbp;
323
        ASSERT(if (!c) {
324
                printk(KERN_ERR "jffs_rename(): The old_dir inode "
325
                       "didn't have a reference to a jffs_file struct\n");
326
                return -1;
327
        });
328
 
329
        if (!JFFS_ENOUGH_SPACE(c->fmc)) {
330
                D1(printk("jffs_rename(): Free size = %u\n",
331
                          jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
332
                D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
333
                return -ENOSPC;
334
        }
335
 
336
        while (c->rename_lock) {
337
                sleep_on(&c->rename_wait);
338
        }
339
        c->rename_lock = 1;
340
 
341
        /* Check the lengths of the names.  */
342
        if ((old_len > JFFS_MAX_NAME_LEN) || (new_len > JFFS_MAX_NAME_LEN)) {
343
                result = -ENAMETOOLONG;
344
                goto jffs_rename_end;
345
        }
346
        /* Find the the old directory.  */
347
        if (!(old_dir_f = (struct jffs_file *)old_dir->u.generic_ip)) {
348
                D(printk("jffs_rename(): Old dir invalid.\n"));
349
                result = -ENOTDIR;
350
                goto jffs_rename_end;
351
        }
352
        /* See if it really is a directory.  */
353
        if (!S_ISDIR(old_dir_f->mode)) {
354
                D(printk("jffs_rename(): old_dir is not a directory.\n"));
355
                result = -ENOTDIR;
356
                goto jffs_rename_end;
357
        }
358
        /* Try to find the file to move.  */
359
        if (!(f = jffs_find_child(old_dir_f, old_name, old_len))) {
360
                result = -ENOENT;
361
                goto jffs_rename_end;
362
        }
363
        /* Try to find the new directory's node.  */
364
        if (!(new_dir_f = (struct jffs_file *)new_dir->u.generic_ip)) {
365
                D(printk("jffs_rename(): New dir invalid.\n"));
366
                result = -ENOTDIR;
367
                goto jffs_rename_end;
368
        }
369
        /* See if the node really is a directory.  */
370
        if (!S_ISDIR(new_dir_f->mode)) {
371
                D(printk("jffs_rename(): The new position of the node "
372
                         "is not a directory.\n"));
373
                result = -ENOTDIR;
374
                goto jffs_rename_end;
375
        }
376
 
377
        /* Create a node and initialize as much as needed.  */
378
        if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
379
                                                  GFP_KERNEL))) {
380
                D(printk("jffs_rename(): Allocation failed: node == 0\n"));
381
                result = -ENOMEM;
382
                goto jffs_rename_end;
383
        }
384
        DJM(no_jffs_node++);
385
        node->data_offset = 0;
386
        node->removed_size = 0;
387
 
388
        /* Initialize the raw inode.  */
389
        raw_inode.magic = JFFS_MAGIC_BITMASK;
390
        raw_inode.ino = f->ino;
391
        raw_inode.pino = new_dir_f->ino;
392
        raw_inode.version = f->highest_version + 1;
393
        raw_inode.mode = f->mode;
394
        raw_inode.uid = current->fsuid;
395
        raw_inode.gid = current->fsgid;
396
#if 0
397
        raw_inode.uid = f->uid;
398
        raw_inode.gid = f->gid;
399
#endif
400
        raw_inode.atime = CURRENT_TIME;
401
        raw_inode.mtime = raw_inode.atime;
402
        raw_inode.ctime = f->ctime;
403
        raw_inode.offset = 0;
404
        raw_inode.dsize = 0;
405
        raw_inode.rsize = 0;
406
        raw_inode.nsize = new_len;
407
        raw_inode.nlink = f->nlink;
408
        raw_inode.spare = 0;
409
        raw_inode.rename = 0;
410
        raw_inode.deleted = 0;
411
 
412
        /* See if there already exists a file with the same name as
413
           new_name.  */
414
        if ((del_f = jffs_find_child(new_dir_f, new_name, new_len))) {
415
                raw_inode.rename = 1;
416
                /*raw_inode.mode = del_f->ino;*/
417
        }
418
 
419
        /* Write the new node to the flash memory.  */
420
        if ((result = jffs_write_node(c, node, &raw_inode, new_name,
421
                                      (unsigned char*)&rename_data)) < 0) {
422
                D(printk("jffs_rename(): Failed to write node to flash.\n"));
423
                kfree(node);
424
                DJM(no_jffs_node--);
425
                goto jffs_rename_end;
426
        }
427
 
428
        if (raw_inode.rename) {
429
                /* The file with the same name must be deleted.  */
430
                c->fmc->no_call_gc = 1;
431
                if ((result = jffs_remove(new_dir, new_name, new_len,
432
                                          del_f->mode, 0)) < 0) {
433
                        /* This is really bad.  */
434
                        printk(KERN_ERR "JFFS: An error occurred in "
435
                               "rename().\n");
436
                }
437
                c->fmc->no_call_gc = 0;
438
        }
439
 
440
        if (old_dir_f != new_dir_f) {
441
                /* Remove the file from its old position in the
442
                   filesystem tree.  */
443
                jffs_unlink_file_from_tree(f);
444
        }
445
 
446
        /* Insert the new node into the file system.  */
447
        if ((result = jffs_insert_node(c, f, &raw_inode,
448
                                       new_name, node)) < 0) {
449
                D(printk(KERN_ERR "jffs_rename(): jffs_insert_node() "
450
                         "failed!\n"));
451
        }
452
 
453
        if (old_dir_f != new_dir_f) {
454
                /* Insert the file to its new position in the
455
                   file system.  */
456
                jffs_insert_file_into_tree(f);
457
        }
458
 
459
        /* This is a kind of update of the inode we're about to make
460
           here.  This is what they do in ext2fs.  Kind of.  */
461
        if ((inode = iget(new_dir->i_sb, f->ino))) {
462
                inode->i_ctime = CURRENT_TIME;
463
                inode->i_dirt = 1;
464
                iput(inode);
465
        }
466
 
467
jffs_rename_end:
468
        iput(old_dir);
469
        iput(new_dir);
470
        c->rename_lock = 0;
471
        wake_up(&c->rename_wait);
472
        return result;
473
} /* jffs_rename()  */
474
 
475
 
476
/* Read the contents of a directory.  Used by programs like `ls'
477
   for instance.  */
478
static int
479
jffs_readdir(struct inode *dir, struct file *filp, void *dirent, filldir_t filldir)
480
{
481
        struct jffs_file *f;
482
        int j;
483
        int ddino;
484
 
485
        D2(printk("jffs_readdir(): dir: 0x%p, filp: 0x%p\n", dir, filp));
486
 
487
        if (!dir || !S_ISDIR(dir->i_mode)) {
488
                D(printk("jffs_readdir(): 'dir' is NULL or not a dir!\n"));
489
                return -EBADF;
490
        }
491
 
492
        switch (filp->f_pos)
493
        {
494
        case 0:
495
                D3(printk("jffs_readdir(): \".\" %lu\n", dir->i_ino));
496
                if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino) < 0) {
497
                        return 0;
498
                }
499
                filp->f_pos = 1;
500
        case 1:
501
                if (dir->i_ino == JFFS_MIN_INO) {
502
                        ddino = dir->i_sb->s_covered->i_ino;
503
                }
504
                else {
505
                        ddino = ((struct jffs_file *)dir->u.generic_ip)->pino;
506
                }
507
                D3(printk("jffs_readdir(): \"..\" %u\n", ddino));
508
                if (filldir(dirent, "..", 2, filp->f_pos, ddino) < 0)
509
                        return 0;
510
                filp->f_pos++;
511
        default:
512
                f = ((struct jffs_file *)dir->u.generic_ip)->children;
513
                for (j = 2; (j < filp->f_pos) && f; j++) {
514
                        f = f->sibling_next;
515
                }
516
                for (; f ; f = f->sibling_next) {
517
                        D3(printk("jffs_readdir(): \"%s\" ino: %u\n",
518
                                  (f->name ? f->name : ""), f->ino));
519
                        if (filldir(dirent, f->name, f->nsize,
520
                                    filp->f_pos , f->ino) < 0)
521
                                return 0;
522
                        filp->f_pos++;
523
                }
524
        }
525
        return filp->f_pos;
526
} /* jffs_readdir()  */
527
 
528
 
529
/* Find a file in a directory. If the file exists, return its
530
   corresponding inode in the argument `result'.  */
531
static int
532
jffs_lookup(struct inode *dir, const char *name, int len,
533
            struct inode **result)
534
{
535
        struct jffs_file *d;
536
        struct jffs_file *f;
537
        int r = 0;
538
 
539
        D3({
540
                char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
541
                memcpy(s, name, len);
542
                s[len] = '\0';
543
                printk("jffs_lookup(): dir: 0x%p, name: \"%s\"\n", dir, s);
544
                kfree(s);
545
        });
546
 
547
        *result = (struct inode *)0;
548
        if (!dir) {
549
                return -ENOENT;
550
        }
551
        if (!S_ISDIR(dir->i_mode)) {
552
                r = -ENOTDIR;
553
                goto jffs_lookup_end;
554
        }
555
        if (len > JFFS_MAX_NAME_LEN) {
556
                r = -ENAMETOOLONG;
557
                goto jffs_lookup_end;
558
        }
559
 
560
        if (!(d = (struct jffs_file *)dir->u.generic_ip)) {
561
                D(printk("jffs_lookup(): No such inode! (%lu)\n", dir->i_ino));
562
                r = -ENOENT;
563
                goto jffs_lookup_end;
564
        }
565
 
566
        /* Get the corresponding inode to the file.  */
567
        if ((len == 1) && (name[0] == '.')) {
568
                if (!(*result = iget(dir->i_sb, d->ino))) {
569
                        D(printk("jffs_lookup(): . iget() ==> NULL\n"));
570
                        r = -ENOENT;
571
                }
572
        }
573
        else if ((len == 2) && (name[0] == '.') && (name[1] == '.')) {
574
                if (!(*result = iget(dir->i_sb, d->pino))) {
575
                        D(printk("jffs_lookup(): .. iget() ==> NULL\n"));
576
                        r = -ENOENT;
577
                }
578
        }
579
        else if ((f = jffs_find_child(d, name, len))) {
580
                if (!(*result = iget(dir->i_sb, f->ino))) {
581
                        D(printk("jffs_lookup(): iget() ==> NULL\n"));
582
                        r = -ENOENT;
583
                }
584
        }
585
        else {
586
                D3(printk("jffs_lookup(): Couldn't find the file. "
587
                          "f = 0x%p, name = \"%s\", d = 0x%p, d->ino = %u\n",
588
                          f, name, d, d->ino));
589
                r = -ENOENT;
590
        }
591
 
592
jffs_lookup_end:
593
        iput(dir);
594
        return r;
595
} /* jffs_lookup()  */
596
 
597
 
598
/* Try to read a page of data from a file.  */
599
static int
600
jffs_readpage(struct inode *inode, struct page *page)
601
{
602
        unsigned long buf;
603
        unsigned long read_len;
604
        int result = -EIO;
605
        struct jffs_file *f = (struct jffs_file *)inode->u.generic_ip;
606
        int r;
607
 
608
        D2(printk("***jffs_readpage(): file = \"%s\", page->offset = %lu\n",
609
                  (f->name ? f->name : ""), page->offset));
610
 
611
        page->count++;
612
        set_bit(PG_locked, &page->flags);
613
        buf = page_address(page);
614
        clear_bit(PG_uptodate, &page->flags);
615
        clear_bit(PG_error, &page->flags);
616
 
617
        if (page->offset < inode->i_size) {
618
                read_len = jffs_min(inode->i_size - page->offset, PAGE_SIZE);
619
                r = jffs_read_data(f, (char *)buf, page->offset, read_len);
620
                if (r == read_len) {
621
                        if (read_len < PAGE_SIZE) {
622
                                memset((void *)(buf + read_len), 0,
623
                                       PAGE_SIZE - read_len);
624
                        }
625
                        set_bit(PG_uptodate, &page->flags);
626
                        result = 0;
627
                }
628
                D(else {
629
                        printk("***jffs_readpage(): Read error! "
630
                               "Wanted to read %lu bytes but only "
631
                               "read %d bytes.\n", read_len, r);
632
                });
633
        }
634
        if (result) {
635
                set_bit(PG_error, &page->flags);
636
                memset((void *)buf, 0, PAGE_SIZE);
637
        }
638
 
639
        clear_bit(PG_locked, &page->flags);
640
        wake_up(&page->wait);
641
        free_page(buf);
642
 
643
        D3(printk("jffs_readpage(): Leaving...\n"));
644
 
645
        return result;
646
} /* jffs_readpage()  */
647
 
648
 
649
/* Create a new directory.  */
650
static int
651
jffs_mkdir(struct inode *dir, const char *name, int len, int mode)
652
{
653
        struct jffs_raw_inode raw_inode;
654
        struct jffs_control *c;
655
        struct jffs_node *node;
656
        struct jffs_file *dir_f;
657
        int dir_mode;
658
        int result = 0;
659
 
660
        D1({
661
                char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
662
                memcpy(_name, name, len);
663
                _name[len] = '\0';
664
                printk("***jffs_mkdir(): dir = 0x%p, name = \"%s\", "
665
                       "len = %d, mode = 0x%08x\n", dir, _name, len, mode);
666
                kfree(_name);
667
        });
668
 
669
        if (!dir) {
670
                return -ENOENT;
671
        }
672
        if (len > JFFS_MAX_NAME_LEN) {
673
                result = -ENAMETOOLONG;
674
                goto jffs_mkdir_end;
675
        }
676
 
677
        dir_f = (struct jffs_file *)dir->u.generic_ip;
678
        ASSERT(if (!dir_f) {
679
                printk(KERN_ERR "jffs_mkdir(): No reference to a "
680
                       "jffs_file struct in inode.\n");
681
                result = -1;
682
                goto jffs_mkdir_end;
683
        });
684
 
685
        c = dir_f->c;
686
 
687
        if (!JFFS_ENOUGH_SPACE(c->fmc)) {
688
                D1(printk("jffs_mkdir(): Free size = %u\n",
689
                          jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
690
                D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
691
                result = -ENOSPC;
692
                goto jffs_mkdir_end;
693
        }
694
 
695
        /* If there already exists a file or directory with the same name,
696
           then this operation should fail. I originally thought that VFS
697
           should take care of this issue.  */
698
        if (jffs_find_child(dir_f, name, len)) {
699
                D(printk("jffs_mkdir(): There already exists a file or "
700
                         "directory with the same name!\n"));
701
                result = -EEXIST;
702
                goto jffs_mkdir_end;
703
        }
704
 
705
        dir_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX)
706
                              & ~current->fs->umask);
707
        if (dir->i_mode & S_ISGID) {
708
                dir_mode |= S_ISGID;
709
        }
710
 
711
        /* Create a node and initialize it as much as needed.  */
712
        if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
713
                                                  GFP_KERNEL))) {
714
                D(printk("jffs_mkdir(): Allocation failed: node == 0\n"));
715
                result = -ENOMEM;
716
                goto jffs_mkdir_end;
717
        }
718
        DJM(no_jffs_node++);
719
        node->data_offset = 0;
720
        node->removed_size = 0;
721
 
722
        /* Initialize the raw inode.  */
723
        raw_inode.magic = JFFS_MAGIC_BITMASK;
724
        raw_inode.ino = c->next_ino++;
725
        raw_inode.pino = dir_f->ino;
726
        raw_inode.version = 1;
727
        raw_inode.mode = dir_mode;
728
        raw_inode.uid = current->fsuid;
729
        raw_inode.gid = current->fsgid;
730
        raw_inode.atime = CURRENT_TIME;
731
        raw_inode.mtime = raw_inode.atime;
732
        raw_inode.ctime = raw_inode.atime;
733
        raw_inode.offset = 0;
734
        raw_inode.dsize = 0;
735
        raw_inode.rsize = 0;
736
        raw_inode.nsize = len;
737
        raw_inode.nlink = 1;
738
        raw_inode.spare = 0;
739
        raw_inode.rename = 0;
740
        raw_inode.deleted = 0;
741
 
742
        /* Write the new node to the flash.  */
743
        if (jffs_write_node(c, node, &raw_inode, name, 0) < 0) {
744
                D(printk("jffs_mkdir(): jffs_write_node() failed.\n"));
745
                kfree(node);
746
                DJM(no_jffs_node--);
747
                result = -1;
748
                goto jffs_mkdir_end;
749
        }
750
 
751
        /* Insert the new node into the file system.  */
752
        result = jffs_insert_node(c, 0, &raw_inode, name, node);
753
 
754
jffs_mkdir_end:
755
        iput(dir);
756
        return result;
757
} /* jffs_mkdir()  */
758
 
759
 
760
/* Remove a directory.  */
761
static int
762
jffs_rmdir(struct inode *dir, const char *name, int len)
763
{
764
        D3(printk("***jffs_rmdir()\n"));
765
        return jffs_remove(dir, name, len, S_IFDIR, 1);
766
}
767
 
768
 
769
/* Remove any kind of file except for directories.  */
770
static int
771
jffs_unlink(struct inode *dir, const char *name, int len)
772
{
773
        D3(printk("***jffs_unlink()\n"));
774
        return jffs_remove(dir, name, len, 0, 1);
775
}
776
 
777
 
778
/* Remove a JFFS entry, i.e. plain files, directories, etc.  Here we
779
   shouldn't test for free space on the device.  */
780
static int
781
jffs_remove(struct inode *dir, const char *name, int len, int type,
782
            int must_iput)
783
{
784
        struct jffs_raw_inode raw_inode;
785
        struct jffs_control *c;
786
        struct jffs_file *dir_f; /* The file-to-remove's parent.  */
787
        struct jffs_file *del_f; /* The file to remove.  */
788
        struct jffs_node *del_node;
789
        struct inode *inode = 0;
790
        int result = 0;
791
 
792
        D1({
793
                char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
794
                memcpy(_name, name, len);
795
                _name[len] = '\0';
796
                printk("***jffs_remove(): file = \"%s\"\n", _name);
797
                kfree(_name);
798
        });
799
 
800
        if (!dir) {
801
                return -ENOENT;
802
        }
803
        if (len > JFFS_MAX_NAME_LEN) {
804
                result = -ENAMETOOLONG;
805
                goto jffs_remove_end;
806
        }
807
 
808
        dir_f = (struct jffs_file *) dir->u.generic_ip;
809
        c = dir_f->c;
810
 
811
        if (!(del_f = jffs_find_child(dir_f, name, len))) {
812
                D(printk("jffs_remove(): jffs_find_child() failed.\n"));
813
                result = -ENOENT;
814
                goto jffs_remove_end;
815
        }
816
 
817
        if (S_ISDIR(type)) {
818
                if (!S_ISDIR(del_f->mode)) {
819
                        result = -ENOTDIR;
820
                        goto jffs_remove_end;
821
                }
822
                if (del_f->children) {
823
                        result = -ENOTEMPTY;
824
                        goto jffs_remove_end;
825
                }
826
        }
827
        else if (S_ISDIR(del_f->mode)) {
828
                D(printk("jffs_remove(): node is a directory "
829
                         "but it shouldn't be.\n"));
830
                result = -EPERM;
831
                goto jffs_remove_end;
832
        }
833
 
834
        if (!(inode = iget(dir->i_sb, del_f->ino))) {
835
                printk(KERN_ERR "JFFS: Unlink failed.\n");
836
                result = -ENOENT;
837
                goto jffs_remove_end;
838
        }
839
 
840
        /* Create a node for the deletion.  */
841
        if (!(del_node = (struct jffs_node *)
842
                         kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
843
                D(printk("jffs_remove(): Allocation failed!\n"));
844
                result = -ENOMEM;
845
                goto jffs_remove_end;
846
        }
847
        DJM(no_jffs_node++);
848
        del_node->data_offset = 0;
849
        del_node->removed_size = 0;
850
 
851
        /* Initialize the raw inode.  */
852
        raw_inode.magic = JFFS_MAGIC_BITMASK;
853
        raw_inode.ino = del_f->ino;
854
        raw_inode.pino = del_f->pino;
855
        raw_inode.version = del_f->highest_version + 1;
856
        raw_inode.mode = del_f->mode;
857
        raw_inode.uid = current->fsuid;
858
        raw_inode.gid = current->fsgid;
859
        raw_inode.atime = CURRENT_TIME;
860
        raw_inode.mtime = del_f->mtime;
861
        raw_inode.ctime = raw_inode.atime;
862
        raw_inode.offset = 0;
863
        raw_inode.dsize = 0;
864
        raw_inode.rsize = 0;
865
        raw_inode.nsize = 0;
866
        raw_inode.nlink = del_f->nlink;
867
        raw_inode.spare = 0;
868
        raw_inode.rename = 0;
869
        raw_inode.deleted = 1;
870
 
871
        /* Write the new node to the flash memory.  */
872
        if (jffs_write_node(c, del_node, &raw_inode, 0, 0) < 0) {
873
                kfree(del_node);
874
                DJM(no_jffs_node--);
875
                result = -1;
876
                goto jffs_remove_end;
877
        }
878
 
879
        /* Update the file.  This operation will make the file disappear
880
           from the in-memory file system structures.  */
881
        jffs_insert_node(c, del_f, &raw_inode, 0, del_node);
882
 
883
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
884
        dir->i_dirt = 1;
885
        inode->i_nlink = inode->i_nlink ? inode->i_nlink - 1 : 0;
886
        if (inode->i_nlink == 0) {
887
                inode->u.generic_ip = 0;
888
        }
889
        inode->i_dirt = 1;
890
        inode->i_ctime = dir->i_ctime;
891
 
892
jffs_remove_end:
893
        if (must_iput) {
894
                iput(dir);
895
        }
896
        if (inode) {
897
                iput(inode);
898
        }
899
        return result;
900
} /* jffs_remove()  */
901
 
902
 
903
static int
904
jffs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev)
905
{
906
        struct jffs_raw_inode raw_inode;
907
        struct jffs_file *dir_f;
908
        struct jffs_node *node = 0;
909
        struct jffs_control *c;
910
        int result = 0;
911
        kdev_t dev = to_kdev_t(rdev);
912
 
913
        D1(printk("***jffs_mknod()\n"));
914
 
915
        if (!dir) {
916
                return -ENOENT;
917
        }
918
        if (len > JFFS_MAX_NAME_LEN) {
919
                result = -ENAMETOOLONG;
920
                goto jffs_mknod_end;
921
        }
922
 
923
        dir_f = (struct jffs_file *)dir->u.generic_ip;
924
        c = dir_f->c;
925
 
926
        if (!JFFS_ENOUGH_SPACE(c->fmc)) {
927
                D1(printk("jffs_mknod(): Free size = %u\n",
928
                          jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
929
                D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
930
                result = -ENOSPC;
931
                goto jffs_mknod_end;
932
        }
933
 
934
        /* Check and see if the file exists already.  */
935
        if (jffs_find_child(dir_f, name, len)) {
936
                D(printk("jffs_mknod(): There already exists a file or "
937
                         "directory with the same name!\n"));
938
                result = -EEXIST;
939
                goto jffs_mknod_end;
940
        }
941
 
942
        /* Create and initialize a new node.  */
943
        if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
944
                                                  GFP_KERNEL))) {
945
                D(printk("jffs_mknod(): Allocation failed!\n"));
946
                result = -ENOMEM;
947
                goto jffs_mknod_err;
948
        }
949
        DJM(no_jffs_node++);
950
        node->data_offset = 0;
951
        node->removed_size = 0;
952
 
953
        /* Initialize the raw inode.  */
954
        raw_inode.magic = JFFS_MAGIC_BITMASK;
955
        raw_inode.ino = c->next_ino++;
956
        raw_inode.pino = dir_f->ino;
957
        raw_inode.version = 1;
958
        raw_inode.mode = mode;
959
        raw_inode.uid = current->fsuid;
960
        raw_inode.gid = current->fsgid;
961
        raw_inode.atime = CURRENT_TIME;
962
        raw_inode.mtime = raw_inode.atime;
963
        raw_inode.ctime = raw_inode.atime;
964
        raw_inode.offset = 0;
965
        raw_inode.dsize = sizeof(kdev_t);
966
        raw_inode.rsize = 0;
967
        raw_inode.nsize = len;
968
        raw_inode.nlink = 1;
969
        raw_inode.spare = 0;
970
        raw_inode.rename = 0;
971
        raw_inode.deleted = 0;
972
 
973
        /* Write the new node to the flash.  */
974
        if (jffs_write_node(c, node, &raw_inode, name,
975
                            (unsigned char *)&dev) < 0) {
976
                D(printk("jffs_mknod(): jffs_write_node() failed.\n"));
977
                result = -1;
978
                goto jffs_mknod_err;
979
        }
980
 
981
        /* Insert the new node into the file system.  */
982
        if (jffs_insert_node(c, 0, &raw_inode, name, node) < 0) {
983
                result = -1;
984
                goto jffs_mknod_end;
985
        }
986
 
987
        goto jffs_mknod_end;
988
 
989
jffs_mknod_err:
990
        if (node) {
991
                kfree(node);
992
                DJM(no_jffs_node--);
993
        }
994
 
995
jffs_mknod_end:
996
        iput(dir);
997
        return result;
998
} /* jffs_mknod()  */
999
 
1000
 
1001
static int
1002
jffs_symlink(struct inode *dir, const char *name, int len, const char *symname)
1003
{
1004
        struct jffs_raw_inode raw_inode;
1005
        struct jffs_control *c;
1006
        struct jffs_file *dir_f;
1007
        struct jffs_node *node;
1008
        int symname_len = strlen(symname);
1009
 
1010
        D1({
1011
                char *_name = (char *)kmalloc(len + 1, GFP_KERNEL);
1012
                char *_symname = (char *)kmalloc(symname_len + 1, GFP_KERNEL);
1013
                memcpy(_name, name, len);
1014
                _name[len] = '\0';
1015
                memcpy(_symname, symname, symname_len);
1016
                _symname[symname_len] = '\0';
1017
                printk("***jffs_symlink(): dir = 0x%p, name = \"%s\", "
1018
                       "symname = \"%s\"\n", dir, _name, _symname);
1019
                kfree(_name);
1020
                kfree(_symname);
1021
        });
1022
 
1023
        if (!dir) {
1024
                return -ENOENT;
1025
        }
1026
        if (len > JFFS_MAX_NAME_LEN) {
1027
                iput(dir);
1028
                return -ENAMETOOLONG;
1029
        }
1030
 
1031
        dir_f = (struct jffs_file *)dir->u.generic_ip;
1032
        ASSERT(if (!dir_f) {
1033
                printk(KERN_ERR "jffs_symlink(): No reference to a "
1034
                       "jffs_file struct in inode.\n");
1035
                iput(dir);
1036
                return -1;
1037
        });
1038
 
1039
        c = dir_f->c;
1040
 
1041
        if (!JFFS_ENOUGH_SPACE(c->fmc)) {
1042
                D1(printk("jffs_symlink(): Free size = %u\n",
1043
                          jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
1044
                D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
1045
                iput(dir);
1046
                return -ENOSPC;
1047
        }
1048
 
1049
        /* Check so there isn't an already existing file with the
1050
           specified name.  */
1051
        if (jffs_find_child(dir_f, name, len)) {
1052
                iput(dir);
1053
                return -EEXIST;
1054
        }
1055
 
1056
        /* Create a node and initialize it as much as needed.  */
1057
        if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
1058
                                                  GFP_KERNEL))) {
1059
                D(printk("jffs_symlink(): Allocation failed: node == NULL\n"));
1060
                iput(dir);
1061
                return -ENOMEM;
1062
        }
1063
        DJM(no_jffs_node++);
1064
        node->data_offset = 0;
1065
        node->removed_size = 0;
1066
 
1067
        /* Initialize the raw inode.  */
1068
        raw_inode.magic = JFFS_MAGIC_BITMASK;
1069
        raw_inode.ino = c->next_ino++;
1070
        raw_inode.pino = dir_f->ino;
1071
        raw_inode.version = 1;
1072
        raw_inode.mode = S_IFLNK | S_IRWXUGO;
1073
        raw_inode.uid = current->fsuid;
1074
        raw_inode.gid = current->fsgid;
1075
        raw_inode.atime = CURRENT_TIME;
1076
        raw_inode.mtime = raw_inode.atime;
1077
        raw_inode.ctime = raw_inode.atime;
1078
        raw_inode.offset = 0;
1079
        raw_inode.dsize = symname_len;
1080
        raw_inode.rsize = 0;
1081
        raw_inode.nsize = len;
1082
        raw_inode.nlink = 1;
1083
        raw_inode.spare = 0;
1084
        raw_inode.rename = 0;
1085
        raw_inode.deleted = 0;
1086
 
1087
        /* Write the new node to the flash.  */
1088
        if (jffs_write_node(c, node, &raw_inode, name,
1089
                            (const unsigned char *)symname) < 0) {
1090
                D(printk("jffs_symlink(): jffs_write_node() failed.\n"));
1091
                kfree(node);
1092
                DJM(no_jffs_node--);
1093
                iput(dir);
1094
                return -1;
1095
        }
1096
 
1097
        /* Insert the new node into the file system.  */
1098
        if (jffs_insert_node(c, 0, &raw_inode, name, node) < 0) {
1099
                iput(dir);
1100
                return -1;
1101
        }
1102
 
1103
        iput(dir);
1104
        return 0;
1105
} /* jffs_symlink()  */
1106
 
1107
 
1108
/* Read the path that a symbolic link is referring to.  */
1109
static int
1110
jffs_readlink(struct inode *inode, char *buffer, int buflen)
1111
{
1112
        struct jffs_file *f;
1113
        int i;
1114
        char *link;
1115
        int result;
1116
 
1117
        D2(printk("***jffs_readlink()\n"));
1118
 
1119
        /* Continue only if the file is a symbolic link.  */
1120
        if (!S_ISLNK(inode->i_mode)) {
1121
                result = -EINVAL;
1122
                goto jffs_readlink_end1;
1123
        }
1124
        f = (struct jffs_file *)inode->u.generic_ip;
1125
        ASSERT(if (!f) {
1126
                printk(KERN_ERR "jffs_readlink(): No reference to a "
1127
                       "jffs_file struct in inode.\n");
1128
                result = -1;
1129
                goto jffs_readlink_end1;
1130
        });
1131
        if (!(link = (char *)kmalloc(f->size + 1, GFP_KERNEL))) {
1132
                result = -ENOMEM;
1133
                goto jffs_readlink_end1;
1134
        }
1135
        if ((result = jffs_read_data(f, link, 0, f->size)) < 0) {
1136
                goto jffs_readlink_end2;
1137
        }
1138
        link[result] = '\0';
1139
        for (i = 0; (i < buflen) && (i < result); i++) {
1140
                put_user(link[i], buffer++);
1141
        }
1142
        UPDATE_ATIME(inode);
1143
 
1144
jffs_readlink_end2:
1145
        kfree(link);
1146
jffs_readlink_end1:
1147
        iput(inode);
1148
        return result;
1149
} /* jffs_readlink()  */
1150
 
1151
 
1152
static int
1153
jffs_follow_link(struct inode *dir, struct inode *inode, int flag,
1154
                 int mode, struct inode **res_inode)
1155
{
1156
        struct jffs_file *f;
1157
        char *link;
1158
        int r;
1159
 
1160
        D3(printk("jffs_follow_link(): dir = 0x%p, "
1161
                  "inode = 0x%p, flag = 0x%08x, mode = 0x%08x\n",
1162
                  dir, inode, flag, mode));
1163
 
1164
        *res_inode = 0;
1165
        if (!dir) {
1166
                dir = current->fs->root;
1167
                dir->i_count++;
1168
        }
1169
        if (!inode) {
1170
                iput(dir);
1171
                return -ENOENT;
1172
        }
1173
        if (!S_ISLNK(inode->i_mode)) {
1174
                *res_inode = inode;
1175
                iput(dir);
1176
                return 0;
1177
        }
1178
        if (current->link_count > 5) {
1179
                iput(inode);
1180
                iput(dir);
1181
                return -ELOOP;
1182
        }
1183
 
1184
        f = (struct jffs_file *)inode->u.generic_ip;
1185
        if (!(link = (char *)kmalloc(f->size + 1, GFP_KERNEL))) {
1186
                D(printk("jffs_follow_link(): kmalloc() failed.\n"));
1187
                iput(inode);
1188
                iput(dir);
1189
                return -ENOMEM;
1190
        }
1191
        r = jffs_read_data(f, link, 0, f->size);
1192
        if (r < f->size) {
1193
                D(printk("jffs_follow_link(): Failed to read symname.\n"));
1194
                kfree(link);
1195
                iput(inode);
1196
                iput(dir);
1197
                return -EIO;
1198
        }
1199
        link[r] = '\0';
1200
        UPDATE_ATIME(inode);
1201
        current->link_count++;
1202
        r = open_namei(link, flag, mode, res_inode, dir);
1203
        current->link_count--;
1204
        kfree(link);
1205
        iput(inode);
1206
        return r;
1207
} /* jffs_follow_link()  */
1208
 
1209
 
1210
/* Create an inode inside a JFFS directory (dir) and return it.  */
1211
static int
1212
jffs_create(struct inode *dir, const char *name, int len,
1213
            int mode, struct inode **result)
1214
{
1215
        struct jffs_raw_inode raw_inode;
1216
        struct jffs_control *c;
1217
        struct jffs_node *node;
1218
        struct jffs_file *dir_f; /* JFFS representation of the directory.  */
1219
        struct inode *inode;
1220
 
1221
        *result = (struct inode *)0;
1222
 
1223
        D1({
1224
                char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
1225
                memcpy(s, name, len);
1226
                s[len] = '\0';
1227
                printk("jffs_create(): dir: 0x%p, name: \"%s\"\n", dir, s);
1228
                kfree(s);
1229
        });
1230
 
1231
        if (!dir) {
1232
                return -ENOENT;
1233
        }
1234
        if (len > JFFS_MAX_NAME_LEN) {
1235
                iput(dir);
1236
                return -ENAMETOOLONG;
1237
        }
1238
 
1239
        dir_f = (struct jffs_file *)dir->u.generic_ip;
1240
        ASSERT(if (!dir_f) {
1241
                printk(KERN_ERR "jffs_create(): No reference to a "
1242
                       "jffs_file struct in inode.\n");
1243
                iput(dir);
1244
                return -1;
1245
        });
1246
 
1247
        c = dir_f->c;
1248
 
1249
        if (!JFFS_ENOUGH_SPACE(c->fmc)) {
1250
                D1(printk("jffs_create(): Free size = %u\n",
1251
                          jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
1252
                D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
1253
                iput(dir);
1254
                return -ENOSPC;
1255
        }
1256
 
1257
        /* If there already exists a file or directory with the same name,
1258
           then this operation should fail. I originally thought that VFS
1259
           should take care of this issue.  */
1260
        if (jffs_find_child(dir_f, name, len)) {
1261
                D(printk("jffs_create(): There already exists a file or "
1262
                         "directory named \"%s\"!\n", name));
1263
                iput(dir);
1264
                return -EEXIST;
1265
        }
1266
 
1267
        /* Create a node and initialize as much as needed.  */
1268
        if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
1269
                                                  GFP_KERNEL))) {
1270
                D(printk("jffs_create(): Allocation failed: node == 0\n"));
1271
                iput(dir);
1272
                return -ENOMEM;
1273
        }
1274
        DJM(no_jffs_node++);
1275
        node->data_offset = 0;
1276
        node->removed_size = 0;
1277
 
1278
        /* Initialize the raw inode.  */
1279
        raw_inode.magic = JFFS_MAGIC_BITMASK;
1280
        raw_inode.ino = c->next_ino++;
1281
        raw_inode.pino = dir_f->ino;
1282
        raw_inode.version = 1;
1283
        raw_inode.mode = mode;
1284
        raw_inode.uid = current->fsuid;
1285
        raw_inode.gid = current->fsgid;
1286
        raw_inode.atime = CURRENT_TIME;
1287
        raw_inode.mtime = raw_inode.atime;
1288
        raw_inode.ctime = raw_inode.atime;
1289
        raw_inode.offset = 0;
1290
        raw_inode.dsize = 0;
1291
        raw_inode.rsize = 0;
1292
        raw_inode.nsize = len;
1293
        raw_inode.nlink = 1;
1294
        raw_inode.spare = 0;
1295
        raw_inode.rename = 0;
1296
        raw_inode.deleted = 0;
1297
 
1298
        /* Write the new node to the flash.  */
1299
        if (jffs_write_node(c, node, &raw_inode, name, 0) < 0) {
1300
                D(printk("jffs_create(): jffs_write_node() failed.\n"));
1301
                kfree(node);
1302
                DJM(no_jffs_node--);
1303
                iput(dir);
1304
                return -1;
1305
        }
1306
 
1307
        /* Insert the new node into the file system.  */
1308
        if (jffs_insert_node(c, 0, &raw_inode, name, node) < 0) {
1309
                iput(dir);
1310
                return -1;
1311
        }
1312
 
1313
        /* Initialize an inode.  */
1314
        if (!(inode = get_empty_inode())) {
1315
                iput(dir);
1316
                return -1;
1317
        }
1318
        inode->i_dev = dir->i_sb->s_dev;
1319
        inode->i_ino = raw_inode.ino;
1320
        inode->i_mode = mode;
1321
        inode->i_nlink = raw_inode.nlink;
1322
        inode->i_uid = raw_inode.uid;
1323
        inode->i_gid = raw_inode.gid;
1324
        inode->i_rdev = 0;
1325
        inode->i_size = 0;
1326
        inode->i_atime = raw_inode.atime;
1327
        inode->i_mtime = raw_inode.mtime;
1328
        inode->i_ctime = raw_inode.ctime;
1329
        inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */
1330
        inode->i_blocks = 0;
1331
        inode->i_version = 0;
1332
        inode->i_nrpages = 0;
1333
        /*inode->i_sem = 0;*/
1334
        inode->i_op = &jffs_file_inode_operations;
1335
        inode->i_sb = dir->i_sb;
1336
        inode->i_wait = 0;
1337
        inode->i_flock = 0;
1338
        inode->i_count = 1;
1339
        inode->i_flags = dir->i_sb->s_flags;
1340
        inode->i_dirt = 1;
1341
        inode->u.generic_ip = (void *)jffs_find_file(c, raw_inode.ino);
1342
 
1343
        iput(dir);
1344
        *result = inode;
1345
        return 0;
1346
} /* jffs_create()  */
1347
 
1348
 
1349
/* Write, append or rewrite data to an existing file.  */
1350
static int
1351
jffs_file_write(struct inode *inode, struct file *filp,
1352
                const char *buf, int count)
1353
{
1354
        struct jffs_raw_inode raw_inode;
1355
        struct jffs_control *c;
1356
        struct jffs_file *f;
1357
        struct jffs_node *node;
1358
        int written = 0;
1359
        int pos;
1360
 
1361
        D2(printk("***jffs_file_write(): inode: 0x%p (ino: %lu), "
1362
                  "filp: 0x%p, buf: 0x%p, count: %d\n",
1363
                  inode, inode->i_ino, filp, buf, count));
1364
 
1365
        if (!inode) {
1366
                D(printk("jffs_file_write(): inode == NULL\n"));
1367
                return -EINVAL;
1368
        }
1369
 
1370
        if (inode->i_sb->s_flags & MS_RDONLY) {
1371
                D(printk("jffs_file_write(): MS_RDONLY\n"));
1372
                return -ENOSPC;
1373
        }
1374
        if (!S_ISREG(inode->i_mode)) {
1375
                D(printk("jffs_file_write(): inode->i_mode == 0x%08x\n",
1376
                         inode->i_mode));
1377
                return -EINVAL;
1378
        }
1379
 
1380
        if (!(f = (struct jffs_file *)inode->u.generic_ip)) {
1381
                D(printk("jffs_file_write(): inode->u.generic_ip = 0x%p\n",
1382
                         inode->u.generic_ip));
1383
                return -EINVAL;
1384
        }
1385
        c = f->c;
1386
 
1387
        if (!JFFS_ENOUGH_SPACE(c->fmc)) {
1388
                D1(printk("jffs_file_write(): Free size = %u\n",
1389
                          jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
1390
                D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
1391
                return -ENOSPC;
1392
        }
1393
 
1394
        if (filp->f_flags & O_APPEND) {
1395
                pos = inode->i_size;
1396
        }
1397
        else {
1398
                pos = filp->f_pos;
1399
        }
1400
 
1401
        /* Things are going to be written so we could allocate and
1402
           initialize the necessary data structures now.  */
1403
        if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
1404
                                                  GFP_KERNEL))) {
1405
                D(printk("jffs_file_write(): node == 0\n"));
1406
                return -ENOMEM;
1407
        }
1408
        DJM(no_jffs_node++);
1409
        node->data_offset = f->size;
1410
        node->removed_size = 0;
1411
 
1412
        /* Initialize the raw inode.  */
1413
        raw_inode.magic = JFFS_MAGIC_BITMASK;
1414
        raw_inode.ino = f->ino;
1415
        raw_inode.pino = f->pino;
1416
        raw_inode.version = f->highest_version + 1;
1417
        raw_inode.mode = f->mode;
1418
        raw_inode.uid = current->fsuid;
1419
        raw_inode.gid = current->fsgid;
1420
        raw_inode.atime = CURRENT_TIME;
1421
        raw_inode.mtime = raw_inode.atime;
1422
        raw_inode.ctime = f->ctime;
1423
        raw_inode.offset = f->size;
1424
        raw_inode.dsize = count;
1425
        raw_inode.rsize = 0;
1426
        raw_inode.nsize = 0;
1427
        raw_inode.nlink = f->nlink;
1428
        raw_inode.spare = 0;
1429
        raw_inode.rename = 0;
1430
        raw_inode.deleted = 0;
1431
 
1432
        /* Write the new node to the flash.  */
1433
        if ((written = jffs_write_node(c, node, &raw_inode, 0,
1434
                                       (const unsigned char *)buf)) < 0) {
1435
                D(printk("jffs_file_write(): jffs_write_node() failed.\n"));
1436
                kfree(node);
1437
                DJM(no_jffs_node--);
1438
                return -1;
1439
        }
1440
 
1441
        /* Insert the new node into the file system.  */
1442
        if (jffs_insert_node(c, f, &raw_inode, 0, node) < 0) {
1443
                return -1;
1444
        }
1445
        pos += written;
1446
        filp->f_pos = pos;
1447
 
1448
        D3(printk("jffs_file_write(): new f_pos %d.\n", pos));
1449
 
1450
        /* Fix things in the real inode.  */
1451
        if (pos > inode->i_size) {
1452
                inode->i_size = pos;
1453
        }
1454
        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
1455
        inode->i_dirt = 1;
1456
 
1457
        return written;
1458
} /* jffs_file_write()  */
1459
 
1460
 
1461
/* This is our ioctl() routine.  */
1462
static int
1463
jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1464
           unsigned long arg)
1465
{
1466
        struct jffs_control *c;
1467
        int err;
1468
 
1469
        D2(printk("***jffs_ioctl(): cmd = 0x%08x, arg = 0x%08lx\n", cmd, arg));
1470
 
1471
        if (!(c = (struct jffs_control *)inode->i_sb->u.generic_sbp)) {
1472
                printk(KERN_ERR "JFFS: Bad inode in ioctl() call. "
1473
                       "(cmd = 0x%08x)\n", cmd);
1474
                return -1;
1475
        }
1476
 
1477
        switch (cmd) {
1478
        case JFFS_PRINT_HASH:
1479
                jffs_print_hash_table(c);
1480
                break;
1481
        case JFFS_PRINT_TREE:
1482
                jffs_print_tree(c->root, 0);
1483
                break;
1484
        case JFFS_GET_STATUS:
1485
                {
1486
                        struct jffs_flash_status fst;
1487
                        struct jffs_fmcontrol *fmc = c->fmc;
1488
                        printk("Flash status -- ");
1489
                        err = verify_area(VERIFY_WRITE,
1490
                                          (struct jffs_flash_status *)arg,
1491
                                          sizeof(struct jffs_flash_status));
1492
                        if (err) {
1493
                                D(printk("jffs_ioctl(): Bad arg in "
1494
                                         "JFFS_GET_STATUS ioctl!\n"));
1495
                                return err;
1496
                        }
1497
                        fst.size = fmc->flash_size;
1498
                        fst.used = fmc->used_size;
1499
                        fst.dirty = fmc->dirty_size;
1500
                        fst.begin = fmc->head->offset;
1501
                        fst.end = fmc->tail->offset + fmc->tail->size;
1502
                        printk("size: %d, used: %d, dirty: %d, "
1503
                               "begin: %d, end: %d\n",
1504
                               fst.size, fst.used, fst.dirty,
1505
                               fst.begin, fst.end);
1506
                        memcpy_tofs((struct jffs_flash_status *)arg, &fst,
1507
                                    sizeof(struct jffs_flash_status));
1508
                }
1509
                break;
1510
        default:
1511
                return -ENOTTY;
1512
        }
1513
 
1514
        return 0;
1515
} /* jffs_ioctl()  */
1516
 
1517
 
1518
static struct file_operations jffs_file_operations =
1519
{
1520
        NULL,                 /* lseek - default */
1521
        generic_file_read,    /* read */
1522
        jffs_file_write,      /* write */
1523
        NULL,                 /* readdir */
1524
        NULL,                 /* select - default */
1525
        jffs_ioctl,           /* ioctl */
1526
        generic_file_mmap,    /* mmap */
1527
        NULL,                 /* open */
1528
        NULL,                 /* release */
1529
        NULL,                 /* fsync */
1530
        NULL,                 /* fasync */
1531
        NULL,                 /* check_media_change */
1532
        NULL                  /* revalidate */
1533
};
1534
 
1535
static struct inode_operations jffs_file_inode_operations =
1536
{
1537
        &jffs_file_operations,
1538
        NULL,                 /* create */
1539
        jffs_lookup,          /* lookup */
1540
        NULL,                 /* link */
1541
        NULL,                 /* unlink */
1542
        NULL,                 /* symlink */
1543
        NULL,                 /* mkdir */
1544
        NULL,                 /* rmdir */
1545
        NULL,                 /* mknod */
1546
        NULL,                 /* rename */
1547
        NULL,                 /* readlink */
1548
        NULL,                 /* follow_link */
1549
        jffs_readpage,        /* readpage */
1550
        NULL,                 /* writepage */
1551
        NULL,                 /* bmap -- not really */
1552
        NULL,                 /* truncate */
1553
        NULL,                 /* permission */
1554
        NULL                  /* smap */
1555
};
1556
 
1557
 
1558
static struct file_operations jffs_dir_operations =
1559
{
1560
        NULL,                 /* lseek - default */
1561
        NULL,                 /* read */
1562
        NULL,                 /* write */
1563
        jffs_readdir,         /* readdir */
1564
        NULL,                 /* select - default */
1565
        NULL,                 /* ioctl */
1566
        NULL,                 /* mmap */
1567
        NULL,                 /* open */
1568
        NULL,                 /* release */
1569
        NULL,                 /* fsync */
1570
        NULL,                 /* fasync */
1571
        NULL,                 /* check_media_change */
1572
        NULL                  /* revalidate */
1573
};
1574
 
1575
static struct inode_operations jffs_dir_inode_operations =
1576
{
1577
        &jffs_dir_operations,
1578
        jffs_create,           /* create */
1579
        jffs_lookup,           /* lookup */
1580
        NULL,                  /* link */
1581
        jffs_unlink,           /* unlink */
1582
        jffs_symlink,          /* symlink */
1583
        jffs_mkdir,            /* mkdir */
1584
        jffs_rmdir,            /* rmdir */
1585
        jffs_mknod,            /* mknod */
1586
        jffs_rename,           /* rename */
1587
        NULL,                  /* readlink */
1588
        NULL,                  /* follow_link */
1589
        NULL,                  /* readpage */
1590
        NULL,                  /* writepage */
1591
        NULL,                  /* bmap */
1592
        NULL,                  /* truncate */
1593
        NULL,                  /* permission */
1594
        NULL                   /* smap */
1595
};
1596
 
1597
 
1598
static struct inode_operations jffs_symlink_inode_operations =
1599
{
1600
        NULL,                  /* No file operations.  */
1601
        NULL,                  /* create */
1602
        NULL,                  /* lookup */
1603
        NULL,                  /* link */
1604
        NULL,                  /* unlink */
1605
        NULL,                  /* symlink */
1606
        NULL,                  /* mkdir */
1607
        NULL,                  /* rmdir */
1608
        NULL,                  /* mknod */
1609
        NULL,                  /* rename */
1610
        jffs_readlink,         /* readlink */
1611
        jffs_follow_link,      /* follow_link */
1612
        NULL,                  /* readpage */
1613
        NULL,                  /* writepage */
1614
        NULL,                  /* bmap */
1615
        NULL,                  /* truncate */
1616
        NULL,                  /* permission */
1617
        NULL                   /* smap */
1618
};
1619
 
1620
 
1621
/* Initialize an inode for the VFS.  */
1622
static void
1623
jffs_read_inode(struct inode *inode)
1624
{
1625
        struct jffs_file *f;
1626
        struct jffs_control *c;
1627
 
1628
        D3(printk("jffs_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
1629
 
1630
        if (!inode->i_sb) {
1631
                D(printk("jffs_read_inode(): !inode->i_sb ==> "
1632
                         "No super block!\n"));
1633
                return;
1634
        }
1635
        c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
1636
        if (!(f = jffs_find_file(c, inode->i_ino))) {
1637
                D(printk("jffs_read_inode(): No such inode (%lu).\n",
1638
                         inode->i_ino));
1639
                return;
1640
        }
1641
        inode->u.generic_ip = (void *)f;
1642
        inode->i_mode = f->mode;
1643
        inode->i_nlink = f->nlink;
1644
        inode->i_uid = f->uid;
1645
        inode->i_gid = f->gid;
1646
        inode->i_size = f->size;
1647
        inode->i_atime = f->atime;
1648
        inode->i_mtime = f->mtime;
1649
        inode->i_ctime = f->ctime;
1650
        inode->i_blksize = PAGE_SIZE;
1651
        inode->i_blocks = 0;
1652
        if (S_ISREG(inode->i_mode)) {
1653
                inode->i_op = &jffs_file_inode_operations;
1654
        }
1655
        else if (S_ISDIR(inode->i_mode)) {
1656
                inode->i_op = &jffs_dir_inode_operations;
1657
        }
1658
        else if (S_ISLNK(inode->i_mode)) {
1659
                inode->i_op = &jffs_symlink_inode_operations;
1660
        }
1661
        else if (S_ISCHR(inode->i_mode)) {
1662
                inode->i_op = &chrdev_inode_operations;
1663
        }
1664
        else if (S_ISBLK(inode->i_mode)) {
1665
                inode->i_op = &blkdev_inode_operations;
1666
        }
1667
 
1668
        /* If the node is a device of some sort, then the number of the
1669
           device should be read from the flash memory and then added
1670
           to the inode's i_rdev member.  */
1671
        if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
1672
                kdev_t rdev;
1673
                jffs_read_data(f, (char *)&rdev, 0, sizeof(kdev_t));
1674
                inode->i_rdev = kdev_t_to_nr(rdev);
1675
        }
1676
}
1677
 
1678
 
1679
void
1680
jffs_write_super(struct super_block *sb)
1681
{
1682
#ifdef USE_GC
1683
        jffs_garbage_collect((struct jffs_control *)sb->u.generic_sbp);
1684
#endif
1685
}
1686
 
1687
 
1688
static struct super_operations jffs_ops =
1689
{
1690
        jffs_read_inode,    /* read inode */
1691
        jffs_notify_change, /* notify change */
1692
        NULL,               /* write inode */
1693
        NULL,               /* put inode */
1694
        jffs_put_super,     /* put super */
1695
        jffs_write_super,   /* write super */
1696
        jffs_statfs,        /* statfs */
1697
        NULL                /* remount */
1698
};
1699
 
1700
 
1701
static struct file_system_type jffs_fs_type =
1702
{
1703
        jffs_read_super,
1704
        "jffs",
1705
        1,
1706
        NULL
1707
};
1708
 
1709
 
1710
int
1711
init_jffs_fs(void)
1712
{
1713
        printk("JFFS "
1714
#if defined(JFFS_FLASH_SHORTCUT) && JFFS_FLASH_SHORTCUT
1715
               "(Flash Shortcut) "
1716
#endif
1717
               "version " JFFS_VERSION_STRING
1718
               ", (C) 1999, 2000  Axis Communications AB\n");
1719
        return register_filesystem(&jffs_fs_type);
1720
}
1721
 
1722
 
1723
#ifdef MODULE
1724
int
1725
init_module(void)
1726
{
1727
        int status;
1728
 
1729
        if ((status = init_jffs_fs()) == 0) {
1730
                register_symtab(0);
1731
        }
1732
        return status;
1733
}
1734
 
1735
void
1736
cleanup_module(void)
1737
{
1738
        unregister_filesystem(&jffs_fs_type);
1739
}
1740
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.