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