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