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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [jffs/] [inode-v23.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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