The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/jffs/inode-v23.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    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.70 2001/10/02 09:16:02 dwmw2 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");

Cache object: 70bc87d9a415c245781b06791ae7b337


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.