yaffs-direct: Basic tests. Add lpthread flag for background gc support
[yaffs2.git] / yaffs_vfs_multi.c
1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2011 Aleph One Ltd.
5  *   for Toby Churchill Ltd and Brightstar Engineering
6  *
7  * Created by Charles Manning <charles@aleph1.co.uk>
8  * Acknowledgements:
9  * Luc van OostenRyck for numerous patches.
10  * Nick Bane for numerous patches.
11  * Nick Bane for 2.5/2.6 integration.
12  * Andras Toth for mknod rdev issue.
13  * Michael Fischer for finding the problem with inode inconsistency.
14  * Some code bodily lifted from JFFS
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License version 2 as
18  * published by the Free Software Foundation.
19  */
20
21 /*
22  *
23  * This is the file system front-end to YAFFS that hooks it up to
24  * the VFS.
25  *
26  * Special notes:
27  * >> 2.4: sb->u.generic_sbp points to the struct yaffs_dev associated with
28  *         this superblock
29  * >> 2.6: sb->s_fs_info  points to the struct yaffs_dev associated with this
30  *         superblock
31  * >> inode->u.generic_ip points to the associated struct yaffs_obj.
32  */
33
34 /*
35  * There are two variants of the VFS glue code. This variant should compile
36  * for any version of Linux.
37  */
38 #include <linux/version.h>
39
40 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10))
41 #define YAFFS_COMPILE_BACKGROUND
42 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23))
43 #define YAFFS_COMPILE_FREEZER
44 #endif
45 #endif
46
47 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
48 #define YAFFS_COMPILE_EXPORTFS
49 #endif
50
51 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
52 #define YAFFS_USE_SETATTR_COPY
53 #define YAFFS_USE_TRUNCATE_SETSIZE
54 #endif
55 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
56 #define YAFFS_HAS_EVICT_INODE
57 #endif
58
59 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
60 #define YAFFS_NEW_FOLLOW_LINK 1
61 #else
62 #define YAFFS_NEW_FOLLOW_LINK 0
63 #endif
64
65 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
66 #define YAFFS_HAS_WRITE_SUPER
67 #endif
68
69
70 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
71 #include <linux/config.h>
72 #endif
73
74 #include <linux/kernel.h>
75 #include <linux/module.h>
76 #include <linux/slab.h>
77 #include <linux/init.h>
78 #include <linux/fs.h>
79 #include <linux/proc_fs.h>
80 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
81 #include <linux/smp_lock.h>
82 #endif
83 #include <linux/pagemap.h>
84 #include <linux/mtd/mtd.h>
85 #include <linux/interrupt.h>
86 #include <linux/string.h>
87 #include <linux/ctype.h>
88
89 #if (YAFFS_NEW_FOLLOW_LINK == 1)
90 #include <linux/namei.h>
91 #endif
92
93 #ifdef YAFFS_COMPILE_EXPORTFS
94 #include <linux/exportfs.h>
95 #endif
96
97 #ifdef YAFFS_COMPILE_BACKGROUND
98 #include <linux/kthread.h>
99 #include <linux/delay.h>
100 #endif
101 #ifdef YAFFS_COMPILE_FREEZER
102 #include <linux/freezer.h>
103 #endif
104
105 #include <asm/div64.h>
106
107 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
108
109 #include <linux/statfs.h>
110
111 #define UnlockPage(p) unlock_page(p)
112 #define Page_Uptodate(page)     test_bit(PG_uptodate, &(page)->flags)
113
114 /* FIXME: use sb->s_id instead ? */
115 #define yaffs_devname(sb, buf)  bdevname(sb->s_bdev, buf)
116
117 #else
118
119 #include <linux/locks.h>
120 #define BDEVNAME_SIZE           0
121 #define yaffs_devname(sb, buf)  kdevname(sb->s_dev)
122
123 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
124 /* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */
125 #define __user
126 #endif
127
128 #endif
129
130 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
131 #define YPROC_ROOT  (&proc_root)
132 #else
133 #define YPROC_ROOT  NULL
134 #endif
135
136 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
137 #define Y_INIT_TIMER(a) init_timer(a)
138 #else
139 #define Y_INIT_TIMER(a) init_timer_on_stack(a)
140 #endif
141
142 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
143 #define YAFFS_USE_WRITE_BEGIN_END 1
144 #else
145 #define YAFFS_USE_WRITE_BEGIN_END 0
146 #endif
147
148 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
149 #define YAFFS_SUPER_HAS_DIRTY
150 #endif
151
152
153 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
154 #define set_nlink(inode, count)  do { (inode)->i_nlink = (count); } while(0)
155 #endif
156
157 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
158 static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
159 {
160         uint64_t result = partition_size;
161         do_div(result, block_size);
162         return (uint32_t) result;
163 }
164 #else
165 #define YCALCBLOCKS(s, b) ((s)/(b))
166 #endif
167
168 #include <linux/uaccess.h>
169 #include <linux/mtd/mtd.h>
170
171 #include "yportenv.h"
172 #include "yaffs_trace.h"
173 #include "yaffs_guts.h"
174 #include "yaffs_attribs.h"
175
176 #include "yaffs_linux.h"
177
178 #include "yaffs_mtdif.h"
179 #include "yaffs_packedtags2.h"
180 #include "yaffs_getblockinfo.h"
181
182 unsigned int yaffs_trace_mask =
183                 YAFFS_TRACE_BAD_BLOCKS |
184                 YAFFS_TRACE_ALWAYS |
185                 0;
186
187 unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
188 unsigned int yaffs_auto_checkpoint = 1;
189 unsigned int yaffs_gc_control = 1;
190 unsigned int yaffs_bg_enable = 1;
191 unsigned int yaffs_auto_select = 1;
192 /* Module Parameters */
193 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
194 module_param(yaffs_trace_mask, uint, 0644);
195 module_param(yaffs_wr_attempts, uint, 0644);
196 module_param(yaffs_auto_checkpoint, uint, 0644);
197 module_param(yaffs_gc_control, uint, 0644);
198 module_param(yaffs_bg_enable, uint, 0644);
199 #else
200 MODULE_PARM(yaffs_trace_mask, "i");
201 MODULE_PARM(yaffs_wr_attempts, "i");
202 MODULE_PARM(yaffs_auto_checkpoint, "i");
203 MODULE_PARM(yaffs_gc_control, "i");
204 #endif
205
206 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
207 /* use iget and read_inode */
208 #define Y_IGET(sb, inum) iget((sb), (inum))
209
210 #else
211 /* Call local equivalent */
212 #define YAFFS_USE_OWN_IGET
213 #define Y_IGET(sb, inum) yaffs_iget((sb), (inum))
214
215 #endif
216
217 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
218 #define yaffs_inode_to_obj_lv(iptr) ((iptr)->i_private)
219 #else
220 #define yaffs_inode_to_obj_lv(iptr) ((iptr)->u.generic_ip)
221 #endif
222
223 #define yaffs_inode_to_obj(iptr) \
224         ((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr)))
225 #define yaffs_dentry_to_obj(dptr) yaffs_inode_to_obj((dptr)->d_inode)
226
227 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
228 #define yaffs_super_to_dev(sb)  ((struct yaffs_dev *)sb->s_fs_info)
229 #else
230 #define yaffs_super_to_dev(sb)  ((struct yaffs_dev *)sb->u.generic_sbp)
231 #endif
232
233 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
234 #define Y_CLEAR_INODE(i) clear_inode(i)
235 #else
236 #define Y_CLEAR_INODE(i) end_writeback(i)
237 #endif
238
239 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
240 #define YAFFS_USE_DIR_ITERATE
241 #endif
242
243 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
244 #define YAFFS_NEW_PROCFS
245 #include <linux/seq_file.h>
246 #endif
247
248
249 #define update_dir_time(dir) do {\
250                         (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
251                 } while (0)
252
253 static void yaffs_fill_inode_from_obj(struct inode *inode,
254                                       struct yaffs_obj *obj);
255
256
257 static void yaffs_gross_lock(struct yaffs_dev *dev)
258 {
259         yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locking %p", current);
260         mutex_lock(&(yaffs_dev_to_lc(dev)->gross_lock));
261         yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locked %p", current);
262 }
263
264 static void yaffs_gross_unlock(struct yaffs_dev *dev)
265 {
266         yaffs_trace(YAFFS_TRACE_LOCK, "yaffs unlocking %p", current);
267         mutex_unlock(&(yaffs_dev_to_lc(dev)->gross_lock));
268 }
269
270
271 static int yaffs_readpage_nolock(struct file *f, struct page *pg)
272 {
273         /* Lifted from jffs2 */
274
275         struct yaffs_obj *obj;
276         unsigned char *pg_buf;
277         int ret;
278         loff_t pos = ((loff_t) pg->index) << PAGE_CACHE_SHIFT;
279         struct yaffs_dev *dev;
280
281         yaffs_trace(YAFFS_TRACE_OS,
282                 "yaffs_readpage_nolock at %lld, size %08x",
283                 (long long)pos,
284                 (unsigned)PAGE_CACHE_SIZE);
285
286         obj = yaffs_dentry_to_obj(f->f_dentry);
287
288         dev = obj->my_dev;
289
290 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
291         BUG_ON(!PageLocked(pg));
292 #else
293         if (!PageLocked(pg))
294                 PAGE_BUG(pg);
295 #endif
296
297         pg_buf = kmap(pg);
298         /* FIXME: Can kmap fail? */
299
300         yaffs_gross_lock(dev);
301
302         ret = yaffs_file_rd(obj, pg_buf, pos, PAGE_CACHE_SIZE);
303
304         yaffs_gross_unlock(dev);
305
306         if (ret >= 0)
307                 ret = 0;
308
309         if (ret) {
310                 ClearPageUptodate(pg);
311                 SetPageError(pg);
312         } else {
313                 SetPageUptodate(pg);
314                 ClearPageError(pg);
315         }
316
317         flush_dcache_page(pg);
318         kunmap(pg);
319
320         yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage_nolock done");
321         return ret;
322 }
323
324 static int yaffs_readpage_unlock(struct file *f, struct page *pg)
325 {
326         int ret = yaffs_readpage_nolock(f, pg);
327         UnlockPage(pg);
328         return ret;
329 }
330
331 static int yaffs_readpage(struct file *f, struct page *pg)
332 {
333         int ret;
334
335         yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage");
336         ret = yaffs_readpage_unlock(f, pg);
337         yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage done");
338         return ret;
339 }
340
341
342 static void yaffs_set_super_dirty_val(struct yaffs_dev *dev, int val)
343 {
344         struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev);
345
346         if (lc)
347                 lc->dirty = val;
348
349 # ifdef YAFFS_SUPER_HAS_DIRTY
350         {
351                 struct super_block *sb = lc->super;
352
353                 if (sb)
354                         sb->s_dirt = val;
355         }
356 #endif
357
358 }
359
360 static void yaffs_set_super_dirty(struct yaffs_dev *dev)
361 {
362         yaffs_set_super_dirty_val(dev, 1);
363 }
364
365 static void yaffs_clear_super_dirty(struct yaffs_dev *dev)
366 {
367         yaffs_set_super_dirty_val(dev, 0);
368 }
369
370 static int yaffs_check_super_dirty(struct yaffs_dev *dev)
371 {
372         struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev);
373
374         if (lc && lc->dirty)
375                 return 1;
376
377 # ifdef YAFFS_SUPER_HAS_DIRTY
378         {
379                 struct super_block *sb = lc->super;
380
381                 if (sb && sb->s_dirt)
382                         return 1;
383         }
384 #endif
385         return 0;
386
387 }
388
389 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
390 static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
391 #else
392 static int yaffs_writepage(struct page *page)
393 #endif
394 {
395         struct yaffs_dev *dev;
396         struct address_space *mapping = page->mapping;
397         struct inode *inode;
398         unsigned long end_index;
399         char *buffer;
400         struct yaffs_obj *obj;
401         int n_written = 0;
402         unsigned n_bytes;
403         loff_t i_size;
404
405         if (!mapping)
406                 BUG();
407         inode = mapping->host;
408         if (!inode)
409                 BUG();
410         i_size = i_size_read(inode);
411
412         end_index = i_size >> PAGE_CACHE_SHIFT;
413
414         if (page->index < end_index)
415                 n_bytes = PAGE_CACHE_SIZE;
416         else {
417                 n_bytes = i_size & (PAGE_CACHE_SIZE - 1);
418
419                 if (page->index > end_index || !n_bytes) {
420                         yaffs_trace(YAFFS_TRACE_OS,
421                                 "yaffs_writepage at %lld, inode size = %lld!!",
422                                 ((loff_t)page->index) << PAGE_CACHE_SHIFT,
423                                 inode->i_size);
424                         yaffs_trace(YAFFS_TRACE_OS,
425                                 "                -> don't care!!");
426
427                         zero_user_segment(page, 0, PAGE_CACHE_SIZE);
428                         set_page_writeback(page);
429                         unlock_page(page);
430                         end_page_writeback(page);
431                         return 0;
432                 }
433         }
434
435         if (n_bytes != PAGE_CACHE_SIZE)
436                 zero_user_segment(page, n_bytes, PAGE_CACHE_SIZE);
437
438         get_page(page);
439
440         buffer = kmap(page);
441
442         obj = yaffs_inode_to_obj(inode);
443         dev = obj->my_dev;
444         yaffs_gross_lock(dev);
445
446         yaffs_trace(YAFFS_TRACE_OS,
447                 "yaffs_writepage at %lld, size %08x",
448                 ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes);
449         yaffs_trace(YAFFS_TRACE_OS,
450                 "writepag0: obj = %lld, ino = %lld",
451                 obj->variant.file_variant.file_size, inode->i_size);
452
453         n_written = yaffs_wr_file(obj, buffer,
454                                   ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes, 0);
455
456         yaffs_set_super_dirty(dev);
457
458         yaffs_trace(YAFFS_TRACE_OS,
459                 "writepag1: obj = %lld, ino = %lld",
460                 obj->variant.file_variant.file_size, inode->i_size);
461
462         yaffs_gross_unlock(dev);
463
464         kunmap(page);
465         set_page_writeback(page);
466         unlock_page(page);
467         end_page_writeback(page);
468         put_page(page);
469
470         return (n_written == n_bytes) ? 0 : -ENOSPC;
471 }
472
473 /* Space holding and freeing is done to ensure we have space available for write_begin/end */
474 /* For now we just assume few parallel writes and check against a small number. */
475 /* Todo: need to do this with a counter to handle parallel reads better */
476
477 static ssize_t yaffs_hold_space(struct file *f)
478 {
479         struct yaffs_obj *obj;
480         struct yaffs_dev *dev;
481
482         int n_free_chunks;
483
484         obj = yaffs_dentry_to_obj(f->f_dentry);
485
486         dev = obj->my_dev;
487
488         yaffs_gross_lock(dev);
489
490         n_free_chunks = yaffs_get_n_free_chunks(dev);
491
492         yaffs_gross_unlock(dev);
493
494         return (n_free_chunks > 20) ? 1 : 0;
495 }
496
497 static void yaffs_release_space(struct file *f)
498 {
499         struct yaffs_obj *obj;
500         struct yaffs_dev *dev;
501
502         obj = yaffs_dentry_to_obj(f->f_dentry);
503
504         dev = obj->my_dev;
505
506         yaffs_gross_lock(dev);
507
508         yaffs_gross_unlock(dev);
509 }
510
511 #if (YAFFS_USE_WRITE_BEGIN_END > 0)
512 static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
513                              loff_t pos, unsigned len, unsigned flags,
514                              struct page **pagep, void **fsdata)
515 {
516         struct page *pg = NULL;
517         pgoff_t index = pos >> PAGE_CACHE_SHIFT;
518
519         int ret = 0;
520         int space_held = 0;
521
522         /* Get a page */
523 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
524         pg = grab_cache_page_write_begin(mapping, index, flags);
525 #else
526         pg = __grab_cache_page(mapping, index);
527 #endif
528
529         *pagep = pg;
530         if (!pg) {
531                 ret = -ENOMEM;
532                 goto out;
533         }
534         yaffs_trace(YAFFS_TRACE_OS,
535                 "start yaffs_write_begin index %d(%x) uptodate %d",
536                 (int)index, (int)index, Page_Uptodate(pg) ? 1 : 0);
537
538         /* Get fs space */
539         space_held = yaffs_hold_space(filp);
540
541         if (!space_held) {
542                 ret = -ENOSPC;
543                 goto out;
544         }
545
546         /* Update page if required */
547
548         if (!Page_Uptodate(pg))
549                 ret = yaffs_readpage_nolock(filp, pg);
550
551         if (ret)
552                 goto out;
553
554         /* Happy path return */
555         yaffs_trace(YAFFS_TRACE_OS, "end yaffs_write_begin - ok");
556
557         return 0;
558
559 out:
560         yaffs_trace(YAFFS_TRACE_OS,
561                 "end yaffs_write_begin fail returning %d", ret);
562         if (space_held)
563                 yaffs_release_space(filp);
564         if (pg) {
565                 unlock_page(pg);
566                 page_cache_release(pg);
567         }
568         return ret;
569 }
570
571 #else
572
573 static int yaffs_prepare_write(struct file *f, struct page *pg,
574                                unsigned offset, unsigned to)
575 {
576         yaffs_trace(YAFFS_TRACE_OS, "yaffs_prepair_write");
577
578         if (!Page_Uptodate(pg))
579                 return yaffs_readpage_nolock(f, pg);
580         return 0;
581 }
582 #endif
583
584
585 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
586                                 loff_t * pos)
587 {
588         struct yaffs_obj *obj;
589         int n_written;
590         loff_t ipos;
591         struct inode *inode;
592         struct yaffs_dev *dev;
593
594         obj = yaffs_dentry_to_obj(f->f_dentry);
595
596         if (!obj) {
597                 yaffs_trace(YAFFS_TRACE_OS,
598                         "yaffs_file_write: hey obj is null!");
599                 return -EINVAL;
600         }
601
602         dev = obj->my_dev;
603
604         yaffs_gross_lock(dev);
605
606         inode = f->f_dentry->d_inode;
607
608         if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
609                 ipos = inode->i_size;
610         else
611                 ipos = *pos;
612
613         yaffs_trace(YAFFS_TRACE_OS,
614                 "yaffs_file_write about to write writing %u(%x) bytes to object %d at %lld",
615                 (unsigned)n, (unsigned)n, obj->obj_id, ipos);
616
617         n_written = yaffs_wr_file(obj, buf, ipos, n, 0);
618
619         yaffs_set_super_dirty(dev);
620
621         yaffs_trace(YAFFS_TRACE_OS,
622                 "yaffs_file_write: %d(%x) bytes written",
623                 (unsigned)n, (unsigned)n);
624
625         if (n_written > 0) {
626                 ipos += n_written;
627                 *pos = ipos;
628                 if (ipos > inode->i_size) {
629                         inode->i_size = ipos;
630                         inode->i_blocks = (ipos + 511) >> 9;
631
632                         yaffs_trace(YAFFS_TRACE_OS,
633                                 "yaffs_file_write size updated to %lld bytes, %d blocks",
634                                 ipos, (int)(inode->i_blocks));
635                 }
636
637         }
638         yaffs_gross_unlock(dev);
639         return (n_written == 0) && (n > 0) ? -ENOSPC : n_written;
640 }
641
642
643 #if (YAFFS_USE_WRITE_BEGIN_END > 0)
644 static int yaffs_write_end(struct file *filp, struct address_space *mapping,
645                            loff_t pos, unsigned len, unsigned copied,
646                            struct page *pg, void *fsdadata)
647 {
648         int ret = 0;
649         void *addr, *kva;
650         uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
651
652         kva = kmap(pg);
653         addr = kva + offset_into_page;
654
655         yaffs_trace(YAFFS_TRACE_OS,
656                 "yaffs_write_end addr %p pos %lld n_bytes %d",
657                 addr, pos, copied);
658
659         ret = yaffs_file_write(filp, addr, copied, &pos);
660
661         if (ret != copied) {
662                 yaffs_trace(YAFFS_TRACE_OS,
663                         "yaffs_write_end not same size ret %d  copied %d",
664                         ret, copied);
665                 SetPageError(pg);
666         }
667
668         kunmap(pg);
669
670         yaffs_release_space(filp);
671         unlock_page(pg);
672         page_cache_release(pg);
673         return ret;
674 }
675 #else
676
677 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
678                               unsigned to)
679 {
680         void *addr, *kva;
681
682         loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
683         int n_bytes = to - offset;
684         int n_written;
685
686         kva = kmap(pg);
687         addr = kva + offset;
688
689         yaffs_trace(YAFFS_TRACE_OS,
690                 "yaffs_commit_write addr %p pos %lld n_bytes %d",
691                 addr, pos, n_bytes);
692
693         n_written = yaffs_file_write(f, addr, n_bytes, &pos);
694
695         if (n_written != n_bytes) {
696                 yaffs_trace(YAFFS_TRACE_OS,
697                         "yaffs_commit_write not same size n_written %d  n_bytes %d",
698                         n_written, n_bytes);
699                 SetPageError(pg);
700         }
701         kunmap(pg);
702
703         yaffs_trace(YAFFS_TRACE_OS,
704                 "yaffs_commit_write returning %d",
705                 n_written == n_bytes ? 0 : n_written);
706
707         return n_written == n_bytes ? 0 : n_written;
708 }
709 #endif
710
711 static struct address_space_operations yaffs_file_address_operations = {
712         .readpage = yaffs_readpage,
713         .writepage = yaffs_writepage,
714 #if (YAFFS_USE_WRITE_BEGIN_END > 0)
715         .write_begin = yaffs_write_begin,
716         .write_end = yaffs_write_end,
717 #else
718         .prepare_write = yaffs_prepare_write,
719         .commit_write = yaffs_commit_write,
720 #endif
721 };
722
723
724 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
725 static int yaffs_file_flush(struct file *file, fl_owner_t id)
726 #else
727 static int yaffs_file_flush(struct file *file)
728 #endif
729 {
730         struct yaffs_obj *obj = yaffs_dentry_to_obj(file->f_dentry);
731
732         struct yaffs_dev *dev = obj->my_dev;
733
734         yaffs_trace(YAFFS_TRACE_OS,
735                 "yaffs_file_flush object %d (%s)",
736                 obj->obj_id,
737                 obj->dirty ? "dirty" : "clean");
738
739         yaffs_gross_lock(dev);
740
741         yaffs_flush_file(obj, 1, 0);
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);
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);
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);
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
2583
2584 static const struct super_operations yaffs_super_ops = {
2585         .statfs = yaffs_statfs,
2586
2587 #ifndef YAFFS_USE_OWN_IGET
2588         .read_inode = yaffs_read_inode,
2589 #endif
2590 #ifdef YAFFS_HAS_PUT_INODE
2591         .put_inode = yaffs_put_inode,
2592 #endif
2593         .put_super = yaffs_put_super,
2594 #ifdef YAFFS_HAS_EVICT_INODE
2595         .evict_inode = yaffs_evict_inode,
2596 #else
2597         .delete_inode = yaffs_delete_inode,
2598         .clear_inode = yaffs_clear_inode,
2599 #endif
2600         .sync_fs = yaffs_sync_fs,
2601 #ifdef YAFFS_HAS_WRITE_SUPER
2602         .write_super = yaffs_write_super,
2603 #endif
2604 };
2605
2606 struct yaffs_options {
2607         int inband_tags;
2608         int skip_checkpoint_read;
2609         int skip_checkpoint_write;
2610         int no_cache;
2611         int tags_ecc_on;
2612         int tags_ecc_overridden;
2613         int lazy_loading_enabled;
2614         int lazy_loading_overridden;
2615         int empty_lost_and_found;
2616         int empty_lost_and_found_overridden;
2617         int disable_summary;
2618 };
2619
2620 #define MAX_OPT_LEN 30
2621 static int yaffs_parse_options(struct yaffs_options *options,
2622                                const char *options_str)
2623 {
2624         char cur_opt[MAX_OPT_LEN + 1];
2625         int p;
2626         int error = 0;
2627
2628         /* Parse through the options which is a comma seperated list */
2629
2630         while (options_str && *options_str && !error) {
2631                 memset(cur_opt, 0, MAX_OPT_LEN + 1);
2632                 p = 0;
2633
2634                 while (*options_str == ',')
2635                         options_str++;
2636
2637                 while (*options_str && *options_str != ',') {
2638                         if (p < MAX_OPT_LEN) {
2639                                 cur_opt[p] = *options_str;
2640                                 p++;
2641                         }
2642                         options_str++;
2643                 }
2644
2645                 if (!strcmp(cur_opt, "inband-tags")) {
2646                         options->inband_tags = 1;
2647                 } else if (!strcmp(cur_opt, "tags-ecc-off")) {
2648                         options->tags_ecc_on = 0;
2649                         options->tags_ecc_overridden = 1;
2650                 } else if (!strcmp(cur_opt, "tags-ecc-on")) {
2651                         options->tags_ecc_on = 1;
2652                         options->tags_ecc_overridden = 1;
2653                 } else if (!strcmp(cur_opt, "lazy-loading-off")) {
2654                         options->lazy_loading_enabled = 0;
2655                         options->lazy_loading_overridden = 1;
2656                 } else if (!strcmp(cur_opt, "lazy-loading-on")) {
2657                         options->lazy_loading_enabled = 1;
2658                         options->lazy_loading_overridden = 1;
2659                 } else if (!strcmp(cur_opt, "disable-summary")) {
2660                         options->disable_summary = 1;
2661                 } else if (!strcmp(cur_opt, "empty-lost-and-found-off")) {
2662                         options->empty_lost_and_found = 0;
2663                         options->empty_lost_and_found_overridden = 1;
2664                 } else if (!strcmp(cur_opt, "empty-lost-and-found-on")) {
2665                         options->empty_lost_and_found = 1;
2666                         options->empty_lost_and_found_overridden = 1;
2667                 } else if (!strcmp(cur_opt, "no-cache")) {
2668                         options->no_cache = 1;
2669                 } else if (!strcmp(cur_opt, "no-checkpoint-read")) {
2670                         options->skip_checkpoint_read = 1;
2671                 } else if (!strcmp(cur_opt, "no-checkpoint-write")) {
2672                         options->skip_checkpoint_write = 1;
2673                 } else if (!strcmp(cur_opt, "no-checkpoint")) {
2674                         options->skip_checkpoint_read = 1;
2675                         options->skip_checkpoint_write = 1;
2676                 } else {
2677                         printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
2678                                cur_opt);
2679                         error = 1;
2680                 }
2681         }
2682
2683         return error;
2684 }
2685
2686
2687 static struct dentry *yaffs_make_root(struct inode *inode)
2688 {
2689 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
2690         struct dentry *root = d_alloc_root(inode);
2691
2692         if (!root)
2693                 iput(inode);
2694
2695         return root;
2696 #else
2697         return d_make_root(inode);
2698 #endif
2699 }
2700
2701
2702
2703
2704 static struct super_block *yaffs_internal_read_super(int yaffs_version,
2705                                                      struct super_block *sb,
2706                                                      void *data, int silent)
2707 {
2708         int n_blocks;
2709         struct inode *inode = NULL;
2710         struct dentry *root;
2711         struct yaffs_dev *dev = 0;
2712         char devname_buf[BDEVNAME_SIZE + 1];
2713         struct mtd_info *mtd;
2714         int err;
2715         char *data_str = (char *)data;
2716         struct yaffs_linux_context *context = NULL;
2717         struct yaffs_param *param;
2718
2719         int read_only = 0;
2720         int inband_tags = 0;
2721
2722         struct yaffs_options options;
2723
2724         unsigned mount_id;
2725         int found;
2726         struct yaffs_linux_context *context_iterator;
2727         struct list_head *l;
2728
2729         if (!sb) {
2730                 printk(KERN_INFO "yaffs: sb is NULL\n");
2731                 return NULL;
2732         }
2733
2734         sb->s_magic = YAFFS_MAGIC;
2735         sb->s_op = &yaffs_super_ops;
2736         sb->s_flags |= MS_NOATIME;
2737
2738         read_only = ((sb->s_flags & MS_RDONLY) != 0);
2739
2740 #ifdef YAFFS_COMPILE_EXPORTFS
2741         sb->s_export_op = &yaffs_export_ops;
2742 #endif
2743
2744         if (!sb->s_dev)
2745                 printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
2746         else if (!yaffs_devname(sb, devname_buf))
2747                 printk(KERN_INFO "yaffs: devname is NULL\n");
2748         else
2749                 printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
2750                        sb->s_dev,
2751                        yaffs_devname(sb, devname_buf), read_only ? "ro" : "rw");
2752
2753         if (!data_str)
2754                 data_str = "";
2755
2756         printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
2757
2758         memset(&options, 0, sizeof(options));
2759
2760         if (yaffs_parse_options(&options, data_str)) {
2761                 /* Option parsing failed */
2762                 return NULL;
2763         }
2764
2765         sb->s_blocksize = PAGE_CACHE_SIZE;
2766         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
2767
2768         yaffs_trace(YAFFS_TRACE_OS,
2769                 "yaffs_read_super: Using yaffs%d", yaffs_version);
2770         yaffs_trace(YAFFS_TRACE_OS,
2771                 "yaffs_read_super: block size %d", (int)(sb->s_blocksize));
2772
2773         yaffs_trace(YAFFS_TRACE_ALWAYS,
2774                 "yaffs: Attempting MTD mount of %u.%u,\"%s\"",
2775                 MAJOR(sb->s_dev), MINOR(sb->s_dev),
2776                 yaffs_devname(sb, devname_buf));
2777
2778         /* Get the device */
2779         mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
2780         if (IS_ERR(mtd)) {
2781                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2782                         "yaffs: MTD device %u either not valid or unavailable",
2783                         MINOR(sb->s_dev));
2784                 return NULL;
2785         }
2786
2787         if (yaffs_auto_select && yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) {
2788                 yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs2");
2789                 yaffs_version = 2;
2790         }
2791
2792         /* Added NCB 26/5/2006 for completeness */
2793         if (yaffs_version == 2 && !options.inband_tags
2794             && WRITE_SIZE(mtd) == 512) {
2795                 yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1");
2796                 yaffs_version = 1;
2797         }
2798
2799         if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) ||
2800             options.inband_tags)
2801                 inband_tags = 1;
2802
2803         if(yaffs_verify_mtd(mtd, yaffs_version, inband_tags) < 0)
2804                 return NULL;
2805
2806         /* OK, so if we got here, we have an MTD that's NAND and looks
2807          * like it has the right capabilities
2808          * Set the struct yaffs_dev up for mtd
2809          */
2810
2811         if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
2812                 read_only = 1;
2813                 printk(KERN_INFO
2814                        "yaffs: mtd is read only, setting superblock read only\n"
2815                 );
2816                 sb->s_flags |= MS_RDONLY;
2817         }
2818
2819         dev = kmalloc(sizeof(struct yaffs_dev), GFP_KERNEL);
2820         context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
2821
2822         if (!dev || !context) {
2823                 kfree(dev);
2824                 kfree(context);
2825                 dev = NULL;
2826                 context = NULL;
2827
2828                 /* Deep shit could not allocate device structure */
2829                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2830                         "yaffs_read_super: Failed trying to allocate struct yaffs_dev."
2831                 );
2832                 return NULL;
2833         }
2834         memset(dev, 0, sizeof(struct yaffs_dev));
2835         param = &(dev->param);
2836
2837         memset(context, 0, sizeof(struct yaffs_linux_context));
2838         dev->os_context = context;
2839         INIT_LIST_HEAD(&(context->context_list));
2840         context->dev = dev;
2841         context->super = sb;
2842
2843         dev->read_only = read_only;
2844
2845 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2846         sb->s_fs_info = dev;
2847 #else
2848         sb->u.generic_sbp = dev;
2849 #endif
2850
2851
2852         dev->driver_context = mtd;
2853         param->name = mtd->name;
2854
2855         /* Set up the memory size parameters.... */
2856
2857
2858         param->n_reserved_blocks = 5;
2859         param->n_caches = (options.no_cache) ? 0 : 10;
2860         param->inband_tags = inband_tags;
2861
2862         param->enable_xattr = 1;
2863         if (options.lazy_loading_overridden)
2864                 param->disable_lazy_load = !options.lazy_loading_enabled;
2865
2866         param->defered_dir_update = 1;
2867
2868         if (options.tags_ecc_overridden)
2869                 param->no_tags_ecc = !options.tags_ecc_on;
2870
2871         param->empty_lost_n_found = 1;
2872         param->refresh_period = 500;
2873         param->disable_summary = options.disable_summary;
2874
2875
2876 #ifdef CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING
2877         param->disable_bad_block_marking  = 1;
2878 #endif
2879         if (options.empty_lost_and_found_overridden)
2880                 param->empty_lost_n_found = options.empty_lost_and_found;
2881
2882         /* ... and the functions. */
2883         if (yaffs_version == 2) {
2884                 param->is_yaffs2 = 1;
2885 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2886                 param->total_bytes_per_chunk = mtd->writesize;
2887                 param->chunks_per_block = mtd->erasesize / mtd->writesize;
2888 #else
2889                 param->total_bytes_per_chunk = mtd->oobblock;
2890                 param->chunks_per_block = mtd->erasesize / mtd->oobblock;
2891 #endif
2892                 n_blocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
2893
2894                 param->start_block = 0;
2895                 param->end_block = n_blocks - 1;
2896         } else {
2897                 param->is_yaffs2 = 0;
2898                 n_blocks = YCALCBLOCKS(mtd->size,
2899                              YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
2900
2901                 param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
2902                 param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
2903         }
2904
2905         param->start_block = 0;
2906         param->end_block = n_blocks - 1;
2907
2908         yaffs_mtd_drv_install(dev);
2909
2910         param->sb_dirty_fn = yaffs_set_super_dirty;
2911         param->gc_control_fn = yaffs_gc_control_callback;
2912
2913         yaffs_dev_to_lc(dev)->super = sb;
2914
2915         param->use_nand_ecc = 1;
2916
2917         param->skip_checkpt_rd = options.skip_checkpoint_read;
2918         param->skip_checkpt_wr = options.skip_checkpoint_write;
2919
2920         mutex_lock(&yaffs_context_lock);
2921         /* Get a mount id */
2922         found = 0;
2923         for (mount_id = 0; !found; mount_id++) {
2924                 found = 1;
2925                 list_for_each(l, &yaffs_context_list) {
2926                         context_iterator =
2927                             list_entry(l, struct yaffs_linux_context,
2928                                        context_list);
2929                         if (context_iterator->mount_id == mount_id)
2930                                 found = 0;
2931                 }
2932         }
2933         context->mount_id = mount_id;
2934
2935         list_add_tail(&(yaffs_dev_to_lc(dev)->context_list),
2936                       &yaffs_context_list);
2937         mutex_unlock(&yaffs_context_lock);
2938
2939         /* Directory search handling... */
2940         INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->search_contexts));
2941         param->remove_obj_fn = yaffs_remove_obj_callback;
2942
2943         mutex_init(&(yaffs_dev_to_lc(dev)->gross_lock));
2944
2945         yaffs_gross_lock(dev);
2946
2947         err = yaffs_guts_initialise(dev);
2948
2949         yaffs_trace(YAFFS_TRACE_OS,
2950                 "yaffs_read_super: guts initialised %s",
2951                 (err == YAFFS_OK) ? "OK" : "FAILED");
2952
2953         if (err == YAFFS_OK)
2954                 yaffs_bg_start(dev);
2955
2956         if (!context->bg_thread)
2957                 param->defered_dir_update = 0;
2958
2959         sb->s_maxbytes = yaffs_max_file_size(dev);
2960
2961         /* Release lock before yaffs_get_inode() */
2962         yaffs_gross_unlock(dev);
2963
2964         /* Create root inode */
2965         if (err == YAFFS_OK)
2966                 inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_root(dev));
2967
2968         if (!inode)
2969                 return NULL;
2970
2971         inode->i_op = &yaffs_dir_inode_operations;
2972         inode->i_fop = &yaffs_dir_operations;
2973
2974         yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode");
2975
2976         root = yaffs_make_root(inode);
2977
2978         if (!root)
2979                 return NULL;
2980
2981         sb->s_root = root;
2982         if(!dev->is_checkpointed)
2983                 yaffs_set_super_dirty(dev);
2984
2985         yaffs_trace(YAFFS_TRACE_ALWAYS,
2986                 "yaffs_read_super: is_checkpointed %d",
2987                 dev->is_checkpointed);
2988
2989         yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: done");
2990         return sb;
2991 }
2992
2993 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2994 static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
2995                                          int silent)
2996 {
2997         return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
2998 }
2999
3000 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3001 static struct dentry *yaffs_mount(struct file_system_type *fs_type, int flags,
3002         const char *dev_name, void *data)
3003 {
3004     return mount_bdev(fs_type, flags, dev_name, data, yaffs_internal_read_super_mtd);
3005 }
3006 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3007 static int yaffs_read_super(struct file_system_type *fs,
3008                             int flags, const char *dev_name,
3009                             void *data, struct vfsmount *mnt)
3010 {
3011
3012         return get_sb_bdev(fs, flags, dev_name, data,
3013                            yaffs_internal_read_super_mtd, mnt);
3014 }
3015 #else
3016 static struct super_block *yaffs_read_super(struct file_system_type *fs,
3017                                             int flags, const char *dev_name,
3018                                             void *data)
3019 {
3020
3021         return get_sb_bdev(fs, flags, dev_name, data,
3022                            yaffs_internal_read_super_mtd);
3023 }
3024 #endif
3025
3026 static struct file_system_type yaffs_fs_type = {
3027         .owner = THIS_MODULE,
3028         .name = "yaffs",
3029 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3030         .mount = yaffs_mount,
3031 #else
3032         .get_sb = yaffs_read_super,
3033 #endif
3034         .kill_sb = kill_block_super,
3035         .fs_flags = FS_REQUIRES_DEV,
3036 };
3037 #else
3038 static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
3039                                             int silent)
3040 {
3041         return yaffs_internal_read_super(1, sb, data, silent);
3042 }
3043
3044 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
3045                       FS_REQUIRES_DEV);
3046 #endif
3047
3048
3049 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3050 static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
3051                                           int silent)
3052 {
3053         return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
3054 }
3055
3056 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3057 static struct dentry *yaffs2_mount(struct file_system_type *fs_type, int flags,
3058         const char *dev_name, void *data)
3059 {
3060         return mount_bdev(fs_type, flags, dev_name, data, yaffs2_internal_read_super_mtd);
3061 }
3062 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3063 static int yaffs2_read_super(struct file_system_type *fs,
3064                              int flags, const char *dev_name, void *data,
3065                              struct vfsmount *mnt)
3066 {
3067         return get_sb_bdev(fs, flags, dev_name, data,
3068                            yaffs2_internal_read_super_mtd, mnt);
3069 }
3070 #else
3071 static struct super_block *yaffs2_read_super(struct file_system_type *fs,
3072                                              int flags, const char *dev_name,
3073                                              void *data)
3074 {
3075
3076         return get_sb_bdev(fs, flags, dev_name, data,
3077                            yaffs2_internal_read_super_mtd);
3078 }
3079 #endif
3080
3081 static struct file_system_type yaffs2_fs_type = {
3082         .owner = THIS_MODULE,
3083         .name = "yaffs2",
3084 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3085         .mount = yaffs2_mount,
3086 #else
3087         .get_sb = yaffs2_read_super,
3088 #endif
3089         .kill_sb = kill_block_super,
3090         .fs_flags = FS_REQUIRES_DEV,
3091 };
3092 #else
3093 static struct super_block *yaffs2_read_super(struct super_block *sb,
3094                                              void *data, int silent)
3095 {
3096         return yaffs_internal_read_super(2, sb, data, silent);
3097 }
3098
3099 static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
3100                       FS_REQUIRES_DEV);
3101 #endif
3102
3103
3104 static struct proc_dir_entry *my_proc_entry;
3105
3106 static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
3107 {
3108         struct yaffs_param *param = &dev->param;
3109         int bs[10];
3110
3111         yaffs_count_blocks_by_state(dev,bs);
3112
3113         buf += sprintf(buf, "start_block.......... %d\n", param->start_block);
3114         buf += sprintf(buf, "end_block............ %d\n", param->end_block);
3115         buf += sprintf(buf, "total_bytes_per_chunk %d\n",
3116                                 param->total_bytes_per_chunk);
3117         buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc);
3118         buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
3119         buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2);
3120         buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags);
3121         buf += sprintf(buf, "empty_lost_n_found... %d\n",
3122                                 param->empty_lost_n_found);
3123         buf += sprintf(buf, "disable_lazy_load.... %d\n",
3124                                 param->disable_lazy_load);
3125         buf += sprintf(buf, "disable_bad_block_mrk %d\n",
3126                                 param->disable_bad_block_marking);
3127         buf += sprintf(buf, "refresh_period....... %d\n",
3128                                 param->refresh_period);
3129         buf += sprintf(buf, "n_caches............. %d\n", param->n_caches);
3130         buf += sprintf(buf, "n_reserved_blocks.... %d\n",
3131                                 param->n_reserved_blocks);
3132         buf += sprintf(buf, "always_check_erased.. %d\n",
3133                                 param->always_check_erased);
3134         buf += sprintf(buf, "\n");
3135         buf += sprintf(buf, "block count by state\n");
3136         buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
3137                                 bs[0], bs[1], bs[2], bs[3], bs[4]);
3138         buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
3139                                 bs[5], bs[6], bs[7], bs[8], bs[9]);
3140
3141         return buf;
3142 }
3143
3144 static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
3145 {
3146         buf += sprintf(buf, "max file size....... %lld\n",
3147                                 (long long) yaffs_max_file_size(dev));
3148         buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
3149                                 dev->data_bytes_per_chunk);
3150         buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
3151         buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
3152         buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
3153         buf += sprintf(buf, "blocks_in_checkpt.... %d\n",
3154                                 dev->blocks_in_checkpt);
3155         buf += sprintf(buf, "\n");
3156         buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
3157         buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
3158         buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
3159         buf += sprintf(buf, "\n");
3160         buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
3161         buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
3162         buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
3163         buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
3164         buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
3165         buf += sprintf(buf, "passive_gc_count..... %u\n",
3166                                 dev->passive_gc_count);
3167         buf += sprintf(buf, "oldest_dirty_gc_count %u\n",
3168                                 dev->oldest_dirty_gc_count);
3169         buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
3170         buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
3171         buf += sprintf(buf, "n_retried_writes..... %u\n",
3172                                 dev->n_retried_writes);
3173         buf += sprintf(buf, "n_retired_blocks..... %u\n",
3174                                 dev->n_retired_blocks);
3175         buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
3176         buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
3177         buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n",
3178                                 dev->n_tags_ecc_fixed);
3179         buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n",
3180                                 dev->n_tags_ecc_unfixed);
3181         buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
3182         buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
3183         buf += sprintf(buf, "n_unlinked_files..... %u\n",
3184                                 dev->n_unlinked_files);
3185         buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
3186         buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
3187         buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used);
3188         buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used);
3189
3190         return buf;
3191 }
3192
3193 static int yaffs_proc_read(char *page,
3194                            char **start,
3195                            off_t offset, int count, int *eof, void *data)
3196 {
3197         struct list_head *item;
3198         char *buf = page;
3199         int step = offset;
3200         int n = 0;
3201
3202         /* Get proc_file_read() to step 'offset' by one on each sucessive call.
3203          * We use 'offset' (*ppos) to indicate where we are in dev_list.
3204          * This also assumes the user has posted a read buffer large
3205          * enough to hold the complete output; but that's life in /proc.
3206          */
3207
3208         *(int *)start = 1;
3209
3210         /* Print header first */
3211         if (step == 0)
3212                 buf +=
3213                     sprintf(buf,
3214                             "Multi-version YAFFS built:" __DATE__ " " __TIME__
3215                             "\n");
3216         else if (step == 1)
3217                 buf += sprintf(buf, "\n");
3218         else {
3219                 step -= 2;
3220
3221                 mutex_lock(&yaffs_context_lock);
3222
3223                 /* Locate and print the Nth entry.  Order N-squared but N is small. */
3224                 list_for_each(item, &yaffs_context_list) {
3225                         struct yaffs_linux_context *dc =
3226                             list_entry(item, struct yaffs_linux_context,
3227                                        context_list);
3228                         struct yaffs_dev *dev = dc->dev;
3229
3230                         if (n < (step & ~1)) {
3231                                 n += 2;
3232                                 continue;
3233                         }
3234                         if ((step & 1) == 0) {
3235                                 buf +=
3236                                     sprintf(buf, "\nDevice %d \"%s\"\n", n,
3237                                             dev->param.name);
3238                                 buf = yaffs_dump_dev_part0(buf, dev);
3239                         } else {
3240                                 buf = yaffs_dump_dev_part1(buf, dev);
3241                         }
3242
3243                         break;
3244                 }
3245                 mutex_unlock(&yaffs_context_lock);
3246         }
3247
3248         return buf - page < count ? buf - page : count;
3249 }
3250
3251 /**
3252  * Set the verbosity of the warnings and error messages.
3253  *
3254  * Note that the names can only be a..z or _ with the current code.
3255  */
3256
3257 static struct {
3258         char *mask_name;
3259         unsigned mask_bitfield;
3260 } mask_flags[] = {
3261         {"allocate", YAFFS_TRACE_ALLOCATE},
3262         {"always", YAFFS_TRACE_ALWAYS},
3263         {"background", YAFFS_TRACE_BACKGROUND},
3264         {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
3265         {"buffers", YAFFS_TRACE_BUFFERS},
3266         {"bug", YAFFS_TRACE_BUG},
3267         {"checkpt", YAFFS_TRACE_CHECKPOINT},
3268         {"deletion", YAFFS_TRACE_DELETION},
3269         {"erase", YAFFS_TRACE_ERASE},
3270         {"error", YAFFS_TRACE_ERROR},
3271         {"gc_detail", YAFFS_TRACE_GC_DETAIL},
3272         {"gc", YAFFS_TRACE_GC},
3273         {"lock", YAFFS_TRACE_LOCK},
3274         {"mtd", YAFFS_TRACE_MTD},
3275         {"nandaccess", YAFFS_TRACE_NANDACCESS},
3276         {"os", YAFFS_TRACE_OS},
3277         {"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
3278         {"scan", YAFFS_TRACE_SCAN},
3279         {"mount", YAFFS_TRACE_MOUNT},
3280         {"tracing", YAFFS_TRACE_TRACING},
3281         {"sync", YAFFS_TRACE_SYNC},
3282         {"write", YAFFS_TRACE_WRITE},
3283         {"verify", YAFFS_TRACE_VERIFY},
3284         {"verify_nand", YAFFS_TRACE_VERIFY_NAND},
3285         {"verify_full", YAFFS_TRACE_VERIFY_FULL},
3286         {"verify_all", YAFFS_TRACE_VERIFY_ALL},
3287         {"all", 0xffffffff},
3288         {"none", 0},
3289         {NULL, 0},
3290 };
3291
3292 #define MAX_MASK_NAME_LENGTH 40
3293 static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
3294                                           unsigned long count)
3295 {
3296         unsigned rg = 0, mask_bitfield;
3297         char *end;
3298         char *mask_name;
3299         const char *x;
3300         char substring[MAX_MASK_NAME_LENGTH + 1];
3301         int i;
3302         int done = 0;
3303         int add, len = 0;
3304         int pos = 0;
3305
3306         rg = yaffs_trace_mask;
3307
3308         while (!done && (pos < count)) {
3309                 done = 1;
3310                 while ((pos < count) && isspace(buf[pos]))
3311                         pos++;
3312
3313                 switch (buf[pos]) {
3314                 case '+':
3315                 case '-':
3316                 case '=':
3317                         add = buf[pos];
3318                         pos++;
3319                         break;
3320
3321                 default:
3322                         add = ' ';
3323                         break;
3324                 }
3325                 mask_name = NULL;
3326
3327                 mask_bitfield = simple_strtoul(buf + pos, &end, 0);
3328
3329                 if (end > buf + pos) {
3330                         mask_name = "numeral";
3331                         len = end - (buf + pos);
3332                         pos += len;
3333                         done = 0;
3334                 } else {
3335                         for (x = buf + pos, i = 0;
3336                              (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
3337                              i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
3338                                 substring[i] = *x;
3339                         substring[i] = '\0';
3340
3341                         for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3342                                 if (strcmp(substring, mask_flags[i].mask_name)
3343                                     == 0) {
3344                                         mask_name = mask_flags[i].mask_name;
3345                                         mask_bitfield =
3346                                             mask_flags[i].mask_bitfield;
3347                                         done = 0;
3348                                         break;
3349                                 }
3350                         }
3351                 }
3352
3353                 if (mask_name != NULL) {
3354                         done = 0;
3355                         switch (add) {
3356                         case '-':
3357                                 rg &= ~mask_bitfield;
3358                                 break;
3359                         case '+':
3360                                 rg |= mask_bitfield;
3361                                 break;
3362                         case '=':
3363                                 rg = mask_bitfield;
3364                                 break;
3365                         default:
3366                                 rg |= mask_bitfield;
3367                                 break;
3368                         }
3369                 }
3370         }
3371
3372         yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS;
3373
3374         printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask);
3375
3376         if (rg & YAFFS_TRACE_ALWAYS) {
3377                 for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3378                         char flag;
3379                         flag = ((rg & mask_flags[i].mask_bitfield) ==
3380                                 mask_flags[i].mask_bitfield) ? '+' : '-';
3381                         printk(KERN_DEBUG "%c%s\n", flag,
3382                                mask_flags[i].mask_name);
3383                 }
3384         }
3385
3386         return count;
3387 }
3388
3389 /* Debug strings are of the form:
3390  * .bnnn         print info on block n
3391  * .cobjn,chunkn print nand chunk id for objn:chunkn
3392  */
3393
3394 static int yaffs_proc_debug_write(struct file *file, const char *buf,
3395                                           unsigned long count)
3396 {
3397
3398         char str[100];
3399         char *p0;
3400         char *p1;
3401         long p1_val;
3402         long p0_val;
3403         char cmd;
3404         struct list_head *item;
3405
3406         memset(str, 0, sizeof(str));
3407         memcpy(str, buf, min((size_t)count, sizeof(str) -1));
3408
3409         cmd = str[1];
3410
3411         p0 = str + 2;
3412
3413         p1 = p0;
3414
3415         while (*p1 && *p1 != ',') {
3416                 p1++;
3417         }
3418         *p1 = '\0';
3419         p1++;
3420
3421         p0_val = simple_strtol(p0, NULL, 0);
3422         p1_val = simple_strtol(p1, NULL, 0);
3423
3424
3425         mutex_lock(&yaffs_context_lock);
3426
3427         /* Locate and print the Nth entry.  Order N-squared but N is small. */
3428         list_for_each(item, &yaffs_context_list) {
3429                 struct yaffs_linux_context *dc =
3430                     list_entry(item, struct yaffs_linux_context,
3431                                context_list);
3432                 struct yaffs_dev *dev = dc->dev;
3433
3434                 if (cmd == 'b') {
3435                         struct yaffs_block_info *bi;
3436
3437                         bi = yaffs_get_block_info(dev,p0_val);
3438
3439                         if(bi) {
3440                                 printk("Block %d: state %d, retire %d, use %d, seq %d\n",
3441                                         (int)p0_val, bi->block_state,
3442                                         bi->needs_retiring, bi->pages_in_use,
3443                                         bi->seq_number);
3444                         }
3445                 } else if (cmd == 'c') {
3446                         struct yaffs_obj *obj;
3447                         int nand_chunk;
3448
3449                         obj = yaffs_find_by_number(dev, p0_val);
3450                         if (!obj)
3451                                 printk("No obj %d\n", (int)p0_val);
3452                         else {
3453                                 if(p1_val == 0)
3454                                         nand_chunk = obj->hdr_chunk;
3455                                 else
3456                                         nand_chunk =
3457                                                 yaffs_find_chunk_in_file(obj,
3458                                                         p1_val, NULL);
3459                                 printk("Nand chunk for %d:%d is %d\n",
3460                                         (int)p0_val, (int)p1_val, nand_chunk);
3461                         }
3462                 }
3463         }
3464
3465         mutex_unlock(&yaffs_context_lock);
3466
3467         return count;
3468 }
3469
3470
3471 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
3472 static int yaffs_proc_write(struct file *file, const char *buf,
3473                             unsigned long count, void *ppos)
3474 #else
3475 static ssize_t yaffs_proc_write(struct file *file, const char __user *buf,
3476                             size_t count, loff_t *ppos)
3477 #endif
3478 {
3479         if (buf[0] == '.')
3480                 return yaffs_proc_debug_write(file, buf, count);
3481         return yaffs_proc_write_trace_options(file, buf, count);
3482 }
3483
3484 /* Stuff to handle installation of file systems */
3485 struct file_system_to_install {
3486         struct file_system_type *fst;
3487         int installed;
3488 };
3489
3490 static struct file_system_to_install fs_to_install[] = {
3491         {&yaffs_fs_type, 0},
3492         {&yaffs2_fs_type, 0},
3493         {NULL, 0}
3494 };
3495
3496
3497 #ifdef YAFFS_NEW_PROCFS
3498 static int yaffs_proc_show(struct seq_file *m, void *v)
3499 {
3500         /* FIXME: Unify in a better way? */
3501         char buffer[512];
3502         char *start;
3503         int len;
3504
3505         len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL);
3506         seq_puts(m, buffer);
3507         return 0;
3508 }
3509
3510 static int yaffs_proc_open(struct inode *inode, struct file *file)
3511 {
3512         return single_open(file, yaffs_proc_show, NULL);
3513 }
3514
3515 static struct file_operations procfs_ops = {
3516         .owner = THIS_MODULE,
3517         .open  = yaffs_proc_open,
3518         .read  = seq_read,
3519         .write = yaffs_proc_write,
3520 };
3521
3522 static int yaffs_procfs_init(void)
3523 {
3524         /* Install the proc_fs entries */
3525         my_proc_entry = proc_create("yaffs",
3526                                     S_IRUGO | S_IFREG,
3527                                     YPROC_ROOT,
3528                                     &procfs_ops);
3529
3530         if (my_proc_entry) {
3531                 return 0;
3532         } else {
3533                 return -ENOMEM;
3534         }
3535 }
3536
3537 #else
3538
3539
3540 static int yaffs_procfs_init(void)
3541 {
3542         /* Install the proc_fs entries */
3543         my_proc_entry = create_proc_entry("yaffs",
3544                                           S_IRUGO | S_IFREG, YPROC_ROOT);
3545
3546         if (my_proc_entry) {
3547                 my_proc_entry->write_proc = yaffs_proc_write;
3548                 my_proc_entry->read_proc = yaffs_proc_read;
3549                 my_proc_entry->data = NULL;
3550                 return 0;
3551         } else {
3552                 return -ENOMEM;
3553         }
3554 }
3555
3556 #endif
3557
3558
3559 static int __init init_yaffs_fs(void)
3560 {
3561         int error = 0;
3562         struct file_system_to_install *fsinst;
3563
3564         yaffs_trace(YAFFS_TRACE_ALWAYS,
3565                 "yaffs built " __DATE__ " " __TIME__ " Installing.");
3566
3567         mutex_init(&yaffs_context_lock);
3568
3569         error = yaffs_procfs_init();
3570         if (error)
3571                 return error;
3572
3573         /* Now add the file system entries */
3574
3575         fsinst = fs_to_install;
3576
3577         while (fsinst->fst && !error) {
3578                 error = register_filesystem(fsinst->fst);
3579                 if (!error)
3580                         fsinst->installed = 1;
3581                 fsinst++;
3582         }
3583
3584         /* Any errors? uninstall  */
3585         if (error) {
3586                 fsinst = fs_to_install;
3587
3588                 while (fsinst->fst) {
3589                         if (fsinst->installed) {
3590                                 unregister_filesystem(fsinst->fst);
3591                                 fsinst->installed = 0;
3592                         }
3593                         fsinst++;
3594                 }
3595         }
3596
3597         return error;
3598 }
3599
3600 static void __exit exit_yaffs_fs(void)
3601 {
3602
3603         struct file_system_to_install *fsinst;
3604
3605         yaffs_trace(YAFFS_TRACE_ALWAYS,
3606                 "yaffs built " __DATE__ " " __TIME__ " removing.");
3607
3608         remove_proc_entry("yaffs", YPROC_ROOT);
3609
3610         fsinst = fs_to_install;
3611
3612         while (fsinst->fst) {
3613                 if (fsinst->installed) {
3614                         unregister_filesystem(fsinst->fst);
3615                         fsinst->installed = 0;
3616                 }
3617                 fsinst++;
3618         }
3619 }
3620
3621 module_init(init_yaffs_fs)
3622     module_exit(exit_yaffs_fs)
3623
3624     MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
3625 MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2011");
3626 MODULE_LICENSE("GPL");