]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/fs/jffs2/v2_0/src/fs-ecos.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / fs / jffs2 / v2_0 / src / fs-ecos.c
1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright (C) 2001-2003 Red Hat, Inc.
5  *
6  * Created by Dominic Ostrowski <dominic.ostrowski@3glab.com>
7  * Contributors: David Woodhouse, Nick Garnett, Richard Panton.
8  *
9  * For licensing information, see the file 'LICENCE' in this directory.
10  *
11  * $Id$
12  *
13  */
14
15 #include <linux/kernel.h>
16 #include "nodelist.h"
17 #include <linux/pagemap.h>
18 #include <linux/crc32.h>
19 #include "compr.h"
20 #include <errno.h>
21 #include <string.h>
22 #include <cyg/io/config_keys.h>
23
24 #if (__GNUC__ == 3) && (__GNUC_MINOR__ == 2) && \
25     (defined (__arm__) || defined (_mips))
26 #error This compiler is known to be broken. Please see:
27 #error "http://ecos.sourceware.org/ml/ecos-patches/2003-08/msg00006.html"
28 #endif
29
30 //==========================================================================
31 // Forward definitions
32
33 // Filesystem operations
34 static int jffs2_mount(cyg_fstab_entry * fste, cyg_mtab_entry * mte);
35 static int jffs2_umount(cyg_mtab_entry * mte);
36 static int jffs2_open(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
37                       int mode, cyg_file * fte);
38 #ifdef CYGOPT_FS_JFFS2_WRITE
39 static int jffs2_ops_unlink(cyg_mtab_entry * mte, cyg_dir dir,
40                             const char *name);
41 static int jffs2_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name);
42 static int jffs2_ops_rmdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name);
43 static int jffs2_ops_rename(cyg_mtab_entry * mte, cyg_dir dir1,
44                             const char *name1, cyg_dir dir2, const char *name2);
45 static int jffs2_ops_link(cyg_mtab_entry * mte, cyg_dir dir1, const char *name1,
46                           cyg_dir dir2, const char *name2, int type);
47 #endif
48 static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
49                          cyg_file * fte);
50 static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
51                        cyg_dir * dir_out);
52 static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
53                       struct stat *buf);
54 static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
55                          int key, void *buf, int len);
56 static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
57                          int key, void *buf, int len);
58
59 // File operations
60 static int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
61 #ifdef CYGOPT_FS_JFFS2_WRITE
62 static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
63 #endif
64 static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence);
65 static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
66                           CYG_ADDRWORD data);
67 static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
68 static int jffs2_fo_close(struct CYG_FILE_TAG *fp);
69 static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf);
70 static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
71                             int len);
72 static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
73                             int len);
74
75 // Directory operations
76 static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
77 static int jffs2_fo_dirlseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence);
78
79
80 static int jffs2_read_inode (struct _inode *inode);
81 static void jffs2_clear_inode (struct _inode *inode);
82 static int jffs2_truncate_file (struct _inode *inode);
83
84 //==========================================================================
85 // Filesystem table entries
86
87 // -------------------------------------------------------------------------
88 // Fstab entry.
89 // This defines the entry in the filesystem table.
90 // For simplicity we use _FILESYSTEM synchronization for all accesses since
91 // we should never block in any filesystem operations.
92
93 #ifdef CYGOPT_FS_JFFS2_WRITE
94 FSTAB_ENTRY(jffs2_fste, "jffs2", 0,
95             CYG_SYNCMODE_FILE_FILESYSTEM | CYG_SYNCMODE_IO_FILESYSTEM,
96             jffs2_mount,
97             jffs2_umount,
98             jffs2_open,
99             jffs2_ops_unlink,
100             jffs2_ops_mkdir,
101             jffs2_ops_rmdir,
102             jffs2_ops_rename,
103             jffs2_ops_link,
104             jffs2_opendir,
105             jffs2_chdir, jffs2_stat, jffs2_getinfo, jffs2_setinfo);
106 #else
107 FSTAB_ENTRY(jffs2_fste, "jffs2", 0,
108             CYG_SYNCMODE_FILE_FILESYSTEM | CYG_SYNCMODE_IO_FILESYSTEM,
109             jffs2_mount,
110             jffs2_umount,
111             jffs2_open,
112             (cyg_fsop_unlink *)cyg_fileio_erofs,
113             (cyg_fsop_mkdir *)cyg_fileio_erofs,
114             (cyg_fsop_rmdir *)cyg_fileio_erofs,
115             (cyg_fsop_rename *)cyg_fileio_erofs,
116             (cyg_fsop_link *)cyg_fileio_erofs,
117             jffs2_opendir,
118             jffs2_chdir, jffs2_stat, jffs2_getinfo, jffs2_setinfo);
119 #endif
120
121 // -------------------------------------------------------------------------
122 // File operations.
123 // This set of file operations are used for normal open files.
124
125 static cyg_fileops jffs2_fileops = {
126         jffs2_fo_read,
127 #ifdef CYGOPT_FS_JFFS2_WRITE
128         jffs2_fo_write,
129 #else
130         (cyg_fileop_write *) cyg_fileio_erofs,
131 #endif
132         jffs2_fo_lseek,
133         jffs2_fo_ioctl,
134         cyg_fileio_seltrue,
135         jffs2_fo_fsync,
136         jffs2_fo_close,
137         jffs2_fo_fstat,
138         jffs2_fo_getinfo,
139         jffs2_fo_setinfo
140 };
141
142 // -------------------------------------------------------------------------
143 // Directory file operations.
144 // This set of operations are used for open directories. Most entries
145 // point to error-returning stub functions. Only the read, lseek and
146 // close entries are functional.
147
148 static cyg_fileops jffs2_dirops = {
149         jffs2_fo_dirread,
150         (cyg_fileop_write *) cyg_fileio_enosys,
151         jffs2_fo_dirlseek,
152         (cyg_fileop_ioctl *) cyg_fileio_enosys,
153         cyg_fileio_seltrue,
154         (cyg_fileop_fsync *) cyg_fileio_enosys,
155         jffs2_fo_close,
156         (cyg_fileop_fstat *) cyg_fileio_enosys,
157         (cyg_fileop_getinfo *) cyg_fileio_enosys,
158         (cyg_fileop_setinfo *) cyg_fileio_enosys
159 };
160
161 //==========================================================================
162 // STATIC VARIABLES !!!
163
164 static unsigned char gc_buffer[PAGE_CACHE_SIZE];        //avoids malloc when user may be under memory pressure
165 static unsigned char n_fs_mounted = 0;  // a counter to track the number of jffs2 instances mounted
166
167 //==========================================================================
168 // Directory operations
169
170 struct jffs2_dirsearch {
171         struct _inode *dir;         // directory to search
172         const unsigned char *path;  // path to follow
173         struct _inode *node;        // Node found
174         const unsigned char *name;  // last name fragment used
175         int namelen;                // name fragment length
176         cyg_bool last;              // last name in path?
177 };
178
179 typedef struct jffs2_dirsearch jffs2_dirsearch;
180
181 //==========================================================================
182 // Ref count and nlink management
183
184
185 // FIXME: This seems like real cruft. Wouldn't it be better just to do the
186 // right thing?
187 static void icache_evict(struct _inode *root_i, struct _inode *i)
188 {
189         struct _inode *this = root_i, *next;
190
191  restart:
192         D2(printf("icache_evict\n"));
193         // If this is an absolute search path from the root,
194         // remove all cached inodes with i_count of zero (these are only 
195         // held where needed for dotdot filepaths)
196         while (this) {
197                 next = this->i_cache_next;
198                 if (this != i && this->i_count == 0) {
199                         struct _inode *parent = this->i_parent;
200                         if (this->i_cache_next)
201                                 this->i_cache_next->i_cache_prev = this->i_cache_prev;
202                         if (this->i_cache_prev)
203                                 this->i_cache_prev->i_cache_next = this->i_cache_next;
204                         jffs2_clear_inode(this);
205                         memset(this, 0x5a, sizeof(*this));
206                         free(this);
207                         if (parent && parent != this) {
208                                 parent->i_count--;
209                                 this = root_i;
210                                 goto restart;
211                         }
212                 }
213                 this = next;
214         }
215 }
216
217 //==========================================================================
218 // Directory search
219
220 // -------------------------------------------------------------------------
221 // init_dirsearch()
222 // Initialize a dirsearch object to start a search
223
224 static void init_dirsearch(jffs2_dirsearch * ds,
225                            struct _inode *dir, const unsigned char *name)
226 {
227         D2(printf("init_dirsearch name = %s\n", name));
228         D2(printf("init_dirsearch dir = %x\n", dir));
229
230         dir->i_count++;
231         ds->dir = dir;
232         ds->path = name;
233         ds->node = dir;
234         ds->name = name;
235         ds->namelen = 0;
236         ds->last = false;
237 }
238
239 // -------------------------------------------------------------------------
240 // find_entry()
241 // Search a single directory for the next name in a path and update the
242 // dirsearch object appropriately.
243
244 static int find_entry(jffs2_dirsearch * ds)
245 {
246         struct _inode *dir = ds->dir;
247         const unsigned char *name = ds->path;
248         const unsigned char *n = name;
249         char namelen = 0;
250         struct _inode *d;
251
252         D2(printf("find_entry\n"));
253
254         // check that we really have a directory
255         if (!S_ISDIR(dir->i_mode))
256                 return ENOTDIR;
257
258         // Isolate the next element of the path name. 
259         while (*n != '\0' && *n != '/')
260                 n++, namelen++;
261
262         // Check if this is the last path element.
263         while( *n == '/') n++;
264         if (*n == '\0')
265                 ds->last = true;
266
267         // update name in dirsearch object
268         ds->name = name;
269         ds->namelen = namelen;
270
271         if (name[0] == '.')
272                 switch (namelen) {
273                 default:
274                         break;
275                 case 2:
276                         // Dot followed by not Dot, treat as any other name 
277                         if (name[1] != '.')
278                                 break;
279                         // Dot Dot 
280                         // Move back up the search path
281                         D2(printf("find_entry found ..\n"));
282                         ds->dir = ds->node;
283                         ds->node = ds->dir->i_parent;
284                         ds->node->i_count++;
285                         return ENOERR;
286                 case 1:
287                         // Dot is consumed
288                         D2(printf("find_entry found .\n"));
289                         ds->node = ds->dir;
290                         ds->dir->i_count++;
291                         return ENOERR;
292                 }
293
294         // Here we have the name and its length set up.
295         // Search the directory for a matching entry
296
297         D2(printf("find_entry for name = %s\n", ds->path));
298         d = jffs2_lookup(dir, name, namelen);
299         D2(printf("find_entry got dir = %x\n", d));
300
301         if (d == NULL)
302                 return ENOENT;
303         if (IS_ERR(d))
304                 return -PTR_ERR(d);
305
306         // If it's a new directory inode, increase refcount on its parent
307         if (S_ISDIR(d->i_mode) && !d->i_parent) {
308                 d->i_parent = dir;
309                 dir->i_count++;
310         }
311
312         // pass back the node we have found
313         ds->node = d;
314         return ENOERR;
315
316 }
317
318 // -------------------------------------------------------------------------
319 // jffs2_find()
320 // Main interface to directory search code. This is used in all file
321 // level operations to locate the object named by the pathname.
322
323 // Returns with use count incremented on both the sought object and 
324 // the directory it was found in
325 static int jffs2_find(jffs2_dirsearch * d)
326 {
327         int err;
328
329         D2(printf("jffs2_find for path =%s\n", d->path));
330
331         // Short circuit empty paths
332         if (*(d->path) == '\0') {
333                 d->node->i_count++;
334                 return ENOERR;
335         }
336
337         // iterate down directory tree until we find the object
338         // we want.
339         for (;;) {
340                 err = find_entry(d);
341
342                 if (err != ENOERR)
343                         return err;
344
345                 if (d->last)
346                         return ENOERR;
347
348                 /* We're done with it, although it we found a subdir that
349                    will have caused the refcount to have been increased */
350                 jffs2_iput(d->dir);
351
352                 // Update dirsearch object to search next directory.
353                 d->dir = d->node;
354                 d->path += d->namelen;
355                 while (*(d->path) == '/')
356                         d->path++;      // skip dirname separators
357         }
358 }
359
360 //==========================================================================
361 // Pathconf support
362 // This function provides support for pathconf() and fpathconf().
363
364 static int jffs2_pathconf(struct _inode *node, struct cyg_pathconf_info *info)
365 {
366         int err = ENOERR;
367         D2(printf("jffs2_pathconf\n"));
368
369         switch (info->name) {
370         case _PC_LINK_MAX:
371                 info->value = LINK_MAX;
372                 break;
373
374         case _PC_MAX_CANON:
375                 info->value = -1;       // not supported
376                 err = EINVAL;
377                 break;
378
379         case _PC_MAX_INPUT:
380                 info->value = -1;       // not supported
381                 err = EINVAL;
382                 break;
383
384         case _PC_NAME_MAX:
385                 info->value = NAME_MAX;
386                 break;
387
388         case _PC_PATH_MAX:
389                 info->value = PATH_MAX;
390                 break;
391
392         case _PC_PIPE_BUF:
393                 info->value = -1;       // not supported
394                 err = EINVAL;
395                 break;
396
397         case _PC_ASYNC_IO:
398                 info->value = -1;       // not supported
399                 err = EINVAL;
400                 break;
401
402         case _PC_CHOWN_RESTRICTED:
403                 info->value = -1;       // not supported
404                 err = EINVAL;
405                 break;
406
407         case _PC_NO_TRUNC:
408                 info->value = 0;
409                 break;
410
411         case _PC_PRIO_IO:
412                 info->value = 0;
413                 break;
414
415         case _PC_SYNC_IO:
416                 info->value = 0;
417                 break;
418
419         case _PC_VDISABLE:
420                 info->value = -1;       // not supported
421                 err = EINVAL;
422                 break;
423
424         default:
425                 err = EINVAL;
426                 break;
427         }
428
429         return err;
430 }
431
432 //==========================================================================
433 // Filesystem operations
434
435 // -------------------------------------------------------------------------
436 // jffs2_mount()
437 // Process a mount request. This mainly creates a root for the
438 // filesystem.
439 static int jffs2_read_super(struct super_block *sb)
440 {
441         struct jffs2_sb_info *c;
442         Cyg_ErrNo err;
443         cyg_uint32 len;
444         cyg_io_flash_getconfig_devsize_t ds;
445         cyg_io_flash_getconfig_blocksize_t bs;
446
447         D1(printk(KERN_DEBUG "jffs2: read_super\n"));
448
449         c = JFFS2_SB_INFO(sb);
450
451         len = sizeof (ds);
452         err = cyg_io_get_config(sb->s_dev,
453                                 CYG_IO_GET_CONFIG_FLASH_DEVSIZE, &ds, &len);
454         if (err != ENOERR) {
455                 D1(printf
456                    ("jffs2: cyg_io_get_config failed to get dev size: %d\n",
457                     err));
458                 return err;
459         }
460         len = sizeof (bs);
461         bs.offset = 0;
462         err = cyg_io_get_config(sb->s_dev,
463                                 CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE, &bs, &len);
464         if (err != ENOERR) {
465                 D1(printf
466                    ("jffs2: cyg_io_get_config failed to get block size: %d\n",
467                     err));
468                 return err;
469         }
470
471         c->sector_size = bs.block_size;
472         c->flash_size = ds.dev_size;
473         c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
474
475         err = jffs2_do_mount_fs(c);
476         if (err)
477                 return -err;
478
479         D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n"));
480         sb->s_root = jffs2_iget(sb, 1);
481         if (IS_ERR(sb->s_root)) {
482                 D1(printk(KERN_WARNING "get root inode failed\n"));
483                 err = PTR_ERR(sb->s_root);
484                 sb->s_root = NULL;
485                 goto out_nodes;
486         }
487
488         return 0;
489
490       out_nodes:
491         jffs2_free_ino_caches(c);
492         jffs2_free_raw_node_refs(c);
493         free(c->blocks);
494
495         return err;
496 }
497
498 static int jffs2_mount(cyg_fstab_entry * fste, cyg_mtab_entry * mte)
499 {
500         extern cyg_mtab_entry cyg_mtab[], cyg_mtab_end;
501         struct super_block *jffs2_sb = NULL;
502         struct jffs2_sb_info *c;
503         cyg_mtab_entry *m;
504         cyg_io_handle_t t;
505         Cyg_ErrNo err;
506
507         D2(printf("jffs2_mount\n"));
508
509         err = cyg_io_lookup(mte->devname, &t);
510         if (err != ENOERR)
511                 return -err;
512
513         // Iterate through the mount table to see if we're mounted
514         // FIXME: this should be done better - perhaps if the superblock
515         // can be stored as an inode in the icache.
516         for (m = &cyg_mtab[0]; m != &cyg_mtab_end; m++) {
517                 // stop if there are more than the configured maximum
518                 if (m - &cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX) {
519                         m = &cyg_mtab_end;
520                         break;
521                 }
522                 if (m->valid && strcmp(m->fsname, "jffs2") == 0 &&
523                     strcmp(m->devname, mte->devname) == 0) {
524                         jffs2_sb = (struct super_block *) m->data;
525                 }
526         }
527
528         if (jffs2_sb == NULL) {
529                 jffs2_sb = malloc(sizeof (struct super_block));
530
531                 if (jffs2_sb == NULL)
532                         return ENOMEM;
533
534                 c = JFFS2_SB_INFO(jffs2_sb);
535                 memset(jffs2_sb, 0, sizeof (struct super_block));
536                 jffs2_sb->s_dev = t;
537
538                 c->inocache_list = malloc(sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
539                 if (!c->inocache_list) {
540                         free(jffs2_sb);
541                         return ENOMEM;
542                 }
543                 memset(c->inocache_list, 0, sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
544                 if (n_fs_mounted++ == 0) {
545                         jffs2_create_slab_caches(); // No error check, cannot fail
546                         jffs2_compressors_init(); 
547                 }
548
549                 err = jffs2_read_super(jffs2_sb);
550
551                 if (err) {
552                         if (--n_fs_mounted == 0) {
553                                 jffs2_destroy_slab_caches();
554                                 jffs2_compressors_exit();
555                         }
556                         
557                         free(jffs2_sb);
558                         free(c->inocache_list);
559                         return err;
560                 }
561
562                 jffs2_sb->s_root->i_parent = jffs2_sb->s_root;  // points to itself, no dotdot paths above mountpoint
563                 jffs2_sb->s_root->i_cache_prev = NULL;  // root inode, so always null
564                 jffs2_sb->s_root->i_cache_next = NULL;
565                 jffs2_sb->s_root->i_count = 1;  // Ensures the root inode is always in ram until umount
566
567                 D2(printf("jffs2_mount erasing pending blocks\n"));
568 #ifdef CYGOPT_FS_JFFS2_WRITE
569                 if (!jffs2_is_readonly(c))
570                     jffs2_erase_pending_blocks(c,0);
571 #endif
572 #ifdef CYGOPT_FS_JFFS2_GCTHREAD
573                 jffs2_start_garbage_collect_thread(c);
574 #endif
575         }
576         mte->data = (CYG_ADDRWORD) jffs2_sb;
577
578         jffs2_sb->s_mount_count++;
579         mte->root = (cyg_dir) jffs2_sb->s_root;
580         D2(printf("jffs2_mounted superblock at %x\n", mte->root));
581
582         return ENOERR;
583 }
584
585 extern cyg_dir cyg_cdir_dir;
586 extern cyg_mtab_entry *cyg_cdir_mtab_entry;
587
588 // -------------------------------------------------------------------------
589 // jffs2_umount()
590 // Unmount the filesystem. 
591
592 static int jffs2_umount(cyg_mtab_entry * mte)
593 {
594         struct _inode *root = (struct _inode *) mte->root;
595         struct super_block *jffs2_sb = root->i_sb;
596         struct jffs2_sb_info *c = JFFS2_SB_INFO(jffs2_sb);
597         struct jffs2_full_dirent *fd, *next;
598
599         D2(printf("jffs2_umount\n"));
600
601         // Only really umount if this is the only mount
602         if (jffs2_sb->s_mount_count == 1) {
603                 icache_evict(root, NULL);
604                 if (root->i_cache_next != NULL) {
605                         struct _inode *inode = root;
606                         printf("Refuse to unmount.\n");
607                         while (inode) {
608                                 printf("Ino #%u has use count %d\n",
609                                        inode->i_ino, inode->i_count);
610                                 inode = inode->i_cache_next;
611                         }
612                         // root icount was set to 1 on mount
613                         return EBUSY;
614                 }
615                 if (root->i_count == 2 &&
616                     cyg_cdir_mtab_entry == mte &&
617                     cyg_cdir_dir == (cyg_dir)root &&
618                     !strcmp(mte->name, "/")) {
619                         /* If we were mounted on root, there's no
620                            way for the cwd to change out and free 
621                            the file system for unmounting. So we hack
622                            it -- if cwd is '/' we unset it. Perhaps
623                            we should allow chdir(NULL) to unset
624                            cyg_cdir_dir? */
625                         cyg_cdir_dir = CYG_DIR_NULL;
626                         jffs2_iput(root);
627                 }
628                 /* Argh. The fileio code sets this; never clears it */
629                 if (cyg_cdir_mtab_entry == mte)
630                         cyg_cdir_mtab_entry = NULL;
631
632                 if (root->i_count != 1) {
633                         printf("Ino #1 has use count %d\n",
634                                root->i_count);
635                         return EBUSY;
636                 }
637 #ifdef CYGOPT_FS_JFFS2_GCTHREAD
638                 jffs2_stop_garbage_collect_thread(c);
639 #endif
640                 jffs2_iput(root);       // Time to free the root inode
641
642                 // free directory entries
643                 for (fd = root->jffs2_i.dents; fd; fd = next) {
644                   next=fd->next;
645                   jffs2_free_full_dirent(fd);
646                 }
647
648                 free(root);
649                 //Clear root inode
650                 //root_i = NULL;
651
652                 // Clean up the super block and root inode
653                 jffs2_free_ino_caches(c);
654                 jffs2_free_raw_node_refs(c);
655                 free(c->blocks);
656                 free(c->inocache_list);
657                 free(jffs2_sb);
658                 // Clear superblock & root pointer
659                 mte->root = CYG_DIR_NULL;
660                 mte->data = 0;
661                 mte->fs->data = 0;      // fstab entry, visible to all mounts. No current mount
662                 // That's all folks.
663                 D2(printf("jffs2_umount No current mounts\n"));
664         } else {
665                 jffs2_sb->s_mount_count--;
666         }
667         if (--n_fs_mounted == 0) {
668                 jffs2_destroy_slab_caches();        
669                 jffs2_compressors_exit();
670         }
671         return ENOERR;
672 }
673
674 // -------------------------------------------------------------------------
675 // jffs2_open()
676 // Open a file for reading or writing.
677
678 static int jffs2_open(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
679                       int mode, cyg_file * file)
680 {
681
682         jffs2_dirsearch ds;
683         struct _inode *node = NULL;
684         int err;
685
686         D2(printf("jffs2_open\n"));
687
688         /* If no chdir has been called and we were the first file system
689            mounted, we get called with dir == NULL. Deal with it */
690         if (!dir)
691                 dir = mte->root;
692
693 #ifndef CYGOPT_FS_JFFS2_WRITE
694         if (mode & (O_CREAT|O_TRUNC|O_WRONLY))
695                 return EROFS;
696 #endif
697         init_dirsearch(&ds, (struct _inode *) dir, 
698                        (const unsigned char *) name);
699
700         err = jffs2_find(&ds);
701
702         if (err == ENOENT) {
703 #ifdef CYGOPT_FS_JFFS2_WRITE
704                 if (ds.last && (mode & O_CREAT)) {
705
706                         // No node there, if the O_CREAT bit is set then we must
707                         // create a new one. The dir and name fields of the dirsearch
708                         // object will have been updated so we know where to put it.
709
710                         err = jffs2_create(ds.dir, ds.name, S_IRUGO|S_IXUGO|S_IWUSR|S_IFREG, &node);
711
712                         if (err != 0) {
713                                 //Possible orphaned inode on the flash - but will be gc'd
714                                 jffs2_iput(ds.dir);
715                                 return -err;
716                         }
717
718                         err = ENOERR;
719                 }
720 #endif
721         } else if (err == ENOERR) {
722                 // The node exists. If the O_CREAT and O_EXCL bits are set, we
723                 // must fail the open.
724
725                 if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
726                         jffs2_iput(ds.node);
727                         err = EEXIST;
728                 } else
729                         node = ds.node;
730         }
731
732         // Finished with the directory now 
733         jffs2_iput(ds.dir);
734
735         if (err != ENOERR)
736                 return err;
737
738         // Check that we actually have a file here
739         if (S_ISDIR(node->i_mode)) {
740                 jffs2_iput(node);
741                 return EISDIR;
742         }
743
744              // If the O_TRUNC bit is set we must clean out the file data.
745         if (mode & O_TRUNC) {
746 #ifdef CYGOPT_FS_JFFS2_WRITE
747              err = jffs2_truncate_file(node);
748              if (err) {
749                   jffs2_iput(node);
750                   return err;
751              }
752 #else
753              jffs2_iput(node);
754              return EROFS;
755 #endif
756         }
757         
758         // Initialise the file object
759         file->f_flag |= mode & CYG_FILE_MODE_MASK;
760         file->f_type = CYG_FILE_TYPE_FILE;
761         file->f_ops = &jffs2_fileops;
762         file->f_offset = (mode & O_APPEND) ? node->i_size : 0;
763         file->f_data = (CYG_ADDRWORD) node;
764         file->f_xops = 0;
765
766         return ENOERR;
767 }
768
769 #ifdef CYGOPT_FS_JFFS2_WRITE
770 // -------------------------------------------------------------------------
771 // jffs2_ops_unlink()
772 // Remove a file link from its directory.
773
774 static int jffs2_ops_unlink(cyg_mtab_entry * mte, cyg_dir dir, const char *name)
775 {
776         jffs2_dirsearch ds;
777         int err;
778
779         D2(printf("jffs2_ops_unlink\n"));
780
781         init_dirsearch(&ds, (struct _inode *) dir, 
782                        (const unsigned char *)name);
783
784         err = jffs2_find(&ds);
785
786         if (err != ENOERR) {
787                 jffs2_iput(ds.dir);
788                 return err;
789         }
790
791         // Cannot unlink directories, use rmdir() instead
792         if (S_ISDIR(ds.node->i_mode)) {
793                 jffs2_iput(ds.dir);
794                 jffs2_iput(ds.node);
795                 return EPERM;
796         }
797
798         // Delete it from its directory
799
800         err = jffs2_unlink(ds.dir, ds.node, ds.name);
801         jffs2_iput(ds.dir);
802         jffs2_iput(ds.node);
803
804         return -err;
805 }
806
807 // -------------------------------------------------------------------------
808 // jffs2_ops_mkdir()
809 // Create a new directory.
810
811 static int jffs2_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name)
812 {
813         jffs2_dirsearch ds;
814         int err;
815
816         D2(printf("jffs2_ops_mkdir\n"));
817
818         init_dirsearch(&ds, (struct _inode *) dir, 
819                        (const unsigned char *)name);
820
821         err = jffs2_find(&ds);
822
823         if (err == ENOENT) {
824                 if (ds.last) {
825                         // The entry does not exist, and it is the last element in
826                         // the pathname, so we can create it here.
827
828                         err = -jffs2_mkdir(ds.dir, ds.name, S_IRUGO|S_IXUGO|S_IWUSR);
829                 }
830                 // If this was not the last element, then an intermediate
831                 // directory does not exist.
832         } else {
833                 // If there we no error, something already exists with that
834                 // name, so we cannot create another one.
835                if (err == ENOERR) {
836                         jffs2_iput(ds.node);
837                         err = EEXIST;
838                }
839         }
840         jffs2_iput(ds.dir);
841         return err;
842 }
843
844 // -------------------------------------------------------------------------
845 // jffs2_ops_rmdir()
846 // Remove a directory.
847
848 static int jffs2_ops_rmdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name)
849 {
850         jffs2_dirsearch ds;
851         int err;
852
853         D2(printf("jffs2_ops_rmdir\n"));
854
855         init_dirsearch(&ds, (struct _inode *) dir, 
856                        (const unsigned char *)name);
857
858         err = jffs2_find(&ds);
859
860         if (err != ENOERR) {
861                 jffs2_iput(ds.dir);
862                 return err;
863         }
864
865         // Check that this is actually a directory.
866         if (!S_ISDIR(ds.node->i_mode)) {
867                 jffs2_iput(ds.dir);
868                 jffs2_iput(ds.node);
869                 return EPERM;
870         }
871
872         err = jffs2_rmdir(ds.dir, ds.node, ds.name);
873
874         jffs2_iput(ds.dir);
875         jffs2_iput(ds.node);
876         return -err;
877 }
878
879 // -------------------------------------------------------------------------
880 // jffs2_ops_rename()
881 // Rename a file/dir.
882
883 static int jffs2_ops_rename(cyg_mtab_entry * mte, cyg_dir dir1,
884                             const char *name1, cyg_dir dir2, const char *name2)
885 {
886         jffs2_dirsearch ds1, ds2;
887         int err;
888
889         D2(printf("jffs2_ops_rename\n"));
890
891         init_dirsearch(&ds1, (struct _inode *) dir1, 
892                        (const unsigned char *)name1);
893
894         err = jffs2_find(&ds1);
895
896         if (err != ENOERR) {
897                 jffs2_iput(ds1.dir);
898                 return err;
899         }
900
901         init_dirsearch(&ds2, (struct _inode *) dir2, 
902                        (const unsigned char *)name2);
903
904         err = jffs2_find(&ds2);
905
906         // Allow through renames to non-existent objects.
907         if (ds2.last && err == ENOENT) {
908                 ds2.node = NULL;
909                 err = ENOERR;
910         }
911
912         if (err != ENOERR) {
913                 jffs2_iput(ds1.dir);
914                 jffs2_iput(ds1.node);
915                 jffs2_iput(ds2.dir);
916                 return err;
917         }
918
919         // Null rename, just return
920         if (ds1.node == ds2.node) {
921                 err = ENOERR;
922                 goto out;
923         }
924
925         // First deal with any entry that is at the destination
926         if (ds2.node) {
927                 // Check that we are renaming like-for-like
928
929                 if (!S_ISDIR(ds1.node->i_mode) && S_ISDIR(ds2.node->i_mode)) {
930                         err = EISDIR;
931                         goto out;
932                 }
933
934                 if (S_ISDIR(ds1.node->i_mode) && !S_ISDIR(ds2.node->i_mode)) {
935                         err = ENOTDIR;
936                         goto out;
937                 }
938
939                 // Now delete the destination directory entry
940                 /* Er, what happened to atomicity of rename()? */
941                 err = -jffs2_unlink(ds2.dir, ds2.node, ds2.name);
942
943                 if (err != 0)
944                         goto out;
945
946         }
947         // Now we know that there is no clashing node at the destination,
948         // make a new direntry at the destination and delete the old entry
949         // at the source.
950
951         err = -jffs2_rename(ds1.dir, ds1.node, ds1.name, ds2.dir, ds2.name);
952
953         // Update directory times
954         if (!err)
955                 ds1.dir->i_ctime =
956                     ds1.dir->i_mtime =
957                     ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp();
958  out:
959         jffs2_iput(ds1.dir);
960         if (S_ISDIR(ds1.node->i_mode)) {
961                 /* Renamed a directory to elsewhere... so fix up its
962                    i_parent pointer and the i_counts of its old and
963                    new parents. */
964                 jffs2_iput(ds1.node->i_parent);
965                 ds1.node->i_parent = ds2.dir;
966                 /* We effectively increase its use count by not... */
967         } else {
968                 jffs2_iput(ds2.dir); /* ... doing this */
969         }
970         jffs2_iput(ds1.node);
971         if (ds2.node)
972                 jffs2_iput(ds2.node);
973  
974         return err;
975 }
976
977 // -------------------------------------------------------------------------
978 // jffs2_ops_link()
979 // Make a new directory entry for a file.
980
981 static int jffs2_ops_link(cyg_mtab_entry * mte, cyg_dir dir1, const char *name1,
982                           cyg_dir dir2, const char *name2, int type)
983 {
984         jffs2_dirsearch ds1, ds2;
985         int err;
986
987         D2(printf("jffs2_ops_link\n"));
988
989         // Only do hard links for now in this filesystem
990         if (type != CYG_FSLINK_HARD)
991                 return EINVAL;
992
993         init_dirsearch(&ds1, (struct _inode *) dir1, 
994                        (const unsigned char *) name1);
995
996         err = jffs2_find(&ds1);
997
998         if (err != ENOERR) {
999                 jffs2_iput(ds1.dir);
1000                 return err;
1001         }
1002
1003         init_dirsearch(&ds2, (struct _inode *) dir2, 
1004                        (const unsigned char *) name2);
1005
1006         err = jffs2_find(&ds2);
1007
1008         // Don't allow links to existing objects
1009         if (err == ENOERR) {
1010                 jffs2_iput(ds1.dir);
1011                 jffs2_iput(ds1.node);
1012                 jffs2_iput(ds2.dir);
1013                 jffs2_iput(ds2.node);
1014                 return EEXIST;
1015         }
1016
1017         // Allow through links to non-existing terminal objects
1018         if (ds2.last && err == ENOENT) {
1019                 ds2.node = NULL;
1020                 err = ENOERR;
1021         }
1022
1023         if (err != ENOERR) {
1024                 jffs2_iput(ds1.dir);
1025                 jffs2_iput(ds1.node);
1026                 jffs2_iput(ds2.dir);
1027                 return err;
1028         }
1029
1030         // Now we know that there is no existing node at the destination,
1031         // make a new direntry at the destination.
1032
1033         err = jffs2_link(ds1.node, ds2.dir, ds2.name);
1034
1035         if (err == 0)
1036                 ds1.node->i_ctime =
1037                     ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp();
1038
1039         jffs2_iput(ds1.dir);
1040         jffs2_iput(ds1.node);
1041         jffs2_iput(ds2.dir);
1042
1043         return -err;
1044 }
1045 #endif /* CYGOPT_FS_JFFS2_WRITE */
1046 // -------------------------------------------------------------------------
1047 // jffs2_opendir()
1048 // Open a directory for reading.
1049
1050 static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
1051                          cyg_file * file)
1052 {
1053         jffs2_dirsearch ds;
1054         int err;
1055
1056         D2(printf("jffs2_opendir\n"));
1057
1058         init_dirsearch(&ds, (struct _inode *) dir, 
1059                        (const unsigned char *) name);
1060
1061         err = jffs2_find(&ds);
1062
1063         jffs2_iput(ds.dir);
1064
1065         if (err != ENOERR)
1066                 return err;
1067
1068         // check it is really a directory.
1069         if (!S_ISDIR(ds.node->i_mode)) {
1070                 jffs2_iput(ds.node);
1071                 return ENOTDIR;
1072         }
1073
1074         // Initialize the file object, setting the f_ops field to a
1075         // special set of file ops.
1076
1077         file->f_type = CYG_FILE_TYPE_FILE;
1078         file->f_ops = &jffs2_dirops;
1079         file->f_offset = 0;
1080         file->f_data = (CYG_ADDRWORD) ds.node;
1081         file->f_xops = 0;
1082
1083         return ENOERR;
1084
1085 }
1086
1087 // -------------------------------------------------------------------------
1088 // jffs2_chdir()
1089 // Change directory support.
1090
1091 static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
1092                        cyg_dir * dir_out)
1093 {
1094         D2(printf("jffs2_chdir\n"));
1095
1096         if (dir_out != NULL) {
1097                 // This is a request to get a new directory pointer in
1098                 // *dir_out.
1099
1100                 jffs2_dirsearch ds;
1101                 int err;
1102
1103                 init_dirsearch(&ds, (struct _inode *) dir, 
1104                                (const unsigned char *) name);
1105
1106                 err = jffs2_find(&ds);
1107                 jffs2_iput(ds.dir);
1108
1109                 if (err != ENOERR)
1110                         return err;
1111
1112                 // check it is a directory
1113                 if (!S_ISDIR(ds.node->i_mode)) {
1114                         jffs2_iput(ds.node);
1115                         return ENOTDIR;
1116                 }
1117                 
1118                 // Pass it out
1119                 *dir_out = (cyg_dir) ds.node;
1120         } else {
1121                 // If no output dir is required, this means that the mte and
1122                 // dir arguments are the current cdir setting and we should
1123                 // forget this fact.
1124
1125                 struct _inode *node = (struct _inode *) dir;
1126
1127                 // Just decrement directory reference count.
1128                 jffs2_iput(node);
1129         }
1130
1131         return ENOERR;
1132 }
1133
1134 // -------------------------------------------------------------------------
1135 // jffs2_stat()
1136 // Get struct stat info for named object.
1137
1138 static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
1139                       struct stat *buf)
1140 {
1141         jffs2_dirsearch ds;
1142         int err;
1143
1144         D2(printf("jffs2_stat\n"));
1145
1146         init_dirsearch(&ds, (struct _inode *) dir, 
1147                        (const unsigned char *) name);
1148
1149         err = jffs2_find(&ds);
1150         jffs2_iput(ds.dir);
1151
1152         if (err != ENOERR)
1153                 return err;
1154
1155         // Fill in the status
1156         buf->st_mode = ds.node->i_mode;
1157         buf->st_ino = ds.node->i_ino;
1158         buf->st_dev = 0;
1159         buf->st_nlink = ds.node->i_nlink;
1160         buf->st_uid = ds.node->i_uid;
1161         buf->st_gid = ds.node->i_gid;
1162         buf->st_size = ds.node->i_size;
1163         buf->st_atime = ds.node->i_atime;
1164         buf->st_mtime = ds.node->i_mtime;
1165         buf->st_ctime = ds.node->i_ctime;
1166
1167         jffs2_iput(ds.node);
1168
1169         return ENOERR;
1170 }
1171
1172 // -------------------------------------------------------------------------
1173 // jffs2_getinfo()
1174 // Getinfo. Currently only support pathconf().
1175
1176 static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
1177                          int key, void *buf, int len)
1178 {
1179         jffs2_dirsearch ds;
1180         int err;
1181
1182         D2(printf("jffs2_getinfo\n"));
1183
1184         init_dirsearch(&ds, (struct _inode *) dir, 
1185                        (const unsigned char *) name);
1186
1187         err = jffs2_find(&ds);
1188         jffs2_iput(ds.dir);
1189
1190         if (err != ENOERR)
1191                 return err;
1192
1193         switch (key) {
1194         case FS_INFO_CONF:
1195                 err = jffs2_pathconf(ds.node, (struct cyg_pathconf_info *) buf);
1196                 break;
1197
1198         default:
1199                 err = EINVAL;
1200         }
1201
1202         jffs2_iput(ds.node);
1203         return err;
1204 }
1205
1206 // -------------------------------------------------------------------------
1207 // jffs2_setinfo()
1208 // Setinfo. Nothing to support here at present.
1209
1210 static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
1211                          int key, void *buf, int len)
1212 {
1213         // No setinfo keys supported at present
1214
1215         D2(printf("jffs2_setinfo\n"));
1216
1217         return EINVAL;
1218 }
1219
1220 //==========================================================================
1221 // File operations
1222
1223 // -------------------------------------------------------------------------
1224 // jffs2_fo_read()
1225 // Read data from the file.
1226
1227 static int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
1228 {
1229         struct _inode *inode = (struct _inode *) fp->f_data;
1230         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1231         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1232         int i;
1233         ssize_t resid = uio->uio_resid;
1234         off_t pos = fp->f_offset;
1235
1236         down(&f->sem);
1237
1238         // Loop over the io vectors until there are none left
1239         for (i = 0; i < uio->uio_iovcnt && pos < inode->i_size; i++) {
1240                 int ret;
1241                 cyg_iovec *iov = &uio->uio_iov[i];
1242                 off_t len = min(iov->iov_len, inode->i_size - pos);
1243
1244                 D2(printf("jffs2_fo_read inode size %d\n", inode->i_size));
1245
1246                 ret =
1247                     jffs2_read_inode_range(c, f,
1248                                            (unsigned char *) iov->iov_base, pos,
1249                                            len);
1250                 if (ret) {
1251                         D1(printf
1252                            ("jffs2_fo_read(): read_inode_range failed %d\n",
1253                             ret));
1254                         uio->uio_resid = resid;
1255                         up(&f->sem);
1256                         return -ret;
1257                 }
1258                 resid -= len;
1259                 pos += len;
1260         }
1261
1262         // We successfully read some data, update the node's access time
1263         // and update the file offset and transfer residue.
1264
1265         inode->i_atime = cyg_timestamp();
1266
1267         uio->uio_resid = resid;
1268         fp->f_offset = pos;
1269
1270         up(&f->sem);
1271
1272         return ENOERR;
1273 }
1274
1275
1276 #ifdef CYGOPT_FS_JFFS2_WRITE
1277 // -------------------------------------------------------------------------
1278 // jffs2_fo_write()
1279 // Write data to file.
1280 static int jffs2_extend_file (struct _inode *inode, struct jffs2_raw_inode *ri,
1281                        unsigned long offset)
1282 {
1283         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1284         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1285         struct jffs2_full_dnode *fn;
1286         uint32_t phys_ofs, alloc_len;
1287         int ret = 0;
1288
1289         /* Make new hole frag from old EOF to new page */
1290         D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
1291                   (unsigned int)inode->i_size, offset));
1292
1293         ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);
1294         if (ret)
1295                 return ret;
1296
1297         down(&f->sem);
1298
1299         ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
1300         ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
1301         ri->totlen = cpu_to_je32(sizeof(*ri));
1302         ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
1303
1304         ri->version = cpu_to_je32(++f->highest_version);
1305         ri->isize = cpu_to_je32(max((uint32_t)inode->i_size, offset));
1306
1307         ri->offset = cpu_to_je32(inode->i_size);
1308         ri->dsize = cpu_to_je32(offset - inode->i_size);
1309         ri->csize = cpu_to_je32(0);
1310         ri->compr = JFFS2_COMPR_ZERO;
1311         ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
1312         ri->data_crc = cpu_to_je32(0);
1313                 
1314         fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
1315         jffs2_complete_reservation(c);
1316         if (IS_ERR(fn)) {
1317                 ret = PTR_ERR(fn);
1318                 up(&f->sem);
1319                 return ret;
1320         }
1321         ret = jffs2_add_full_dnode_to_inode(c, f, fn);
1322         if (f->metadata) {
1323                 jffs2_mark_node_obsolete(c, f->metadata->raw);
1324                 jffs2_free_full_dnode(f->metadata);
1325                 f->metadata = NULL;
1326         }
1327         if (ret) {
1328                 D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));
1329                 jffs2_mark_node_obsolete(c, fn->raw);
1330                 jffs2_free_full_dnode(fn);
1331                 up(&f->sem);
1332                 return ret;
1333         }
1334         inode->i_size = offset;
1335         up(&f->sem);
1336         return 0;
1337 }
1338
1339 // jffs2_fo_open()
1340 // Truncate a file
1341 static int jffs2_truncate_file (struct _inode *inode)
1342 {
1343      struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1344      struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1345      struct jffs2_full_dnode *new_metadata, * old_metadata;
1346      struct jffs2_raw_inode *ri;
1347      uint32_t phys_ofs, alloclen;
1348      int err;
1349      
1350      ri = jffs2_alloc_raw_inode();
1351      if (!ri) {
1352           return ENOMEM;
1353      }
1354      err = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
1355      
1356      if (err) {
1357           jffs2_free_raw_inode(ri);
1358           return err;
1359      }
1360      down(&f->sem);
1361      ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
1362      ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
1363      ri->totlen = cpu_to_je32(sizeof(*ri));
1364      ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
1365      
1366      ri->ino = cpu_to_je32(inode->i_ino);
1367      ri->version = cpu_to_je32(++f->highest_version);
1368      
1369      ri->uid = cpu_to_je16(inode->i_uid);
1370      ri->gid = cpu_to_je16(inode->i_gid);
1371      ri->mode = cpu_to_jemode(inode->i_mode);
1372      ri->isize = cpu_to_je32(0);
1373      ri->atime = cpu_to_je32(inode->i_atime);
1374      ri->mtime = cpu_to_je32(cyg_timestamp());
1375      ri->offset = cpu_to_je32(0);
1376      ri->csize = ri->dsize = cpu_to_je32(0);
1377      ri->compr = JFFS2_COMPR_NONE;
1378      ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
1379      ri->data_crc = cpu_to_je32(0);
1380      new_metadata = jffs2_write_dnode(c, f, ri, NULL, 0, 
1381                                       phys_ofs, ALLOC_NORMAL);
1382      if (IS_ERR(new_metadata)) {
1383           jffs2_complete_reservation(c);
1384           jffs2_free_raw_inode(ri);
1385           up(&f->sem);
1386           return PTR_ERR(new_metadata);
1387      }
1388      
1389      /* It worked. Update the inode */
1390      inode->i_mtime = cyg_timestamp();
1391      inode->i_size = 0;
1392      old_metadata = f->metadata;
1393      jffs2_truncate_fragtree (c, &f->fragtree, 0);
1394      f->metadata = new_metadata;
1395      if (old_metadata) {
1396           jffs2_mark_node_obsolete(c, old_metadata->raw);
1397           jffs2_free_full_dnode(old_metadata);
1398      }
1399      jffs2_free_raw_inode(ri);
1400      
1401      up(&f->sem);
1402      jffs2_complete_reservation(c);
1403      
1404      return 0;
1405 }
1406
1407 static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
1408 {
1409         struct _inode *inode = (struct _inode *) fp->f_data;
1410         off_t pos = fp->f_offset;
1411         ssize_t resid = uio->uio_resid;
1412         struct jffs2_raw_inode ri;
1413         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1414         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1415         int i;
1416
1417         // If the APPEND mode bit was supplied, force all writes to
1418         // the end of the file.
1419         if (fp->f_flag & CYG_FAPPEND)
1420                 pos = fp->f_offset = inode->i_size;
1421
1422         if (pos < 0)
1423                 return EINVAL;
1424
1425         memset(&ri, 0, sizeof(ri));
1426
1427         ri.ino = cpu_to_je32(f->inocache->ino);
1428         ri.mode = cpu_to_jemode(inode->i_mode);
1429         ri.uid = cpu_to_je16(inode->i_uid);
1430         ri.gid = cpu_to_je16(inode->i_gid);
1431         ri.atime = ri.ctime = ri.mtime = cpu_to_je32(cyg_timestamp());
1432
1433         if (pos > inode->i_size) {
1434                 int err;
1435                 ri.version = cpu_to_je32(++f->highest_version);
1436                 err = jffs2_extend_file(inode, &ri, pos);
1437                 if (err)
1438                         return -err;
1439         }
1440         ri.isize = cpu_to_je32(inode->i_size);
1441
1442         // Now loop over the iovecs until they are all done, or
1443         // we get an error.
1444         for (i = 0; i < uio->uio_iovcnt; i++) {
1445                 cyg_iovec *iov = &uio->uio_iov[i];
1446                 unsigned char *buf = iov->iov_base;
1447                 off_t len = iov->iov_len;
1448
1449                 uint32_t writtenlen;
1450                 int err;
1451
1452                 D2(printf("jffs2_fo_write page_start_pos %d\n", pos));
1453                 D2(printf("jffs2_fo_write transfer size %d\n", len));
1454
1455                 err = jffs2_write_inode_range(c, f, &ri, buf,
1456                                               pos, len, &writtenlen);
1457                 if (err)
1458                         return -err;
1459                 
1460                 if (writtenlen != len)
1461                         return ENOSPC;
1462
1463                 pos += len;
1464                 resid -= len;
1465         }
1466
1467         // We wrote some data successfully, update the modified and access
1468         // times of the inode, increase its size appropriately, and update
1469         // the file offset and transfer residue.
1470         inode->i_mtime = inode->i_ctime = je32_to_cpu(ri.mtime);
1471         if (pos > inode->i_size)
1472                 inode->i_size = pos;
1473
1474         uio->uio_resid = resid;
1475         fp->f_offset = pos;
1476
1477         return ENOERR;
1478 }
1479 #endif /* CYGOPT_FS_JFFS2_WRITE */
1480
1481 // -------------------------------------------------------------------------
1482 // jffs2_fo_lseek()
1483 // Seek to a new file position.
1484
1485 static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * apos, int whence)
1486 {
1487         struct _inode *node = (struct _inode *) fp->f_data;
1488         off_t pos = *apos;
1489
1490         D2(printf("jffs2_fo_lseek\n"));
1491
1492         switch (whence) {
1493         case SEEK_SET:
1494                 // Pos is already where we want to be.
1495                 break;
1496
1497         case SEEK_CUR:
1498                 // Add pos to current offset.
1499                 pos += fp->f_offset;
1500                 break;
1501
1502         case SEEK_END:
1503                 // Add pos to file size.
1504                 pos += node->i_size;
1505                 break;
1506
1507         default:
1508                 return EINVAL;
1509         }
1510
1511         if (pos < 0 )
1512                 return EINVAL;
1513
1514         // All OK, set fp offset and return new position.
1515         *apos = fp->f_offset = pos;
1516
1517         return ENOERR;
1518 }
1519
1520 // -------------------------------------------------------------------------
1521 // jffs2_fo_ioctl()
1522 // Handle ioctls. Currently none are defined.
1523
1524 static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
1525                           CYG_ADDRWORD data)
1526 {
1527         // No Ioctls currenly defined.
1528
1529         D2(printf("jffs2_fo_ioctl\n"));
1530
1531         return EINVAL;
1532 }
1533
1534 // -------------------------------------------------------------------------
1535 // jffs2_fo_fsync().
1536 // Force the file out to data storage.
1537
1538 static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
1539 {
1540         // Data is always permanently where it belongs, nothing to do
1541         // here.
1542
1543         D2(printf("jffs2_fo_fsync\n"));
1544
1545         return ENOERR;
1546 }
1547
1548 // -------------------------------------------------------------------------
1549 // jffs2_fo_close()
1550 // Close a file. We just decrement the refcnt and let it go away if
1551 // that is all that is keeping it here.
1552
1553 static int jffs2_fo_close(struct CYG_FILE_TAG *fp)
1554 {
1555         struct _inode *node = (struct _inode *) fp->f_data;
1556
1557         D2(printf("jffs2_fo_close\n"));
1558
1559         jffs2_iput(node);
1560
1561         fp->f_data = 0;         // zero data pointer
1562
1563         return ENOERR;
1564 }
1565
1566 // -------------------------------------------------------------------------
1567 //jffs2_fo_fstat()
1568 // Get file status.
1569
1570 static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf)
1571 {
1572         struct _inode *node = (struct _inode *) fp->f_data;
1573
1574         D2(printf("jffs2_fo_fstat\n"));
1575
1576         // Fill in the status
1577         buf->st_mode = node->i_mode;
1578         buf->st_ino = node->i_ino;
1579         buf->st_dev = 0;
1580         buf->st_nlink = node->i_nlink;
1581         buf->st_uid = node->i_uid;
1582         buf->st_gid = node->i_gid;
1583         buf->st_size = node->i_size;
1584         buf->st_atime = node->i_atime;
1585         buf->st_mtime = node->i_mtime;
1586         buf->st_ctime = node->i_ctime;
1587
1588         return ENOERR;
1589 }
1590
1591 // -------------------------------------------------------------------------
1592 // jffs2_fo_getinfo()
1593 // Get info. Currently only supports fpathconf().
1594
1595 static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
1596                             int len)
1597 {
1598         struct _inode *node = (struct _inode *) fp->f_data;
1599         int err;
1600
1601         D2(printf("jffs2_fo_getinfo\n"));
1602
1603         switch (key) {
1604         case FS_INFO_CONF:
1605                 err = jffs2_pathconf(node, (struct cyg_pathconf_info *) buf);
1606                 break;
1607
1608         default:
1609                 err = EINVAL;
1610         }
1611         return err;
1612
1613         return ENOERR;
1614 }
1615
1616 // -------------------------------------------------------------------------
1617 // jffs2_fo_setinfo()
1618 // Set info. Nothing supported here.
1619
1620 static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
1621                             int len)
1622 {
1623         // No setinfo key supported at present
1624
1625         D2(printf("jffs2_fo_setinfo\n"));
1626
1627         return ENOERR;
1628 }
1629
1630 //==========================================================================
1631 // Directory operations
1632
1633 // -------------------------------------------------------------------------
1634 // jffs2_fo_dirread()
1635 // Read a single directory entry from a file.
1636
1637 static __inline void filldir(char *nbuf, int nlen, const unsigned char *name, int namlen)
1638 {
1639         int len = nlen < namlen ? nlen : namlen;
1640         memcpy(nbuf, name, len);
1641         nbuf[len] = '\0';
1642 }
1643
1644 static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
1645 {
1646         struct _inode *d_inode = (struct _inode *) fp->f_data;
1647         struct dirent *ent = (struct dirent *) uio->uio_iov[0].iov_base;
1648         char *nbuf = ent->d_name;
1649 #ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE
1650         struct _inode *c_ino;
1651 #endif
1652         int nlen = sizeof (ent->d_name) - 1;
1653         off_t len = uio->uio_iov[0].iov_len;
1654         struct jffs2_inode_info *f;
1655         struct jffs2_sb_info *c;
1656         struct _inode *inode = d_inode;
1657         struct jffs2_full_dirent *fd;
1658         unsigned long offset, curofs;
1659         int found = 1;
1660
1661         if (len < sizeof (struct dirent))
1662                 return EINVAL;
1663
1664         D1(printk
1665            (KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", d_inode->i_ino));
1666
1667         f = JFFS2_INODE_INFO(inode);
1668         c = JFFS2_SB_INFO(inode->i_sb);
1669
1670         offset = fp->f_offset;
1671
1672         if (offset == 0) {
1673                 D1(printk
1674                    (KERN_DEBUG "Dirent 0: \".\", ino #%lu\n", inode->i_ino));
1675                 filldir(nbuf, nlen, (const unsigned char *) ".", 1);
1676 #ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE
1677                 // Flags here are the same as jffs2_mkdir. Make sure
1678                 // d_type is the same as st_mode of calling stat.
1679                 ent->d_type = 
1680                   jemode_to_cpu(cpu_to_jemode(S_IRUGO|S_IXUGO|S_IWUSR|S_IFDIR));
1681 #endif
1682                 goto out;
1683         }
1684         if (offset == 1) {
1685                 filldir(nbuf, nlen, (const unsigned char *) "..", 2);
1686 #ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE
1687                 // Flags here are the same as jffs2_mkdir. Make sure
1688                 // d_type is the same as st_mode of calling stat.
1689                 ent->d_type = 
1690                   jemode_to_cpu(cpu_to_jemode(S_IRUGO|S_IXUGO|S_IWUSR|S_IFDIR));
1691 #endif
1692                 goto out;
1693         }
1694
1695         curofs = 1;
1696         down(&f->sem);
1697         for (fd = f->dents; fd; fd = fd->next) {
1698
1699                 curofs++;
1700                 /* First loop: curofs = 2; offset = 2 */
1701                 if (curofs < offset) {
1702                         D2(printk
1703                            (KERN_DEBUG
1704                             "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
1705                             fd->name, fd->ino, fd->type, curofs, offset));
1706                         continue;
1707                 }
1708                 if (!fd->ino) {
1709                         D2(printk
1710                            (KERN_DEBUG "Skipping deletion dirent \"%s\"\n",
1711                             fd->name));
1712                         offset++;
1713                         continue;
1714                 }
1715                 D2(printk
1716                    (KERN_DEBUG "Dirent %ld: \"%s\", ino #%u, type %d\n", offset,
1717                     fd->name, fd->ino, fd->type));
1718                 filldir(nbuf, nlen, fd->name, strlen((char *)fd->name));
1719 #ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE
1720                 c_ino = jffs2_iget(inode->i_sb, fd->ino);
1721                 if(IS_ERR(c_ino)) {
1722                         D1(printk(KERN_WARNING "get entry inode failed\n"));
1723                         // fileio already set it to zero, so not needed here
1724                         // ent->d_type = 0;
1725                 }
1726                 else {
1727                         ent->d_type = c_ino->i_mode;
1728                         jffs2_iput(c_ino);
1729                 }
1730 #endif
1731                 goto out_sem;
1732         }
1733         /* Reached the end of the directory */
1734         found = 0;
1735       out_sem:
1736         up(&f->sem);
1737       out:
1738         fp->f_offset = ++offset;
1739         if (found) {
1740                 uio->uio_resid -= sizeof (struct dirent);
1741         }
1742         return ENOERR;
1743 }
1744
1745 // -------------------------------------------------------------------------
1746 // jffs2_fo_dirlseek()
1747 // Seek directory to start.
1748
1749 static int jffs2_fo_dirlseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence)
1750 {
1751         // Only allow SEEK_SET to zero
1752
1753         D2(printf("jffs2_fo_dirlseek\n"));
1754
1755         if (whence != SEEK_SET || *pos != 0)
1756                 return EINVAL;
1757
1758         *pos = fp->f_offset = 0;
1759
1760         return ENOERR;
1761 }
1762
1763 //==========================================================================
1764 // 
1765 // Called by JFFS2
1766 // ===============
1767 // 
1768 //
1769 //==========================================================================
1770
1771 unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, 
1772                                    struct jffs2_inode_info *f, 
1773                                    unsigned long offset,
1774                                    unsigned long *priv)
1775 {
1776         /* FIXME: This works only with one file system mounted at a time */
1777         int ret;
1778
1779         ret = jffs2_read_inode_range(c, f, gc_buffer, 
1780                                      offset & ~(PAGE_CACHE_SIZE-1), PAGE_CACHE_SIZE);
1781         if (ret)
1782                 return ERR_PTR(ret);
1783
1784         return gc_buffer;
1785 }
1786
1787 void jffs2_gc_release_page(struct jffs2_sb_info *c,
1788                            unsigned char *ptr,
1789                            unsigned long *priv)
1790 {
1791         /* Do nothing */
1792 }
1793
1794 static struct _inode *new_inode(struct super_block *sb)
1795 {
1796
1797         // Only called in write.c jffs2_new_inode
1798         // Always adds itself to inode cache
1799
1800         struct _inode *inode;
1801         struct _inode *cached_inode;
1802
1803         inode = malloc(sizeof (struct _inode));
1804         if (inode == NULL)
1805                 return 0;
1806
1807         D2(printf
1808            ("malloc new_inode %x ####################################\n",
1809             inode));
1810
1811         memset(inode, 0, sizeof (struct _inode));
1812         inode->i_sb = sb;
1813         inode->i_ino = 1;
1814         inode->i_count = 1;
1815         inode->i_nlink = 1;     // Let JFFS2 manage the link count
1816         inode->i_size = 0;
1817
1818         inode->i_cache_next = NULL;     // Newest inode, about to be cached
1819
1820         // Add to the icache
1821         for (cached_inode = sb->s_root; cached_inode != NULL;
1822              cached_inode = cached_inode->i_cache_next) {
1823                 if (cached_inode->i_cache_next == NULL) {
1824                         cached_inode->i_cache_next = inode;     // Current last in cache points to newcomer
1825                         inode->i_cache_prev = cached_inode;     // Newcomer points back to last
1826                         break;
1827                 }
1828         }
1829         return inode;
1830 }
1831
1832 static struct _inode *ilookup(struct super_block *sb, cyg_uint32 ino)
1833 {
1834         struct _inode *inode = NULL;
1835
1836         D2(printf("ilookup\n"));
1837         // Check for this inode in the cache
1838         for (inode = sb->s_root; inode != NULL; inode = inode->i_cache_next) {
1839                 if (inode->i_ino == ino) {
1840                         inode->i_count++;
1841                         break;
1842                 }
1843         }
1844         return inode;
1845 }
1846
1847 struct _inode *jffs2_iget(struct super_block *sb, cyg_uint32 ino)
1848 {
1849         // Called in super.c jffs2_read_super, dir.c jffs2_lookup,
1850         // and gc.c jffs2_garbage_collect_pass
1851
1852         // Must first check for cached inode 
1853         // If this fails let new_inode create one
1854
1855         struct _inode *inode;
1856         int err;
1857
1858         D2(printf("jffs2_iget\n"));
1859
1860         inode = ilookup(sb, ino);
1861         if (inode)
1862                 return inode;
1863
1864         // Not cached, so malloc it
1865         inode = new_inode(sb);
1866         if (inode == NULL)
1867                 return ERR_PTR(-ENOMEM);
1868
1869         inode->i_ino = ino;
1870
1871         err = jffs2_read_inode(inode);
1872         if (err) {
1873                 printf("jffs2_read_inode() failed\n");
1874                 inode->i_nlink = 0; // free _this_ bad inode right now
1875                 jffs2_iput(inode);
1876                 inode = NULL;
1877                 return ERR_PTR(err);
1878         }
1879         return inode;
1880 }
1881
1882 // -------------------------------------------------------------------------
1883 // Decrement the reference count on an inode. If this makes the ref count
1884 // zero, then this inode can be freed.
1885
1886 void jffs2_iput(struct _inode *i)
1887 {
1888         // Called in jffs2_find 
1889         // (and jffs2_open and jffs2_ops_mkdir?)
1890         // super.c jffs2_read_super,
1891         // and gc.c jffs2_garbage_collect_pass
1892  recurse:
1893         if (!i) {
1894                 printf("jffs2_iput() called with NULL inode\n");
1895                 // and let it fault... 
1896         }
1897
1898         i->i_count--;
1899
1900         if (i->i_count < 0)
1901                 BUG();
1902
1903         if (i->i_count)
1904                 return;
1905         
1906         if (!i->i_nlink) {
1907                 struct _inode *parent;
1908
1909                 // Remove from the icache linked list and free immediately
1910                 if (i->i_cache_prev)
1911                         i->i_cache_prev->i_cache_next = i->i_cache_next;
1912                 if (i->i_cache_next)
1913                         i->i_cache_next->i_cache_prev = i->i_cache_prev;
1914
1915                 parent = i->i_parent;
1916                 jffs2_clear_inode(i);
1917                 memset(i, 0x5a, sizeof(*i));
1918                 free(i);
1919
1920                 if (parent && parent != i) {
1921                         i = parent;
1922                         goto recurse;
1923                 }
1924
1925         } else {
1926                 // Evict some _other_ inode with i_count zero, leaving
1927                 // this latest one in the cache for a while 
1928                 icache_evict(i->i_sb->s_root, i);
1929         }
1930 }
1931
1932
1933 // -------------------------------------------------------------------------
1934 // EOF jffs2.c
1935
1936
1937 static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
1938 {
1939         memset(f, 0, sizeof(*f));
1940         init_MUTEX_LOCKED(&f->sem);
1941 }
1942
1943 static void jffs2_clear_inode (struct _inode *inode)
1944 {
1945         /* We can forget about this inode for now - drop all
1946          *  the nodelists associated with it, etc.
1947          */
1948         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1949         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1950
1951         D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
1952
1953         jffs2_do_clear_inode(c, f);
1954 }
1955
1956
1957 /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
1958    fill in the raw_inode while you're at it. */
1959 struct _inode *jffs2_new_inode (struct _inode *dir_i, int mode, struct jffs2_raw_inode *ri)
1960 {
1961         struct _inode *inode;
1962         struct super_block *sb = dir_i->i_sb;
1963         struct jffs2_sb_info *c;
1964         struct jffs2_inode_info *f;
1965         int ret;
1966
1967         D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
1968
1969         c = JFFS2_SB_INFO(sb);
1970         
1971         inode = new_inode(sb);
1972         
1973         if (!inode)
1974                 return ERR_PTR(-ENOMEM);
1975
1976         f = JFFS2_INODE_INFO(inode);
1977         jffs2_init_inode_info(f);
1978
1979         memset(ri, 0, sizeof(*ri));
1980         /* Set OS-specific defaults for new inodes */
1981         ri->uid = ri->gid = cpu_to_je16(0);
1982         ri->mode =  cpu_to_jemode(mode);
1983         ret = jffs2_do_new_inode (c, f, mode, ri);
1984         if (ret) {
1985                 // forceful evict: f->sem is locked already, and the
1986                 // inode is bad.
1987                 if (inode->i_cache_prev)
1988                        inode->i_cache_prev->i_cache_next = inode->i_cache_next;
1989                 if (inode->i_cache_next)
1990                        inode->i_cache_next->i_cache_prev = inode->i_cache_prev; 
1991                 up(&(f->sem));
1992                 jffs2_clear_inode(inode);
1993                 memset(inode, 0x6a, sizeof(*inode));
1994                 free(inode);
1995                 return ERR_PTR(ret);
1996         }
1997         inode->i_nlink = 1;
1998         inode->i_ino = je32_to_cpu(ri->ino);
1999         inode->i_mode = jemode_to_cpu(ri->mode);
2000         inode->i_gid = je16_to_cpu(ri->gid);
2001         inode->i_uid = je16_to_cpu(ri->uid);
2002         inode->i_atime = inode->i_ctime = inode->i_mtime = cyg_timestamp();
2003         ri->atime = ri->mtime = ri->ctime = cpu_to_je32(inode->i_mtime);
2004
2005         inode->i_size = 0;
2006
2007         return inode;
2008 }
2009
2010
2011 static int jffs2_read_inode (struct _inode *inode)
2012 {
2013         struct jffs2_inode_info *f;
2014         struct jffs2_sb_info *c;
2015         struct jffs2_raw_inode latest_node;
2016         int ret;
2017
2018         D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
2019
2020         f = JFFS2_INODE_INFO(inode);
2021         c = JFFS2_SB_INFO(inode->i_sb);
2022
2023         jffs2_init_inode_info(f);
2024         
2025         ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
2026
2027         if (ret) {
2028                 up(&f->sem);
2029                 return ret;
2030         }
2031         inode->i_mode = jemode_to_cpu(latest_node.mode);
2032         inode->i_uid = je16_to_cpu(latest_node.uid);
2033         inode->i_gid = je16_to_cpu(latest_node.gid);
2034         inode->i_size = je32_to_cpu(latest_node.isize);
2035         inode->i_atime = je32_to_cpu(latest_node.atime);
2036         inode->i_mtime = je32_to_cpu(latest_node.mtime);
2037         inode->i_ctime = je32_to_cpu(latest_node.ctime);
2038
2039         inode->i_nlink = f->inocache->nlink;
2040         up(&f->sem);
2041
2042         D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
2043         return 0;
2044 }
2045
2046
2047 void jffs2_gc_release_inode(struct jffs2_sb_info *c,
2048                                    struct jffs2_inode_info *f)
2049 {
2050         jffs2_iput(OFNI_EDONI_2SFFJ(f));
2051 }
2052
2053 struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
2054                                                      int inum, int nlink)
2055 {
2056         struct _inode *inode;
2057         struct jffs2_inode_cache *ic;
2058         if (!nlink) {
2059                 /* The inode has zero nlink but its nodes weren't yet marked
2060                    obsolete. This has to be because we're still waiting for 
2061                    the final (close() and) jffs2_iput() to happen.
2062
2063                    There's a possibility that the final jffs2_iput() could have 
2064                    happened while we were contemplating. In order to ensure
2065                    that we don't cause a new read_inode() (which would fail)
2066                    for the inode in question, we use ilookup() in this case
2067                    instead of jffs2_iget().
2068
2069                    The nlink can't _become_ zero at this point because we're 
2070                    holding the alloc_sem, and jffs2_do_unlink() would also
2071                    need that while decrementing nlink on any inode.
2072                 */
2073                 inode = ilookup(OFNI_BS_2SFFJ(c), inum);
2074                 if (!inode) {
2075                         D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
2076                                   inum));
2077
2078                         spin_lock(&c->inocache_lock);
2079                         ic = jffs2_get_ino_cache(c, inum);
2080                         if (!ic) {
2081                                 D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));
2082                                 spin_unlock(&c->inocache_lock);
2083                                 return NULL;
2084                         }
2085                         if (ic->state != INO_STATE_CHECKEDABSENT) {
2086                                 /* Wait for progress. Don't just loop */
2087                                 D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",
2088                                           ic->ino, ic->state));
2089                                 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
2090                         } else {
2091                                 spin_unlock(&c->inocache_lock);
2092                         }
2093
2094                         return NULL;
2095                 }
2096         } else {
2097                 /* Inode has links to it still; they're not going away because
2098                    jffs2_do_unlink() would need the alloc_sem and we have it.
2099                    Just jffs2_iget() it, and if read_inode() is necessary that's OK.
2100                 */
2101                 inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum);
2102                 if (IS_ERR(inode))
2103                         return (void *)inode;
2104         }
2105
2106         return JFFS2_INODE_INFO(inode);
2107 }
2108
2109
2110
2111 uint32_t jffs2_from_os_mode(uint32_t osmode)
2112 {
2113         uint32_t jmode = ((osmode & S_IRUSR)?00400:0) |
2114                 ((osmode & S_IWUSR)?00200:0) |
2115                 ((osmode & S_IXUSR)?00100:0) |
2116                 ((osmode & S_IRGRP)?00040:0) |
2117                 ((osmode & S_IWGRP)?00020:0) |
2118                 ((osmode & S_IXGRP)?00010:0) |
2119                 ((osmode & S_IROTH)?00004:0) |
2120                 ((osmode & S_IWOTH)?00002:0) |
2121                 ((osmode & S_IXOTH)?00001:0);
2122
2123         switch (osmode & S_IFMT) {
2124         case S_IFSOCK:
2125                 return jmode | 0140000;
2126         case S_IFLNK:
2127                 return jmode | 0120000;
2128         case S_IFREG:
2129                 return jmode | 0100000;
2130         case S_IFBLK:
2131                 return jmode | 0060000;
2132         case S_IFDIR:
2133                 return jmode | 0040000;
2134         case S_IFCHR:
2135                 return jmode | 0020000;
2136         case S_IFIFO:
2137                 return jmode | 0010000;
2138         case S_ISUID:
2139                 return jmode | 0004000;
2140         case S_ISGID:
2141                 return jmode | 0002000;
2142 #ifdef S_ISVTX
2143         case S_ISVTX:
2144                 return jmode | 0001000;
2145 #endif
2146         }
2147         printf("os_to_jffs2_mode() cannot convert 0x%x\n", osmode);
2148         BUG();
2149         return 0;
2150 }
2151
2152 uint32_t jffs2_to_os_mode (uint32_t jmode)
2153 {
2154         uint32_t osmode = ((jmode & 00400)?S_IRUSR:0) |
2155                 ((jmode & 00200)?S_IWUSR:0) |
2156                 ((jmode & 00100)?S_IXUSR:0) |
2157                 ((jmode & 00040)?S_IRGRP:0) |
2158                 ((jmode & 00020)?S_IWGRP:0) |
2159                 ((jmode & 00010)?S_IXGRP:0) |
2160                 ((jmode & 00004)?S_IROTH:0) |
2161                 ((jmode & 00002)?S_IWOTH:0) |
2162                 ((jmode & 00001)?S_IXOTH:0);
2163
2164         switch(jmode & 00170000) {
2165         case 0140000:
2166                 return osmode | S_IFSOCK;
2167         case 0120000:
2168                 return osmode | S_IFLNK;
2169         case 0100000:
2170                 return osmode | S_IFREG;
2171         case 0060000:
2172                 return osmode | S_IFBLK;
2173         case 0040000:
2174                 return osmode | S_IFDIR;
2175         case 0020000:
2176                 return osmode | S_IFCHR;
2177         case 0010000:
2178                 return osmode | S_IFIFO;
2179         case 0004000:
2180                 return osmode | S_ISUID;
2181         case 0002000:
2182                 return osmode | S_ISGID;
2183 #ifdef S_ISVTX
2184         case 0001000:
2185                 return osmode | S_ISVTX;
2186 #endif
2187         }
2188         printf("jffs2_to_os_mode() cannot convert 0x%x\n", osmode);
2189         BUG();
2190         return 0;
2191 }