Merge branch 'mainlining'
[yaffs2.git] / yaffs_vfs_multi.c
1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2010 Aleph One Ltd.
5  *   for Toby Churchill Ltd and Brightstar Engineering
6  *
7  * Created by Charles Manning <charles@aleph1.co.uk>
8  * Acknowledgements:
9  * Luc van OostenRyck for numerous patches.
10  * Nick Bane for numerous patches.
11  * Nick Bane for 2.5/2.6 integration.
12  * Andras Toth for mknod rdev issue.
13  * Michael Fischer for finding the problem with inode inconsistency.
14  * Some code bodily lifted from JFFS
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License version 2 as
18  * published by the Free Software Foundation.
19  */
20
21 /*
22  *
23  * This is the file system front-end to YAFFS that hooks it up to
24  * the VFS.
25  *
26  * Special notes:
27  * >> 2.4: sb->u.generic_sbp points to the struct yaffs_dev associated with
28  *         this superblock
29  * >> 2.6: sb->s_fs_info  points to the struct yaffs_dev associated with this
30  *         superblock
31  * >> inode->u.generic_ip points to the associated struct yaffs_obj.
32  */
33
34 /*
35  * There are two variants of the VFS glue code. This variant should compile
36  * for any version of Linux.
37  */
38 #include <linux/version.h>
39
40 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10))
41 #define YAFFS_COMPILE_BACKGROUND
42 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6, 23))
43 #define YAFFS_COMPILE_FREEZER
44 #endif
45 #endif
46
47 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
48 #define YAFFS_COMPILE_EXPORTFS
49 #endif
50
51 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
52 #define YAFFS_USE_SETATTR_COPY
53 #define YAFFS_USE_TRUNCATE_SETSIZE
54 #endif
55 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
56 #define YAFFS_HAS_EVICT_INODE
57 #endif
58
59 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
60 #define YAFFS_NEW_FOLLOW_LINK 1
61 #else
62 #define YAFFS_NEW_FOLLOW_LINK 0
63 #endif
64
65 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
66 #include <linux/config.h>
67 #endif
68
69 #include <linux/kernel.h>
70 #include <linux/module.h>
71 #include <linux/slab.h>
72 #include <linux/init.h>
73 #include <linux/fs.h>
74 #include <linux/proc_fs.h>
75 #include <linux/smp_lock.h>
76 #include <linux/pagemap.h>
77 #include <linux/mtd/mtd.h>
78 #include <linux/interrupt.h>
79 #include <linux/string.h>
80 #include <linux/ctype.h>
81
82 #if (YAFFS_NEW_FOLLOW_LINK == 1)
83 #include <linux/namei.h>
84 #endif
85
86 #ifdef YAFFS_COMPILE_EXPORTFS
87 #include <linux/exportfs.h>
88 #endif
89
90 #ifdef YAFFS_COMPILE_BACKGROUND
91 #include <linux/kthread.h>
92 #include <linux/delay.h>
93 #endif
94 #ifdef YAFFS_COMPILE_FREEZER
95 #include <linux/freezer.h>
96 #endif
97
98 #include <asm/div64.h>
99
100 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
101
102 #include <linux/statfs.h>
103
104 #define UnlockPage(p) unlock_page(p)
105 #define Page_Uptodate(page)     test_bit(PG_uptodate, &(page)->flags)
106
107 /* FIXME: use sb->s_id instead ? */
108 #define yaffs_devname(sb, buf)  bdevname(sb->s_bdev, buf)
109
110 #else
111
112 #include <linux/locks.h>
113 #define BDEVNAME_SIZE           0
114 #define yaffs_devname(sb, buf)  kdevname(sb->s_dev)
115
116 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
117 /* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */
118 #define __user
119 #endif
120
121 #endif
122
123 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
124 #define YPROC_ROOT  (&proc_root)
125 #else
126 #define YPROC_ROOT  NULL
127 #endif
128
129 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26))
130 #define Y_INIT_TIMER(a) init_timer(a)
131 #else
132 #define Y_INIT_TIMER(a) init_timer_on_stack(a)
133 #endif
134
135 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
136 #define WRITE_SIZE_STR "writesize"
137 #define WRITE_SIZE(mtd) ((mtd)->writesize)
138 #else
139 #define WRITE_SIZE_STR "oobblock"
140 #define WRITE_SIZE(mtd) ((mtd)->oobblock)
141 #endif
142
143 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
144 #define YAFFS_USE_WRITE_BEGIN_END 1
145 #else
146 #define YAFFS_USE_WRITE_BEGIN_END 0
147 #endif
148
149 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
150 static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
151 {
152         uint64_t result = partition_size;
153         do_div(result, block_size);
154         return (uint32_t) result;
155 }
156 #else
157 #define YCALCBLOCKS(s, b) ((s)/(b))
158 #endif
159
160 #include <linux/uaccess.h>
161 #include <linux/mtd/mtd.h>
162
163 #include "yportenv.h"
164 #include "yaffs_trace.h"
165 #include "yaffs_guts.h"
166 #include "yaffs_attribs.h"
167
168 #include "yaffs_linux.h"
169
170 #include "yaffs_mtdif.h"
171 #include "yaffs_mtdif1.h"
172 #include "yaffs_mtdif2.h"
173
174 unsigned int yaffs_trace_mask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS;
175 unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
176 unsigned int yaffs_auto_checkpoint = 1;
177 unsigned int yaffs_gc_control = 1;
178 unsigned int yaffs_bg_enable = 1;
179
180 /* Module Parameters */
181 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
182 module_param(yaffs_trace_mask, uint, 0644);
183 module_param(yaffs_wr_attempts, uint, 0644);
184 module_param(yaffs_auto_checkpoint, uint, 0644);
185 module_param(yaffs_gc_control, uint, 0644);
186 module_param(yaffs_bg_enable, uint, 0644);
187 #else
188 MODULE_PARM(yaffs_trace_mask, "i");
189 MODULE_PARM(yaffs_wr_attempts, "i");
190 MODULE_PARM(yaffs_auto_checkpoint, "i");
191 MODULE_PARM(yaffs_gc_control, "i");
192 #endif
193
194 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
195 /* use iget and read_inode */
196 #define Y_IGET(sb, inum) iget((sb), (inum))
197 static void yaffs_read_inode(struct inode *inode);
198
199 #else
200 /* Call local equivalent */
201 #define YAFFS_USE_OWN_IGET
202 #define Y_IGET(sb, inum) yaffs_iget((sb), (inum))
203
204 static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino);
205 #endif
206
207 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
208 #define yaffs_inode_to_obj_lv(iptr) ((iptr)->i_private)
209 #else
210 #define yaffs_inode_to_obj_lv(iptr) ((iptr)->u.generic_ip)
211 #endif
212
213 #define yaffs_inode_to_obj(iptr) ((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr)))
214 #define yaffs_dentry_to_obj(dptr) yaffs_inode_to_obj((dptr)->d_inode)
215
216 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
217 #define yaffs_super_to_dev(sb)  ((struct yaffs_dev *)sb->s_fs_info)
218 #else
219 #define yaffs_super_to_dev(sb)  ((struct yaffs_dev *)sb->u.generic_sbp)
220 #endif
221
222 #define update_dir_time(dir) do {\
223                         (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
224                 } while(0)
225
226 static void yaffs_put_super(struct super_block *sb);
227
228 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
229                                 loff_t * pos);
230 static ssize_t yaffs_hold_space(struct file *f);
231 static void yaffs_release_space(struct file *f);
232
233 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
234 static int yaffs_file_flush(struct file *file, fl_owner_t id);
235 #else
236 static int yaffs_file_flush(struct file *file);
237 #endif
238
239 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
240 static int yaffs_sync_object(struct file *file, int datasync);
241 #else
242 static int yaffs_sync_object(struct file *file, struct dentry *dentry,
243                              int datasync);
244 #endif
245
246 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
247
248 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
249 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
250                         struct nameidata *n);
251 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
252                                    struct nameidata *n);
253 #else
254 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode);
255 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry);
256 #endif
257 static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
258                       struct dentry *dentry);
259 static int yaffs_unlink(struct inode *dir, struct dentry *dentry);
260 static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
261                          const char *symname);
262 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
263
264 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
265 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
266                        dev_t dev);
267 #else
268 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
269                        int dev);
270 #endif
271 static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
272                         struct inode *new_dir, struct dentry *new_dentry);
273 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
274
275 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
276 static int yaffs_sync_fs(struct super_block *sb, int wait);
277 static void yaffs_write_super(struct super_block *sb);
278 #else
279 static int yaffs_sync_fs(struct super_block *sb);
280 static int yaffs_write_super(struct super_block *sb);
281 #endif
282
283 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
284 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf);
285 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
286 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
287 #else
288 static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
289 #endif
290
291 #ifdef YAFFS_HAS_PUT_INODE
292 static void yaffs_put_inode(struct inode *inode);
293 #endif
294
295 #ifdef YAFFS_HAS_EVICT_INODE
296 static void yaffs_evict_inode(struct inode *);
297 #else
298 static void yaffs_delete_inode(struct inode *);
299 static void yaffs_clear_inode(struct inode *);
300 #endif
301
302 static int yaffs_readpage(struct file *file, struct page *page);
303 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
304 static int yaffs_writepage(struct page *page, struct writeback_control *wbc);
305 #else
306 static int yaffs_writepage(struct page *page);
307 #endif
308
309 #ifdef CONFIG_YAFFS_XATTR
310 int yaffs_setxattr(struct dentry *dentry, const char *name,
311                    const void *value, size_t size, int flags);
312 ssize_t yaffs_getxattr(struct dentry *dentry, const char *name, void *buff,
313                        size_t size);
314 int yaffs_removexattr(struct dentry *dentry, const char *name);
315 ssize_t yaffs_listxattr(struct dentry *dentry, char *buff, size_t size);
316 #endif
317
318 #if (YAFFS_USE_WRITE_BEGIN_END != 0)
319 static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
320                              loff_t pos, unsigned len, unsigned flags,
321                              struct page **pagep, void **fsdata);
322 static int yaffs_write_end(struct file *filp, struct address_space *mapping,
323                            loff_t pos, unsigned len, unsigned copied,
324                            struct page *pg, void *fsdadata);
325 #else
326 static int yaffs_prepare_write(struct file *f, struct page *pg,
327                                unsigned offset, unsigned to);
328 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
329                               unsigned to);
330
331 #endif
332
333 static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
334                           int buflen);
335 #if (YAFFS_NEW_FOLLOW_LINK == 1)
336 void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias);
337 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
338 #else
339 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
340 #endif
341
342 static void yaffs_touch_super(struct yaffs_dev *dev);
343
344 static int yaffs_vfs_setattr(struct inode *, struct iattr *);
345
346 static struct address_space_operations yaffs_file_address_operations = {
347         .readpage = yaffs_readpage,
348         .writepage = yaffs_writepage,
349 #if (YAFFS_USE_WRITE_BEGIN_END > 0)
350         .write_begin = yaffs_write_begin,
351         .write_end = yaffs_write_end,
352 #else
353         .prepare_write = yaffs_prepare_write,
354         .commit_write = yaffs_commit_write,
355 #endif
356 };
357
358 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
359 static const struct file_operations yaffs_file_operations = {
360         .read = do_sync_read,
361         .write = do_sync_write,
362         .aio_read = generic_file_aio_read,
363         .aio_write = generic_file_aio_write,
364         .mmap = generic_file_mmap,
365         .flush = yaffs_file_flush,
366         .fsync = yaffs_sync_object,
367         .splice_read = generic_file_splice_read,
368         .splice_write = generic_file_splice_write,
369         .llseek = generic_file_llseek,
370 };
371
372 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
373
374 static const struct file_operations yaffs_file_operations = {
375         .read = do_sync_read,
376         .write = do_sync_write,
377         .aio_read = generic_file_aio_read,
378         .aio_write = generic_file_aio_write,
379         .mmap = generic_file_mmap,
380         .flush = yaffs_file_flush,
381         .fsync = yaffs_sync_object,
382         .sendfile = generic_file_sendfile,
383 };
384
385 #else
386
387 static const struct file_operations yaffs_file_operations = {
388         .read = generic_file_read,
389         .write = generic_file_write,
390         .mmap = generic_file_mmap,
391         .flush = yaffs_file_flush,
392         .fsync = yaffs_sync_object,
393 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
394         .sendfile = generic_file_sendfile,
395 #endif
396 };
397 #endif
398
399 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25))
400 static void zero_user_segment(struct page *page, unsigned start, unsigned end)
401 {
402         void *kaddr = kmap_atomic(page, KM_USER0);
403         memset(kaddr + start, 0, end - start);
404         kunmap_atomic(kaddr, KM_USER0);
405         flush_dcache_page(page);
406 }
407 #endif
408
409 static const struct inode_operations yaffs_file_inode_operations = {
410         .setattr = yaffs_setattr,
411 #ifdef CONFIG_YAFFS_XATTR
412         .setxattr = yaffs_setxattr,
413         .getxattr = yaffs_getxattr,
414         .listxattr = yaffs_listxattr,
415         .removexattr = yaffs_removexattr,
416 #endif
417 };
418
419 static const struct inode_operations yaffs_symlink_inode_operations = {
420         .readlink = yaffs_readlink,
421         .follow_link = yaffs_follow_link,
422 #if (YAFFS_NEW_FOLLOW_LINK == 1)
423         .put_link = yaffs_put_link,
424 #endif
425         .setattr = yaffs_setattr,
426 #ifdef CONFIG_YAFFS_XATTR
427         .setxattr = yaffs_setxattr,
428         .getxattr = yaffs_getxattr,
429         .listxattr = yaffs_listxattr,
430         .removexattr = yaffs_removexattr,
431 #endif
432 };
433
434 static const struct inode_operations yaffs_dir_inode_operations = {
435         .create = yaffs_create,
436         .lookup = yaffs_lookup,
437         .link = yaffs_link,
438         .unlink = yaffs_unlink,
439         .symlink = yaffs_symlink,
440         .mkdir = yaffs_mkdir,
441         .rmdir = yaffs_unlink,
442         .mknod = yaffs_mknod,
443         .rename = yaffs_rename,
444         .setattr = yaffs_setattr,
445 #ifdef CONFIG_YAFFS_XATTR
446         .setxattr = yaffs_setxattr,
447         .getxattr = yaffs_getxattr,
448         .listxattr = yaffs_listxattr,
449         .removexattr = yaffs_removexattr,
450 #endif
451 };
452
453 static const struct file_operations yaffs_dir_operations = {
454         .read = generic_read_dir,
455         .readdir = yaffs_readdir,
456         .fsync = yaffs_sync_object,
457         .llseek = generic_file_llseek,
458 };
459
460 static const struct super_operations yaffs_super_ops = {
461         .statfs = yaffs_statfs,
462
463 #ifndef YAFFS_USE_OWN_IGET
464         .read_inode = yaffs_read_inode,
465 #endif
466 #ifdef YAFFS_HAS_PUT_INODE
467         .put_inode = yaffs_put_inode,
468 #endif
469         .put_super = yaffs_put_super,
470 #ifdef YAFFS_HAS_EVICT_INODE
471         .evict_inode = yaffs_evict_inode,
472 #else
473         .delete_inode = yaffs_delete_inode,
474         .clear_inode = yaffs_clear_inode,
475 #endif
476         .sync_fs = yaffs_sync_fs,
477         .write_super = yaffs_write_super,
478 };
479
480 static int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr)
481 {
482 #ifdef  YAFFS_USE_SETATTR_COPY
483         setattr_copy(inode, attr);
484         return 0;
485 #else
486         return inode_setattr(inode, attr);
487 #endif
488
489 }
490
491 static int yaffs_vfs_setsize(struct inode *inode, loff_t newsize)
492 {
493 #ifdef  YAFFS_USE_TRUNCATE_SETSIZE
494         truncate_setsize(inode, newsize);
495         return 0;
496 #else
497         truncate_inode_pages(&inode->i_data, newsize);
498         return 0;
499 #endif
500
501 }
502
503 static unsigned yaffs_gc_control_callback(struct yaffs_dev *dev)
504 {
505         return yaffs_gc_control;
506 }
507
508 static void yaffs_gross_lock(struct yaffs_dev *dev)
509 {
510         T(YAFFS_TRACE_LOCK, (TSTR("yaffs locking %p\n"), current));
511         mutex_lock(&(yaffs_dev_to_lc(dev)->gross_lock));
512         T(YAFFS_TRACE_LOCK, (TSTR("yaffs locked %p\n"), current));
513 }
514
515 static void yaffs_gross_unlock(struct yaffs_dev *dev)
516 {
517         T(YAFFS_TRACE_LOCK, (TSTR("yaffs unlocking %p\n"), current));
518         mutex_unlock(&(yaffs_dev_to_lc(dev)->gross_lock));
519 }
520
521 #ifdef YAFFS_COMPILE_EXPORTFS
522
523 static struct inode *yaffs2_nfs_get_inode(struct super_block *sb, uint64_t ino,
524                                           uint32_t generation)
525 {
526         return Y_IGET(sb, ino);
527 }
528
529 static struct dentry *yaffs2_fh_to_dentry(struct super_block *sb,
530                                           struct fid *fid, int fh_len,
531                                           int fh_type)
532 {
533         return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
534                                     yaffs2_nfs_get_inode);
535 }
536
537 static struct dentry *yaffs2_fh_to_parent(struct super_block *sb,
538                                           struct fid *fid, int fh_len,
539                                           int fh_type)
540 {
541         return generic_fh_to_parent(sb, fid, fh_len, fh_type,
542                                     yaffs2_nfs_get_inode);
543 }
544
545 struct dentry *yaffs2_get_parent(struct dentry *dentry)
546 {
547
548         struct super_block *sb = dentry->d_inode->i_sb;
549         struct dentry *parent = ERR_PTR(-ENOENT);
550         struct inode *inode;
551         unsigned long parent_ino;
552         struct yaffs_obj *d_obj;
553         struct yaffs_obj *parent_obj;
554
555         d_obj = yaffs_inode_to_obj(dentry->d_inode);
556
557         if (d_obj) {
558                 parent_obj = d_obj->parent;
559                 if (parent_obj) {
560                         parent_ino = yaffs_get_obj_inode(parent_obj);
561                         inode = Y_IGET(sb, parent_ino);
562
563                         if (IS_ERR(inode)) {
564                                 parent = ERR_CAST(inode);
565                         } else {
566                                 parent = d_obtain_alias(inode);
567                                 if (!IS_ERR(parent)) {
568                                         parent = ERR_PTR(-ENOMEM);
569                                         iput(inode);
570                                 }
571                         }
572                 }
573         }
574
575         return parent;
576 }
577
578 /* Just declare a zero structure as a NULL value implies
579  * using the default functions of exportfs.
580  */
581
582 static struct export_operations yaffs_export_ops = {
583         .fh_to_dentry = yaffs2_fh_to_dentry,
584         .fh_to_parent = yaffs2_fh_to_parent,
585         .get_parent = yaffs2_get_parent,
586 };
587
588 #endif
589
590 /*-----------------------------------------------------------------*/
591 /* Directory search context allows us to unlock access to yaffs during
592  * filldir without causing problems with the directory being modified.
593  * This is similar to the tried and tested mechanism used in yaffs direct.
594  *
595  * A search context iterates along a doubly linked list of siblings in the
596  * directory. If the iterating object is deleted then this would corrupt
597  * the list iteration, likely causing a crash. The search context avoids
598  * this by using the remove_obj_fn to move the search context to the
599  * next object before the object is deleted.
600  *
601  * Many readdirs (and thus seach conexts) may be alive simulateously so
602  * each struct yaffs_dev has a list of these.
603  *
604  * A seach context lives for the duration of a readdir.
605  *
606  * All these functions must be called while yaffs is locked.
607  */
608
609 struct yaffs_search_context {
610         struct yaffs_dev *dev;
611         struct yaffs_obj *dir_obj;
612         struct yaffs_obj *next_return;
613         struct list_head others;
614 };
615
616 /*
617  * yaffs_new_search() creates a new search context, initialises it and
618  * adds it to the device's search context list.
619  *
620  * Called at start of readdir.
621  */
622 static struct yaffs_search_context *yaffs_new_search(struct yaffs_obj *dir)
623 {
624         struct yaffs_dev *dev = dir->my_dev;
625         struct yaffs_search_context *sc =
626             YMALLOC(sizeof(struct yaffs_search_context));
627         if (sc) {
628                 sc->dir_obj = dir;
629                 sc->dev = dev;
630                 if (list_empty(&sc->dir_obj->variant.dir_variant.children))
631                         sc->next_return = NULL;
632                 else
633                         sc->next_return =
634                             list_entry(dir->variant.dir_variant.children.next,
635                                        struct yaffs_obj, siblings);
636                 INIT_LIST_HEAD(&sc->others);
637                 list_add(&sc->others, &(yaffs_dev_to_lc(dev)->search_contexts));
638         }
639         return sc;
640 }
641
642 /*
643  * yaffs_search_end() disposes of a search context and cleans up.
644  */
645 static void yaffs_search_end(struct yaffs_search_context *sc)
646 {
647         if (sc) {
648                 list_del(&sc->others);
649                 YFREE(sc);
650         }
651 }
652
653 /*
654  * yaffs_search_advance() moves a search context to the next object.
655  * Called when the search iterates or when an object removal causes
656  * the search context to be moved to the next object.
657  */
658 static void yaffs_search_advance(struct yaffs_search_context *sc)
659 {
660         if (!sc)
661                 return;
662
663         if (sc->next_return == NULL ||
664             list_empty(&sc->dir_obj->variant.dir_variant.children))
665                 sc->next_return = NULL;
666         else {
667                 struct list_head *next = sc->next_return->siblings.next;
668
669                 if (next == &sc->dir_obj->variant.dir_variant.children)
670                         sc->next_return = NULL; /* end of list */
671                 else
672                         sc->next_return =
673                             list_entry(next, struct yaffs_obj, siblings);
674         }
675 }
676
677 /*
678  * yaffs_remove_obj_callback() is called when an object is unlinked.
679  * We check open search contexts and advance any which are currently
680  * on the object being iterated.
681  */
682 static void yaffs_remove_obj_callback(struct yaffs_obj *obj)
683 {
684
685         struct list_head *i;
686         struct yaffs_search_context *sc;
687         struct list_head *search_contexts =
688             &(yaffs_dev_to_lc(obj->my_dev)->search_contexts);
689
690         /* Iterate through the directory search contexts.
691          * If any are currently on the object being removed, then advance
692          * the search context to the next object to prevent a hanging pointer.
693          */
694         list_for_each(i, search_contexts) {
695                 if (i) {
696                         sc = list_entry(i, struct yaffs_search_context, others);
697                         if (sc->next_return == obj)
698                                 yaffs_search_advance(sc);
699                 }
700         }
701
702 }
703
704 /*-----------------------------------------------------------------*/
705
706 static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
707                           int buflen)
708 {
709         unsigned char *alias;
710         int ret;
711
712         struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
713
714         yaffs_gross_lock(dev);
715
716         alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
717
718         yaffs_gross_unlock(dev);
719
720         if (!alias)
721                 return -ENOMEM;
722
723         ret = vfs_readlink(dentry, buffer, buflen, alias);
724         kfree(alias);
725         return ret;
726 }
727
728 #if (YAFFS_NEW_FOLLOW_LINK == 1)
729 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
730 {
731         void *ret;
732 #else
733 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
734 {
735         int ret
736 #endif
737         unsigned char *alias;
738         int ret_int = 0;
739         struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
740
741         yaffs_gross_lock(dev);
742
743         alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
744         yaffs_gross_unlock(dev);
745
746         if (!alias) {
747                 ret_int = -ENOMEM;
748                 goto out;
749         }
750 #if (YAFFS_NEW_FOLLOW_LINK == 1)
751         nd_set_link(nd, alias);
752         ret = alias;
753 out:
754         if (ret_int)
755                 ret = ERR_PTR(ret_int);
756         return ret;
757 #else
758         ret = vfs_follow_link(nd, alias);
759         kfree(alias);
760 out:
761         if (ret_int)
762                 ret = ret_int;
763         return ret;
764 #endif
765 }
766
767 #if (YAFFS_NEW_FOLLOW_LINK == 1)
768 void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias)
769 {
770         kfree(alias);
771 }
772 #endif
773
774 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
775                               struct yaffs_obj *obj);
776
777 /*
778  * Lookup is used to find objects in the fs
779  */
780 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
781
782 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
783                                    struct nameidata *n)
784 #else
785 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
786 #endif
787 {
788         struct yaffs_obj *obj;
789         struct inode *inode = NULL;     /* NCB 2.5/2.6 needs NULL here */
790
791         struct yaffs_dev *dev = yaffs_inode_to_obj(dir)->my_dev;
792
793         if (current != yaffs_dev_to_lc(dev)->readdir_process)
794                 yaffs_gross_lock(dev);
795
796         T(YAFFS_TRACE_OS,
797           (TSTR("yaffs_lookup for %d:%s\n"),
798            yaffs_inode_to_obj(dir)->obj_id, dentry->d_name.name));
799
800         obj = yaffs_find_by_name(yaffs_inode_to_obj(dir), dentry->d_name.name);
801
802         obj = yaffs_get_equivalent_obj(obj);    /* in case it was a hardlink */
803
804         /* Can't hold gross lock when calling yaffs_get_inode() */
805         if (current != yaffs_dev_to_lc(dev)->readdir_process)
806                 yaffs_gross_unlock(dev);
807
808         if (obj) {
809                 T(YAFFS_TRACE_OS,
810                   (TSTR("yaffs_lookup found %d\n"), obj->obj_id));
811
812                 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
813
814                 if (inode) {
815                         T(YAFFS_TRACE_OS, (TSTR("yaffs_loookup dentry \n")));
816 /* #if 0 asserted by NCB for 2.5/6 compatability - falls through to
817  * d_add even if NULL inode */
818 #if 0
819                         /*dget(dentry); // try to solve directory bug */
820                         d_add(dentry, inode);
821
822                         /* return dentry; */
823                         return NULL;
824 #endif
825                 }
826
827         } else {
828                 T(YAFFS_TRACE_OS, (TSTR("yaffs_lookup not found\n")));
829
830         }
831
832 /* added NCB for 2.5/6 compatability - forces add even if inode is
833  * NULL which creates dentry hash */
834         d_add(dentry, inode);
835
836         return NULL;
837 }
838
839 #ifdef YAFFS_HAS_PUT_INODE
840
841 /* For now put inode is just for debugging
842  * Put inode is called when the inode **structure** is put.
843  */
844 static void yaffs_put_inode(struct inode *inode)
845 {
846         T(YAFFS_TRACE_OS,
847           (TSTR("yaffs_put_inode: ino %d, count %d\n"), (int)inode->i_ino,
848            atomic_read(&inode->i_count)));
849
850 }
851 #endif
852
853 static void yaffs_unstitch_obj(struct inode *inode, struct yaffs_obj *obj)
854 {
855         /* Clear the association between the inode and
856          * the struct yaffs_obj.
857          */
858         obj->my_inode = NULL;
859         yaffs_inode_to_obj_lv(inode) = NULL;
860
861         /* If the object freeing was deferred, then the real
862          * free happens now.
863          * This should fix the inode inconsistency problem.
864          */
865         yaffs_handle_defered_free(obj);
866 }
867
868 #ifdef YAFFS_HAS_EVICT_INODE
869 /* yaffs_evict_inode combines into one operation what was previously done in
870  * yaffs_clear_inode() and yaffs_delete_inode()
871  *
872  */
873 static void yaffs_evict_inode(struct inode *inode)
874 {
875         struct yaffs_obj *obj;
876         struct yaffs_dev *dev;
877         int deleteme = 0;
878
879         obj = yaffs_inode_to_obj(inode);
880
881         T(YAFFS_TRACE_OS,
882           (TSTR("yaffs_evict_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
883            atomic_read(&inode->i_count),
884            obj ? "object exists" : "null object"));
885
886         if (!inode->i_nlink && !is_bad_inode(inode))
887                 deleteme = 1;
888         truncate_inode_pages(&inode->i_data, 0);
889         end_writeback(inode);
890
891         if (deleteme && obj) {
892                 dev = obj->my_dev;
893                 yaffs_gross_lock(dev);
894                 yaffs_del_obj(obj);
895                 yaffs_gross_unlock(dev);
896         }
897         if (obj) {
898                 dev = obj->my_dev;
899                 yaffs_gross_lock(dev);
900                 yaffs_unstitch_obj(inode, obj);
901                 yaffs_gross_unlock(dev);
902         }
903
904 }
905 #else
906
907 /* clear is called to tell the fs to release any per-inode data it holds.
908  * The object might still exist on disk and is just being thrown out of the cache
909  * or else the object has actually been deleted and we're being called via
910  * the chain
911  *   yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode()
912  */
913
914 static void yaffs_clear_inode(struct inode *inode)
915 {
916         struct yaffs_obj *obj;
917         struct yaffs_dev *dev;
918
919         obj = yaffs_inode_to_obj(inode);
920
921         T(YAFFS_TRACE_OS,
922           (TSTR("yaffs_clear_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
923            atomic_read(&inode->i_count),
924            obj ? "object exists" : "null object"));
925
926         if (obj) {
927                 dev = obj->my_dev;
928                 yaffs_gross_lock(dev);
929                 yaffs_unstitch_obj(inode, obj);
930                 yaffs_gross_unlock(dev);
931         }
932
933 }
934
935 /* delete is called when the link count is zero and the inode
936  * is put (ie. nobody wants to know about it anymore, time to
937  * delete the file).
938  * NB Must call clear_inode()
939  */
940 static void yaffs_delete_inode(struct inode *inode)
941 {
942         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
943         struct yaffs_dev *dev;
944
945         T(YAFFS_TRACE_OS,
946           (TSTR("yaffs_delete_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
947            atomic_read(&inode->i_count),
948            obj ? "object exists" : "null object"));
949
950         if (obj) {
951                 dev = obj->my_dev;
952                 yaffs_gross_lock(dev);
953                 yaffs_del_obj(obj);
954                 yaffs_gross_unlock(dev);
955         }
956 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
957         truncate_inode_pages(&inode->i_data, 0);
958 #endif
959         clear_inode(inode);
960 }
961 #endif
962
963 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
964 static int yaffs_file_flush(struct file *file, fl_owner_t id)
965 #else
966 static int yaffs_file_flush(struct file *file)
967 #endif
968 {
969         struct yaffs_obj *obj = yaffs_dentry_to_obj(file->f_dentry);
970
971         struct yaffs_dev *dev = obj->my_dev;
972
973         T(YAFFS_TRACE_OS,
974           (TSTR("yaffs_file_flush object %d (%s)\n"), obj->obj_id,
975            obj->dirty ? "dirty" : "clean"));
976
977         yaffs_gross_lock(dev);
978
979         yaffs_flush_file(obj, 1, 0);
980
981         yaffs_gross_unlock(dev);
982
983         return 0;
984 }
985
986 static int yaffs_readpage_nolock(struct file *f, struct page *pg)
987 {
988         /* Lifted from jffs2 */
989
990         struct yaffs_obj *obj;
991         unsigned char *pg_buf;
992         int ret;
993
994         struct yaffs_dev *dev;
995
996         T(YAFFS_TRACE_OS,
997           (TSTR("yaffs_readpage_nolock at %08x, size %08x\n"),
998            (unsigned)(pg->index << PAGE_CACHE_SHIFT),
999            (unsigned)PAGE_CACHE_SIZE));
1000
1001         obj = yaffs_dentry_to_obj(f->f_dentry);
1002
1003         dev = obj->my_dev;
1004
1005 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1006         BUG_ON(!PageLocked(pg));
1007 #else
1008         if (!PageLocked(pg))
1009                 PAGE_BUG(pg);
1010 #endif
1011
1012         pg_buf = kmap(pg);
1013         /* FIXME: Can kmap fail? */
1014
1015         yaffs_gross_lock(dev);
1016
1017         ret = yaffs_file_rd(obj, pg_buf,
1018                             pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
1019
1020         yaffs_gross_unlock(dev);
1021
1022         if (ret >= 0)
1023                 ret = 0;
1024
1025         if (ret) {
1026                 ClearPageUptodate(pg);
1027                 SetPageError(pg);
1028         } else {
1029                 SetPageUptodate(pg);
1030                 ClearPageError(pg);
1031         }
1032
1033         flush_dcache_page(pg);
1034         kunmap(pg);
1035
1036         T(YAFFS_TRACE_OS, (TSTR("yaffs_readpage_nolock done\n")));
1037         return ret;
1038 }
1039
1040 static int yaffs_readpage_unlock(struct file *f, struct page *pg)
1041 {
1042         int ret = yaffs_readpage_nolock(f, pg);
1043         UnlockPage(pg);
1044         return ret;
1045 }
1046
1047 static int yaffs_readpage(struct file *f, struct page *pg)
1048 {
1049         int ret;
1050
1051         T(YAFFS_TRACE_OS, (TSTR("yaffs_readpage\n")));
1052         ret = yaffs_readpage_unlock(f, pg);
1053         T(YAFFS_TRACE_OS, (TSTR("yaffs_readpage done\n")));
1054         return ret;
1055 }
1056
1057 /* writepage inspired by/stolen from smbfs */
1058
1059 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1060 static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
1061 #else
1062 static int yaffs_writepage(struct page *page)
1063 #endif
1064 {
1065         struct yaffs_dev *dev;
1066         struct address_space *mapping = page->mapping;
1067         struct inode *inode;
1068         unsigned long end_index;
1069         char *buffer;
1070         struct yaffs_obj *obj;
1071         int n_written = 0;
1072         unsigned n_bytes;
1073         loff_t i_size;
1074
1075         if (!mapping)
1076                 BUG();
1077         inode = mapping->host;
1078         if (!inode)
1079                 BUG();
1080         i_size = i_size_read(inode);
1081
1082         end_index = i_size >> PAGE_CACHE_SHIFT;
1083
1084         if (page->index < end_index)
1085                 n_bytes = PAGE_CACHE_SIZE;
1086         else {
1087                 n_bytes = i_size & (PAGE_CACHE_SIZE - 1);
1088
1089                 if (page->index > end_index || !n_bytes) {
1090                         T(YAFFS_TRACE_OS,
1091                           (TSTR
1092                            ("yaffs_writepage at %08x, inode size = %08x!!!\n"),
1093                            (unsigned)(page->index << PAGE_CACHE_SHIFT),
1094                            (unsigned)inode->i_size));
1095                         T(YAFFS_TRACE_OS,
1096                           (TSTR("                -> don't care!!\n")));
1097
1098                         zero_user_segment(page, 0, PAGE_CACHE_SIZE);
1099                         set_page_writeback(page);
1100                         unlock_page(page);
1101                         end_page_writeback(page);
1102                         return 0;
1103                 }
1104         }
1105
1106         if (n_bytes != PAGE_CACHE_SIZE)
1107                 zero_user_segment(page, n_bytes, PAGE_CACHE_SIZE);
1108
1109         get_page(page);
1110
1111         buffer = kmap(page);
1112
1113         obj = yaffs_inode_to_obj(inode);
1114         dev = obj->my_dev;
1115         yaffs_gross_lock(dev);
1116
1117         T(YAFFS_TRACE_OS,
1118           (TSTR("yaffs_writepage at %08x, size %08x\n"),
1119            (unsigned)(page->index << PAGE_CACHE_SHIFT), n_bytes));
1120         T(YAFFS_TRACE_OS,
1121           (TSTR("writepag0: obj = %05x, ino = %05x\n"),
1122            (int)obj->variant.file_variant.file_size, (int)inode->i_size));
1123
1124         n_written = yaffs_wr_file(obj, buffer,
1125                                   page->index << PAGE_CACHE_SHIFT, n_bytes, 0);
1126
1127         yaffs_touch_super(dev);
1128
1129         T(YAFFS_TRACE_OS,
1130           (TSTR("writepag1: obj = %05x, ino = %05x\n"),
1131            (int)obj->variant.file_variant.file_size, (int)inode->i_size));
1132
1133         yaffs_gross_unlock(dev);
1134
1135         kunmap(page);
1136         set_page_writeback(page);
1137         unlock_page(page);
1138         end_page_writeback(page);
1139         put_page(page);
1140
1141         return (n_written == n_bytes) ? 0 : -ENOSPC;
1142 }
1143
1144 #if (YAFFS_USE_WRITE_BEGIN_END > 0)
1145 static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
1146                              loff_t pos, unsigned len, unsigned flags,
1147                              struct page **pagep, void **fsdata)
1148 {
1149         struct page *pg = NULL;
1150         pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1151
1152         int ret = 0;
1153         int space_held = 0;
1154
1155         /* Get a page */
1156 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
1157         pg = grab_cache_page_write_begin(mapping, index, flags);
1158 #else
1159         pg = __grab_cache_page(mapping, index);
1160 #endif
1161
1162         *pagep = pg;
1163         if (!pg) {
1164                 ret = -ENOMEM;
1165                 goto out;
1166         }
1167         T(YAFFS_TRACE_OS,
1168           (TSTR("start yaffs_write_begin index %d(%x) uptodate %d\n"),
1169            (int)index, (int)index, Page_Uptodate(pg) ? 1 : 0));
1170
1171         /* Get fs space */
1172         space_held = yaffs_hold_space(filp);
1173
1174         if (!space_held) {
1175                 ret = -ENOSPC;
1176                 goto out;
1177         }
1178
1179         /* Update page if required */
1180
1181         if (!Page_Uptodate(pg))
1182                 ret = yaffs_readpage_nolock(filp, pg);
1183
1184         if (ret)
1185                 goto out;
1186
1187         /* Happy path return */
1188         T(YAFFS_TRACE_OS, (TSTR("end yaffs_write_begin - ok\n")));
1189
1190         return 0;
1191
1192 out:
1193         T(YAFFS_TRACE_OS,
1194           (TSTR("end yaffs_write_begin fail returning %d\n"), ret));
1195         if (space_held)
1196                 yaffs_release_space(filp);
1197         if (pg) {
1198                 unlock_page(pg);
1199                 page_cache_release(pg);
1200         }
1201         return ret;
1202 }
1203
1204 #else
1205
1206 static int yaffs_prepare_write(struct file *f, struct page *pg,
1207                                unsigned offset, unsigned to)
1208 {
1209         T(YAFFS_TRACE_OS, (TSTR("yaffs_prepair_write\n")));
1210
1211         if (!Page_Uptodate(pg))
1212                 return yaffs_readpage_nolock(f, pg);
1213         return 0;
1214 }
1215 #endif
1216
1217 #if (YAFFS_USE_WRITE_BEGIN_END > 0)
1218 static int yaffs_write_end(struct file *filp, struct address_space *mapping,
1219                            loff_t pos, unsigned len, unsigned copied,
1220                            struct page *pg, void *fsdadata)
1221 {
1222         int ret = 0;
1223         void *addr, *kva;
1224         uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
1225
1226         kva = kmap(pg);
1227         addr = kva + offset_into_page;
1228
1229         T(YAFFS_TRACE_OS,
1230           ("yaffs_write_end addr %p pos %x n_bytes %d\n",
1231            addr, (unsigned)pos, copied));
1232
1233         ret = yaffs_file_write(filp, addr, copied, &pos);
1234
1235         if (ret != copied) {
1236                 T(YAFFS_TRACE_OS,
1237                   (TSTR("yaffs_write_end not same size ret %d  copied %d\n"),
1238                    ret, copied));
1239                 SetPageError(pg);
1240         } else {
1241                 /* Nothing */
1242         }
1243
1244         kunmap(pg);
1245
1246         yaffs_release_space(filp);
1247         unlock_page(pg);
1248         page_cache_release(pg);
1249         return ret;
1250 }
1251 #else
1252
1253 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
1254                               unsigned to)
1255 {
1256         void *addr, *kva;
1257
1258         loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
1259         int n_bytes = to - offset;
1260         int n_written;
1261
1262         unsigned spos = pos;
1263         unsigned saddr;
1264
1265         kva = kmap(pg);
1266         addr = kva + offset;
1267
1268         saddr = (unsigned)addr;
1269
1270         T(YAFFS_TRACE_OS,
1271           (TSTR("yaffs_commit_write addr %x pos %x n_bytes %d\n"),
1272            saddr, spos, n_bytes));
1273
1274         n_written = yaffs_file_write(f, addr, n_bytes, &pos);
1275
1276         if (n_written != n_bytes) {
1277                 T(YAFFS_TRACE_OS,
1278                   (TSTR
1279                    ("yaffs_commit_write not same size n_written %d  n_bytes %d\n"),
1280                    n_written, n_bytes));
1281                 SetPageError(pg);
1282         } else {
1283                 /* Nothing */
1284         }
1285
1286         kunmap(pg);
1287
1288         T(YAFFS_TRACE_OS,
1289           (TSTR("yaffs_commit_write returning %d\n"),
1290            n_written == n_bytes ? 0 : n_written));
1291
1292         return n_written == n_bytes ? 0 : n_written;
1293 }
1294 #endif
1295
1296 static void yaffs_fill_inode_from_obj(struct inode *inode,
1297                                       struct yaffs_obj *obj)
1298 {
1299         if (inode && obj) {
1300
1301                 /* Check mode against the variant type and attempt to repair if broken. */
1302                 u32 mode = obj->yst_mode;
1303                 switch (obj->variant_type) {
1304                 case YAFFS_OBJECT_TYPE_FILE:
1305                         if (!S_ISREG(mode)) {
1306                                 obj->yst_mode &= ~S_IFMT;
1307                                 obj->yst_mode |= S_IFREG;
1308                         }
1309
1310                         break;
1311                 case YAFFS_OBJECT_TYPE_SYMLINK:
1312                         if (!S_ISLNK(mode)) {
1313                                 obj->yst_mode &= ~S_IFMT;
1314                                 obj->yst_mode |= S_IFLNK;
1315                         }
1316
1317                         break;
1318                 case YAFFS_OBJECT_TYPE_DIRECTORY:
1319                         if (!S_ISDIR(mode)) {
1320                                 obj->yst_mode &= ~S_IFMT;
1321                                 obj->yst_mode |= S_IFDIR;
1322                         }
1323
1324                         break;
1325                 case YAFFS_OBJECT_TYPE_UNKNOWN:
1326                 case YAFFS_OBJECT_TYPE_HARDLINK:
1327                 case YAFFS_OBJECT_TYPE_SPECIAL:
1328                 default:
1329                         /* TODO? */
1330                         break;
1331                 }
1332
1333                 inode->i_flags |= S_NOATIME;
1334
1335                 inode->i_ino = obj->obj_id;
1336                 inode->i_mode = obj->yst_mode;
1337                 inode->i_uid = obj->yst_uid;
1338                 inode->i_gid = obj->yst_gid;
1339 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
1340                 inode->i_blksize = inode->i_sb->s_blocksize;
1341 #endif
1342 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1343
1344                 inode->i_rdev = old_decode_dev(obj->yst_rdev);
1345                 inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
1346                 inode->i_atime.tv_nsec = 0;
1347                 inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
1348                 inode->i_mtime.tv_nsec = 0;
1349                 inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
1350                 inode->i_ctime.tv_nsec = 0;
1351 #else
1352                 inode->i_rdev = obj->yst_rdev;
1353                 inode->i_atime = obj->yst_atime;
1354                 inode->i_mtime = obj->yst_mtime;
1355                 inode->i_ctime = obj->yst_ctime;
1356 #endif
1357                 inode->i_size = yaffs_get_obj_length(obj);
1358                 inode->i_blocks = (inode->i_size + 511) >> 9;
1359
1360                 inode->i_nlink = yaffs_get_obj_link_count(obj);
1361
1362                 T(YAFFS_TRACE_OS,
1363                   (TSTR
1364                    ("yaffs_fill_inode mode %x uid %d gid %d size %d count %d\n"),
1365                    inode->i_mode, inode->i_uid, inode->i_gid,
1366                    (int)inode->i_size, atomic_read(&inode->i_count)));
1367
1368                 switch (obj->yst_mode & S_IFMT) {
1369                 default:        /* fifo, device or socket */
1370 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1371                         init_special_inode(inode, obj->yst_mode,
1372                                            old_decode_dev(obj->yst_rdev));
1373 #else
1374                         init_special_inode(inode, obj->yst_mode,
1375                                            (dev_t) (obj->yst_rdev));
1376 #endif
1377                         break;
1378                 case S_IFREG:   /* file */
1379                         inode->i_op = &yaffs_file_inode_operations;
1380                         inode->i_fop = &yaffs_file_operations;
1381                         inode->i_mapping->a_ops =
1382                             &yaffs_file_address_operations;
1383                         break;
1384                 case S_IFDIR:   /* directory */
1385                         inode->i_op = &yaffs_dir_inode_operations;
1386                         inode->i_fop = &yaffs_dir_operations;
1387                         break;
1388                 case S_IFLNK:   /* symlink */
1389                         inode->i_op = &yaffs_symlink_inode_operations;
1390                         break;
1391                 }
1392
1393                 yaffs_inode_to_obj_lv(inode) = obj;
1394
1395                 obj->my_inode = inode;
1396
1397         } else {
1398                 T(YAFFS_TRACE_OS,
1399                   (TSTR("yaffs_fill_inode invalid parameters\n")));
1400         }
1401
1402 }
1403
1404 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
1405                               struct yaffs_obj *obj)
1406 {
1407         struct inode *inode;
1408
1409         if (!sb) {
1410                 T(YAFFS_TRACE_OS,
1411                   (TSTR("yaffs_get_inode for NULL super_block!!\n")));
1412                 return NULL;
1413
1414         }
1415
1416         if (!obj) {
1417                 T(YAFFS_TRACE_OS,
1418                   (TSTR("yaffs_get_inode for NULL object!!\n")));
1419                 return NULL;
1420
1421         }
1422
1423         T(YAFFS_TRACE_OS,
1424           (TSTR("yaffs_get_inode for object %d\n"), obj->obj_id));
1425
1426         inode = Y_IGET(sb, obj->obj_id);
1427         if (IS_ERR(inode))
1428                 return NULL;
1429
1430         /* NB Side effect: iget calls back to yaffs_read_inode(). */
1431         /* iget also increments the inode's i_count */
1432         /* NB You can't be holding gross_lock or deadlock will happen! */
1433
1434         return inode;
1435 }
1436
1437 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
1438                                 loff_t * pos)
1439 {
1440         struct yaffs_obj *obj;
1441         int n_written, ipos;
1442         struct inode *inode;
1443         struct yaffs_dev *dev;
1444
1445         obj = yaffs_dentry_to_obj(f->f_dentry);
1446
1447         dev = obj->my_dev;
1448
1449         yaffs_gross_lock(dev);
1450
1451         inode = f->f_dentry->d_inode;
1452
1453         if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
1454                 ipos = inode->i_size;
1455         else
1456                 ipos = *pos;
1457
1458         if (!obj)
1459                 T(YAFFS_TRACE_OS,
1460                   (TSTR("yaffs_file_write: hey obj is null!\n")));
1461         else
1462                 T(YAFFS_TRACE_OS,
1463                   (TSTR("yaffs_file_write about to write writing %u(%x) bytes"
1464                         "to object %d at %d(%x)\n"),
1465                    (unsigned)n, (unsigned)n, obj->obj_id, ipos, ipos));
1466
1467         n_written = yaffs_wr_file(obj, buf, ipos, n, 0);
1468
1469         yaffs_touch_super(dev);
1470
1471         T(YAFFS_TRACE_OS,
1472           (TSTR("yaffs_file_write: %d(%x) bytes written\n"),
1473            (unsigned)n, (unsigned)n));
1474
1475         if (n_written > 0) {
1476                 ipos += n_written;
1477                 *pos = ipos;
1478                 if (ipos > inode->i_size) {
1479                         inode->i_size = ipos;
1480                         inode->i_blocks = (ipos + 511) >> 9;
1481
1482                         T(YAFFS_TRACE_OS,
1483                           (TSTR("yaffs_file_write size updated to %d bytes, "
1484                                 "%d blocks\n"), ipos, (int)(inode->i_blocks)));
1485                 }
1486
1487         }
1488         yaffs_gross_unlock(dev);
1489         return (n_written == 0) && (n > 0) ? -ENOSPC : n_written;
1490 }
1491
1492 /* Space holding and freeing is done to ensure we have space available for write_begin/end */
1493 /* For now we just assume few parallel writes and check against a small number. */
1494 /* Todo: need to do this with a counter to handle parallel reads better */
1495
1496 static ssize_t yaffs_hold_space(struct file *f)
1497 {
1498         struct yaffs_obj *obj;
1499         struct yaffs_dev *dev;
1500
1501         int n_free_chunks;
1502
1503         obj = yaffs_dentry_to_obj(f->f_dentry);
1504
1505         dev = obj->my_dev;
1506
1507         yaffs_gross_lock(dev);
1508
1509         n_free_chunks = yaffs_get_n_free_chunks(dev);
1510
1511         yaffs_gross_unlock(dev);
1512
1513         return (n_free_chunks > 20) ? 1 : 0;
1514 }
1515
1516 static void yaffs_release_space(struct file *f)
1517 {
1518         struct yaffs_obj *obj;
1519         struct yaffs_dev *dev;
1520
1521         obj = yaffs_dentry_to_obj(f->f_dentry);
1522
1523         dev = obj->my_dev;
1524
1525         yaffs_gross_lock(dev);
1526
1527         yaffs_gross_unlock(dev);
1528 }
1529
1530 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
1531 {
1532         struct yaffs_obj *obj;
1533         struct yaffs_dev *dev;
1534         struct yaffs_search_context *sc;
1535         struct inode *inode = f->f_dentry->d_inode;
1536         unsigned long offset, curoffs;
1537         struct yaffs_obj *l;
1538         int ret_val = 0;
1539
1540         char name[YAFFS_MAX_NAME_LENGTH + 1];
1541
1542         obj = yaffs_dentry_to_obj(f->f_dentry);
1543         dev = obj->my_dev;
1544
1545         yaffs_gross_lock(dev);
1546
1547         yaffs_dev_to_lc(dev)->readdir_process = current;
1548
1549         offset = f->f_pos;
1550
1551         sc = yaffs_new_search(obj);
1552         if (!sc) {
1553                 ret_val = -ENOMEM;
1554                 goto out;
1555         }
1556
1557         T(YAFFS_TRACE_OS,
1558           (TSTR("yaffs_readdir: starting at %d\n"), (int)offset));
1559
1560         if (offset == 0) {
1561                 T(YAFFS_TRACE_OS,
1562                   (TSTR("yaffs_readdir: entry . ino %d \n"),
1563                    (int)inode->i_ino));
1564                 yaffs_gross_unlock(dev);
1565                 if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0) {
1566                         yaffs_gross_lock(dev);
1567                         goto out;
1568                 }
1569                 yaffs_gross_lock(dev);
1570                 offset++;
1571                 f->f_pos++;
1572         }
1573         if (offset == 1) {
1574                 T(YAFFS_TRACE_OS,
1575                   (TSTR("yaffs_readdir: entry .. ino %d \n"),
1576                    (int)f->f_dentry->d_parent->d_inode->i_ino));
1577                 yaffs_gross_unlock(dev);
1578                 if (filldir(dirent, "..", 2, offset,
1579                             f->f_dentry->d_parent->d_inode->i_ino,
1580                             DT_DIR) < 0) {
1581                         yaffs_gross_lock(dev);
1582                         goto out;
1583                 }
1584                 yaffs_gross_lock(dev);
1585                 offset++;
1586                 f->f_pos++;
1587         }
1588
1589         curoffs = 1;
1590
1591         /* If the directory has changed since the open or last call to
1592            readdir, rewind to after the 2 canned entries. */
1593         if (f->f_version != inode->i_version) {
1594                 offset = 2;
1595                 f->f_pos = offset;
1596                 f->f_version = inode->i_version;
1597         }
1598
1599         while (sc->next_return) {
1600                 curoffs++;
1601                 l = sc->next_return;
1602                 if (curoffs >= offset) {
1603                         int this_inode = yaffs_get_obj_inode(l);
1604                         int this_type = yaffs_get_obj_type(l);
1605
1606                         yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
1607                         T(YAFFS_TRACE_OS,
1608                           (TSTR("yaffs_readdir: %s inode %d\n"),
1609                            name, yaffs_get_obj_inode(l)));
1610
1611                         yaffs_gross_unlock(dev);
1612
1613                         if (filldir(dirent,
1614                                     name,
1615                                     strlen(name),
1616                                     offset, this_inode, this_type) < 0) {
1617                                 yaffs_gross_lock(dev);
1618                                 goto out;
1619                         }
1620
1621                         yaffs_gross_lock(dev);
1622
1623                         offset++;
1624                         f->f_pos++;
1625                 }
1626                 yaffs_search_advance(sc);
1627         }
1628
1629 out:
1630         yaffs_search_end(sc);
1631         yaffs_dev_to_lc(dev)->readdir_process = NULL;
1632         yaffs_gross_unlock(dev);
1633
1634         return ret_val;
1635 }
1636
1637 /*
1638  * File creation. Allocate an inode, and we're done..
1639  */
1640
1641 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
1642 #define YCRED(x) x
1643 #else
1644 #define YCRED(x) (x->cred)
1645 #endif
1646
1647 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1648 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
1649                        dev_t rdev)
1650 #else
1651 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
1652                        int rdev)
1653 #endif
1654 {
1655         struct inode *inode;
1656
1657         struct yaffs_obj *obj = NULL;
1658         struct yaffs_dev *dev;
1659
1660         struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
1661
1662         int error = -ENOSPC;
1663         uid_t uid = YCRED(current)->fsuid;
1664         gid_t gid =
1665             (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
1666
1667         if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
1668                 mode |= S_ISGID;
1669
1670         if (parent) {
1671                 T(YAFFS_TRACE_OS,
1672                   (TSTR("yaffs_mknod: parent object %d type %d\n"),
1673                    parent->obj_id, parent->variant_type));
1674         } else {
1675                 T(YAFFS_TRACE_OS,
1676                   (TSTR("yaffs_mknod: could not get parent object\n")));
1677                 return -EPERM;
1678         }
1679
1680         T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making oject for %s, "
1681                                 "mode %x dev %x\n"),
1682                            dentry->d_name.name, mode, rdev));
1683
1684         dev = parent->my_dev;
1685
1686         yaffs_gross_lock(dev);
1687
1688         switch (mode & S_IFMT) {
1689         default:
1690                 /* Special (socket, fifo, device...) */
1691                 T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making special\n")));
1692 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1693                 obj =
1694                     yaffs_create_special(parent, dentry->d_name.name, mode, uid,
1695                                          gid, old_encode_dev(rdev));
1696 #else
1697                 obj =
1698                     yaffs_create_special(parent, dentry->d_name.name, mode, uid,
1699                                          gid, rdev);
1700 #endif
1701                 break;
1702         case S_IFREG:           /* file          */
1703                 T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making file\n")));
1704                 obj = yaffs_create_file(parent, dentry->d_name.name, mode, uid,
1705                                         gid);
1706                 break;
1707         case S_IFDIR:           /* directory */
1708                 T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making directory\n")));
1709                 obj = yaffs_create_dir(parent, dentry->d_name.name, mode,
1710                                        uid, gid);
1711                 break;
1712         case S_IFLNK:           /* symlink */
1713                 T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making symlink\n")));
1714                 obj = NULL;     /* Do we ever get here? */
1715                 break;
1716         }
1717
1718         /* Can not call yaffs_get_inode() with gross lock held */
1719         yaffs_gross_unlock(dev);
1720
1721         if (obj) {
1722                 inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
1723                 d_instantiate(dentry, inode);
1724                 update_dir_time(dir);
1725                 T(YAFFS_TRACE_OS,
1726                   (TSTR("yaffs_mknod created object %d count = %d\n"),
1727                    obj->obj_id, atomic_read(&inode->i_count)));
1728                 error = 0;
1729                 yaffs_fill_inode_from_obj(dir, parent);
1730         } else {
1731                 T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod failed making object\n")));
1732                 error = -ENOMEM;
1733         }
1734
1735         return error;
1736 }
1737
1738 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1739 {
1740         int ret_val;
1741         T(YAFFS_TRACE_OS, (TSTR("yaffs_mkdir\n")));
1742         ret_val = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
1743         return ret_val;
1744 }
1745
1746 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1747 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
1748                         struct nameidata *n)
1749 #else
1750 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
1751 #endif
1752 {
1753         T(YAFFS_TRACE_OS, (TSTR("yaffs_create\n")));
1754         return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
1755 }
1756
1757 static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
1758 {
1759         int ret_val;
1760
1761         struct yaffs_dev *dev;
1762         struct yaffs_obj *obj;
1763
1764         T(YAFFS_TRACE_OS,
1765           (TSTR("yaffs_unlink %d:%s\n"),
1766            (int)(dir->i_ino), dentry->d_name.name));
1767         obj = yaffs_inode_to_obj(dir);
1768         dev = obj->my_dev;
1769
1770         yaffs_gross_lock(dev);
1771
1772         ret_val = yaffs_unlinker(obj, dentry->d_name.name);
1773
1774         if (ret_val == YAFFS_OK) {
1775                 dentry->d_inode->i_nlink--;
1776                 dir->i_version++;
1777                 yaffs_gross_unlock(dev);
1778                 mark_inode_dirty(dentry->d_inode);
1779                 update_dir_time(dir);
1780                 return 0;
1781         }
1782         yaffs_gross_unlock(dev);
1783         return -ENOTEMPTY;
1784 }
1785
1786 /*
1787  * Create a link...
1788  */
1789 static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
1790                       struct dentry *dentry)
1791 {
1792         struct inode *inode = old_dentry->d_inode;
1793         struct yaffs_obj *obj = NULL;
1794         struct yaffs_obj *link = NULL;
1795         struct yaffs_dev *dev;
1796
1797         T(YAFFS_TRACE_OS, (TSTR("yaffs_link\n")));
1798
1799         obj = yaffs_inode_to_obj(inode);
1800         dev = obj->my_dev;
1801
1802         yaffs_gross_lock(dev);
1803
1804         if (!S_ISDIR(inode->i_mode))    /* Don't link directories */
1805                 link =
1806                     yaffs_link_obj(yaffs_inode_to_obj(dir), dentry->d_name.name,
1807                                    obj);
1808
1809         if (link) {
1810                 old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
1811                 d_instantiate(dentry, old_dentry->d_inode);
1812                 atomic_inc(&old_dentry->d_inode->i_count);
1813                 T(YAFFS_TRACE_OS,
1814                   (TSTR("yaffs_link link count %d i_count %d\n"),
1815                    old_dentry->d_inode->i_nlink,
1816                    atomic_read(&old_dentry->d_inode->i_count)));
1817         }
1818
1819         yaffs_gross_unlock(dev);
1820
1821         if (link) {
1822                 update_dir_time(dir);
1823                 return 0;
1824         }
1825
1826         return -EPERM;
1827 }
1828
1829 static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
1830                          const char *symname)
1831 {
1832         struct yaffs_obj *obj;
1833         struct yaffs_dev *dev;
1834         uid_t uid = YCRED(current)->fsuid;
1835         gid_t gid =
1836             (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
1837
1838         T(YAFFS_TRACE_OS, (TSTR("yaffs_symlink\n")));
1839
1840         dev = yaffs_inode_to_obj(dir)->my_dev;
1841         yaffs_gross_lock(dev);
1842         obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
1843                                    S_IFLNK | S_IRWXUGO, uid, gid, symname);
1844         yaffs_gross_unlock(dev);
1845
1846         if (obj) {
1847                 struct inode *inode;
1848
1849                 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
1850                 d_instantiate(dentry, inode);
1851                 update_dir_time(dir);
1852                 T(YAFFS_TRACE_OS, (TSTR("symlink created OK\n")));
1853                 return 0;
1854         } else {
1855                 T(YAFFS_TRACE_OS, (TSTR("symlink not created\n")));
1856         }
1857
1858         return -ENOMEM;
1859 }
1860
1861 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
1862 static int yaffs_sync_object(struct file *file, int datasync)
1863 #else
1864 static int yaffs_sync_object(struct file *file, struct dentry *dentry,
1865                              int datasync)
1866 #endif
1867 {
1868
1869         struct yaffs_obj *obj;
1870         struct yaffs_dev *dev;
1871 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
1872         struct dentry *dentry = file->f_path.dentry;
1873 #endif
1874
1875         obj = yaffs_dentry_to_obj(dentry);
1876
1877         dev = obj->my_dev;
1878
1879         T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC, (TSTR("yaffs_sync_object\n")));
1880         yaffs_gross_lock(dev);
1881         yaffs_flush_file(obj, 1, datasync);
1882         yaffs_gross_unlock(dev);
1883         return 0;
1884 }
1885
1886 /*
1887  * The VFS layer already does all the dentry stuff for rename.
1888  *
1889  * NB: POSIX says you can rename an object over an old object of the same name
1890  */
1891 static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
1892                         struct inode *new_dir, struct dentry *new_dentry)
1893 {
1894         struct yaffs_dev *dev;
1895         int ret_val = YAFFS_FAIL;
1896         struct yaffs_obj *target;
1897
1898         T(YAFFS_TRACE_OS, (TSTR("yaffs_rename\n")));
1899         dev = yaffs_inode_to_obj(old_dir)->my_dev;
1900
1901         yaffs_gross_lock(dev);
1902
1903         /* Check if the target is an existing directory that is not empty. */
1904         target = yaffs_find_by_name(yaffs_inode_to_obj(new_dir),
1905                                     new_dentry->d_name.name);
1906
1907         if (target && target->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
1908             !list_empty(&target->variant.dir_variant.children)) {
1909
1910                 T(YAFFS_TRACE_OS, (TSTR("target is non-empty dir\n")));
1911
1912                 ret_val = YAFFS_FAIL;
1913         } else {
1914                 /* Now does unlinking internally using shadowing mechanism */
1915                 T(YAFFS_TRACE_OS, (TSTR("calling yaffs_rename_obj\n")));
1916
1917                 ret_val = yaffs_rename_obj(yaffs_inode_to_obj(old_dir),
1918                                            old_dentry->d_name.name,
1919                                            yaffs_inode_to_obj(new_dir),
1920                                            new_dentry->d_name.name);
1921         }
1922         yaffs_gross_unlock(dev);
1923
1924         if (ret_val == YAFFS_OK) {
1925                 if (target) {
1926                         new_dentry->d_inode->i_nlink--;
1927                         mark_inode_dirty(new_dentry->d_inode);
1928                 }
1929
1930                 update_dir_time(old_dir);
1931                 if (old_dir != new_dir)
1932                         update_dir_time(new_dir);
1933                 return 0;
1934         } else {
1935                 return -ENOTEMPTY;
1936         }
1937 }
1938
1939 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
1940 {
1941         struct inode *inode = dentry->d_inode;
1942         int error = 0;
1943         struct yaffs_dev *dev;
1944
1945         T(YAFFS_TRACE_OS,
1946           (TSTR("yaffs_setattr of object %d\n"),
1947            yaffs_inode_to_obj(inode)->obj_id));
1948
1949         /* Fail if a requested resize >= 2GB */
1950         if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31))
1951                 error = -EINVAL;
1952
1953         if (error == 0)
1954                 error = inode_change_ok(inode, attr);
1955         if (error == 0) {
1956                 int result;
1957                 if (!error) {
1958                         error = yaffs_vfs_setattr(inode, attr);
1959                         T(YAFFS_TRACE_OS, (TSTR("inode_setattr called\n")));
1960                         if (attr->ia_valid & ATTR_SIZE) {
1961                                 yaffs_vfs_setsize(inode, attr->ia_size);
1962                                 inode->i_blocks = (inode->i_size + 511) >> 9;
1963                         }
1964                 }
1965                 dev = yaffs_inode_to_obj(inode)->my_dev;
1966                 if (attr->ia_valid & ATTR_SIZE) {
1967                         T(YAFFS_TRACE_OS, (TSTR("resize to %d(%x)\n"),
1968                                            (int)(attr->ia_size),
1969                                            (int)(attr->ia_size)));
1970                 }
1971                 yaffs_gross_lock(dev);
1972                 result = yaffs_set_attribs(yaffs_inode_to_obj(inode), attr);
1973                 if (result == YAFFS_OK) {
1974                         error = 0;
1975                 } else {
1976                         error = -EPERM;
1977                 }
1978                 yaffs_gross_unlock(dev);
1979
1980         }
1981
1982         T(YAFFS_TRACE_OS, (TSTR("yaffs_setattr done returning %d\n"), error));
1983
1984         return error;
1985 }
1986
1987 #ifdef CONFIG_YAFFS_XATTR
1988 int yaffs_setxattr(struct dentry *dentry, const char *name,
1989                    const void *value, size_t size, int flags)
1990 {
1991         struct inode *inode = dentry->d_inode;
1992         int error = 0;
1993         struct yaffs_dev *dev;
1994         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
1995
1996         T(YAFFS_TRACE_OS, (TSTR("yaffs_setxattr of object %d\n"), obj->obj_id));
1997
1998         if (error == 0) {
1999                 int result;
2000                 dev = obj->my_dev;
2001                 yaffs_gross_lock(dev);
2002                 result = yaffs_set_xattrib(obj, name, value, size, flags);
2003                 if (result == YAFFS_OK)
2004                         error = 0;
2005                 else if (result < 0)
2006                         error = result;
2007                 yaffs_gross_unlock(dev);
2008
2009         }
2010         T(YAFFS_TRACE_OS, (TSTR("yaffs_setxattr done returning %d\n"), error));
2011
2012         return error;
2013 }
2014
2015 ssize_t yaffs_getxattr(struct dentry * dentry, const char *name, void *buff,
2016                        size_t size)
2017 {
2018         struct inode *inode = dentry->d_inode;
2019         int error = 0;
2020         struct yaffs_dev *dev;
2021         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
2022
2023         T(YAFFS_TRACE_OS,
2024           (TSTR("yaffs_getxattr \"%s\" from object %d\n"), name, obj->obj_id));
2025
2026         if (error == 0) {
2027                 dev = obj->my_dev;
2028                 yaffs_gross_lock(dev);
2029                 error = yaffs_get_xattrib(obj, name, buff, size);
2030                 yaffs_gross_unlock(dev);
2031
2032         }
2033         T(YAFFS_TRACE_OS, (TSTR("yaffs_getxattr done returning %d\n"), error));
2034
2035         return error;
2036 }
2037
2038 int yaffs_removexattr(struct dentry *dentry, const char *name)
2039 {
2040         struct inode *inode = dentry->d_inode;
2041         int error = 0;
2042         struct yaffs_dev *dev;
2043         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
2044
2045         T(YAFFS_TRACE_OS,
2046           (TSTR("yaffs_removexattr of object %d\n"), obj->obj_id));
2047
2048         if (error == 0) {
2049                 int result;
2050                 dev = obj->my_dev;
2051                 yaffs_gross_lock(dev);
2052                 result = yaffs_remove_xattrib(obj, name);
2053                 if (result == YAFFS_OK)
2054                         error = 0;
2055                 else if (result < 0)
2056                         error = result;
2057                 yaffs_gross_unlock(dev);
2058
2059         }
2060         T(YAFFS_TRACE_OS,
2061           (TSTR("yaffs_removexattr done returning %d\n"), error));
2062
2063         return error;
2064 }
2065
2066 ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size)
2067 {
2068         struct inode *inode = dentry->d_inode;
2069         int error = 0;
2070         struct yaffs_dev *dev;
2071         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
2072
2073         T(YAFFS_TRACE_OS,
2074           (TSTR("yaffs_listxattr of object %d\n"), obj->obj_id));
2075
2076         if (error == 0) {
2077                 dev = obj->my_dev;
2078                 yaffs_gross_lock(dev);
2079                 error = yaffs_list_xattrib(obj, buff, size);
2080                 yaffs_gross_unlock(dev);
2081
2082         }
2083         T(YAFFS_TRACE_OS, (TSTR("yaffs_listxattr done returning %d\n"), error));
2084
2085         return error;
2086 }
2087
2088 #endif
2089
2090 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2091 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
2092 {
2093         struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
2094         struct super_block *sb = dentry->d_sb;
2095 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2096 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
2097 {
2098         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2099 #else
2100 static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
2101 {
2102         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2103 #endif
2104
2105         T(YAFFS_TRACE_OS, (TSTR("yaffs_statfs\n")));
2106
2107         yaffs_gross_lock(dev);
2108
2109         buf->f_type = YAFFS_MAGIC;
2110         buf->f_bsize = sb->s_blocksize;
2111         buf->f_namelen = 255;
2112
2113         if (dev->data_bytes_per_chunk & (dev->data_bytes_per_chunk - 1)) {
2114                 /* Do this if chunk size is not a power of 2 */
2115
2116                 uint64_t bytes_in_dev;
2117                 uint64_t bytes_free;
2118
2119                 bytes_in_dev =
2120                     ((uint64_t)
2121                      ((dev->param.end_block - dev->param.start_block +
2122                        1))) * ((uint64_t) (dev->param.chunks_per_block *
2123                                            dev->data_bytes_per_chunk));
2124
2125                 do_div(bytes_in_dev, sb->s_blocksize);  /* bytes_in_dev becomes the number of blocks */
2126                 buf->f_blocks = bytes_in_dev;
2127
2128                 bytes_free = ((uint64_t) (yaffs_get_n_free_chunks(dev))) *
2129                     ((uint64_t) (dev->data_bytes_per_chunk));
2130
2131                 do_div(bytes_free, sb->s_blocksize);
2132
2133                 buf->f_bfree = bytes_free;
2134
2135         } else if (sb->s_blocksize > dev->data_bytes_per_chunk) {
2136
2137                 buf->f_blocks =
2138                     (dev->param.end_block - dev->param.start_block + 1) *
2139                     dev->param.chunks_per_block /
2140                     (sb->s_blocksize / dev->data_bytes_per_chunk);
2141                 buf->f_bfree =
2142                     yaffs_get_n_free_chunks(dev) /
2143                     (sb->s_blocksize / dev->data_bytes_per_chunk);
2144         } else {
2145                 buf->f_blocks =
2146                     (dev->param.end_block - dev->param.start_block + 1) *
2147                     dev->param.chunks_per_block *
2148                     (dev->data_bytes_per_chunk / sb->s_blocksize);
2149
2150                 buf->f_bfree =
2151                     yaffs_get_n_free_chunks(dev) *
2152                     (dev->data_bytes_per_chunk / sb->s_blocksize);
2153         }
2154
2155         buf->f_files = 0;
2156         buf->f_ffree = 0;
2157         buf->f_bavail = buf->f_bfree;
2158
2159         yaffs_gross_unlock(dev);
2160         return 0;
2161 }
2162
2163 static void yaffs_flush_inodes(struct super_block *sb)
2164 {
2165         struct inode *iptr;
2166         struct yaffs_obj *obj;
2167
2168         list_for_each_entry(iptr, &sb->s_inodes, i_sb_list) {
2169                 obj = yaffs_inode_to_obj(iptr);
2170                 if (obj) {
2171                         T(YAFFS_TRACE_OS, (TSTR("flushing obj %d\n"),
2172                                            obj->obj_id));
2173                         yaffs_flush_file(obj, 1, 0);
2174                 }
2175         }
2176 }
2177
2178 static void yaffs_flush_super(struct super_block *sb, int do_checkpoint)
2179 {
2180         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2181         if (!dev)
2182                 return;
2183
2184         yaffs_flush_inodes(sb);
2185         yaffs_update_dirty_dirs(dev);
2186         yaffs_flush_whole_cache(dev);
2187         if (do_checkpoint)
2188                 yaffs_checkpoint_save(dev);
2189 }
2190
2191 static unsigned yaffs_bg_gc_urgency(struct yaffs_dev *dev)
2192 {
2193         unsigned erased_chunks =
2194             dev->n_erased_blocks * dev->param.chunks_per_block;
2195         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2196         unsigned scattered = 0; /* Free chunks not in an erased block */
2197
2198         if (erased_chunks < dev->n_free_chunks)
2199                 scattered = (dev->n_free_chunks - erased_chunks);
2200
2201         if (!context->bg_running)
2202                 return 0;
2203         else if (scattered < (dev->param.chunks_per_block * 2))
2204                 return 0;
2205         else if (erased_chunks > dev->n_free_chunks / 2)
2206                 return 0;
2207         else if (erased_chunks > dev->n_free_chunks / 4)
2208                 return 1;
2209         else
2210                 return 2;
2211 }
2212
2213 static int yaffs_do_sync_fs(struct super_block *sb, int request_checkpoint)
2214 {
2215
2216         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2217         unsigned int oneshot_checkpoint = (yaffs_auto_checkpoint & 4);
2218         unsigned gc_urgent = yaffs_bg_gc_urgency(dev);
2219         int do_checkpoint;
2220
2221         T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
2222           (TSTR("yaffs_do_sync_fs: gc-urgency %d %s %s%s\n"),
2223            gc_urgent,
2224            sb->s_dirt ? "dirty" : "clean",
2225            request_checkpoint ? "checkpoint requested" : "no checkpoint",
2226            oneshot_checkpoint ? " one-shot" : ""));
2227
2228         yaffs_gross_lock(dev);
2229         do_checkpoint = ((request_checkpoint && !gc_urgent) ||
2230                          oneshot_checkpoint) && !dev->is_checkpointed;
2231
2232         if (sb->s_dirt || do_checkpoint) {
2233                 yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint);
2234                 sb->s_dirt = 0;
2235                 if (oneshot_checkpoint)
2236                         yaffs_auto_checkpoint &= ~4;
2237         }
2238         yaffs_gross_unlock(dev);
2239
2240         return 0;
2241 }
2242
2243 /*
2244  * yaffs background thread functions .
2245  * yaffs_bg_thread_fn() the thread function
2246  * yaffs_bg_start() launches the background thread.
2247  * yaffs_bg_stop() cleans up the background thread.
2248  *
2249  * NB: 
2250  * The thread should only run after the yaffs is initialised
2251  * The thread should be stopped before yaffs is unmounted.
2252  * The thread should not do any writing while the fs is in read only.
2253  */
2254
2255 #ifdef YAFFS_COMPILE_BACKGROUND
2256
2257 void yaffs_background_waker(unsigned long data)
2258 {
2259         wake_up_process((struct task_struct *)data);
2260 }
2261
2262 static int yaffs_bg_thread_fn(void *data)
2263 {
2264         struct yaffs_dev *dev = (struct yaffs_dev *)data;
2265         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2266         unsigned long now = jiffies;
2267         unsigned long next_dir_update = now;
2268         unsigned long next_gc = now;
2269         unsigned long expires;
2270         unsigned int urgency;
2271
2272         int gc_result;
2273         struct timer_list timer;
2274
2275         T(YAFFS_TRACE_BACKGROUND,
2276           (TSTR("yaffs_background starting for dev %p\n"), (void *)dev));
2277
2278 #ifdef YAFFS_COMPILE_FREEZER
2279         set_freezable();
2280 #endif
2281         while (context->bg_running) {
2282                 T(YAFFS_TRACE_BACKGROUND, (TSTR("yaffs_background\n")));
2283
2284                 if (kthread_should_stop())
2285                         break;
2286
2287 #ifdef YAFFS_COMPILE_FREEZER
2288                 if (try_to_freeze())
2289                         continue;
2290 #endif
2291                 yaffs_gross_lock(dev);
2292
2293                 now = jiffies;
2294
2295                 if (time_after(now, next_dir_update) && yaffs_bg_enable) {
2296                         yaffs_update_dirty_dirs(dev);
2297                         next_dir_update = now + HZ;
2298                 }
2299
2300                 if (time_after(now, next_gc) && yaffs_bg_enable) {
2301                         if (!dev->is_checkpointed) {
2302                                 urgency = yaffs_bg_gc_urgency(dev);
2303                                 gc_result = yaffs_bg_gc(dev, urgency);
2304                                 if (urgency > 1)
2305                                         next_gc = now + HZ / 20 + 1;
2306                                 else if (urgency > 0)
2307                                         next_gc = now + HZ / 10 + 1;
2308                                 else
2309                                         next_gc = now + HZ * 2;
2310                         } else  {
2311                                 /*
2312                                  * gc not running so set to next_dir_update
2313                                  * to cut down on wake ups
2314                                  */
2315                                 next_gc = next_dir_update;
2316                         }
2317                 }
2318                 yaffs_gross_unlock(dev);
2319 #if 1
2320                 expires = next_dir_update;
2321                 if (time_before(next_gc, expires))
2322                         expires = next_gc;
2323                 if (time_before(expires, now))
2324                         expires = now + HZ;
2325
2326                 Y_INIT_TIMER(&timer);
2327                 timer.expires = expires + 1;
2328                 timer.data = (unsigned long)current;
2329                 timer.function = yaffs_background_waker;
2330
2331                 set_current_state(TASK_INTERRUPTIBLE);
2332                 add_timer(&timer);
2333                 schedule();
2334                 del_timer_sync(&timer);
2335 #else
2336                 msleep(10);
2337 #endif
2338         }
2339
2340         return 0;
2341 }
2342
2343 static int yaffs_bg_start(struct yaffs_dev *dev)
2344 {
2345         int retval = 0;
2346         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2347
2348         if (dev->read_only)
2349                 return -1;
2350
2351         context->bg_running = 1;
2352
2353         context->bg_thread = kthread_run(yaffs_bg_thread_fn,
2354                                          (void *)dev, "yaffs-bg-%d",
2355                                          context->mount_id);
2356
2357         if (IS_ERR(context->bg_thread)) {
2358                 retval = PTR_ERR(context->bg_thread);
2359                 context->bg_thread = NULL;
2360                 context->bg_running = 0;
2361         }
2362         return retval;
2363 }
2364
2365 static void yaffs_bg_stop(struct yaffs_dev *dev)
2366 {
2367         struct yaffs_linux_context *ctxt = yaffs_dev_to_lc(dev);
2368
2369         ctxt->bg_running = 0;
2370
2371         if (ctxt->bg_thread) {
2372                 kthread_stop(ctxt->bg_thread);
2373                 ctxt->bg_thread = NULL;
2374         }
2375 }
2376 #else
2377 static int yaffs_bg_thread_fn(void *data)
2378 {
2379         return 0;
2380 }
2381
2382 static int yaffs_bg_start(struct yaffs_dev *dev)
2383 {
2384         return 0;
2385 }
2386
2387 static void yaffs_bg_stop(struct yaffs_dev *dev)
2388 {
2389 }
2390 #endif
2391
2392 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2393 static void yaffs_write_super(struct super_block *sb)
2394 #else
2395 static int yaffs_write_super(struct super_block *sb)
2396 #endif
2397 {
2398         unsigned request_checkpoint = (yaffs_auto_checkpoint >= 2);
2399
2400         T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
2401           (TSTR("yaffs_write_super%s\n"),
2402            request_checkpoint ? " checkpt" : ""));
2403
2404         yaffs_do_sync_fs(sb, request_checkpoint);
2405
2406 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
2407         return 0;
2408 #endif
2409 }
2410
2411 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2412 static int yaffs_sync_fs(struct super_block *sb, int wait)
2413 #else
2414 static int yaffs_sync_fs(struct super_block *sb)
2415 #endif
2416 {
2417         unsigned request_checkpoint = (yaffs_auto_checkpoint >= 1);
2418
2419         T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
2420           (TSTR("yaffs_sync_fs%s\n"), request_checkpoint ? " checkpt" : ""));
2421
2422         yaffs_do_sync_fs(sb, request_checkpoint);
2423
2424         return 0;
2425 }
2426
2427 #ifdef YAFFS_USE_OWN_IGET
2428
2429 static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
2430 {
2431         struct inode *inode;
2432         struct yaffs_obj *obj;
2433         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2434
2435         T(YAFFS_TRACE_OS, (TSTR("yaffs_iget for %lu\n"), ino));
2436
2437         inode = iget_locked(sb, ino);
2438         if (!inode)
2439                 return ERR_PTR(-ENOMEM);
2440         if (!(inode->i_state & I_NEW))
2441                 return inode;
2442
2443         /* NB This is called as a side effect of other functions, but
2444          * we had to release the lock to prevent deadlocks, so
2445          * need to lock again.
2446          */
2447
2448         yaffs_gross_lock(dev);
2449
2450         obj = yaffs_find_by_number(dev, inode->i_ino);
2451
2452         yaffs_fill_inode_from_obj(inode, obj);
2453
2454         yaffs_gross_unlock(dev);
2455
2456         unlock_new_inode(inode);
2457         return inode;
2458 }
2459
2460 #else
2461
2462 static void yaffs_read_inode(struct inode *inode)
2463 {
2464         /* NB This is called as a side effect of other functions, but
2465          * we had to release the lock to prevent deadlocks, so
2466          * need to lock again.
2467          */
2468
2469         struct yaffs_obj *obj;
2470         struct yaffs_dev *dev = yaffs_super_to_dev(inode->i_sb);
2471
2472         T(YAFFS_TRACE_OS,
2473           (TSTR("yaffs_read_inode for %d\n"), (int)inode->i_ino));
2474
2475         if (current != yaffs_dev_to_lc(dev)->readdir_process)
2476                 yaffs_gross_lock(dev);
2477
2478         obj = yaffs_find_by_number(dev, inode->i_ino);
2479
2480         yaffs_fill_inode_from_obj(inode, obj);
2481
2482         if (current != yaffs_dev_to_lc(dev)->readdir_process)
2483                 yaffs_gross_unlock(dev);
2484 }
2485
2486 #endif
2487
2488 static LIST_HEAD(yaffs_context_list);
2489 struct mutex yaffs_context_lock;
2490
2491 static void yaffs_put_super(struct super_block *sb)
2492 {
2493         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2494
2495         T(YAFFS_TRACE_OS, (TSTR("yaffs_put_super\n")));
2496
2497         T(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
2498           (TSTR("Shutting down yaffs background thread\n")));
2499         yaffs_bg_stop(dev);
2500         T(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
2501           (TSTR("yaffs background thread shut down\n")));
2502
2503         yaffs_gross_lock(dev);
2504
2505         yaffs_flush_super(sb, 1);
2506
2507         if (yaffs_dev_to_lc(dev)->put_super_fn)
2508                 yaffs_dev_to_lc(dev)->put_super_fn(sb);
2509
2510         yaffs_deinitialise(dev);
2511
2512         yaffs_gross_unlock(dev);
2513
2514         mutex_lock(&yaffs_context_lock);
2515         list_del_init(&(yaffs_dev_to_lc(dev)->context_list));
2516         mutex_unlock(&yaffs_context_lock);
2517
2518         if (yaffs_dev_to_lc(dev)->spare_buffer) {
2519                 YFREE(yaffs_dev_to_lc(dev)->spare_buffer);
2520                 yaffs_dev_to_lc(dev)->spare_buffer = NULL;
2521         }
2522
2523         kfree(dev);
2524 }
2525
2526 static void yaffs_mtd_put_super(struct super_block *sb)
2527 {
2528         struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb));
2529
2530         if (mtd->sync)
2531                 mtd->sync(mtd);
2532
2533         put_mtd_device(mtd);
2534 }
2535
2536 static void yaffs_touch_super(struct yaffs_dev *dev)
2537 {
2538         struct super_block *sb = yaffs_dev_to_lc(dev)->super;
2539
2540         T(YAFFS_TRACE_OS, (TSTR("yaffs_touch_super() sb = %p\n"), sb));
2541         if (sb)
2542                 sb->s_dirt = 1;
2543 }
2544
2545 struct yaffs_options {
2546         int inband_tags;
2547         int skip_checkpoint_read;
2548         int skip_checkpoint_write;
2549         int no_cache;
2550         int tags_ecc_on;
2551         int tags_ecc_overridden;
2552         int lazy_loading_enabled;
2553         int lazy_loading_overridden;
2554         int empty_lost_and_found;
2555         int empty_lost_and_found_overridden;
2556 };
2557
2558 #define MAX_OPT_LEN 30
2559 static int yaffs_parse_options(struct yaffs_options *options,
2560                                const char *options_str)
2561 {
2562         char cur_opt[MAX_OPT_LEN + 1];
2563         int p;
2564         int error = 0;
2565
2566         /* Parse through the options which is a comma seperated list */
2567
2568         while (options_str && *options_str && !error) {
2569                 memset(cur_opt, 0, MAX_OPT_LEN + 1);
2570                 p = 0;
2571
2572                 while (*options_str == ',')
2573                         options_str++;
2574
2575                 while (*options_str && *options_str != ',') {
2576                         if (p < MAX_OPT_LEN) {
2577                                 cur_opt[p] = *options_str;
2578                                 p++;
2579                         }
2580                         options_str++;
2581                 }
2582
2583                 if (!strcmp(cur_opt, "inband-tags")) {
2584                         options->inband_tags = 1;
2585                 } else if (!strcmp(cur_opt, "tags-ecc-off")) {
2586                         options->tags_ecc_on = 0;
2587                         options->tags_ecc_overridden = 1;
2588                 } else if (!strcmp(cur_opt, "tags-ecc-on")) {
2589                         options->tags_ecc_on = 1;
2590                         options->tags_ecc_overridden = 1;
2591                 } else if (!strcmp(cur_opt, "lazy-loading-off")) {
2592                         options->lazy_loading_enabled = 0;
2593                         options->lazy_loading_overridden = 1;
2594                 } else if (!strcmp(cur_opt, "lazy-loading-on")) {
2595                         options->lazy_loading_enabled = 1;
2596                         options->lazy_loading_overridden = 1;
2597                 } else if (!strcmp(cur_opt, "empty-lost-and-found-off")) {
2598                         options->empty_lost_and_found = 0;
2599                         options->empty_lost_and_found_overridden = 1;
2600                 } else if (!strcmp(cur_opt, "empty-lost-and-found-on")) {
2601                         options->empty_lost_and_found = 1;
2602                         options->empty_lost_and_found_overridden = 1;
2603                 } else if (!strcmp(cur_opt, "no-cache")) {
2604                         options->no_cache = 1;
2605                 } else if (!strcmp(cur_opt, "no-checkpoint-read")) {
2606                         options->skip_checkpoint_read = 1;
2607                 } else if (!strcmp(cur_opt, "no-checkpoint-write")) {
2608                         options->skip_checkpoint_write = 1;
2609                 } else if (!strcmp(cur_opt, "no-checkpoint")) {
2610                         options->skip_checkpoint_read = 1;
2611                         options->skip_checkpoint_write = 1;
2612                 } else {
2613                         printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
2614                                cur_opt);
2615                         error = 1;
2616                 }
2617         }
2618
2619         return error;
2620 }
2621
2622 static struct super_block *yaffs_internal_read_super(int yaffs_version,
2623                                                      struct super_block *sb,
2624                                                      void *data, int silent)
2625 {
2626         int n_blocks;
2627         struct inode *inode = NULL;
2628         struct dentry *root;
2629         struct yaffs_dev *dev = 0;
2630         char devname_buf[BDEVNAME_SIZE + 1];
2631         struct mtd_info *mtd;
2632         int err;
2633         char *data_str = (char *)data;
2634         struct yaffs_linux_context *context = NULL;
2635         struct yaffs_param *param;
2636
2637         int read_only = 0;
2638
2639         struct yaffs_options options;
2640
2641         unsigned mount_id;
2642         int found;
2643         struct yaffs_linux_context *context_iterator;
2644         struct list_head *l;
2645
2646         sb->s_magic = YAFFS_MAGIC;
2647         sb->s_op = &yaffs_super_ops;
2648         sb->s_flags |= MS_NOATIME;
2649
2650         read_only = ((sb->s_flags & MS_RDONLY) != 0);
2651
2652 #ifdef YAFFS_COMPILE_EXPORTFS
2653         sb->s_export_op = &yaffs_export_ops;
2654 #endif
2655
2656         if (!sb)
2657                 printk(KERN_INFO "yaffs: sb is NULL\n");
2658         else if (!sb->s_dev)
2659                 printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
2660         else if (!yaffs_devname(sb, devname_buf))
2661                 printk(KERN_INFO "yaffs: devname is NULL\n");
2662         else
2663                 printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
2664                        sb->s_dev,
2665                        yaffs_devname(sb, devname_buf), read_only ? "ro" : "rw");
2666
2667         if (!data_str)
2668                 data_str = "";
2669
2670         printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
2671
2672         memset(&options, 0, sizeof(options));
2673
2674         if (yaffs_parse_options(&options, data_str)) {
2675                 /* Option parsing failed */
2676                 return NULL;
2677         }
2678
2679         sb->s_blocksize = PAGE_CACHE_SIZE;
2680         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
2681
2682         T(YAFFS_TRACE_OS,
2683           (TSTR("yaffs_read_super: Using yaffs%d\n"), yaffs_version));
2684         T(YAFFS_TRACE_OS,
2685           (TSTR("yaffs_read_super: block size %d\n"), (int)(sb->s_blocksize)));
2686
2687         T(YAFFS_TRACE_ALWAYS,
2688           (TSTR("yaffs: Attempting MTD mount of %u.%u,\"%s\"\n"),
2689            MAJOR(sb->s_dev), MINOR(sb->s_dev), yaffs_devname(sb, devname_buf)));
2690
2691         /* Check it's an mtd device..... */
2692         if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR)
2693                 return NULL;    /* This isn't an mtd device */
2694
2695         /* Get the device */
2696         mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
2697         if (!mtd) {
2698                 T(YAFFS_TRACE_ALWAYS,
2699                   (TSTR("yaffs: MTD device #%u doesn't appear to exist\n"),
2700                    MINOR(sb->s_dev)));
2701                 return NULL;
2702         }
2703         /* Check it's NAND */
2704         if (mtd->type != MTD_NANDFLASH) {
2705                 T(YAFFS_TRACE_ALWAYS,
2706                   (TSTR("yaffs: MTD device is not NAND it's type %d\n"),
2707                    mtd->type));
2708                 return NULL;
2709         }
2710
2711         T(YAFFS_TRACE_OS, (TSTR(" erase %p\n"), mtd->erase));
2712         T(YAFFS_TRACE_OS, (TSTR(" read %p\n"), mtd->read));
2713         T(YAFFS_TRACE_OS, (TSTR(" write %p\n"), mtd->write));
2714         T(YAFFS_TRACE_OS, (TSTR(" readoob %p\n"), mtd->read_oob));
2715         T(YAFFS_TRACE_OS, (TSTR(" writeoob %p\n"), mtd->write_oob));
2716         T(YAFFS_TRACE_OS, (TSTR(" block_isbad %p\n"), mtd->block_isbad));
2717         T(YAFFS_TRACE_OS, (TSTR(" block_markbad %p\n"), mtd->block_markbad));
2718         T(YAFFS_TRACE_OS, (TSTR(" %s %d\n"), WRITE_SIZE_STR, WRITE_SIZE(mtd)));
2719         T(YAFFS_TRACE_OS, (TSTR(" oobsize %d\n"), mtd->oobsize));
2720         T(YAFFS_TRACE_OS, (TSTR(" erasesize %d\n"), mtd->erasesize));
2721 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
2722         T(YAFFS_TRACE_OS, (TSTR(" size %u\n"), mtd->size));
2723 #else
2724         T(YAFFS_TRACE_OS, (TSTR(" size %lld\n"), mtd->size));
2725 #endif
2726
2727 #ifdef CONFIG_YAFFS_AUTO_YAFFS2
2728
2729         if (yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) {
2730                 T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: auto selecting yaffs2\n")));
2731                 yaffs_version = 2;
2732         }
2733
2734         /* Added NCB 26/5/2006 for completeness */
2735         if (yaffs_version == 2 && !options.inband_tags
2736             && WRITE_SIZE(mtd) == 512) {
2737                 T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: auto selecting yaffs1\n")));
2738                 yaffs_version = 1;
2739         }
2740 #endif
2741
2742         if (yaffs_version == 2) {
2743                 /* Check for version 2 style functions */
2744                 if (!mtd->erase ||
2745                     !mtd->block_isbad ||
2746                     !mtd->block_markbad || !mtd->read || !mtd->write ||
2747 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2748                     !mtd->read_oob || !mtd->write_oob) {
2749 #else
2750                     !mtd->write_ecc ||
2751                     !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
2752 #endif
2753                         T(YAFFS_TRACE_ALWAYS,
2754                           (TSTR("yaffs: MTD device does not support required "
2755                                 "functions\n")));
2756                         return NULL;
2757                 }
2758
2759                 if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
2760                      mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
2761                     !options.inband_tags) {
2762                         T(YAFFS_TRACE_ALWAYS,
2763                           (TSTR("yaffs: MTD device does not have the "
2764                                 "right page sizes\n")));
2765                         return NULL;
2766                 }
2767         } else {
2768                 /* Check for V1 style functions */
2769                 if (!mtd->erase || !mtd->read || !mtd->write ||
2770 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2771                     !mtd->read_oob || !mtd->write_oob) {
2772 #else
2773                     !mtd->write_ecc ||
2774                     !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
2775 #endif
2776                         T(YAFFS_TRACE_ALWAYS,
2777                           (TSTR("yaffs: MTD device does not support required "
2778                                 "functions\n")));
2779                         return NULL;
2780                 }
2781
2782                 if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK ||
2783                     mtd->oobsize != YAFFS_BYTES_PER_SPARE) {
2784                         T(YAFFS_TRACE_ALWAYS,
2785                           (TSTR("yaffs: MTD device does not support have the "
2786                                 "right page sizes\n")));
2787                         return NULL;
2788                 }
2789         }
2790
2791         /* OK, so if we got here, we have an MTD that's NAND and looks
2792          * like it has the right capabilities
2793          * Set the struct yaffs_dev up for mtd
2794          */
2795
2796         if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
2797                 read_only = 1;
2798                 printk(KERN_INFO
2799                        "yaffs: mtd is read only, setting superblock read only");
2800                 sb->s_flags |= MS_RDONLY;
2801         }
2802
2803         dev = kmalloc(sizeof(struct yaffs_dev), GFP_KERNEL);
2804         context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
2805
2806         if (!dev || !context) {
2807                 if (dev)
2808                         kfree(dev);
2809                 if (context)
2810                         kfree(context);
2811                 dev = NULL;
2812                 context = NULL;
2813         }
2814
2815         if (!dev) {
2816                 /* Deep shit could not allocate device structure */
2817                 T(YAFFS_TRACE_ALWAYS,
2818                   (TSTR("yaffs_read_super: Failed trying to allocate "
2819                         "struct yaffs_dev. \n")));
2820                 return NULL;
2821         }
2822         memset(dev, 0, sizeof(struct yaffs_dev));
2823         param = &(dev->param);
2824
2825         memset(context, 0, sizeof(struct yaffs_linux_context));
2826         dev->os_context = context;
2827         INIT_LIST_HEAD(&(context->context_list));
2828         context->dev = dev;
2829         context->super = sb;
2830
2831         dev->read_only = read_only;
2832
2833 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2834         sb->s_fs_info = dev;
2835 #else
2836         sb->u.generic_sbp = dev;
2837 #endif
2838
2839         dev->driver_context = mtd;
2840         param->name = mtd->name;
2841
2842         /* Set up the memory size parameters.... */
2843
2844         n_blocks =
2845             YCALCBLOCKS(mtd->size,
2846                         (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));
2847
2848         param->start_block = 0;
2849         param->end_block = n_blocks - 1;
2850         param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
2851         param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
2852         param->n_reserved_blocks = 5;
2853         param->n_caches = (options.no_cache) ? 0 : 10;
2854         param->inband_tags = options.inband_tags;
2855
2856 #ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
2857         param->disable_lazy_load = 1;
2858 #endif
2859 #ifdef CONFIG_YAFFS_XATTR
2860         param->enable_xattr = 1;
2861 #endif
2862         if (options.lazy_loading_overridden)
2863                 param->disable_lazy_load = !options.lazy_loading_enabled;
2864
2865 #ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
2866         param->no_tags_ecc = 1;
2867 #endif
2868
2869 #ifdef CONFIG_YAFFS_DISABLE_BACKGROUND
2870 #else
2871         param->defered_dir_update = 1;
2872 #endif
2873
2874         if (options.tags_ecc_overridden)
2875                 param->no_tags_ecc = !options.tags_ecc_on;
2876
2877 #ifdef CONFIG_YAFFS_EMPTY_LOST_AND_FOUND
2878         param->empty_lost_n_found = 1;
2879 #endif
2880
2881 #ifdef CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING
2882         param->refresh_period = 0;
2883 #else
2884         param->refresh_period = 500;
2885 #endif
2886
2887 #ifdef CONFIG_YAFFS__ALWAYS_CHECK_CHUNK_ERASED
2888         param->always_check_erased = 1;
2889 #endif
2890
2891         if (options.empty_lost_and_found_overridden)
2892                 param->empty_lost_n_found = options.empty_lost_and_found;
2893
2894         /* ... and the functions. */
2895         if (yaffs_version == 2) {
2896                 param->write_chunk_tags_fn = nandmtd2_write_chunk_tags;
2897                 param->read_chunk_tags_fn = nandmtd2_read_chunk_tags;
2898                 param->bad_block_fn = nandmtd2_mark_block_bad;
2899                 param->query_block_fn = nandmtd2_query_block;
2900                 yaffs_dev_to_lc(dev)->spare_buffer = YMALLOC(mtd->oobsize);
2901                 param->is_yaffs2 = 1;
2902 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2903                 param->total_bytes_per_chunk = mtd->writesize;
2904                 param->chunks_per_block = mtd->erasesize / mtd->writesize;
2905 #else
2906                 param->total_bytes_per_chunk = mtd->oobblock;
2907                 param->chunks_per_block = mtd->erasesize / mtd->oobblock;
2908 #endif
2909                 n_blocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
2910
2911                 param->start_block = 0;
2912                 param->end_block = n_blocks - 1;
2913         } else {
2914 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2915                 /* use the MTD interface in yaffs_mtdif1.c */
2916                 param->write_chunk_tags_fn = nandmtd1_write_chunk_tags;
2917                 param->read_chunk_tags_fn = nandmtd1_read_chunk_tags;
2918                 param->bad_block_fn = nandmtd1_mark_block_bad;
2919                 param->query_block_fn = nandmtd1_query_block;
2920 #else
2921                 param->write_chunk_fn = nandmtd_write_chunk;
2922                 param->read_chunk_fn = nandmtd_read_chunk;
2923 #endif
2924                 param->is_yaffs2 = 0;
2925         }
2926         /* ... and common functions */
2927         param->erase_fn = nandmtd_erase_block;
2928         param->initialise_flash_fn = nandmtd_initialise;
2929
2930         yaffs_dev_to_lc(dev)->put_super_fn = yaffs_mtd_put_super;
2931
2932         param->sb_dirty_fn = yaffs_touch_super;
2933         param->gc_control = yaffs_gc_control_callback;
2934
2935         yaffs_dev_to_lc(dev)->super = sb;
2936
2937 #ifndef CONFIG_YAFFS_DOES_ECC
2938         param->use_nand_ecc = 1;
2939 #endif
2940
2941 #ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES
2942         param->wide_tnodes_disabled = 1;
2943 #endif
2944
2945         param->skip_checkpt_rd = options.skip_checkpoint_read;
2946         param->skip_checkpt_wr = options.skip_checkpoint_write;
2947
2948         mutex_lock(&yaffs_context_lock);
2949         /* Get a mount id */
2950         found = 0;
2951         for (mount_id = 0; !found; mount_id++) {
2952                 found = 1;
2953                 list_for_each(l, &yaffs_context_list) {
2954                         context_iterator =
2955                             list_entry(l, struct yaffs_linux_context,
2956                                        context_list);
2957                         if (context_iterator->mount_id == mount_id)
2958                                 found = 0;
2959                 }
2960         }
2961         context->mount_id = mount_id;
2962
2963         list_add_tail(&(yaffs_dev_to_lc(dev)->context_list),
2964                       &yaffs_context_list);
2965         mutex_unlock(&yaffs_context_lock);
2966
2967         /* Directory search handling... */
2968         INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->search_contexts));
2969         param->remove_obj_fn = yaffs_remove_obj_callback;
2970
2971         mutex_init(&(yaffs_dev_to_lc(dev)->gross_lock));
2972
2973         yaffs_gross_lock(dev);
2974
2975         err = yaffs_guts_initialise(dev);
2976
2977         T(YAFFS_TRACE_OS,
2978           (TSTR("yaffs_read_super: guts initialised %s\n"),
2979            (err == YAFFS_OK) ? "OK" : "FAILED"));
2980
2981         if (err == YAFFS_OK)
2982                 yaffs_bg_start(dev);
2983
2984         if (!context->bg_thread)
2985                 param->defered_dir_update = 0;
2986
2987         /* Release lock before yaffs_get_inode() */
2988         yaffs_gross_unlock(dev);
2989
2990         /* Create root inode */
2991         if (err == YAFFS_OK)
2992                 inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_root(dev));
2993
2994         if (!inode)
2995                 return NULL;
2996
2997         inode->i_op = &yaffs_dir_inode_operations;
2998         inode->i_fop = &yaffs_dir_operations;
2999
3000         T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: got root inode\n")));
3001
3002         root = d_alloc_root(inode);
3003
3004         T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: d_alloc_root done\n")));
3005
3006         if (!root) {
3007                 iput(inode);
3008                 return NULL;
3009         }
3010         sb->s_root = root;
3011         sb->s_dirt = !dev->is_checkpointed;
3012         T(YAFFS_TRACE_ALWAYS,
3013           (TSTR("yaffs_read_super: is_checkpointed %d\n"),
3014            dev->is_checkpointed));
3015
3016         T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: done\n")));
3017         return sb;
3018 }
3019
3020 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3021 static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
3022                                          int silent)
3023 {
3024         return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
3025 }
3026
3027 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3028 static int yaffs_read_super(struct file_system_type *fs,
3029                             int flags, const char *dev_name,
3030                             void *data, struct vfsmount *mnt)
3031 {
3032
3033         return get_sb_bdev(fs, flags, dev_name, data,
3034                            yaffs_internal_read_super_mtd, mnt);
3035 }
3036 #else
3037 static struct super_block *yaffs_read_super(struct file_system_type *fs,
3038                                             int flags, const char *dev_name,
3039                                             void *data)
3040 {
3041
3042         return get_sb_bdev(fs, flags, dev_name, data,
3043                            yaffs_internal_read_super_mtd);
3044 }
3045 #endif
3046
3047 static struct file_system_type yaffs_fs_type = {
3048         .owner = THIS_MODULE,
3049         .name = "yaffs",
3050         .get_sb = yaffs_read_super,
3051         .kill_sb = kill_block_super,
3052         .fs_flags = FS_REQUIRES_DEV,
3053 };
3054 #else
3055 static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
3056                                             int silent)
3057 {
3058         return yaffs_internal_read_super(1, sb, data, silent);
3059 }
3060
3061 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
3062                       FS_REQUIRES_DEV);
3063 #endif
3064
3065 #ifdef CONFIG_YAFFS_YAFFS2
3066
3067 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3068 static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
3069                                           int silent)
3070 {
3071         return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
3072 }
3073
3074 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3075 static int yaffs2_read_super(struct file_system_type *fs,
3076                              int flags, const char *dev_name, void *data,
3077                              struct vfsmount *mnt)
3078 {
3079         return get_sb_bdev(fs, flags, dev_name, data,
3080                            yaffs2_internal_read_super_mtd, mnt);
3081 }
3082 #else
3083 static struct super_block *yaffs2_read_super(struct file_system_type *fs,
3084                                              int flags, const char *dev_name,
3085                                              void *data)
3086 {
3087
3088         return get_sb_bdev(fs, flags, dev_name, data,
3089                            yaffs2_internal_read_super_mtd);
3090 }
3091 #endif
3092
3093 static struct file_system_type yaffs2_fs_type = {
3094         .owner = THIS_MODULE,
3095         .name = "yaffs2",
3096         .get_sb = yaffs2_read_super,
3097         .kill_sb = kill_block_super,
3098         .fs_flags = FS_REQUIRES_DEV,
3099 };
3100 #else
3101 static struct super_block *yaffs2_read_super(struct super_block *sb,
3102                                              void *data, int silent)
3103 {
3104         return yaffs_internal_read_super(2, sb, data, silent);
3105 }
3106
3107 static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
3108                       FS_REQUIRES_DEV);
3109 #endif
3110
3111 #endif /* CONFIG_YAFFS_YAFFS2 */
3112
3113 static struct proc_dir_entry *my_proc_entry;
3114 static struct proc_dir_entry *debug_proc_entry;
3115
3116 static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
3117 {
3118         buf +=
3119             sprintf(buf, "start_block.......... %d\n", dev->param.start_block);
3120         buf += sprintf(buf, "end_block............ %d\n", dev->param.end_block);
3121         buf +=
3122             sprintf(buf, "total_bytes_per_chunk %d\n",
3123                     dev->param.total_bytes_per_chunk);
3124         buf +=
3125             sprintf(buf, "use_nand_ecc......... %d\n", dev->param.use_nand_ecc);
3126         buf +=
3127             sprintf(buf, "no_tags_ecc.......... %d\n", dev->param.no_tags_ecc);
3128         buf += sprintf(buf, "is_yaffs2............ %d\n", dev->param.is_yaffs2);
3129         buf +=
3130             sprintf(buf, "inband_tags.......... %d\n", dev->param.inband_tags);
3131         buf +=
3132             sprintf(buf, "empty_lost_n_found... %d\n",
3133                     dev->param.empty_lost_n_found);
3134         buf +=
3135             sprintf(buf, "disable_lazy_load.... %d\n",
3136                     dev->param.disable_lazy_load);
3137         buf +=
3138             sprintf(buf, "refresh_period....... %d\n",
3139                     dev->param.refresh_period);
3140         buf += sprintf(buf, "n_caches............. %d\n", dev->param.n_caches);
3141         buf +=
3142             sprintf(buf, "n_reserved_blocks.... %d\n",
3143                     dev->param.n_reserved_blocks);
3144         buf +=
3145             sprintf(buf, "always_check_erased.. %d\n",
3146                     dev->param.always_check_erased);
3147
3148         buf += sprintf(buf, "\n");
3149
3150         return buf;
3151 }
3152
3153 static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
3154 {
3155         buf +=
3156             sprintf(buf, "data_bytes_per_chunk. %d\n",
3157                     dev->data_bytes_per_chunk);
3158         buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
3159         buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
3160         buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
3161         buf +=
3162             sprintf(buf, "blocks_in_checkpt.... %d\n", dev->blocks_in_checkpt);
3163         buf += sprintf(buf, "\n");
3164         buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
3165         buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
3166         buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
3167         buf += sprintf(buf, "\n");
3168         buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
3169         buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
3170         buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
3171         buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
3172         buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
3173         buf +=
3174             sprintf(buf, "passive_gc_count..... %u\n", dev->passive_gc_count);
3175         buf +=
3176             sprintf(buf, "oldest_dirty_gc_count %u\n",
3177                     dev->oldest_dirty_gc_count);
3178         buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
3179         buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
3180         buf +=
3181             sprintf(buf, "n_retired_writes..... %u\n", dev->n_retired_writes);
3182         buf +=
3183             sprintf(buf, "n_retired_blocks..... %u\n", dev->n_retired_blocks);
3184         buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
3185         buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
3186         buf +=
3187             sprintf(buf, "n_tags_ecc_fixed..... %u\n", dev->n_tags_ecc_fixed);
3188         buf +=
3189             sprintf(buf, "n_tags_ecc_unfixed... %u\n", dev->n_tags_ecc_unfixed);
3190         buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
3191         buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
3192         buf +=
3193             sprintf(buf, "n_unlinked_files..... %u\n", dev->n_unlinked_files);
3194         buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
3195         buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
3196
3197         return buf;
3198 }
3199
3200 static int yaffs_proc_read(char *page,
3201                            char **start,
3202                            off_t offset, int count, int *eof, void *data)
3203 {
3204         struct list_head *item;
3205         char *buf = page;
3206         int step = offset;
3207         int n = 0;
3208
3209         /* Get proc_file_read() to step 'offset' by one on each sucessive call.
3210          * We use 'offset' (*ppos) to indicate where we are in dev_list.
3211          * This also assumes the user has posted a read buffer large
3212          * enough to hold the complete output; but that's life in /proc.
3213          */
3214
3215         *(int *)start = 1;
3216
3217         /* Print header first */
3218         if (step == 0)
3219                 buf +=
3220                     sprintf(buf,
3221                             "Multi-version YAFFS built:" __DATE__ " " __TIME__
3222                             "\n");
3223         else if (step == 1)
3224                 buf += sprintf(buf, "\n");
3225         else {
3226                 step -= 2;
3227
3228                 mutex_lock(&yaffs_context_lock);
3229
3230                 /* Locate and print the Nth entry.  Order N-squared but N is small. */
3231                 list_for_each(item, &yaffs_context_list) {
3232                         struct yaffs_linux_context *dc =
3233                             list_entry(item, struct yaffs_linux_context,
3234                                        context_list);
3235                         struct yaffs_dev *dev = dc->dev;
3236
3237                         if (n < (step & ~1)) {
3238                                 n += 2;
3239                                 continue;
3240                         }
3241                         if ((step & 1) == 0) {
3242                                 buf +=
3243                                     sprintf(buf, "\nDevice %d \"%s\"\n", n,
3244                                             dev->param.name);
3245                                 buf = yaffs_dump_dev_part0(buf, dev);
3246                         } else {
3247                                 buf = yaffs_dump_dev_part1(buf, dev);
3248                         }
3249
3250                         break;
3251                 }
3252                 mutex_unlock(&yaffs_context_lock);
3253         }
3254
3255         return buf - page < count ? buf - page : count;
3256 }
3257
3258 static int yaffs_stats_proc_read(char *page,
3259                                  char **start,
3260                                  off_t offset, int count, int *eof, void *data)
3261 {
3262         struct list_head *item;
3263         char *buf = page;
3264         int n = 0;
3265
3266         mutex_lock(&yaffs_context_lock);
3267
3268         /* Locate and print the Nth entry.  Order N-squared but N is small. */
3269         list_for_each(item, &yaffs_context_list) {
3270                 struct yaffs_linux_context *dc =
3271                     list_entry(item, struct yaffs_linux_context, context_list);
3272                 struct yaffs_dev *dev = dc->dev;
3273
3274                 int erased_chunks;
3275
3276                 erased_chunks =
3277                     dev->n_erased_blocks * dev->param.chunks_per_block;
3278
3279                 buf += sprintf(buf, "%d, %d, %d, %u, %u, %u, %u\n",
3280                                n, dev->n_free_chunks, erased_chunks,
3281                                dev->bg_gcs, dev->oldest_dirty_gc_count,
3282                                dev->n_obj, dev->n_tnodes);
3283         }
3284         mutex_unlock(&yaffs_context_lock);
3285
3286         return buf - page < count ? buf - page : count;
3287 }
3288
3289 /**
3290  * Set the verbosity of the warnings and error messages.
3291  *
3292  * Note that the names can only be a..z or _ with the current code.
3293  */
3294
3295 static struct {
3296         char *mask_name;
3297         unsigned mask_bitfield;
3298 } mask_flags[] = {
3299         {"allocate", YAFFS_TRACE_ALLOCATE},
3300         {"always", YAFFS_TRACE_ALWAYS},
3301         {"background", YAFFS_TRACE_BACKGROUND},
3302         {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
3303         {"buffers", YAFFS_TRACE_BUFFERS},
3304         {"bug", YAFFS_TRACE_BUG},
3305         {"checkpt", YAFFS_TRACE_CHECKPOINT},
3306         {"deletion", YAFFS_TRACE_DELETION},
3307         {"erase", YAFFS_TRACE_ERASE},
3308         {"error", YAFFS_TRACE_ERROR},
3309         {"gc_detail", YAFFS_TRACE_GC_DETAIL},
3310         {"gc", YAFFS_TRACE_GC},
3311         {"lock", YAFFS_TRACE_LOCK},
3312         {"mtd", YAFFS_TRACE_MTD},
3313         {"nandaccess", YAFFS_TRACE_NANDACCESS},
3314         {"os", YAFFS_TRACE_OS},
3315         {"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
3316         {"scan", YAFFS_TRACE_SCAN},
3317         {"mount", YAFFS_TRACE_MOUNT},
3318         {"tracing", YAFFS_TRACE_TRACING},
3319         {"sync", YAFFS_TRACE_SYNC},
3320         {"write", YAFFS_TRACE_WRITE},
3321         {"verify", YAFFS_TRACE_VERIFY},
3322         {"verify_nand", YAFFS_TRACE_VERIFY_NAND},
3323         {"verify_full", YAFFS_TRACE_VERIFY_FULL},
3324         {"verify_all", YAFFS_TRACE_VERIFY_ALL},
3325         {"all", 0xffffffff},
3326         {"none", 0},
3327         {NULL, 0},
3328 };
3329
3330 #define MAX_MASK_NAME_LENGTH 40
3331 static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
3332                                           unsigned long count, void *data)
3333 {
3334         unsigned rg = 0, mask_bitfield;
3335         char *end;
3336         char *mask_name;
3337         const char *x;
3338         char substring[MAX_MASK_NAME_LENGTH + 1];
3339         int i;
3340         int done = 0;
3341         int add, len = 0;
3342         int pos = 0;
3343
3344         rg = yaffs_trace_mask;
3345
3346         while (!done && (pos < count)) {
3347                 done = 1;
3348                 while ((pos < count) && isspace(buf[pos]))
3349                         pos++;
3350
3351                 switch (buf[pos]) {
3352                 case '+':
3353                 case '-':
3354                 case '=':
3355                         add = buf[pos];
3356                         pos++;
3357                         break;
3358
3359                 default:
3360                         add = ' ';
3361                         break;
3362                 }
3363                 mask_name = NULL;
3364
3365                 mask_bitfield = simple_strtoul(buf + pos, &end, 0);
3366
3367                 if (end > buf + pos) {
3368                         mask_name = "numeral";
3369                         len = end - (buf + pos);
3370                         pos += len;
3371                         done = 0;
3372                 } else {
3373                         for (x = buf + pos, i = 0;
3374                              (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
3375                              i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
3376                                 substring[i] = *x;
3377                         substring[i] = '\0';
3378
3379                         for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3380                                 if (strcmp(substring, mask_flags[i].mask_name)
3381                                     == 0) {
3382                                         mask_name = mask_flags[i].mask_name;
3383                                         mask_bitfield =
3384                                             mask_flags[i].mask_bitfield;
3385                                         done = 0;
3386                                         break;
3387                                 }
3388                         }
3389                 }
3390
3391                 if (mask_name != NULL) {
3392                         done = 0;
3393                         switch (add) {
3394                         case '-':
3395                                 rg &= ~mask_bitfield;
3396                                 break;
3397                         case '+':
3398                                 rg |= mask_bitfield;
3399                                 break;
3400                         case '=':
3401                                 rg = mask_bitfield;
3402                                 break;
3403                         default:
3404                                 rg |= mask_bitfield;
3405                                 break;
3406                         }
3407                 }
3408         }
3409
3410         yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS;
3411
3412         printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask);
3413
3414         if (rg & YAFFS_TRACE_ALWAYS) {
3415                 for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3416                         char flag;
3417                         flag = ((rg & mask_flags[i].mask_bitfield) ==
3418                                 mask_flags[i].mask_bitfield) ? '+' : '-';
3419                         printk(KERN_DEBUG "%c%s\n", flag,
3420                                mask_flags[i].mask_name);
3421                 }
3422         }
3423
3424         return count;
3425 }
3426
3427 static int yaffs_proc_write(struct file *file, const char *buf,
3428                             unsigned long count, void *data)
3429 {
3430         return yaffs_proc_write_trace_options(file, buf, count, data);
3431 }
3432
3433 /* Stuff to handle installation of file systems */
3434 struct file_system_to_install {
3435         struct file_system_type *fst;
3436         int installed;
3437 };
3438
3439 static struct file_system_to_install fs_to_install[] = {
3440         {&yaffs_fs_type, 0},
3441         {&yaffs2_fs_type, 0},
3442         {NULL, 0}
3443 };
3444
3445 static int __init init_yaffs_fs(void)
3446 {
3447         int error = 0;
3448         struct file_system_to_install *fsinst;
3449
3450         T(YAFFS_TRACE_ALWAYS,
3451           (TSTR("yaffs built " __DATE__ " " __TIME__ " Installing. \n")));
3452
3453 #ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
3454         T(YAFFS_TRACE_ALWAYS,
3455           (TSTR
3456            (" \n\n\n\nYAFFS-WARNING CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED selected.\n\n\n\n")));
3457 #endif
3458
3459         mutex_init(&yaffs_context_lock);
3460
3461         /* Install the proc_fs entries */
3462         my_proc_entry = create_proc_entry("yaffs",
3463                                           S_IRUGO | S_IFREG, YPROC_ROOT);
3464
3465         if (my_proc_entry) {
3466                 my_proc_entry->write_proc = yaffs_proc_write;
3467                 my_proc_entry->read_proc = yaffs_proc_read;
3468                 my_proc_entry->data = NULL;
3469         } else {
3470                 return -ENOMEM;
3471         }
3472
3473         debug_proc_entry = create_proc_entry("yaffs_stats",
3474                                              S_IRUGO | S_IFREG, YPROC_ROOT);
3475
3476         if (debug_proc_entry) {
3477                 debug_proc_entry->write_proc = NULL;
3478                 debug_proc_entry->read_proc = yaffs_stats_proc_read;
3479                 debug_proc_entry->data = NULL;
3480         } else {
3481                 return -ENOMEM;
3482         }
3483
3484         /* Now add the file system entries */
3485
3486         fsinst = fs_to_install;
3487
3488         while (fsinst->fst && !error) {
3489                 error = register_filesystem(fsinst->fst);
3490                 if (!error)
3491                         fsinst->installed = 1;
3492                 fsinst++;
3493         }
3494
3495         /* Any errors? uninstall  */
3496         if (error) {
3497                 fsinst = fs_to_install;
3498
3499                 while (fsinst->fst) {
3500                         if (fsinst->installed) {
3501                                 unregister_filesystem(fsinst->fst);
3502                                 fsinst->installed = 0;
3503                         }
3504                         fsinst++;
3505                 }
3506         }
3507
3508         return error;
3509 }
3510
3511 static void __exit exit_yaffs_fs(void)
3512 {
3513
3514         struct file_system_to_install *fsinst;
3515
3516         T(YAFFS_TRACE_ALWAYS,
3517           (TSTR("yaffs built " __DATE__ " " __TIME__ " removing. \n")));
3518
3519         remove_proc_entry("yaffs", YPROC_ROOT);
3520         remove_proc_entry("yaffs_stats", YPROC_ROOT);
3521
3522         fsinst = fs_to_install;
3523
3524         while (fsinst->fst) {
3525                 if (fsinst->installed) {
3526                         unregister_filesystem(fsinst->fst);
3527                         fsinst->installed = 0;
3528                 }
3529                 fsinst++;
3530         }
3531 }
3532
3533 module_init(init_yaffs_fs)
3534     module_exit(exit_yaffs_fs)
3535
3536     MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
3537 MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2010");
3538 MODULE_LICENSE("GPL");