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