~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/jffs/inode-v23.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.