Change enums to u32 for stored fields
[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         .read = do_sync_read,
780         .write = do_sync_write,
781         .aio_read = generic_file_aio_read,
782         .aio_write = generic_file_aio_write,
783         .mmap = generic_file_mmap,
784         .flush = yaffs_file_flush,
785         .fsync = yaffs_sync_object,
786         .splice_read = generic_file_splice_read,
787         .splice_write = generic_file_splice_write,
788         .llseek = generic_file_llseek,
789 };
790
791 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
792
793 static const struct file_operations yaffs_file_operations = {
794         .read = do_sync_read,
795         .write = do_sync_write,
796         .aio_read = generic_file_aio_read,
797         .aio_write = generic_file_aio_write,
798         .mmap = generic_file_mmap,
799         .flush = yaffs_file_flush,
800         .fsync = yaffs_sync_object,
801         .sendfile = generic_file_sendfile,
802 };
803
804 #else
805
806 static const struct file_operations yaffs_file_operations = {
807         .read = generic_file_read,
808         .write = generic_file_write,
809         .mmap = generic_file_mmap,
810         .flush = yaffs_file_flush,
811         .fsync = yaffs_sync_object,
812 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
813         .sendfile = generic_file_sendfile,
814 #endif
815 };
816 #endif
817
818
819
820
821 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
822 static void zero_user_segment(struct page *page, unsigned start, unsigned end)
823 {
824         void *kaddr = kmap_atomic(page, KM_USER0);
825         memset(kaddr + start, 0, end - start);
826         kunmap_atomic(kaddr, KM_USER0);
827         flush_dcache_page(page);
828 }
829 #endif
830
831
832 static int yaffs_vfs_setsize(struct inode *inode, loff_t newsize)
833 {
834 #ifdef YAFFS_USE_TRUNCATE_SETSIZE
835         truncate_setsize(inode, newsize);
836         return 0;
837 #else
838         truncate_inode_pages(&inode->i_data, newsize);
839         return 0;
840 #endif
841
842 }
843
844
845 static int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr)
846 {
847 #ifdef YAFFS_USE_SETATTR_COPY
848         setattr_copy(inode, attr);
849         return 0;
850 #else
851         return inode_setattr(inode, attr);
852 #endif
853
854 }
855
856 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
857 {
858         struct inode *inode = dentry->d_inode;
859         int error = 0;
860         struct yaffs_dev *dev;
861
862         yaffs_trace(YAFFS_TRACE_OS,
863                 "yaffs_setattr of object %d",
864                 yaffs_inode_to_obj(inode)->obj_id);
865 #if 0
866         /* Fail if a requested resize >= 2GB */
867         if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31))
868                 error = -EINVAL;
869 #endif
870
871         if (error == 0)
872                 error = inode_change_ok(inode, attr);
873         if (error == 0) {
874                 int result;
875                 if (!error) {
876                         error = yaffs_vfs_setattr(inode, attr);
877                         yaffs_trace(YAFFS_TRACE_OS, "inode_setattr called");
878                         if (attr->ia_valid & ATTR_SIZE) {
879                                 yaffs_vfs_setsize(inode, attr->ia_size);
880                                 inode->i_blocks = (inode->i_size + 511) >> 9;
881                         }
882                 }
883                 dev = yaffs_inode_to_obj(inode)->my_dev;
884                 if (attr->ia_valid & ATTR_SIZE) {
885                         yaffs_trace(YAFFS_TRACE_OS,
886                                 "resize to %d(%x)",
887                                 (int)(attr->ia_size),
888                                 (int)(attr->ia_size));
889                 }
890                 yaffs_gross_lock(dev);
891                 result = yaffs_set_attribs(yaffs_inode_to_obj(inode), attr);
892                 if (result == YAFFS_OK) {
893                         error = 0;
894                 } else {
895                         error = -EPERM;
896                 }
897                 yaffs_gross_unlock(dev);
898
899         }
900
901         yaffs_trace(YAFFS_TRACE_OS, "yaffs_setattr done returning %d", error);
902
903         return error;
904 }
905
906 static int yaffs_setxattr(struct dentry *dentry, const char *name,
907                    const void *value, size_t size, int flags)
908 {
909         struct inode *inode = dentry->d_inode;
910         int error = 0;
911         struct yaffs_dev *dev;
912         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
913
914         yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr of object %d", obj->obj_id);
915
916         if (error == 0) {
917                 int result;
918                 dev = obj->my_dev;
919                 yaffs_gross_lock(dev);
920                 result = yaffs_set_xattrib(obj, name, value, size, flags);
921                 if (result == YAFFS_OK)
922                         error = 0;
923                 else if (result < 0)
924                         error = result;
925                 yaffs_gross_unlock(dev);
926
927         }
928         yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr done returning %d", error);
929
930         return error;
931 }
932
933 static ssize_t yaffs_getxattr(struct dentry * dentry, const char *name,
934                         void *buff, size_t size)
935 {
936         struct inode *inode = dentry->d_inode;
937         int error = 0;
938         struct yaffs_dev *dev;
939         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
940
941         yaffs_trace(YAFFS_TRACE_OS,
942                 "yaffs_getxattr \"%s\" from object %d",
943                 name, obj->obj_id);
944
945         if (error == 0) {
946                 dev = obj->my_dev;
947                 yaffs_gross_lock(dev);
948                 error = yaffs_get_xattrib(obj, name, buff, size);
949                 yaffs_gross_unlock(dev);
950
951         }
952         yaffs_trace(YAFFS_TRACE_OS, "yaffs_getxattr done returning %d", error);
953
954         return error;
955 }
956
957 static int yaffs_removexattr(struct dentry *dentry, const char *name)
958 {
959         struct inode *inode = dentry->d_inode;
960         int error = 0;
961         struct yaffs_dev *dev;
962         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
963
964         yaffs_trace(YAFFS_TRACE_OS,
965                 "yaffs_removexattr of object %d", obj->obj_id);
966
967         if (error == 0) {
968                 int result;
969                 dev = obj->my_dev;
970                 yaffs_gross_lock(dev);
971                 result = yaffs_remove_xattrib(obj, name);
972                 if (result == YAFFS_OK)
973                         error = 0;
974                 else if (result < 0)
975                         error = result;
976                 yaffs_gross_unlock(dev);
977
978         }
979         yaffs_trace(YAFFS_TRACE_OS,
980                 "yaffs_removexattr done returning %d", error);
981
982         return error;
983 }
984
985 static ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size)
986 {
987         struct inode *inode = dentry->d_inode;
988         int error = 0;
989         struct yaffs_dev *dev;
990         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
991
992         yaffs_trace(YAFFS_TRACE_OS,
993                 "yaffs_listxattr of object %d", obj->obj_id);
994
995         if (error == 0) {
996                 dev = obj->my_dev;
997                 yaffs_gross_lock(dev);
998                 error = yaffs_list_xattrib(obj, buff, size);
999                 yaffs_gross_unlock(dev);
1000
1001         }
1002         yaffs_trace(YAFFS_TRACE_OS,
1003                 "yaffs_listxattr done returning %d", error);
1004
1005         return error;
1006 }
1007
1008
1009 static const struct inode_operations yaffs_file_inode_operations = {
1010         .setattr = yaffs_setattr,
1011         .setxattr = yaffs_setxattr,
1012         .getxattr = yaffs_getxattr,
1013         .listxattr = yaffs_listxattr,
1014         .removexattr = yaffs_removexattr,
1015 };
1016
1017
1018 static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
1019                           int buflen)
1020 {
1021         unsigned char *alias;
1022         int ret;
1023
1024         struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
1025
1026         yaffs_gross_lock(dev);
1027
1028         alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
1029
1030         yaffs_gross_unlock(dev);
1031
1032         if (!alias)
1033                 return -ENOMEM;
1034
1035 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
1036         ret = vfs_readlink(dentry, buffer, buflen, alias);
1037 #else
1038         ret = readlink_copy(buffer, buflen, alias);
1039 #endif
1040         kfree(alias);
1041         return ret;
1042 }
1043
1044 #if (YAFFS_NEW_FOLLOW_LINK == 1)
1045 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
1046 {
1047         void *ret;
1048 #else
1049 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
1050 {
1051         int ret
1052 #endif
1053         unsigned char *alias;
1054         int ret_int = 0;
1055         struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
1056
1057         yaffs_gross_lock(dev);
1058
1059         alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
1060         yaffs_gross_unlock(dev);
1061
1062         if (!alias) {
1063                 ret_int = -ENOMEM;
1064                 goto out;
1065         }
1066 #if (YAFFS_NEW_FOLLOW_LINK == 1)
1067         nd_set_link(nd, alias);
1068         ret = alias;
1069 out:
1070         if (ret_int)
1071                 ret = ERR_PTR(ret_int);
1072         return ret;
1073 #else
1074         ret = vfs_follow_link(nd, alias);
1075         kfree(alias);
1076 out:
1077         if (ret_int)
1078                 ret = ret_int;
1079         return ret;
1080 #endif
1081 }
1082
1083
1084 #ifdef YAFFS_HAS_PUT_INODE
1085
1086 /* For now put inode is just for debugging
1087  * Put inode is called when the inode **structure** is put.
1088  */
1089 static void yaffs_put_inode(struct inode *inode)
1090 {
1091         yaffs_trace(YAFFS_TRACE_OS,
1092                 "yaffs_put_inode: ino %d, count %d"),
1093                 (int)inode->i_ino, atomic_read(&inode->i_count);
1094
1095 }
1096 #endif
1097
1098 #if (YAFFS_NEW_FOLLOW_LINK == 1)
1099 void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias)
1100 {
1101         kfree(alias);
1102 }
1103 #endif
1104
1105 static const struct inode_operations yaffs_symlink_inode_operations = {
1106         .readlink = yaffs_readlink,
1107         .follow_link = yaffs_follow_link,
1108 #if (YAFFS_NEW_FOLLOW_LINK == 1)
1109         .put_link = yaffs_put_link,
1110 #endif
1111         .setattr = yaffs_setattr,
1112         .setxattr = yaffs_setxattr,
1113         .getxattr = yaffs_getxattr,
1114         .listxattr = yaffs_listxattr,
1115         .removexattr = yaffs_removexattr,
1116 };
1117
1118 #ifdef YAFFS_USE_OWN_IGET
1119
1120 static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
1121 {
1122         struct inode *inode;
1123         struct yaffs_obj *obj;
1124         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
1125
1126         yaffs_trace(YAFFS_TRACE_OS, "yaffs_iget for %lu", ino);
1127
1128         inode = iget_locked(sb, ino);
1129         if (!inode)
1130                 return ERR_PTR(-ENOMEM);
1131         if (!(inode->i_state & I_NEW))
1132                 return inode;
1133
1134         /* NB This is called as a side effect of other functions, but
1135          * we had to release the lock to prevent deadlocks, so
1136          * need to lock again.
1137          */
1138
1139         yaffs_gross_lock(dev);
1140
1141         obj = yaffs_find_by_number(dev, inode->i_ino);
1142
1143         yaffs_fill_inode_from_obj(inode, obj);
1144
1145         yaffs_gross_unlock(dev);
1146
1147         unlock_new_inode(inode);
1148         return inode;
1149 }
1150
1151 #else
1152
1153 static void yaffs_read_inode(struct inode *inode)
1154 {
1155         /* NB This is called as a side effect of other functions, but
1156          * we had to release the lock to prevent deadlocks, so
1157          * need to lock again.
1158          */
1159
1160         struct yaffs_obj *obj;
1161         struct yaffs_dev *dev = yaffs_super_to_dev(inode->i_sb);
1162
1163         yaffs_trace(YAFFS_TRACE_OS,
1164                 "yaffs_read_inode for %d", (int)inode->i_ino);
1165
1166         if (current != yaffs_dev_to_lc(dev)->readdir_process)
1167                 yaffs_gross_lock(dev);
1168
1169         obj = yaffs_find_by_number(dev, inode->i_ino);
1170
1171         yaffs_fill_inode_from_obj(inode, obj);
1172
1173         if (current != yaffs_dev_to_lc(dev)->readdir_process)
1174                 yaffs_gross_unlock(dev);
1175 }
1176
1177 #endif
1178
1179
1180
1181 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
1182                               struct yaffs_obj *obj)
1183 {
1184         struct inode *inode;
1185
1186         if (!sb) {
1187                 yaffs_trace(YAFFS_TRACE_OS,
1188                         "yaffs_get_inode for NULL super_block!!");
1189                 return NULL;
1190
1191         }
1192
1193         if (!obj) {
1194                 yaffs_trace(YAFFS_TRACE_OS,
1195                         "yaffs_get_inode for NULL object!!");
1196                 return NULL;
1197
1198         }
1199
1200         yaffs_trace(YAFFS_TRACE_OS,
1201                 "yaffs_get_inode for object %d", obj->obj_id);
1202
1203         inode = Y_IGET(sb, obj->obj_id);
1204         if (IS_ERR(inode))
1205                 return NULL;
1206
1207         /* NB Side effect: iget calls back to yaffs_read_inode(). */
1208         /* iget also increments the inode's i_count */
1209         /* NB You can't be holding gross_lock or deadlock will happen! */
1210
1211         return inode;
1212 }
1213
1214
1215
1216 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
1217 #define YCRED(x) x
1218 #else
1219 #define YCRED(x) (x->cred)
1220 #endif
1221
1222 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
1223 #define YPROC_uid(p) (YCRED(p)->fsuid)
1224 #define YPROC_gid(p) (YCRED(p)->fsgid)
1225 #define EXTRACT_gid(x) x
1226 #define EXTRACT_uid(x) x
1227 #define MAKE_gid(x) x
1228 #define MAKE_uid(x) x
1229 #else
1230 #define YPROC_uid(p) from_kuid(&init_user_ns, YCRED(p)->fsuid)
1231 #define YPROC_gid(p) from_kgid(&init_user_ns, YCRED(p)->fsgid)
1232 #define EXTRACT_gid(x) from_kgid(&init_user_ns, x)
1233 #define EXTRACT_uid(x) from_kuid(&init_user_ns, x)
1234 #define MAKE_gid(x) make_kgid(&init_user_ns, x)
1235 #define MAKE_uid(x) make_kuid(&init_user_ns, x)
1236 #endif
1237
1238
1239 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
1240 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
1241                        dev_t rdev)
1242 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1243 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
1244                        dev_t rdev)
1245 #else
1246 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
1247                        int rdev)
1248 #endif
1249 {
1250         struct inode *inode;
1251
1252         struct yaffs_obj *obj = NULL;
1253         struct yaffs_dev *dev;
1254
1255         struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
1256
1257         int error = -ENOSPC;
1258         uid_t uid = YPROC_uid(current);
1259         gid_t gid =
1260             (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current);
1261
1262         if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
1263                 mode |= S_ISGID;
1264
1265         if (parent) {
1266                 yaffs_trace(YAFFS_TRACE_OS,
1267                         "yaffs_mknod: parent object %d type %d",
1268                         parent->obj_id, parent->variant_type);
1269         } else {
1270                 yaffs_trace(YAFFS_TRACE_OS,
1271                         "yaffs_mknod: could not get parent object");
1272                 return -EPERM;
1273         }
1274
1275         yaffs_trace(YAFFS_TRACE_OS,
1276                 "yaffs_mknod: making oject for %s, mode %x dev %x",
1277                 dentry->d_name.name, mode, rdev);
1278
1279         dev = parent->my_dev;
1280
1281         yaffs_gross_lock(dev);
1282
1283         switch (mode & S_IFMT) {
1284         default:
1285                 /* Special (socket, fifo, device...) */
1286                 yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making special");
1287 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1288                 obj =
1289                     yaffs_create_special(parent, dentry->d_name.name, mode, uid,
1290                                          gid, old_encode_dev(rdev));
1291 #else
1292                 obj =
1293                     yaffs_create_special(parent, dentry->d_name.name, mode, uid,
1294                                          gid, rdev);
1295 #endif
1296                 break;
1297         case S_IFREG:           /* file          */
1298                 yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making file");
1299                 obj = yaffs_create_file(parent, dentry->d_name.name, mode, uid,
1300                                         gid);
1301                 break;
1302         case S_IFDIR:           /* directory */
1303                 yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making directory");
1304                 obj = yaffs_create_dir(parent, dentry->d_name.name, mode,
1305                                        uid, gid);
1306                 break;
1307         case S_IFLNK:           /* symlink */
1308                 yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making symlink");
1309                 obj = NULL;     /* Do we ever get here? */
1310                 break;
1311         }
1312
1313         /* Can not call yaffs_get_inode() with gross lock held */
1314         yaffs_gross_unlock(dev);
1315
1316         if (obj) {
1317                 inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
1318                 d_instantiate(dentry, inode);
1319                 update_dir_time(dir);
1320                 yaffs_trace(YAFFS_TRACE_OS,
1321                         "yaffs_mknod created object %d count = %d",
1322                         obj->obj_id, atomic_read(&inode->i_count));
1323                 error = 0;
1324                 yaffs_fill_inode_from_obj(dir, parent);
1325         } else {
1326                 yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod failed making object");
1327                 error = -ENOMEM;
1328         }
1329
1330         return error;
1331 }
1332
1333 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
1334 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1335 #else
1336 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1337 #endif
1338 {
1339         int ret_val;
1340         yaffs_trace(YAFFS_TRACE_OS, "yaffs_mkdir");
1341         ret_val = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
1342         return ret_val;
1343 }
1344
1345
1346 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
1347 static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1348                         bool dummy)
1349 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
1350 static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1351                         struct nameidata *n)
1352 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1353 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
1354                         struct nameidata *n)
1355 #else
1356 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
1357 #endif
1358 {
1359         yaffs_trace(YAFFS_TRACE_OS, "yaffs_create");
1360         return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
1361 }
1362
1363 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
1364 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
1365                                    unsigned int dummy)
1366 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1367 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
1368                                    struct nameidata *n)
1369 #else
1370 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
1371 #endif
1372 {
1373         struct yaffs_obj *obj;
1374         struct inode *inode = NULL;     /* NCB 2.5/2.6 needs NULL here */
1375
1376         struct yaffs_dev *dev = yaffs_inode_to_obj(dir)->my_dev;
1377
1378         if (current != yaffs_dev_to_lc(dev)->readdir_process)
1379                 yaffs_gross_lock(dev);
1380
1381         yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup for %d:%s",
1382                 yaffs_inode_to_obj(dir)->obj_id, dentry->d_name.name);
1383
1384         obj = yaffs_find_by_name(yaffs_inode_to_obj(dir), dentry->d_name.name);
1385
1386         obj = yaffs_get_equivalent_obj(obj);    /* in case it was a hardlink */
1387
1388         /* Can't hold gross lock when calling yaffs_get_inode() */
1389         if (current != yaffs_dev_to_lc(dev)->readdir_process)
1390                 yaffs_gross_unlock(dev);
1391
1392         if (obj) {
1393                 yaffs_trace(YAFFS_TRACE_OS,
1394                         "yaffs_lookup found %d", obj->obj_id);
1395
1396                 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
1397         } else {
1398                 yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup not found");
1399
1400         }
1401
1402 /* added NCB for 2.5/6 compatability - forces add even if inode is
1403  * NULL which creates dentry hash */
1404         d_add(dentry, inode);
1405
1406         return NULL;
1407 }
1408
1409 /*
1410  * Create a link...
1411  */
1412 static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
1413                       struct dentry *dentry)
1414 {
1415         struct inode *inode = old_dentry->d_inode;
1416         struct yaffs_obj *obj = NULL;
1417         struct yaffs_obj *link = NULL;
1418         struct yaffs_dev *dev;
1419
1420         yaffs_trace(YAFFS_TRACE_OS, "yaffs_link");
1421
1422         obj = yaffs_inode_to_obj(inode);
1423         dev = obj->my_dev;
1424
1425         yaffs_gross_lock(dev);
1426
1427         if (!S_ISDIR(inode->i_mode))    /* Don't link directories */
1428                 link =
1429                     yaffs_link_obj(yaffs_inode_to_obj(dir), dentry->d_name.name,
1430                                    obj);
1431
1432         if (link) {
1433                 set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
1434                 d_instantiate(dentry, old_dentry->d_inode);
1435                 atomic_inc(&old_dentry->d_inode->i_count);
1436                 yaffs_trace(YAFFS_TRACE_OS,
1437                         "yaffs_link link count %d i_count %d",
1438                         old_dentry->d_inode->i_nlink,
1439                         atomic_read(&old_dentry->d_inode->i_count));
1440         }
1441
1442         yaffs_gross_unlock(dev);
1443
1444         if (link) {
1445                 update_dir_time(dir);
1446                 return 0;
1447         }
1448
1449         return -EPERM;
1450 }
1451
1452 static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
1453                          const char *symname)
1454 {
1455         struct yaffs_obj *obj;
1456         struct yaffs_dev *dev;
1457         uid_t uid = YPROC_uid(current);
1458         gid_t gid =
1459             (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current);
1460
1461         yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
1462
1463         if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
1464                                 YAFFS_MAX_NAME_LENGTH)
1465                 return -ENAMETOOLONG;
1466
1467         if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
1468                                 YAFFS_MAX_ALIAS_LENGTH)
1469                 return -ENAMETOOLONG;
1470
1471         dev = yaffs_inode_to_obj(dir)->my_dev;
1472         yaffs_gross_lock(dev);
1473         obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
1474                                    S_IFLNK | S_IRWXUGO, uid, gid, symname);
1475         yaffs_gross_unlock(dev);
1476
1477         if (obj) {
1478                 struct inode *inode;
1479
1480                 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
1481                 d_instantiate(dentry, inode);
1482                 update_dir_time(dir);
1483                 yaffs_trace(YAFFS_TRACE_OS, "symlink created OK");
1484                 return 0;
1485         } else {
1486                 yaffs_trace(YAFFS_TRACE_OS, "symlink not created");
1487         }
1488
1489         return -ENOMEM;
1490 }
1491
1492 /*
1493  * The VFS layer already does all the dentry stuff for rename.
1494  *
1495  * NB: POSIX says you can rename an object over an old object of the same name
1496  */
1497 static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
1498                         struct inode *new_dir, struct dentry *new_dentry)
1499 {
1500         struct yaffs_dev *dev;
1501         int ret_val = YAFFS_FAIL;
1502         struct yaffs_obj *target;
1503
1504         yaffs_trace(YAFFS_TRACE_OS, "yaffs_rename");
1505         dev = yaffs_inode_to_obj(old_dir)->my_dev;
1506
1507         yaffs_gross_lock(dev);
1508
1509         /* Check if the target is an existing directory that is not empty. */
1510         target = yaffs_find_by_name(yaffs_inode_to_obj(new_dir),
1511                                     new_dentry->d_name.name);
1512
1513         if (target && target->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
1514             !list_empty(&target->variant.dir_variant.children)) {
1515
1516                 yaffs_trace(YAFFS_TRACE_OS, "target is non-empty dir");
1517
1518                 ret_val = YAFFS_FAIL;
1519         } else {
1520                 /* Now does unlinking internally using shadowing mechanism */
1521                 yaffs_trace(YAFFS_TRACE_OS, "calling yaffs_rename_obj");
1522
1523                 ret_val = yaffs_rename_obj(yaffs_inode_to_obj(old_dir),
1524                                            old_dentry->d_name.name,
1525                                            yaffs_inode_to_obj(new_dir),
1526                                            new_dentry->d_name.name);
1527         }
1528         yaffs_gross_unlock(dev);
1529
1530         if (ret_val == YAFFS_OK) {
1531                 if (target)
1532                         inode_dec_link_count(new_dentry->d_inode);
1533
1534                 update_dir_time(old_dir);
1535                 if (old_dir != new_dir)
1536                         update_dir_time(new_dir);
1537                 return 0;
1538         } else {
1539                 return -ENOTEMPTY;
1540         }
1541 }
1542
1543
1544
1545
1546 static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
1547 {
1548         int ret_val;
1549
1550         struct yaffs_dev *dev;
1551         struct yaffs_obj *obj;
1552
1553         yaffs_trace(YAFFS_TRACE_OS, "yaffs_unlink %d:%s",
1554                 (int)(dir->i_ino), dentry->d_name.name);
1555         obj = yaffs_inode_to_obj(dir);
1556         dev = obj->my_dev;
1557
1558         yaffs_gross_lock(dev);
1559
1560         ret_val = yaffs_unlinker(obj, dentry->d_name.name);
1561
1562         if (ret_val == YAFFS_OK) {
1563                 inode_dec_link_count(dentry->d_inode);
1564                 dir->i_version++;
1565                 yaffs_gross_unlock(dev);
1566                 update_dir_time(dir);
1567                 return 0;
1568         }
1569         yaffs_gross_unlock(dev);
1570         return -ENOTEMPTY;
1571 }
1572
1573
1574
1575 static const struct inode_operations yaffs_dir_inode_operations = {
1576         .create = yaffs_create,
1577         .lookup = yaffs_lookup,
1578         .link = yaffs_link,
1579         .unlink = yaffs_unlink,
1580         .symlink = yaffs_symlink,
1581         .mkdir = yaffs_mkdir,
1582         .rmdir = yaffs_unlink,
1583         .mknod = yaffs_mknod,
1584         .rename = yaffs_rename,
1585         .setattr = yaffs_setattr,
1586         .setxattr = yaffs_setxattr,
1587         .getxattr = yaffs_getxattr,
1588         .listxattr = yaffs_listxattr,
1589         .removexattr = yaffs_removexattr,
1590 };
1591
1592 /*-----------------------------------------------------------------*/
1593 /* Directory search context allows us to unlock access to yaffs during
1594  * filldir without causing problems with the directory being modified.
1595  * This is similar to the tried and tested mechanism used in yaffs direct.
1596  *
1597  * A search context iterates along a doubly linked list of siblings in the
1598  * directory. If the iterating object is deleted then this would corrupt
1599  * the list iteration, likely causing a crash. The search context avoids
1600  * this by using the remove_obj_fn to move the search context to the
1601  * next object before the object is deleted.
1602  *
1603  * Many readdirs (and thus seach conexts) may be alive simulateously so
1604  * each struct yaffs_dev has a list of these.
1605  *
1606  * A seach context lives for the duration of a readdir.
1607  *
1608  * All these functions must be called while yaffs is locked.
1609  */
1610
1611 struct yaffs_search_context {
1612         struct yaffs_dev *dev;
1613         struct yaffs_obj *dir_obj;
1614         struct yaffs_obj *next_return;
1615         struct list_head others;
1616 };
1617
1618 /*
1619  * yaffs_new_search() creates a new search context, initialises it and
1620  * adds it to the device's search context list.
1621  *
1622  * Called at start of readdir.
1623  */
1624 static struct yaffs_search_context *yaffs_new_search(struct yaffs_obj *dir)
1625 {
1626         struct yaffs_dev *dev = dir->my_dev;
1627         struct yaffs_search_context *sc =
1628             kmalloc(sizeof(struct yaffs_search_context), GFP_NOFS);
1629         if (sc) {
1630                 sc->dir_obj = dir;
1631                 sc->dev = dev;
1632                 if (list_empty(&sc->dir_obj->variant.dir_variant.children))
1633                         sc->next_return = NULL;
1634                 else
1635                         sc->next_return =
1636                             list_entry(dir->variant.dir_variant.children.next,
1637                                        struct yaffs_obj, siblings);
1638                 INIT_LIST_HEAD(&sc->others);
1639                 list_add(&sc->others, &(yaffs_dev_to_lc(dev)->search_contexts));
1640         }
1641         return sc;
1642 }
1643
1644 /*
1645  * yaffs_search_end() disposes of a search context and cleans up.
1646  */
1647 static void yaffs_search_end(struct yaffs_search_context *sc)
1648 {
1649         if (sc) {
1650                 list_del(&sc->others);
1651                 kfree(sc);
1652         }
1653 }
1654
1655 /*
1656  * yaffs_search_advance() moves a search context to the next object.
1657  * Called when the search iterates or when an object removal causes
1658  * the search context to be moved to the next object.
1659  */
1660 static void yaffs_search_advance(struct yaffs_search_context *sc)
1661 {
1662         if (!sc)
1663                 return;
1664
1665         if (sc->next_return == NULL ||
1666             list_empty(&sc->dir_obj->variant.dir_variant.children))
1667                 sc->next_return = NULL;
1668         else {
1669                 struct list_head *next = sc->next_return->siblings.next;
1670
1671                 if (next == &sc->dir_obj->variant.dir_variant.children)
1672                         sc->next_return = NULL; /* end of list */
1673                 else
1674                         sc->next_return =
1675                             list_entry(next, struct yaffs_obj, siblings);
1676         }
1677 }
1678
1679 /*
1680  * yaffs_remove_obj_callback() is called when an object is unlinked.
1681  * We check open search contexts and advance any which are currently
1682  * on the object being iterated.
1683  */
1684 static void yaffs_remove_obj_callback(struct yaffs_obj *obj)
1685 {
1686
1687         struct list_head *i;
1688         struct yaffs_search_context *sc;
1689         struct list_head *search_contexts =
1690             &(yaffs_dev_to_lc(obj->my_dev)->search_contexts);
1691
1692         /* Iterate through the directory search contexts.
1693          * If any are currently on the object being removed, then advance
1694          * the search context to the next object to prevent a hanging pointer.
1695          */
1696         list_for_each(i, search_contexts) {
1697                 sc = list_entry(i, struct yaffs_search_context, others);
1698                 if (sc->next_return == obj)
1699                         yaffs_search_advance(sc);
1700         }
1701
1702 }
1703
1704
1705 /*-----------------------------------------------------------------*/
1706
1707 #ifdef YAFFS_USE_DIR_ITERATE
1708 static int yaffs_iterate(struct file *f, struct dir_context *dc)
1709 {
1710         struct yaffs_obj *obj;
1711         struct yaffs_dev *dev;
1712         struct yaffs_search_context *sc;
1713         unsigned long curoffs;
1714         struct yaffs_obj *l;
1715         int ret_val = 0;
1716
1717         char name[YAFFS_MAX_NAME_LENGTH + 1];
1718
1719         obj = yaffs_dentry_to_obj(f->f_dentry);
1720         dev = obj->my_dev;
1721
1722         yaffs_gross_lock(dev);
1723
1724         yaffs_dev_to_lc(dev)->readdir_process = current;
1725
1726         sc = yaffs_new_search(obj);
1727         if (!sc) {
1728                 ret_val = -ENOMEM;
1729                 goto out;
1730         }
1731
1732         if (!dir_emit_dots(f, dc))
1733                 return 0;
1734
1735         curoffs = 1;
1736
1737         while (sc->next_return) {
1738                 curoffs++;
1739                 l = sc->next_return;
1740                 if (curoffs >= dc->pos) {
1741                         int this_inode = yaffs_get_obj_inode(l);
1742                         int this_type = yaffs_get_obj_type(l);
1743
1744                         yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
1745                         yaffs_trace(YAFFS_TRACE_OS,
1746                                 "yaffs_readdir: %s inode %d",
1747                                 name, yaffs_get_obj_inode(l));
1748
1749                         yaffs_gross_unlock(dev);
1750
1751                         if (!dir_emit(dc,
1752                                       name,
1753                                       strlen(name),
1754                                       this_inode,
1755                                       this_type)) {
1756                                 yaffs_gross_lock(dev);
1757                                 goto out;
1758                         }
1759
1760                         yaffs_gross_lock(dev);
1761
1762                         dc->pos++;
1763                         f->f_pos++;
1764                 }
1765                 yaffs_search_advance(sc);
1766         }
1767
1768 out:
1769         yaffs_search_end(sc);
1770         yaffs_dev_to_lc(dev)->readdir_process = NULL;
1771         yaffs_gross_unlock(dev);
1772
1773         return ret_val;
1774 }
1775
1776 #else
1777
1778 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
1779 {
1780         struct yaffs_obj *obj;
1781         struct yaffs_dev *dev;
1782         struct yaffs_search_context *sc;
1783         struct inode *inode = f->f_dentry->d_inode;
1784         unsigned long offset, curoffs;
1785         struct yaffs_obj *l;
1786         int ret_val = 0;
1787
1788         char name[YAFFS_MAX_NAME_LENGTH + 1];
1789
1790         obj = yaffs_dentry_to_obj(f->f_dentry);
1791         dev = obj->my_dev;
1792
1793         yaffs_gross_lock(dev);
1794
1795         yaffs_dev_to_lc(dev)->readdir_process = current;
1796
1797         offset = f->f_pos;
1798
1799         sc = yaffs_new_search(obj);
1800         if (!sc) {
1801                 ret_val = -ENOMEM;
1802                 goto out;
1803         }
1804
1805         yaffs_trace(YAFFS_TRACE_OS,
1806                 "yaffs_readdir: starting at %d", (int)offset);
1807
1808         if (offset == 0) {
1809                 yaffs_trace(YAFFS_TRACE_OS,
1810                         "yaffs_readdir: entry . ino %d",
1811                         (int)inode->i_ino);
1812                 yaffs_gross_unlock(dev);
1813                 if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0) {
1814                         yaffs_gross_lock(dev);
1815                         goto out;
1816                 }
1817                 yaffs_gross_lock(dev);
1818                 offset++;
1819                 f->f_pos++;
1820         }
1821         if (offset == 1) {
1822                 yaffs_trace(YAFFS_TRACE_OS,
1823                         "yaffs_readdir: entry .. ino %d",
1824                         (int)f->f_dentry->d_parent->d_inode->i_ino);
1825                 yaffs_gross_unlock(dev);
1826                 if (filldir(dirent, "..", 2, offset,
1827                             f->f_dentry->d_parent->d_inode->i_ino,
1828                             DT_DIR) < 0) {
1829                         yaffs_gross_lock(dev);
1830                         goto out;
1831                 }
1832                 yaffs_gross_lock(dev);
1833                 offset++;
1834                 f->f_pos++;
1835         }
1836
1837         curoffs = 1;
1838
1839         /* If the directory has changed since the open or last call to
1840            readdir, rewind to after the 2 canned entries. */
1841         if (f->f_version != inode->i_version) {
1842                 offset = 2;
1843                 f->f_pos = offset;
1844                 f->f_version = inode->i_version;
1845         }
1846
1847         while (sc->next_return) {
1848                 curoffs++;
1849                 l = sc->next_return;
1850                 if (curoffs >= offset) {
1851                         int this_inode = yaffs_get_obj_inode(l);
1852                         int this_type = yaffs_get_obj_type(l);
1853
1854                         yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
1855                         yaffs_trace(YAFFS_TRACE_OS,
1856                                 "yaffs_readdir: %s inode %d",
1857                                 name, yaffs_get_obj_inode(l));
1858
1859                         yaffs_gross_unlock(dev);
1860
1861                         if (filldir(dirent,
1862                                     name,
1863                                     strlen(name),
1864                                     offset, this_inode, this_type) < 0) {
1865                                 yaffs_gross_lock(dev);
1866                                 goto out;
1867                         }
1868
1869                         yaffs_gross_lock(dev);
1870
1871                         offset++;
1872                         f->f_pos++;
1873                 }
1874                 yaffs_search_advance(sc);
1875         }
1876
1877 out:
1878         yaffs_search_end(sc);
1879         yaffs_dev_to_lc(dev)->readdir_process = NULL;
1880         yaffs_gross_unlock(dev);
1881
1882         return ret_val;
1883 }
1884
1885 #endif
1886
1887 static const struct file_operations yaffs_dir_operations = {
1888         .read = generic_read_dir,
1889 #ifdef YAFFS_USE_DIR_ITERATE
1890         .iterate = yaffs_iterate,
1891 #else
1892         .readdir = yaffs_readdir,
1893 #endif
1894         .fsync = yaffs_sync_object,
1895         .llseek = generic_file_llseek,
1896 };
1897
1898 static void yaffs_fill_inode_from_obj(struct inode *inode,
1899                                       struct yaffs_obj *obj)
1900 {
1901         if (inode && obj) {
1902
1903                 /* Check mode against the variant type and attempt to repair if broken. */
1904                 u32 mode = obj->yst_mode;
1905                 switch (obj->variant_type) {
1906                 case YAFFS_OBJECT_TYPE_FILE:
1907                         if (!S_ISREG(mode)) {
1908                                 obj->yst_mode &= ~S_IFMT;
1909                                 obj->yst_mode |= S_IFREG;
1910                         }
1911
1912                         break;
1913                 case YAFFS_OBJECT_TYPE_SYMLINK:
1914                         if (!S_ISLNK(mode)) {
1915                                 obj->yst_mode &= ~S_IFMT;
1916                                 obj->yst_mode |= S_IFLNK;
1917                         }
1918
1919                         break;
1920                 case YAFFS_OBJECT_TYPE_DIRECTORY:
1921                         if (!S_ISDIR(mode)) {
1922                                 obj->yst_mode &= ~S_IFMT;
1923                                 obj->yst_mode |= S_IFDIR;
1924                         }
1925
1926                         break;
1927                 case YAFFS_OBJECT_TYPE_UNKNOWN:
1928                 case YAFFS_OBJECT_TYPE_HARDLINK:
1929                 case YAFFS_OBJECT_TYPE_SPECIAL:
1930                 default:
1931                         /* TODO? */
1932                         break;
1933                 }
1934
1935                 inode->i_flags |= S_NOATIME;
1936
1937                 inode->i_ino = obj->obj_id;
1938                 inode->i_mode = obj->yst_mode;
1939                 inode->i_uid = MAKE_uid(obj->yst_uid);
1940                 inode->i_gid = MAKE_gid(obj->yst_gid);
1941 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
1942                 inode->i_blksize = inode->i_sb->s_blocksize;
1943 #endif
1944 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1945
1946                 inode->i_rdev = old_decode_dev(obj->yst_rdev);
1947                 inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
1948                 inode->i_atime.tv_nsec = 0;
1949                 inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
1950                 inode->i_mtime.tv_nsec = 0;
1951                 inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
1952                 inode->i_ctime.tv_nsec = 0;
1953 #else
1954                 inode->i_rdev = obj->yst_rdev;
1955                 inode->i_atime = obj->yst_atime;
1956                 inode->i_mtime = obj->yst_mtime;
1957                 inode->i_ctime = obj->yst_ctime;
1958 #endif
1959                 inode->i_size = yaffs_get_obj_length(obj);
1960                 inode->i_blocks = (inode->i_size + 511) >> 9;
1961
1962                 set_nlink(inode, yaffs_get_obj_link_count(obj));
1963
1964                 yaffs_trace(YAFFS_TRACE_OS,
1965                         "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
1966                         inode->i_mode, obj->yst_uid, obj->yst_gid,
1967                         inode->i_size, atomic_read(&inode->i_count));
1968
1969                 switch (obj->yst_mode & S_IFMT) {
1970                 default:        /* fifo, device or socket */
1971 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1972                         init_special_inode(inode, obj->yst_mode,
1973                                            old_decode_dev(obj->yst_rdev));
1974 #else
1975                         init_special_inode(inode, obj->yst_mode,
1976                                            (dev_t) (obj->yst_rdev));
1977 #endif
1978                         break;
1979                 case S_IFREG:   /* file */
1980                         inode->i_op = &yaffs_file_inode_operations;
1981                         inode->i_fop = &yaffs_file_operations;
1982                         inode->i_mapping->a_ops =
1983                             &yaffs_file_address_operations;
1984                         break;
1985                 case S_IFDIR:   /* directory */
1986                         inode->i_op = &yaffs_dir_inode_operations;
1987                         inode->i_fop = &yaffs_dir_operations;
1988                         break;
1989                 case S_IFLNK:   /* symlink */
1990                         inode->i_op = &yaffs_symlink_inode_operations;
1991                         break;
1992                 }
1993
1994                 yaffs_inode_to_obj_lv(inode) = obj;
1995
1996                 obj->my_inode = inode;
1997
1998         } else {
1999                 yaffs_trace(YAFFS_TRACE_OS,
2000                         "yaffs_fill_inode invalid parameters");
2001         }
2002
2003 }
2004
2005
2006
2007 /*
2008  * yaffs background thread functions .
2009  * yaffs_bg_thread_fn() the thread function
2010  * yaffs_bg_start() launches the background thread.
2011  * yaffs_bg_stop() cleans up the background thread.
2012  *
2013  * NB:
2014  * The thread should only run after the yaffs is initialised
2015  * The thread should be stopped before yaffs is unmounted.
2016  * The thread should not do any writing while the fs is in read only.
2017  */
2018
2019 static unsigned yaffs_bg_gc_urgency(struct yaffs_dev *dev)
2020 {
2021         unsigned erased_chunks =
2022             dev->n_erased_blocks * dev->param.chunks_per_block;
2023         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2024         unsigned scattered = 0; /* Free chunks not in an erased block */
2025
2026         if (erased_chunks < dev->n_free_chunks)
2027                 scattered = (dev->n_free_chunks - erased_chunks);
2028
2029         if (!context->bg_running)
2030                 return 0;
2031         else if (scattered < (dev->param.chunks_per_block * 2))
2032                 return 0;
2033         else if (erased_chunks > dev->n_free_chunks / 2)
2034                 return 0;
2035         else if (erased_chunks > dev->n_free_chunks / 4)
2036                 return 1;
2037         else
2038                 return 2;
2039 }
2040
2041 #ifdef YAFFS_COMPILE_BACKGROUND
2042
2043 void yaffs_background_waker(unsigned long data)
2044 {
2045         wake_up_process((struct task_struct *)data);
2046 }
2047
2048 static int yaffs_bg_thread_fn(void *data)
2049 {
2050         struct yaffs_dev *dev = (struct yaffs_dev *)data;
2051         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2052         unsigned long now = jiffies;
2053         unsigned long next_dir_update = now;
2054         unsigned long next_gc = now;
2055         unsigned long expires;
2056         unsigned int urgency;
2057
2058         int gc_result;
2059         struct timer_list timer;
2060
2061         yaffs_trace(YAFFS_TRACE_BACKGROUND,
2062                 "yaffs_background starting for dev %p", (void *)dev);
2063
2064 #ifdef YAFFS_COMPILE_FREEZER
2065         set_freezable();
2066 #endif
2067         while (context->bg_running) {
2068                 yaffs_trace(YAFFS_TRACE_BACKGROUND, "yaffs_background");
2069
2070                 if (kthread_should_stop())
2071                         break;
2072
2073 #ifdef YAFFS_COMPILE_FREEZER
2074                 if (try_to_freeze())
2075                         continue;
2076 #endif
2077                 yaffs_gross_lock(dev);
2078
2079                 now = jiffies;
2080
2081                 if (time_after(now, next_dir_update) && yaffs_bg_enable) {
2082                         yaffs_update_dirty_dirs(dev);
2083                         next_dir_update = now + HZ;
2084                 }
2085
2086                 if (time_after(now, next_gc) && yaffs_bg_enable) {
2087                         if (!dev->is_checkpointed) {
2088                                 urgency = yaffs_bg_gc_urgency(dev);
2089                                 gc_result = yaffs_bg_gc(dev, urgency);
2090                                 if (urgency > 1)
2091                                         next_gc = now + HZ / 20 + 1;
2092                                 else if (urgency > 0)
2093                                         next_gc = now + HZ / 10 + 1;
2094                                 else
2095                                         next_gc = now + HZ * 2;
2096                         } else  {
2097                                 /*
2098                                  * gc not running so set to next_dir_update
2099                                  * to cut down on wake ups
2100                                  */
2101                                 next_gc = next_dir_update;
2102                         }
2103                 }
2104                 yaffs_gross_unlock(dev);
2105 #if 1
2106                 expires = next_dir_update;
2107                 if (time_before(next_gc, expires))
2108                         expires = next_gc;
2109                 if (time_before(expires, now))
2110                         expires = now + HZ;
2111
2112                 Y_INIT_TIMER(&timer);
2113                 timer.expires = expires + 1;
2114                 timer.data = (unsigned long)current;
2115                 timer.function = yaffs_background_waker;
2116
2117                 set_current_state(TASK_INTERRUPTIBLE);
2118                 add_timer(&timer);
2119                 schedule();
2120                 del_timer_sync(&timer);
2121 #else
2122                 msleep(10);
2123 #endif
2124         }
2125
2126         return 0;
2127 }
2128
2129 static int yaffs_bg_start(struct yaffs_dev *dev)
2130 {
2131         int retval = 0;
2132         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2133
2134         if (dev->read_only)
2135                 return -1;
2136
2137         context->bg_running = 1;
2138
2139         context->bg_thread = kthread_run(yaffs_bg_thread_fn,
2140                                          (void *)dev, "yaffs-bg-%d",
2141                                          context->mount_id);
2142
2143         if (IS_ERR(context->bg_thread)) {
2144                 retval = PTR_ERR(context->bg_thread);
2145                 context->bg_thread = NULL;
2146                 context->bg_running = 0;
2147         }
2148         return retval;
2149 }
2150
2151 static void yaffs_bg_stop(struct yaffs_dev *dev)
2152 {
2153         struct yaffs_linux_context *ctxt = yaffs_dev_to_lc(dev);
2154
2155         ctxt->bg_running = 0;
2156
2157         if (ctxt->bg_thread) {
2158                 kthread_stop(ctxt->bg_thread);
2159                 ctxt->bg_thread = NULL;
2160         }
2161 }
2162 #else
2163 static int yaffs_bg_thread_fn(void *data)
2164 {
2165         return 0;
2166 }
2167
2168 static int yaffs_bg_start(struct yaffs_dev *dev)
2169 {
2170         return 0;
2171 }
2172
2173 static void yaffs_bg_stop(struct yaffs_dev *dev)
2174 {
2175 }
2176 #endif
2177
2178
2179 static void yaffs_flush_inodes(struct super_block *sb)
2180 {
2181         struct inode *iptr;
2182         struct yaffs_obj *obj;
2183
2184         list_for_each_entry(iptr, &sb->s_inodes, i_sb_list) {
2185                 obj = yaffs_inode_to_obj(iptr);
2186                 if (obj) {
2187                         yaffs_trace(YAFFS_TRACE_OS,
2188                                 "flushing obj %d",
2189                                 obj->obj_id);
2190                         yaffs_flush_file(obj, 1, 0, 0);
2191                 }
2192         }
2193 }
2194
2195 static void yaffs_flush_super(struct super_block *sb, int do_checkpoint)
2196 {
2197         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2198         if (!dev)
2199                 return;
2200
2201         yaffs_flush_inodes(sb);
2202         yaffs_update_dirty_dirs(dev);
2203         yaffs_flush_whole_cache(dev, 1);
2204         if (do_checkpoint)
2205                 yaffs_checkpoint_save(dev);
2206 }
2207
2208 static LIST_HEAD(yaffs_context_list);
2209 struct mutex yaffs_context_lock;
2210
2211 static void yaffs_put_super(struct super_block *sb)
2212 {
2213         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2214         struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
2215
2216         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
2217                         "yaffs_put_super");
2218
2219         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
2220                 "Shutting down yaffs background thread");
2221         yaffs_bg_stop(dev);
2222         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
2223                 "yaffs background thread shut down");
2224
2225         yaffs_gross_lock(dev);
2226
2227         yaffs_flush_super(sb, 1);
2228
2229         yaffs_deinitialise(dev);
2230
2231         yaffs_gross_unlock(dev);
2232
2233         mutex_lock(&yaffs_context_lock);
2234         list_del_init(&(yaffs_dev_to_lc(dev)->context_list));
2235         mutex_unlock(&yaffs_context_lock);
2236
2237         if (yaffs_dev_to_lc(dev)->spare_buffer) {
2238                 kfree(yaffs_dev_to_lc(dev)->spare_buffer);
2239                 yaffs_dev_to_lc(dev)->spare_buffer = NULL;
2240         }
2241
2242         kfree(dev);
2243
2244         yaffs_put_mtd_device(mtd);
2245
2246         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
2247                         "yaffs_put_super done");
2248 }
2249
2250
2251 static unsigned yaffs_gc_control_callback(struct yaffs_dev *dev)
2252 {
2253         return yaffs_gc_control;
2254 }
2255
2256
2257 #ifdef YAFFS_COMPILE_EXPORTFS
2258
2259 static struct inode *yaffs2_nfs_get_inode(struct super_block *sb, uint64_t ino,
2260                                           uint32_t generation)
2261 {
2262         return Y_IGET(sb, ino);
2263 }
2264
2265 static struct dentry *yaffs2_fh_to_dentry(struct super_block *sb,
2266                                           struct fid *fid, int fh_len,
2267                                           int fh_type)
2268 {
2269         return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
2270                                     yaffs2_nfs_get_inode);
2271 }
2272
2273 static struct dentry *yaffs2_fh_to_parent(struct super_block *sb,
2274                                           struct fid *fid, int fh_len,
2275                                           int fh_type)
2276 {
2277         return generic_fh_to_parent(sb, fid, fh_len, fh_type,
2278                                     yaffs2_nfs_get_inode);
2279 }
2280
2281 struct dentry *yaffs2_get_parent(struct dentry *dentry)
2282 {
2283
2284         struct super_block *sb = dentry->d_inode->i_sb;
2285         struct dentry *parent = ERR_PTR(-ENOENT);
2286         struct inode *inode;
2287         unsigned long parent_ino;
2288         struct yaffs_obj *d_obj;
2289         struct yaffs_obj *parent_obj;
2290
2291         d_obj = yaffs_inode_to_obj(dentry->d_inode);
2292
2293         if (d_obj) {
2294                 parent_obj = d_obj->parent;
2295                 if (parent_obj) {
2296                         parent_ino = yaffs_get_obj_inode(parent_obj);
2297                         inode = Y_IGET(sb, parent_ino);
2298
2299                         if (IS_ERR(inode)) {
2300                                 parent = ERR_CAST(inode);
2301                         } else {
2302                                 parent = d_obtain_alias(inode);
2303                                 if (!IS_ERR(parent)) {
2304                                         parent = ERR_PTR(-ENOMEM);
2305                                         iput(inode);
2306                                 }
2307                         }
2308                 }
2309         }
2310
2311         return parent;
2312 }
2313
2314 /* Just declare a zero structure as a NULL value implies
2315  * using the default functions of exportfs.
2316  */
2317
2318 static struct export_operations yaffs_export_ops = {
2319         .fh_to_dentry = yaffs2_fh_to_dentry,
2320         .fh_to_parent = yaffs2_fh_to_parent,
2321         .get_parent = yaffs2_get_parent,
2322 };
2323
2324 #endif
2325
2326 static void yaffs_unstitch_obj(struct inode *inode, struct yaffs_obj *obj)
2327 {
2328         /* Clear the association between the inode and
2329          * the struct yaffs_obj.
2330          */
2331         obj->my_inode = NULL;
2332         yaffs_inode_to_obj_lv(inode) = NULL;
2333
2334         /* If the object freeing was deferred, then the real
2335          * free happens now.
2336          * This should fix the inode inconsistency problem.
2337          */
2338         yaffs_handle_defered_free(obj);
2339 }
2340
2341 #ifdef YAFFS_HAS_EVICT_INODE
2342 /* yaffs_evict_inode combines into one operation what was previously done in
2343  * yaffs_clear_inode() and yaffs_delete_inode()
2344  *
2345  */
2346 static void yaffs_evict_inode(struct inode *inode)
2347 {
2348         struct yaffs_obj *obj;
2349         struct yaffs_dev *dev;
2350         int deleteme = 0;
2351
2352         obj = yaffs_inode_to_obj(inode);
2353
2354         yaffs_trace(YAFFS_TRACE_OS,
2355                 "yaffs_evict_inode: ino %d, count %d %s",
2356                 (int)inode->i_ino, atomic_read(&inode->i_count),
2357                 obj ? "object exists" : "null object");
2358
2359         if (!inode->i_nlink && !is_bad_inode(inode))
2360                 deleteme = 1;
2361         truncate_inode_pages(&inode->i_data, 0);
2362         Y_CLEAR_INODE(inode);
2363
2364         if (deleteme && obj) {
2365                 dev = obj->my_dev;
2366                 yaffs_gross_lock(dev);
2367                 yaffs_del_obj(obj);
2368                 yaffs_gross_unlock(dev);
2369         }
2370         if (obj) {
2371                 dev = obj->my_dev;
2372                 yaffs_gross_lock(dev);
2373                 yaffs_unstitch_obj(inode, obj);
2374                 yaffs_gross_unlock(dev);
2375         }
2376 }
2377 #else
2378
2379 /* clear is called to tell the fs to release any per-inode data it holds.
2380  * The object might still exist on disk and is just being thrown out of the cache
2381  * or else the object has actually been deleted and we're being called via
2382  * the chain
2383  *   yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode()
2384  */
2385
2386 static void yaffs_clear_inode(struct inode *inode)
2387 {
2388         struct yaffs_obj *obj;
2389         struct yaffs_dev *dev;
2390
2391         obj = yaffs_inode_to_obj(inode);
2392
2393         yaffs_trace(YAFFS_TRACE_OS,
2394                 "yaffs_clear_inode: ino %d, count %d %s",
2395                 (int)inode->i_ino, atomic_read(&inode->i_count),
2396                 obj ? "object exists" : "null object");
2397
2398         if (obj) {
2399                 dev = obj->my_dev;
2400                 yaffs_gross_lock(dev);
2401                 yaffs_unstitch_obj(inode, obj);
2402                 yaffs_gross_unlock(dev);
2403         }
2404
2405 }
2406
2407 /* delete is called when the link count is zero and the inode
2408  * is put (ie. nobody wants to know about it anymore, time to
2409  * delete the file).
2410  * NB Must call clear_inode()
2411  */
2412 static void yaffs_delete_inode(struct inode *inode)
2413 {
2414         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
2415         struct yaffs_dev *dev;
2416
2417         yaffs_trace(YAFFS_TRACE_OS,
2418                 "yaffs_delete_inode: ino %d, count %d %s",
2419                 (int)inode->i_ino, atomic_read(&inode->i_count),
2420                 obj ? "object exists" : "null object");
2421
2422         if (obj) {
2423                 dev = obj->my_dev;
2424                 yaffs_gross_lock(dev);
2425                 yaffs_del_obj(obj);
2426                 yaffs_gross_unlock(dev);
2427         }
2428 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
2429         truncate_inode_pages(&inode->i_data, 0);
2430 #endif
2431         clear_inode(inode);
2432 }
2433 #endif
2434
2435
2436
2437
2438 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2439 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
2440 {
2441         struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
2442         struct super_block *sb = dentry->d_sb;
2443 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2444 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
2445 {
2446         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2447 #else
2448 static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
2449 {
2450         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2451 #endif
2452
2453         yaffs_trace(YAFFS_TRACE_OS, "yaffs_statfs");
2454
2455         yaffs_gross_lock(dev);
2456
2457         buf->f_type = YAFFS_MAGIC;
2458         buf->f_bsize = sb->s_blocksize;
2459         buf->f_namelen = 255;
2460
2461         if (dev->data_bytes_per_chunk & (dev->data_bytes_per_chunk - 1)) {
2462                 /* Do this if chunk size is not a power of 2 */
2463
2464                 uint64_t bytes_in_dev;
2465                 uint64_t bytes_free;
2466
2467                 bytes_in_dev =
2468                     ((uint64_t)
2469                      ((dev->param.end_block - dev->param.start_block +
2470                        1))) * ((uint64_t) (dev->param.chunks_per_block *
2471                                            dev->data_bytes_per_chunk));
2472
2473                 do_div(bytes_in_dev, sb->s_blocksize);  /* bytes_in_dev becomes the number of blocks */
2474                 buf->f_blocks = bytes_in_dev;
2475
2476                 bytes_free = ((uint64_t) (yaffs_get_n_free_chunks(dev))) *
2477                     ((uint64_t) (dev->data_bytes_per_chunk));
2478
2479                 do_div(bytes_free, sb->s_blocksize);
2480
2481                 buf->f_bfree = bytes_free;
2482
2483         } else if (sb->s_blocksize > dev->data_bytes_per_chunk) {
2484
2485                 buf->f_blocks =
2486                     (dev->param.end_block - dev->param.start_block + 1) *
2487                     dev->param.chunks_per_block /
2488                     (sb->s_blocksize / dev->data_bytes_per_chunk);
2489                 buf->f_bfree =
2490                     yaffs_get_n_free_chunks(dev) /
2491                     (sb->s_blocksize / dev->data_bytes_per_chunk);
2492         } else {
2493                 buf->f_blocks =
2494                     (dev->param.end_block - dev->param.start_block + 1) *
2495                     dev->param.chunks_per_block *
2496                     (dev->data_bytes_per_chunk / sb->s_blocksize);
2497
2498                 buf->f_bfree =
2499                     yaffs_get_n_free_chunks(dev) *
2500                     (dev->data_bytes_per_chunk / sb->s_blocksize);
2501         }
2502
2503         buf->f_files = 0;
2504         buf->f_ffree = 0;
2505         buf->f_bavail = buf->f_bfree;
2506
2507         yaffs_gross_unlock(dev);
2508         return 0;
2509 }
2510
2511
2512
2513 static int yaffs_do_sync_fs(struct super_block *sb, int request_checkpoint)
2514 {
2515
2516         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2517         unsigned int oneshot_checkpoint = (yaffs_auto_checkpoint & 4);
2518         unsigned gc_urgent = yaffs_bg_gc_urgency(dev);
2519         int do_checkpoint;
2520         int dirty = yaffs_check_super_dirty(dev);
2521
2522         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
2523                 "yaffs_do_sync_fs: gc-urgency %d %s %s%s",
2524                 gc_urgent,
2525                 dirty ? "dirty" : "clean",
2526                 request_checkpoint ? "checkpoint requested" : "no checkpoint",
2527                 oneshot_checkpoint ? " one-shot" : "");
2528
2529         yaffs_gross_lock(dev);
2530         do_checkpoint = ((request_checkpoint && !gc_urgent) ||
2531                          oneshot_checkpoint) && !dev->is_checkpointed;
2532
2533         if (dirty || do_checkpoint) {
2534                 yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint);
2535                 yaffs_clear_super_dirty(dev);
2536                 if (oneshot_checkpoint)
2537                         yaffs_auto_checkpoint &= ~4;
2538         }
2539         yaffs_gross_unlock(dev);
2540
2541         return 0;
2542 }
2543
2544
2545 #ifdef YAFFS_HAS_WRITE_SUPER
2546 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2547 static void yaffs_write_super(struct super_block *sb)
2548 #else
2549 static int yaffs_write_super(struct super_block *sb)
2550 #endif
2551 {
2552         unsigned request_checkpoint = (yaffs_auto_checkpoint >= 2);
2553
2554         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
2555                 "yaffs_write_super %s",
2556                 request_checkpoint ? " checkpt" : "");
2557
2558         yaffs_do_sync_fs(sb, request_checkpoint);
2559
2560 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
2561         return 0;
2562 #endif
2563 }
2564 #endif
2565
2566 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2567 static int yaffs_sync_fs(struct super_block *sb, int wait)
2568 #else
2569 static int yaffs_sync_fs(struct super_block *sb)
2570 #endif
2571 {
2572         unsigned request_checkpoint = (yaffs_auto_checkpoint >= 1);
2573
2574         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
2575                 "yaffs_sync_fs%s", request_checkpoint ? " checkpt" : "");
2576
2577         yaffs_do_sync_fs(sb, request_checkpoint);
2578
2579         return 0;
2580 }
2581
2582 /* the function only is used to change dev->read_only when this file system
2583  * is remounted.
2584  */
2585 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
2586 {
2587         int read_only = 0;
2588         struct mtd_info *mtd;
2589         struct yaffs_dev *dev = 0;
2590
2591         /* Get the device */
2592         mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
2593         if (!mtd) {
2594                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2595                         "MTD device #%u doesn't appear to exist",
2596                         MINOR(sb->s_dev));
2597                 return 1;
2598         }
2599
2600         /* Check it's NAND */
2601         if (mtd->type != MTD_NANDFLASH) {
2602                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2603                         "MTD device is not NAND it's type %d",
2604                         mtd->type);
2605                 return 1;
2606         }
2607
2608         read_only = ((*flags & MS_RDONLY) != 0);
2609         if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
2610                 read_only = 1;
2611                 printk(KERN_INFO
2612                         "yaffs: mtd is read only, setting superblock read only");
2613                 *flags |= MS_RDONLY;
2614         }
2615
2616         dev = sb->s_fs_info;
2617         dev->read_only = read_only;
2618
2619         return 0;
2620 }
2621
2622 static const struct super_operations yaffs_super_ops = {
2623         .statfs = yaffs_statfs,
2624
2625 #ifndef YAFFS_USE_OWN_IGET
2626         .read_inode = yaffs_read_inode,
2627 #endif
2628 #ifdef YAFFS_HAS_PUT_INODE
2629         .put_inode = yaffs_put_inode,
2630 #endif
2631         .put_super = yaffs_put_super,
2632 #ifdef YAFFS_HAS_EVICT_INODE
2633         .evict_inode = yaffs_evict_inode,
2634 #else
2635         .delete_inode = yaffs_delete_inode,
2636         .clear_inode = yaffs_clear_inode,
2637 #endif
2638         .sync_fs = yaffs_sync_fs,
2639 #ifdef YAFFS_HAS_WRITE_SUPER
2640         .write_super = yaffs_write_super,
2641 #endif
2642         .remount_fs = yaffs_remount_fs,
2643 };
2644
2645 struct yaffs_options {
2646         int inband_tags;
2647         int skip_checkpoint_read;
2648         int skip_checkpoint_write;
2649         int no_cache;
2650         int tags_ecc_on;
2651         int tags_ecc_overridden;
2652         int lazy_loading_enabled;
2653         int lazy_loading_overridden;
2654         int empty_lost_and_found;
2655         int empty_lost_and_found_overridden;
2656         int disable_summary;
2657 };
2658
2659 #define MAX_OPT_LEN 30
2660 static int yaffs_parse_options(struct yaffs_options *options,
2661                                const char *options_str)
2662 {
2663         char cur_opt[MAX_OPT_LEN + 1];
2664         int p;
2665         int error = 0;
2666
2667         /* Parse through the options which is a comma seperated list */
2668
2669         while (options_str && *options_str && !error) {
2670                 memset(cur_opt, 0, MAX_OPT_LEN + 1);
2671                 p = 0;
2672
2673                 while (*options_str == ',')
2674                         options_str++;
2675
2676                 while (*options_str && *options_str != ',') {
2677                         if (p < MAX_OPT_LEN) {
2678                                 cur_opt[p] = *options_str;
2679                                 p++;
2680                         }
2681                         options_str++;
2682                 }
2683
2684                 if (!strcmp(cur_opt, "inband-tags")) {
2685                         options->inband_tags = 1;
2686                 } else if (!strcmp(cur_opt, "tags-ecc-off")) {
2687                         options->tags_ecc_on = 0;
2688                         options->tags_ecc_overridden = 1;
2689                 } else if (!strcmp(cur_opt, "tags-ecc-on")) {
2690                         options->tags_ecc_on = 1;
2691                         options->tags_ecc_overridden = 1;
2692                 } else if (!strcmp(cur_opt, "lazy-loading-off")) {
2693                         options->lazy_loading_enabled = 0;
2694                         options->lazy_loading_overridden = 1;
2695                 } else if (!strcmp(cur_opt, "lazy-loading-on")) {
2696                         options->lazy_loading_enabled = 1;
2697                         options->lazy_loading_overridden = 1;
2698                 } else if (!strcmp(cur_opt, "disable-summary")) {
2699                         options->disable_summary = 1;
2700                 } else if (!strcmp(cur_opt, "empty-lost-and-found-off")) {
2701                         options->empty_lost_and_found = 0;
2702                         options->empty_lost_and_found_overridden = 1;
2703                 } else if (!strcmp(cur_opt, "empty-lost-and-found-on")) {
2704                         options->empty_lost_and_found = 1;
2705                         options->empty_lost_and_found_overridden = 1;
2706                 } else if (!strcmp(cur_opt, "no-cache")) {
2707                         options->no_cache = 1;
2708                 } else if (!strcmp(cur_opt, "no-checkpoint-read")) {
2709                         options->skip_checkpoint_read = 1;
2710                 } else if (!strcmp(cur_opt, "no-checkpoint-write")) {
2711                         options->skip_checkpoint_write = 1;
2712                 } else if (!strcmp(cur_opt, "no-checkpoint")) {
2713                         options->skip_checkpoint_read = 1;
2714                         options->skip_checkpoint_write = 1;
2715                 } else {
2716                         printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
2717                                cur_opt);
2718                         error = 1;
2719                 }
2720         }
2721
2722         return error;
2723 }
2724
2725
2726 static struct dentry *yaffs_make_root(struct inode *inode)
2727 {
2728 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
2729         struct dentry *root = d_alloc_root(inode);
2730
2731         if (!root)
2732                 iput(inode);
2733
2734         return root;
2735 #else
2736         return d_make_root(inode);
2737 #endif
2738 }
2739
2740
2741
2742
2743 static struct super_block *yaffs_internal_read_super(int yaffs_version,
2744                                                      struct super_block *sb,
2745                                                      void *data, int silent)
2746 {
2747         int n_blocks;
2748         struct inode *inode = NULL;
2749         struct dentry *root;
2750         struct yaffs_dev *dev = 0;
2751         char devname_buf[BDEVNAME_SIZE + 1];
2752         struct mtd_info *mtd;
2753         int err;
2754         char *data_str = (char *)data;
2755         struct yaffs_linux_context *context = NULL;
2756         struct yaffs_param *param;
2757
2758         int read_only = 0;
2759         int inband_tags = 0;
2760
2761         struct yaffs_options options;
2762
2763         unsigned mount_id;
2764         int found;
2765         struct yaffs_linux_context *context_iterator;
2766         struct list_head *l;
2767
2768         if (!sb) {
2769                 printk(KERN_INFO "yaffs: sb is NULL\n");
2770                 return NULL;
2771         }
2772
2773         sb->s_magic = YAFFS_MAGIC;
2774         sb->s_op = &yaffs_super_ops;
2775         sb->s_flags |= MS_NOATIME;
2776
2777         read_only = ((sb->s_flags & MS_RDONLY) != 0);
2778
2779 #ifdef YAFFS_COMPILE_EXPORTFS
2780         sb->s_export_op = &yaffs_export_ops;
2781 #endif
2782
2783         if (!sb->s_dev)
2784                 printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
2785         else if (!yaffs_devname(sb, devname_buf))
2786                 printk(KERN_INFO "yaffs: devname is NULL\n");
2787         else
2788                 printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
2789                        sb->s_dev,
2790                        yaffs_devname(sb, devname_buf), read_only ? "ro" : "rw");
2791
2792         if (!data_str)
2793                 data_str = "";
2794
2795         printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
2796
2797         memset(&options, 0, sizeof(options));
2798
2799         if (yaffs_parse_options(&options, data_str)) {
2800                 /* Option parsing failed */
2801                 return NULL;
2802         }
2803
2804         sb->s_blocksize = PAGE_CACHE_SIZE;
2805         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
2806
2807         yaffs_trace(YAFFS_TRACE_OS,
2808                 "yaffs_read_super: Using yaffs%d", yaffs_version);
2809         yaffs_trace(YAFFS_TRACE_OS,
2810                 "yaffs_read_super: block size %d", (int)(sb->s_blocksize));
2811
2812         yaffs_trace(YAFFS_TRACE_ALWAYS,
2813                 "yaffs: Attempting MTD mount of %u.%u,\"%s\"",
2814                 MAJOR(sb->s_dev), MINOR(sb->s_dev),
2815                 yaffs_devname(sb, devname_buf));
2816
2817         /* Get the device */
2818         mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
2819         if (IS_ERR(mtd)) {
2820                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2821                         "yaffs: MTD device %u either not valid or unavailable",
2822                         MINOR(sb->s_dev));
2823                 return NULL;
2824         }
2825
2826         if (yaffs_auto_select && yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) {
2827                 yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs2");
2828                 yaffs_version = 2;
2829         }
2830
2831         /* Added NCB 26/5/2006 for completeness */
2832         if (yaffs_version == 2 && !options.inband_tags
2833             && WRITE_SIZE(mtd) == 512) {
2834                 yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1");
2835                 yaffs_version = 1;
2836         }
2837
2838         if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) ||
2839             options.inband_tags)
2840                 inband_tags = 1;
2841
2842         if(yaffs_verify_mtd(mtd, yaffs_version, inband_tags) < 0)
2843                 return NULL;
2844
2845         /* OK, so if we got here, we have an MTD that's NAND and looks
2846          * like it has the right capabilities
2847          * Set the struct yaffs_dev up for mtd
2848          */
2849
2850         if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
2851                 read_only = 1;
2852                 printk(KERN_INFO
2853                        "yaffs: mtd is read only, setting superblock read only\n"
2854                 );
2855                 sb->s_flags |= MS_RDONLY;
2856         }
2857
2858         dev = kmalloc(sizeof(struct yaffs_dev), GFP_KERNEL);
2859         context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
2860
2861         if (!dev || !context) {
2862                 kfree(dev);
2863                 kfree(context);
2864                 dev = NULL;
2865                 context = NULL;
2866
2867                 /* Deep shit could not allocate device structure */
2868                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2869                         "yaffs_read_super: Failed trying to allocate struct yaffs_dev."
2870                 );
2871                 return NULL;
2872         }
2873         memset(dev, 0, sizeof(struct yaffs_dev));
2874         param = &(dev->param);
2875
2876         memset(context, 0, sizeof(struct yaffs_linux_context));
2877         dev->os_context = context;
2878         INIT_LIST_HEAD(&(context->context_list));
2879         context->dev = dev;
2880         context->super = sb;
2881
2882         dev->read_only = read_only;
2883
2884 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2885         sb->s_fs_info = dev;
2886 #else
2887         sb->u.generic_sbp = dev;
2888 #endif
2889
2890
2891         dev->driver_context = mtd;
2892         param->name = mtd->name;
2893
2894         /* Set up the memory size parameters.... */
2895
2896
2897         param->n_reserved_blocks = 5;
2898         param->n_caches = (options.no_cache) ? 0 : 10;
2899         param->inband_tags = inband_tags;
2900
2901         param->enable_xattr = 1;
2902         if (options.lazy_loading_overridden)
2903                 param->disable_lazy_load = !options.lazy_loading_enabled;
2904
2905         param->defered_dir_update = 1;
2906
2907         if (options.tags_ecc_overridden)
2908                 param->no_tags_ecc = !options.tags_ecc_on;
2909
2910         param->empty_lost_n_found = 1;
2911         param->refresh_period = 500;
2912         param->disable_summary = options.disable_summary;
2913
2914
2915 #ifdef CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING
2916         param->disable_bad_block_marking  = 1;
2917 #endif
2918         if (options.empty_lost_and_found_overridden)
2919                 param->empty_lost_n_found = options.empty_lost_and_found;
2920
2921         /* ... and the functions. */
2922         if (yaffs_version == 2) {
2923                 param->is_yaffs2 = 1;
2924 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2925                 param->total_bytes_per_chunk = mtd->writesize;
2926                 param->chunks_per_block = mtd->erasesize / mtd->writesize;
2927 #else
2928                 param->total_bytes_per_chunk = mtd->oobblock;
2929                 param->chunks_per_block = mtd->erasesize / mtd->oobblock;
2930 #endif
2931                 n_blocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
2932
2933                 param->start_block = 0;
2934                 param->end_block = n_blocks - 1;
2935         } else {
2936                 param->is_yaffs2 = 0;
2937                 n_blocks = YCALCBLOCKS(mtd->size,
2938                              YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
2939
2940                 param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
2941                 param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
2942         }
2943
2944         param->start_block = 0;
2945         param->end_block = n_blocks - 1;
2946
2947         yaffs_mtd_drv_install(dev);
2948
2949         param->sb_dirty_fn = yaffs_set_super_dirty;
2950         param->gc_control_fn = yaffs_gc_control_callback;
2951
2952         yaffs_dev_to_lc(dev)->super = sb;
2953
2954         param->use_nand_ecc = 1;
2955
2956         param->skip_checkpt_rd = options.skip_checkpoint_read;
2957         param->skip_checkpt_wr = options.skip_checkpoint_write;
2958
2959         mutex_lock(&yaffs_context_lock);
2960         /* Get a mount id */
2961         found = 0;
2962         for (mount_id = 0; !found; mount_id++) {
2963                 found = 1;
2964                 list_for_each(l, &yaffs_context_list) {
2965                         context_iterator =
2966                             list_entry(l, struct yaffs_linux_context,
2967                                        context_list);
2968                         if (context_iterator->mount_id == mount_id)
2969                                 found = 0;
2970                 }
2971         }
2972         context->mount_id = mount_id;
2973
2974         list_add_tail(&(yaffs_dev_to_lc(dev)->context_list),
2975                       &yaffs_context_list);
2976         mutex_unlock(&yaffs_context_lock);
2977
2978         /* Directory search handling... */
2979         INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->search_contexts));
2980         param->remove_obj_fn = yaffs_remove_obj_callback;
2981
2982         mutex_init(&(yaffs_dev_to_lc(dev)->gross_lock));
2983
2984         yaffs_gross_lock(dev);
2985
2986         err = yaffs_guts_initialise(dev);
2987
2988         yaffs_trace(YAFFS_TRACE_OS,
2989                 "yaffs_read_super: guts initialised %s",
2990                 (err == YAFFS_OK) ? "OK" : "FAILED");
2991
2992         if (err == YAFFS_OK)
2993                 yaffs_bg_start(dev);
2994
2995         if (!context->bg_thread)
2996                 param->defered_dir_update = 0;
2997
2998         sb->s_maxbytes = yaffs_max_file_size(dev);
2999
3000         /* Release lock before yaffs_get_inode() */
3001         yaffs_gross_unlock(dev);
3002
3003         /* Create root inode */
3004         if (err == YAFFS_OK)
3005                 inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_root(dev));
3006
3007         if (!inode)
3008                 return NULL;
3009
3010         inode->i_op = &yaffs_dir_inode_operations;
3011         inode->i_fop = &yaffs_dir_operations;
3012
3013         yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode");
3014
3015         root = yaffs_make_root(inode);
3016
3017         if (!root)
3018                 return NULL;
3019
3020         sb->s_root = root;
3021         if(!dev->is_checkpointed)
3022                 yaffs_set_super_dirty(dev);
3023
3024         yaffs_trace(YAFFS_TRACE_ALWAYS,
3025                 "yaffs_read_super: is_checkpointed %d",
3026                 dev->is_checkpointed);
3027
3028         yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: done");
3029         return sb;
3030 }
3031
3032 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3033 static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
3034                                          int silent)
3035 {
3036         return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
3037 }
3038
3039 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3040 static struct dentry *yaffs_mount(struct file_system_type *fs_type, int flags,
3041         const char *dev_name, void *data)
3042 {
3043     return mount_bdev(fs_type, flags, dev_name, data, yaffs_internal_read_super_mtd);
3044 }
3045 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3046 static int yaffs_read_super(struct file_system_type *fs,
3047                             int flags, const char *dev_name,
3048                             void *data, struct vfsmount *mnt)
3049 {
3050
3051         return get_sb_bdev(fs, flags, dev_name, data,
3052                            yaffs_internal_read_super_mtd, mnt);
3053 }
3054 #else
3055 static struct super_block *yaffs_read_super(struct file_system_type *fs,
3056                                             int flags, const char *dev_name,
3057                                             void *data)
3058 {
3059
3060         return get_sb_bdev(fs, flags, dev_name, data,
3061                            yaffs_internal_read_super_mtd);
3062 }
3063 #endif
3064
3065 static struct file_system_type yaffs_fs_type = {
3066         .owner = THIS_MODULE,
3067         .name = "yaffs",
3068 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3069         .mount = yaffs_mount,
3070 #else
3071         .get_sb = yaffs_read_super,
3072 #endif
3073         .kill_sb = kill_block_super,
3074         .fs_flags = FS_REQUIRES_DEV,
3075 };
3076 #else
3077 static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
3078                                             int silent)
3079 {
3080         return yaffs_internal_read_super(1, sb, data, silent);
3081 }
3082
3083 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
3084                       FS_REQUIRES_DEV);
3085 #endif
3086
3087
3088 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3089 static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
3090                                           int silent)
3091 {
3092         return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
3093 }
3094
3095 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3096 static struct dentry *yaffs2_mount(struct file_system_type *fs_type, int flags,
3097         const char *dev_name, void *data)
3098 {
3099         return mount_bdev(fs_type, flags, dev_name, data, yaffs2_internal_read_super_mtd);
3100 }
3101 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3102 static int yaffs2_read_super(struct file_system_type *fs,
3103                              int flags, const char *dev_name, void *data,
3104                              struct vfsmount *mnt)
3105 {
3106         return get_sb_bdev(fs, flags, dev_name, data,
3107                            yaffs2_internal_read_super_mtd, mnt);
3108 }
3109 #else
3110 static struct super_block *yaffs2_read_super(struct file_system_type *fs,
3111                                              int flags, const char *dev_name,
3112                                              void *data)
3113 {
3114
3115         return get_sb_bdev(fs, flags, dev_name, data,
3116                            yaffs2_internal_read_super_mtd);
3117 }
3118 #endif
3119
3120 static struct file_system_type yaffs2_fs_type = {
3121         .owner = THIS_MODULE,
3122         .name = "yaffs2",
3123 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3124         .mount = yaffs2_mount,
3125 #else
3126         .get_sb = yaffs2_read_super,
3127 #endif
3128         .kill_sb = kill_block_super,
3129         .fs_flags = FS_REQUIRES_DEV,
3130 };
3131 #else
3132 static struct super_block *yaffs2_read_super(struct super_block *sb,
3133                                              void *data, int silent)
3134 {
3135         return yaffs_internal_read_super(2, sb, data, silent);
3136 }
3137
3138 static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
3139                       FS_REQUIRES_DEV);
3140 #endif
3141
3142
3143 static struct proc_dir_entry *my_proc_entry;
3144
3145 static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
3146 {
3147         struct yaffs_param *param = &dev->param;
3148         int bs[10];
3149
3150         yaffs_count_blocks_by_state(dev,bs);
3151
3152         buf += sprintf(buf, "start_block.......... %d\n", param->start_block);
3153         buf += sprintf(buf, "end_block............ %d\n", param->end_block);
3154         buf += sprintf(buf, "total_bytes_per_chunk %d\n",
3155                                 param->total_bytes_per_chunk);
3156         buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc);
3157         buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
3158         buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2);
3159         buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags);
3160         buf += sprintf(buf, "empty_lost_n_found... %d\n",
3161                                 param->empty_lost_n_found);
3162         buf += sprintf(buf, "disable_lazy_load.... %d\n",
3163                                 param->disable_lazy_load);
3164         buf += sprintf(buf, "disable_bad_block_mrk %d\n",
3165                                 param->disable_bad_block_marking);
3166         buf += sprintf(buf, "refresh_period....... %d\n",
3167                                 param->refresh_period);
3168         buf += sprintf(buf, "n_caches............. %d\n", param->n_caches);
3169         buf += sprintf(buf, "n_reserved_blocks.... %d\n",
3170                                 param->n_reserved_blocks);
3171         buf += sprintf(buf, "always_check_erased.. %d\n",
3172                                 param->always_check_erased);
3173         buf += sprintf(buf, "\n");
3174         buf += sprintf(buf, "block count by state\n");
3175         buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
3176                                 bs[0], bs[1], bs[2], bs[3], bs[4]);
3177         buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
3178                                 bs[5], bs[6], bs[7], bs[8], bs[9]);
3179
3180         return buf;
3181 }
3182
3183 static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
3184 {
3185         buf += sprintf(buf, "max file size....... %lld\n",
3186                                 (long long) yaffs_max_file_size(dev));
3187         buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
3188                                 dev->data_bytes_per_chunk);
3189         buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
3190         buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
3191         buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
3192         buf += sprintf(buf, "blocks_in_checkpt.... %d\n",
3193                                 dev->blocks_in_checkpt);
3194         buf += sprintf(buf, "\n");
3195         buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
3196         buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
3197         buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
3198         buf += sprintf(buf, "\n");
3199         buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
3200         buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
3201         buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
3202         buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
3203         buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
3204         buf += sprintf(buf, "passive_gc_count..... %u\n",
3205                                 dev->passive_gc_count);
3206         buf += sprintf(buf, "oldest_dirty_gc_count %u\n",
3207                                 dev->oldest_dirty_gc_count);
3208         buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
3209         buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
3210         buf += sprintf(buf, "n_retried_writes..... %u\n",
3211                                 dev->n_retried_writes);
3212         buf += sprintf(buf, "n_retired_blocks..... %u\n",
3213                                 dev->n_retired_blocks);
3214         buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
3215         buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
3216         buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n",
3217                                 dev->n_tags_ecc_fixed);
3218         buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n",
3219                                 dev->n_tags_ecc_unfixed);
3220         buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
3221         buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
3222         buf += sprintf(buf, "n_unlinked_files..... %u\n",
3223                                 dev->n_unlinked_files);
3224         buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
3225         buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
3226         buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used);
3227         buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used);
3228
3229         return buf;
3230 }
3231
3232 static int yaffs_proc_read(char *page,
3233                            char **start,
3234                            off_t offset, int count, int *eof, void *data)
3235 {
3236         struct list_head *item;
3237         char *buf = page;
3238         int step = offset;
3239         int n = 0;
3240
3241         /* Get proc_file_read() to step 'offset' by one on each sucessive call.
3242          * We use 'offset' (*ppos) to indicate where we are in dev_list.
3243          * This also assumes the user has posted a read buffer large
3244          * enough to hold the complete output; but that's life in /proc.
3245          */
3246
3247         *(int *)start = 1;
3248
3249         /* Print header first */
3250         if (step == 0)
3251                 buf +=
3252                     sprintf(buf,
3253                             "Multi-version YAFFS built:" __DATE__ " " __TIME__
3254                             "\n");
3255         else if (step == 1)
3256                 buf += sprintf(buf, "\n");
3257         else {
3258                 step -= 2;
3259
3260                 mutex_lock(&yaffs_context_lock);
3261
3262                 /* Locate and print the Nth entry.  Order N-squared but N is small. */
3263                 list_for_each(item, &yaffs_context_list) {
3264                         struct yaffs_linux_context *dc =
3265                             list_entry(item, struct yaffs_linux_context,
3266                                        context_list);
3267                         struct yaffs_dev *dev = dc->dev;
3268
3269                         if (n < (step & ~1)) {
3270                                 n += 2;
3271                                 continue;
3272                         }
3273                         if ((step & 1) == 0) {
3274                                 buf +=
3275                                     sprintf(buf, "\nDevice %d \"%s\"\n", n,
3276                                             dev->param.name);
3277                                 buf = yaffs_dump_dev_part0(buf, dev);
3278                         } else {
3279                                 buf = yaffs_dump_dev_part1(buf, dev);
3280                         }
3281
3282                         break;
3283                 }
3284                 mutex_unlock(&yaffs_context_lock);
3285         }
3286
3287         return buf - page < count ? buf - page : count;
3288 }
3289
3290 /**
3291  * Set the verbosity of the warnings and error messages.
3292  *
3293  * Note that the names can only be a..z or _ with the current code.
3294  */
3295
3296 static struct {
3297         char *mask_name;
3298         unsigned mask_bitfield;
3299 } mask_flags[] = {
3300         {"allocate", YAFFS_TRACE_ALLOCATE},
3301         {"always", YAFFS_TRACE_ALWAYS},
3302         {"background", YAFFS_TRACE_BACKGROUND},
3303         {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
3304         {"buffers", YAFFS_TRACE_BUFFERS},
3305         {"bug", YAFFS_TRACE_BUG},
3306         {"checkpt", YAFFS_TRACE_CHECKPOINT},
3307         {"deletion", YAFFS_TRACE_DELETION},
3308         {"erase", YAFFS_TRACE_ERASE},
3309         {"error", YAFFS_TRACE_ERROR},
3310         {"gc_detail", YAFFS_TRACE_GC_DETAIL},
3311         {"gc", YAFFS_TRACE_GC},
3312         {"lock", YAFFS_TRACE_LOCK},
3313         {"mtd", YAFFS_TRACE_MTD},
3314         {"nandaccess", YAFFS_TRACE_NANDACCESS},
3315         {"os", YAFFS_TRACE_OS},
3316         {"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
3317         {"scan", YAFFS_TRACE_SCAN},
3318         {"mount", YAFFS_TRACE_MOUNT},
3319         {"tracing", YAFFS_TRACE_TRACING},
3320         {"sync", YAFFS_TRACE_SYNC},
3321         {"write", YAFFS_TRACE_WRITE},
3322         {"verify", YAFFS_TRACE_VERIFY},
3323         {"verify_nand", YAFFS_TRACE_VERIFY_NAND},
3324         {"verify_full", YAFFS_TRACE_VERIFY_FULL},
3325         {"verify_all", YAFFS_TRACE_VERIFY_ALL},
3326         {"all", 0xffffffff},
3327         {"none", 0},
3328         {NULL, 0},
3329 };
3330
3331 #define MAX_MASK_NAME_LENGTH 40
3332 static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
3333                                           unsigned long count)
3334 {
3335         unsigned rg = 0, mask_bitfield;
3336         char *end;
3337         char *mask_name;
3338         const char *x;
3339         char substring[MAX_MASK_NAME_LENGTH + 1];
3340         int i;
3341         int done = 0;
3342         int add, len = 0;
3343         int pos = 0;
3344
3345         rg = yaffs_trace_mask;
3346
3347         while (!done && (pos < count)) {
3348                 done = 1;
3349                 while ((pos < count) && isspace(buf[pos]))
3350                         pos++;
3351
3352                 switch (buf[pos]) {
3353                 case '+':
3354                 case '-':
3355                 case '=':
3356                         add = buf[pos];
3357                         pos++;
3358                         break;
3359
3360                 default:
3361                         add = ' ';
3362                         break;
3363                 }
3364                 mask_name = NULL;
3365
3366                 mask_bitfield = simple_strtoul(buf + pos, &end, 0);
3367
3368                 if (end > buf + pos) {
3369                         mask_name = "numeral";
3370                         len = end - (buf + pos);
3371                         pos += len;
3372                         done = 0;
3373                 } else {
3374                         for (x = buf + pos, i = 0;
3375                              (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
3376                              i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
3377                                 substring[i] = *x;
3378                         substring[i] = '\0';
3379
3380                         for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3381                                 if (strcmp(substring, mask_flags[i].mask_name)
3382                                     == 0) {
3383                                         mask_name = mask_flags[i].mask_name;
3384                                         mask_bitfield =
3385                                             mask_flags[i].mask_bitfield;
3386                                         done = 0;
3387                                         break;
3388                                 }
3389                         }
3390                 }
3391
3392                 if (mask_name != NULL) {
3393                         done = 0;
3394                         switch (add) {
3395                         case '-':
3396                                 rg &= ~mask_bitfield;
3397                                 break;
3398                         case '+':
3399                                 rg |= mask_bitfield;
3400                                 break;
3401                         case '=':
3402                                 rg = mask_bitfield;
3403                                 break;
3404                         default:
3405                                 rg |= mask_bitfield;
3406                                 break;
3407                         }
3408                 }
3409         }
3410
3411         yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS;
3412
3413         printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask);
3414
3415         if (rg & YAFFS_TRACE_ALWAYS) {
3416                 for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3417                         char flag;
3418                         flag = ((rg & mask_flags[i].mask_bitfield) ==
3419                                 mask_flags[i].mask_bitfield) ? '+' : '-';
3420                         printk(KERN_DEBUG "%c%s\n", flag,
3421                                mask_flags[i].mask_name);
3422                 }
3423         }
3424
3425         return count;
3426 }
3427
3428 /* Debug strings are of the form:
3429  * .bnnn         print info on block n
3430  * .cobjn,chunkn print nand chunk id for objn:chunkn
3431  */
3432
3433 static int yaffs_proc_debug_write(struct file *file, const char *buf,
3434                                           unsigned long count)
3435 {
3436
3437         char str[100];
3438         char *p0;
3439         char *p1;
3440         long p1_val;
3441         long p0_val;
3442         char cmd;
3443         struct list_head *item;
3444
3445         memset(str, 0, sizeof(str));
3446         memcpy(str, buf, min((size_t)count, sizeof(str) -1));
3447
3448         cmd = str[1];
3449
3450         p0 = str + 2;
3451
3452         p1 = p0;
3453
3454         while (*p1 && *p1 != ',') {
3455                 p1++;
3456         }
3457         *p1 = '\0';
3458         p1++;
3459
3460         p0_val = simple_strtol(p0, NULL, 0);
3461         p1_val = simple_strtol(p1, NULL, 0);
3462
3463
3464         mutex_lock(&yaffs_context_lock);
3465
3466         /* Locate and print the Nth entry.  Order N-squared but N is small. */
3467         list_for_each(item, &yaffs_context_list) {
3468                 struct yaffs_linux_context *dc =
3469                     list_entry(item, struct yaffs_linux_context,
3470                                context_list);
3471                 struct yaffs_dev *dev = dc->dev;
3472
3473                 if (cmd == 'b') {
3474                         struct yaffs_block_info *bi;
3475
3476                         bi = yaffs_get_block_info(dev,p0_val);
3477
3478                         if(bi) {
3479                                 printk("Block %d: state %d, retire %d, use %d, seq %d\n",
3480                                         (int)p0_val, bi->block_state,
3481                                         bi->needs_retiring, bi->pages_in_use,
3482                                         bi->seq_number);
3483                         }
3484                 } else if (cmd == 'c') {
3485                         struct yaffs_obj *obj;
3486                         int nand_chunk;
3487
3488                         obj = yaffs_find_by_number(dev, p0_val);
3489                         if (!obj)
3490                                 printk("No obj %d\n", (int)p0_val);
3491                         else {
3492                                 if(p1_val == 0)
3493                                         nand_chunk = obj->hdr_chunk;
3494                                 else
3495                                         nand_chunk =
3496                                                 yaffs_find_chunk_in_file(obj,
3497                                                         p1_val, NULL);
3498                                 printk("Nand chunk for %d:%d is %d\n",
3499                                         (int)p0_val, (int)p1_val, nand_chunk);
3500                         }
3501                 }
3502         }
3503
3504         mutex_unlock(&yaffs_context_lock);
3505
3506         return count;
3507 }
3508
3509
3510 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
3511 static int yaffs_proc_write(struct file *file, const char *buf,
3512                             unsigned long count, void *ppos)
3513 #else
3514 static ssize_t yaffs_proc_write(struct file *file, const char __user *buf,
3515                             size_t count, loff_t *ppos)
3516 #endif
3517 {
3518         if (buf[0] == '.')
3519                 return yaffs_proc_debug_write(file, buf, count);
3520         return yaffs_proc_write_trace_options(file, buf, count);
3521 }
3522
3523 /* Stuff to handle installation of file systems */
3524 struct file_system_to_install {
3525         struct file_system_type *fst;
3526         int installed;
3527 };
3528
3529 static struct file_system_to_install fs_to_install[] = {
3530         {&yaffs_fs_type, 0},
3531         {&yaffs2_fs_type, 0},
3532         {NULL, 0}
3533 };
3534
3535
3536 #ifdef YAFFS_NEW_PROCFS
3537 static int yaffs_proc_show(struct seq_file *m, void *v)
3538 {
3539         /* FIXME: Unify in a better way? */
3540         char buffer[512];
3541         char *start;
3542         int len;
3543
3544         len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL);
3545         seq_puts(m, buffer);
3546         return 0;
3547 }
3548
3549 static int yaffs_proc_open(struct inode *inode, struct file *file)
3550 {
3551         return single_open(file, yaffs_proc_show, NULL);
3552 }
3553
3554 static struct file_operations procfs_ops = {
3555         .owner = THIS_MODULE,
3556         .open  = yaffs_proc_open,
3557         .read  = seq_read,
3558         .write = yaffs_proc_write,
3559 };
3560
3561 static int yaffs_procfs_init(void)
3562 {
3563         /* Install the proc_fs entries */
3564         my_proc_entry = proc_create("yaffs",
3565                                     S_IRUGO | S_IFREG,