Fix hang caused by returning with lock held
[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                 yaffs_gross_unlock(dev);
1821                 return 0;
1822         }
1823
1824         curoffs = 1;
1825
1826         while (sc->next_return) {
1827                 curoffs++;
1828                 l = sc->next_return;
1829                 if (curoffs >= dc->pos) {
1830                         int this_inode = yaffs_get_obj_inode(l);
1831                         int this_type = yaffs_get_obj_type(l);
1832
1833                         yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
1834                         yaffs_trace(YAFFS_TRACE_OS,
1835                                 "yaffs_readdir: %s inode %d",
1836                                 name, yaffs_get_obj_inode(l));
1837
1838                         yaffs_gross_unlock(dev);
1839
1840                         if (!dir_emit(dc,
1841                                       name,
1842                                       strlen(name),
1843                                       this_inode,
1844                                       this_type)) {
1845                                 yaffs_gross_lock(dev);
1846                                 goto out;
1847                         }
1848
1849                         yaffs_gross_lock(dev);
1850
1851                         dc->pos++;
1852                         f->f_pos++;
1853                 }
1854                 yaffs_search_advance(sc);
1855         }
1856
1857 out:
1858         yaffs_search_end(sc);
1859         yaffs_dev_to_lc(dev)->readdir_process = NULL;
1860         yaffs_gross_unlock(dev);
1861
1862         return ret_val;
1863 }
1864
1865 #else
1866
1867 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
1868 {
1869         struct yaffs_obj *obj;
1870         struct yaffs_dev *dev;
1871         struct yaffs_search_context *sc;
1872         struct inode *inode = Y_GET_DENTRY(f)->d_inode;
1873         unsigned long offset, curoffs;
1874         struct yaffs_obj *l;
1875         int ret_val = 0;
1876
1877         char name[YAFFS_MAX_NAME_LENGTH + 1];
1878
1879         obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f));
1880         dev = obj->my_dev;
1881
1882         yaffs_gross_lock(dev);
1883
1884         yaffs_dev_to_lc(dev)->readdir_process = current;
1885
1886         offset = f->f_pos;
1887
1888         sc = yaffs_new_search(obj);
1889         if (!sc) {
1890                 ret_val = -ENOMEM;
1891                 goto out;
1892         }
1893
1894         yaffs_trace(YAFFS_TRACE_OS,
1895                 "yaffs_readdir: starting at %d", (int)offset);
1896
1897         if (offset == 0) {
1898                 yaffs_trace(YAFFS_TRACE_OS,
1899                         "yaffs_readdir: entry . ino %d",
1900                         (int)inode->i_ino);
1901                 yaffs_gross_unlock(dev);
1902                 if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0) {
1903                         yaffs_gross_lock(dev);
1904                         goto out;
1905                 }
1906                 yaffs_gross_lock(dev);
1907                 offset++;
1908                 f->f_pos++;
1909         }
1910         if (offset == 1) {
1911                 yaffs_trace(YAFFS_TRACE_OS,
1912                         "yaffs_readdir: entry .. ino %d",
1913                         (int)f->f_dentry->d_parent->d_inode->i_ino);
1914                 yaffs_gross_unlock(dev);
1915                 if (filldir(dirent, "..", 2, offset,
1916                             f->f_dentry->d_parent->d_inode->i_ino,
1917                             DT_DIR) < 0) {
1918                         yaffs_gross_lock(dev);
1919                         goto out;
1920                 }
1921                 yaffs_gross_lock(dev);
1922                 offset++;
1923                 f->f_pos++;
1924         }
1925
1926         curoffs = 1;
1927
1928         /* If the directory has changed since the open or last call to
1929            readdir, rewind to after the 2 canned entries. */
1930         if (f->f_version != inode->i_version) {
1931                 offset = 2;
1932                 f->f_pos = offset;
1933                 f->f_version = inode->i_version;
1934         }
1935
1936         while (sc->next_return) {
1937                 curoffs++;
1938                 l = sc->next_return;
1939                 if (curoffs >= offset) {
1940                         int this_inode = yaffs_get_obj_inode(l);
1941                         int this_type = yaffs_get_obj_type(l);
1942
1943                         yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
1944                         yaffs_trace(YAFFS_TRACE_OS,
1945                                 "yaffs_readdir: %s inode %d",
1946                                 name, yaffs_get_obj_inode(l));
1947
1948                         yaffs_gross_unlock(dev);
1949
1950                         if (filldir(dirent,
1951                                     name,
1952                                     strlen(name),
1953                                     offset, this_inode, this_type) < 0) {
1954                                 yaffs_gross_lock(dev);
1955                                 goto out;
1956                         }
1957
1958                         yaffs_gross_lock(dev);
1959
1960                         offset++;
1961                         f->f_pos++;
1962                 }
1963                 yaffs_search_advance(sc);
1964         }
1965
1966 out:
1967         yaffs_search_end(sc);
1968         yaffs_dev_to_lc(dev)->readdir_process = NULL;
1969         yaffs_gross_unlock(dev);
1970
1971         return ret_val;
1972 }
1973
1974 #endif
1975
1976 static const struct file_operations yaffs_dir_operations = {
1977         .read = generic_read_dir,
1978 #ifdef YAFFS_USE_DIR_ITERATE
1979         .iterate = yaffs_iterate,
1980 #else
1981         .readdir = yaffs_readdir,
1982 #endif
1983         .fsync = yaffs_sync_object,
1984         .llseek = generic_file_llseek,
1985 };
1986
1987 static void yaffs_fill_inode_from_obj(struct inode *inode,
1988                                       struct yaffs_obj *obj)
1989 {
1990         if (inode && obj) {
1991
1992                 /* Check mode against the variant type and attempt to repair if broken. */
1993                 u32 mode = obj->yst_mode;
1994                 switch (obj->variant_type) {
1995                 case YAFFS_OBJECT_TYPE_FILE:
1996                         if (!S_ISREG(mode)) {
1997                                 obj->yst_mode &= ~S_IFMT;
1998                                 obj->yst_mode |= S_IFREG;
1999                         }
2000
2001                         break;
2002                 case YAFFS_OBJECT_TYPE_SYMLINK:
2003                         if (!S_ISLNK(mode)) {
2004                                 obj->yst_mode &= ~S_IFMT;
2005                                 obj->yst_mode |= S_IFLNK;
2006                         }
2007
2008                         break;
2009                 case YAFFS_OBJECT_TYPE_DIRECTORY:
2010                         if (!S_ISDIR(mode)) {
2011                                 obj->yst_mode &= ~S_IFMT;
2012                                 obj->yst_mode |= S_IFDIR;
2013                         }
2014
2015                         break;
2016                 case YAFFS_OBJECT_TYPE_UNKNOWN:
2017                 case YAFFS_OBJECT_TYPE_HARDLINK:
2018                 case YAFFS_OBJECT_TYPE_SPECIAL:
2019                 default:
2020                         /* TODO? */
2021                         break;
2022                 }
2023
2024                 inode->i_flags |= S_NOATIME;
2025
2026                 inode->i_ino = obj->obj_id;
2027                 inode->i_mode = obj->yst_mode;
2028                 inode->i_uid = MAKE_uid(obj->yst_uid);
2029                 inode->i_gid = MAKE_gid(obj->yst_gid);
2030 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
2031                 inode->i_blksize = inode->i_sb->s_blocksize;
2032 #endif
2033 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2034
2035                 inode->i_rdev = old_decode_dev(obj->yst_rdev);
2036                 inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
2037                 inode->i_atime.tv_nsec = 0;
2038                 inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
2039                 inode->i_mtime.tv_nsec = 0;
2040                 inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
2041                 inode->i_ctime.tv_nsec = 0;
2042 #else
2043                 inode->i_rdev = obj->yst_rdev;
2044                 inode->i_atime = obj->yst_atime;
2045                 inode->i_mtime = obj->yst_mtime;
2046                 inode->i_ctime = obj->yst_ctime;
2047 #endif
2048                 inode->i_size = yaffs_get_obj_length(obj);
2049                 inode->i_blocks = (inode->i_size + 511) >> 9;
2050
2051                 set_nlink(inode, yaffs_get_obj_link_count(obj));
2052
2053                 yaffs_trace(YAFFS_TRACE_OS,
2054                         "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
2055                         inode->i_mode, obj->yst_uid, obj->yst_gid,
2056                         inode->i_size, atomic_read(&inode->i_count));
2057
2058                 switch (obj->yst_mode & S_IFMT) {
2059                 default:        /* fifo, device or socket */
2060 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2061                         init_special_inode(inode, obj->yst_mode,
2062                                            old_decode_dev(obj->yst_rdev));
2063 #else
2064                         init_special_inode(inode, obj->yst_mode,
2065                                            (dev_t) (obj->yst_rdev));
2066 #endif
2067                         break;
2068                 case S_IFREG:   /* file */
2069                         inode->i_op = &yaffs_file_inode_operations;
2070                         inode->i_fop = &yaffs_file_operations;
2071                         inode->i_mapping->a_ops =
2072                             &yaffs_file_address_operations;
2073                         break;
2074                 case S_IFDIR:   /* directory */
2075                         inode->i_op = &yaffs_dir_inode_operations;
2076                         inode->i_fop = &yaffs_dir_operations;
2077                         break;
2078                 case S_IFLNK:   /* symlink */
2079                         inode->i_op = &yaffs_symlink_inode_operations;
2080                         break;
2081                 }
2082
2083                 yaffs_inode_to_obj_lv(inode) = obj;
2084
2085                 obj->my_inode = inode;
2086
2087         } else {
2088                 yaffs_trace(YAFFS_TRACE_OS,
2089                         "yaffs_fill_inode invalid parameters");
2090         }
2091
2092 }
2093
2094
2095
2096 /*
2097  * yaffs background thread functions .
2098  * yaffs_bg_thread_fn() the thread function
2099  * yaffs_bg_start() launches the background thread.
2100  * yaffs_bg_stop() cleans up the background thread.
2101  *
2102  * NB:
2103  * The thread should only run after the yaffs is initialised
2104  * The thread should be stopped before yaffs is unmounted.
2105  * The thread should not do any writing while the fs is in read only.
2106  */
2107
2108 static unsigned yaffs_bg_gc_urgency(struct yaffs_dev *dev)
2109 {
2110         unsigned erased_chunks =
2111             dev->n_erased_blocks * dev->param.chunks_per_block;
2112         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2113         unsigned scattered = 0; /* Free chunks not in an erased block */
2114
2115         if (erased_chunks < dev->n_free_chunks)
2116                 scattered = (dev->n_free_chunks - erased_chunks);
2117
2118         if (!context->bg_running)
2119                 return 0;
2120         else if (scattered < (dev->param.chunks_per_block * 2))
2121                 return 0;
2122         else if (erased_chunks > dev->n_free_chunks / 2)
2123                 return 0;
2124         else if (erased_chunks > dev->n_free_chunks / 4)
2125                 return 1;
2126         else
2127                 return 2;
2128 }
2129
2130 #ifdef YAFFS_COMPILE_BACKGROUND
2131
2132 void yaffs_background_waker(unsigned long data)
2133 {
2134         wake_up_process((struct task_struct *)data);
2135 }
2136
2137 static int yaffs_bg_thread_fn(void *data)
2138 {
2139         struct yaffs_dev *dev = (struct yaffs_dev *)data;
2140         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2141         unsigned long now = jiffies;
2142         unsigned long next_dir_update = now;
2143         unsigned long next_gc = now;
2144         unsigned long expires;
2145         unsigned int urgency;
2146
2147         int gc_result;
2148         struct timer_list timer;
2149
2150         yaffs_trace(YAFFS_TRACE_BACKGROUND,
2151                 "yaffs_background starting for dev %p", (void *)dev);
2152
2153 #ifdef YAFFS_COMPILE_FREEZER
2154         set_freezable();
2155 #endif
2156         while (context->bg_running) {
2157                 yaffs_trace(YAFFS_TRACE_BACKGROUND, "yaffs_background");
2158
2159                 if (kthread_should_stop())
2160                         break;
2161
2162 #ifdef YAFFS_COMPILE_FREEZER
2163                 if (try_to_freeze())
2164                         continue;
2165 #endif
2166                 yaffs_gross_lock(dev);
2167
2168                 now = jiffies;
2169
2170                 if (time_after(now, next_dir_update) && yaffs_bg_enable) {
2171                         yaffs_update_dirty_dirs(dev);
2172                         next_dir_update = now + HZ;
2173                 }
2174
2175                 if (time_after(now, next_gc) && yaffs_bg_enable) {
2176                         if (!dev->is_checkpointed) {
2177                                 urgency = yaffs_bg_gc_urgency(dev);
2178                                 gc_result = yaffs_bg_gc(dev, urgency);
2179                                 if (urgency > 1)
2180                                         next_gc = now + HZ / 20 + 1;
2181                                 else if (urgency > 0)
2182                                         next_gc = now + HZ / 10 + 1;
2183                                 else
2184                                         next_gc = now + HZ * 2;
2185                         } else  {
2186                                 /*
2187                                  * gc not running so set to next_dir_update
2188                                  * to cut down on wake ups
2189                                  */
2190                                 next_gc = next_dir_update;
2191                         }
2192                 }
2193                 yaffs_gross_unlock(dev);
2194 #if 1
2195                 expires = next_dir_update;
2196                 if (time_before(next_gc, expires))
2197                         expires = next_gc;
2198                 if (time_before(expires, now))
2199                         expires = now + HZ;
2200
2201                 Y_INIT_TIMER(&timer);
2202                 timer.expires = expires + 1;
2203                 timer.data = (unsigned long)current;
2204                 timer.function = yaffs_background_waker;
2205
2206                 set_current_state(TASK_INTERRUPTIBLE);
2207                 add_timer(&timer);
2208                 schedule();
2209                 del_timer_sync(&timer);
2210 #else
2211                 msleep(10);
2212 #endif
2213         }
2214
2215         return 0;
2216 }
2217
2218 static int yaffs_bg_start(struct yaffs_dev *dev)
2219 {
2220         int retval = 0;
2221         struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
2222
2223         if (dev->read_only)
2224                 return -1;
2225
2226         context->bg_running = 1;
2227
2228         context->bg_thread = kthread_run(yaffs_bg_thread_fn,
2229                                          (void *)dev, "yaffs-bg-%d",
2230                                          context->mount_id);
2231
2232         if (IS_ERR(context->bg_thread)) {
2233                 retval = PTR_ERR(context->bg_thread);
2234                 context->bg_thread = NULL;
2235                 context->bg_running = 0;
2236         }
2237         return retval;
2238 }
2239
2240 static void yaffs_bg_stop(struct yaffs_dev *dev)
2241 {
2242         struct yaffs_linux_context *ctxt = yaffs_dev_to_lc(dev);
2243
2244         ctxt->bg_running = 0;
2245
2246         if (ctxt->bg_thread) {
2247                 kthread_stop(ctxt->bg_thread);
2248                 ctxt->bg_thread = NULL;
2249         }
2250 }
2251 #else
2252 static int yaffs_bg_thread_fn(void *data)
2253 {
2254         return 0;
2255 }
2256
2257 static int yaffs_bg_start(struct yaffs_dev *dev)
2258 {
2259         return 0;
2260 }
2261
2262 static void yaffs_bg_stop(struct yaffs_dev *dev)
2263 {
2264 }
2265 #endif
2266
2267
2268 static void yaffs_flush_inodes(struct super_block *sb)
2269 {
2270         struct inode *iptr;
2271         struct yaffs_obj *obj;
2272
2273         list_for_each_entry(iptr, &sb->s_inodes, i_sb_list) {
2274                 obj = yaffs_inode_to_obj(iptr);
2275                 if (obj) {
2276                         yaffs_trace(YAFFS_TRACE_OS,
2277                                 "flushing obj %d",
2278                                 obj->obj_id);
2279                         yaffs_flush_file(obj, 1, 0, 0);
2280                 }
2281         }
2282 }
2283
2284 static void yaffs_flush_super(struct super_block *sb, int do_checkpoint)
2285 {
2286         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2287         if (!dev)
2288                 return;
2289
2290         yaffs_flush_inodes(sb);
2291         yaffs_update_dirty_dirs(dev);
2292         yaffs_flush_whole_cache(dev, 1);
2293         if (do_checkpoint)
2294                 yaffs_checkpoint_save(dev);
2295 }
2296
2297 static LIST_HEAD(yaffs_context_list);
2298 struct mutex yaffs_context_lock;
2299
2300 static void yaffs_put_super(struct super_block *sb)
2301 {
2302         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2303         struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
2304
2305         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
2306                         "yaffs_put_super");
2307
2308         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
2309                 "Shutting down yaffs background thread");
2310         yaffs_bg_stop(dev);
2311         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
2312                 "yaffs background thread shut down");
2313
2314         yaffs_gross_lock(dev);
2315
2316         yaffs_flush_super(sb, 1);
2317
2318         yaffs_deinitialise(dev);
2319
2320         yaffs_gross_unlock(dev);
2321
2322         mutex_lock(&yaffs_context_lock);
2323         list_del_init(&(yaffs_dev_to_lc(dev)->context_list));
2324         mutex_unlock(&yaffs_context_lock);
2325
2326         if (yaffs_dev_to_lc(dev)->spare_buffer) {
2327                 kfree(yaffs_dev_to_lc(dev)->spare_buffer);
2328                 yaffs_dev_to_lc(dev)->spare_buffer = NULL;
2329         }
2330
2331         kfree(dev);
2332
2333         yaffs_put_mtd_device(mtd);
2334
2335         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
2336                         "yaffs_put_super done");
2337 }
2338
2339
2340 static unsigned yaffs_gc_control_callback(struct yaffs_dev *dev)
2341 {
2342         return yaffs_gc_control;
2343 }
2344
2345
2346 #ifdef YAFFS_COMPILE_EXPORTFS
2347
2348 static struct inode *yaffs2_nfs_get_inode(struct super_block *sb, uint64_t ino,
2349                                           uint32_t generation)
2350 {
2351         return Y_IGET(sb, ino);
2352 }
2353
2354 static struct dentry *yaffs2_fh_to_dentry(struct super_block *sb,
2355                                           struct fid *fid, int fh_len,
2356                                           int fh_type)
2357 {
2358         return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
2359                                     yaffs2_nfs_get_inode);
2360 }
2361
2362 static struct dentry *yaffs2_fh_to_parent(struct super_block *sb,
2363                                           struct fid *fid, int fh_len,
2364                                           int fh_type)
2365 {
2366         return generic_fh_to_parent(sb, fid, fh_len, fh_type,
2367                                     yaffs2_nfs_get_inode);
2368 }
2369
2370 struct dentry *yaffs2_get_parent(struct dentry *dentry)
2371 {
2372
2373         struct super_block *sb = dentry->d_inode->i_sb;
2374         struct dentry *parent = ERR_PTR(-ENOENT);
2375         struct inode *inode;
2376         unsigned long parent_ino;
2377         struct yaffs_obj *d_obj;
2378         struct yaffs_obj *parent_obj;
2379
2380         d_obj = yaffs_inode_to_obj(dentry->d_inode);
2381
2382         if (d_obj) {
2383                 parent_obj = d_obj->parent;
2384                 if (parent_obj) {
2385                         parent_ino = yaffs_get_obj_inode(parent_obj);
2386                         inode = Y_IGET(sb, parent_ino);
2387
2388                         if (IS_ERR(inode)) {
2389                                 parent = ERR_CAST(inode);
2390                         } else {
2391                                 parent = d_obtain_alias(inode);
2392                                 if (!IS_ERR(parent)) {
2393                                         parent = ERR_PTR(-ENOMEM);
2394                                         iput(inode);
2395                                 }
2396                         }
2397                 }
2398         }
2399
2400         return parent;
2401 }
2402
2403 /* Just declare a zero structure as a NULL value implies
2404  * using the default functions of exportfs.
2405  */
2406
2407 static struct export_operations yaffs_export_ops = {
2408         .fh_to_dentry = yaffs2_fh_to_dentry,
2409         .fh_to_parent = yaffs2_fh_to_parent,
2410         .get_parent = yaffs2_get_parent,
2411 };
2412
2413 #endif
2414
2415 static void yaffs_unstitch_obj(struct inode *inode, struct yaffs_obj *obj)
2416 {
2417         /* Clear the association between the inode and
2418          * the struct yaffs_obj.
2419          */
2420         obj->my_inode = NULL;
2421         yaffs_inode_to_obj_lv(inode) = NULL;
2422
2423         /* If the object freeing was deferred, then the real
2424          * free happens now.
2425          * This should fix the inode inconsistency problem.
2426          */
2427         yaffs_handle_defered_free(obj);
2428 }
2429
2430 #ifdef YAFFS_HAS_EVICT_INODE
2431 /* yaffs_evict_inode combines into one operation what was previously done in
2432  * yaffs_clear_inode() and yaffs_delete_inode()
2433  *
2434  */
2435 static void yaffs_evict_inode(struct inode *inode)
2436 {
2437         struct yaffs_obj *obj;
2438         struct yaffs_dev *dev;
2439         int deleteme = 0;
2440
2441         obj = yaffs_inode_to_obj(inode);
2442
2443         yaffs_trace(YAFFS_TRACE_OS,
2444                 "yaffs_evict_inode: ino %d, count %d %s",
2445                 (int)inode->i_ino, atomic_read(&inode->i_count),
2446                 obj ? "object exists" : "null object");
2447
2448         if (!inode->i_nlink && !is_bad_inode(inode))
2449                 deleteme = 1;
2450         truncate_inode_pages(&inode->i_data, 0);
2451         Y_CLEAR_INODE(inode);
2452
2453         if (deleteme && obj) {
2454                 dev = obj->my_dev;
2455                 yaffs_gross_lock(dev);
2456                 yaffs_del_obj(obj);
2457                 yaffs_gross_unlock(dev);
2458         }
2459         if (obj) {
2460                 dev = obj->my_dev;
2461                 yaffs_gross_lock(dev);
2462                 yaffs_unstitch_obj(inode, obj);
2463                 yaffs_gross_unlock(dev);
2464         }
2465 }
2466 #else
2467
2468 /* clear is called to tell the fs to release any per-inode data it holds.
2469  * The object might still exist on disk and is just being thrown out of the cache
2470  * or else the object has actually been deleted and we're being called via
2471  * the chain
2472  *   yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode()
2473  */
2474
2475 static void yaffs_clear_inode(struct inode *inode)
2476 {
2477         struct yaffs_obj *obj;
2478         struct yaffs_dev *dev;
2479
2480         obj = yaffs_inode_to_obj(inode);
2481
2482         yaffs_trace(YAFFS_TRACE_OS,
2483                 "yaffs_clear_inode: ino %d, count %d %s",
2484                 (int)inode->i_ino, atomic_read(&inode->i_count),
2485                 obj ? "object exists" : "null object");
2486
2487         if (obj) {
2488                 dev = obj->my_dev;
2489                 yaffs_gross_lock(dev);
2490                 yaffs_unstitch_obj(inode, obj);
2491                 yaffs_gross_unlock(dev);
2492         }
2493
2494 }
2495
2496 /* delete is called when the link count is zero and the inode
2497  * is put (ie. nobody wants to know about it anymore, time to
2498  * delete the file).
2499  * NB Must call clear_inode()
2500  */
2501 static void yaffs_delete_inode(struct inode *inode)
2502 {
2503         struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
2504         struct yaffs_dev *dev;
2505
2506         yaffs_trace(YAFFS_TRACE_OS,
2507                 "yaffs_delete_inode: ino %d, count %d %s",
2508                 (int)inode->i_ino, atomic_read(&inode->i_count),
2509                 obj ? "object exists" : "null object");
2510
2511         if (obj) {
2512                 dev = obj->my_dev;
2513                 yaffs_gross_lock(dev);
2514                 yaffs_del_obj(obj);
2515                 yaffs_gross_unlock(dev);
2516         }
2517 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
2518         truncate_inode_pages(&inode->i_data, 0);
2519 #endif
2520         clear_inode(inode);
2521 }
2522 #endif
2523
2524
2525
2526
2527 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2528 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
2529 {
2530         struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
2531         struct super_block *sb = dentry->d_sb;
2532 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2533 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
2534 {
2535         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2536 #else
2537 static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
2538 {
2539         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2540 #endif
2541
2542         yaffs_trace(YAFFS_TRACE_OS, "yaffs_statfs");
2543
2544         yaffs_gross_lock(dev);
2545
2546         buf->f_type = YAFFS_MAGIC;
2547         buf->f_bsize = sb->s_blocksize;
2548         buf->f_namelen = 255;
2549
2550         if (dev->data_bytes_per_chunk & (dev->data_bytes_per_chunk - 1)) {
2551                 /* Do this if chunk size is not a power of 2 */
2552
2553                 uint64_t bytes_in_dev;
2554                 uint64_t bytes_free;
2555
2556                 bytes_in_dev =
2557                     ((uint64_t)
2558                      ((dev->param.end_block - dev->param.start_block +
2559                        1))) * ((uint64_t) (dev->param.chunks_per_block *
2560                                            dev->data_bytes_per_chunk));
2561
2562                 do_div(bytes_in_dev, sb->s_blocksize);  /* bytes_in_dev becomes the number of blocks */
2563                 buf->f_blocks = bytes_in_dev;
2564
2565                 bytes_free = ((uint64_t) (yaffs_get_n_free_chunks(dev))) *
2566                     ((uint64_t) (dev->data_bytes_per_chunk));
2567
2568                 do_div(bytes_free, sb->s_blocksize);
2569
2570                 buf->f_bfree = bytes_free;
2571
2572         } else if (sb->s_blocksize > dev->data_bytes_per_chunk) {
2573
2574                 buf->f_blocks =
2575                     (dev->param.end_block - dev->param.start_block + 1) *
2576                     dev->param.chunks_per_block /
2577                     (sb->s_blocksize / dev->data_bytes_per_chunk);
2578                 buf->f_bfree =
2579                     yaffs_get_n_free_chunks(dev) /
2580                     (sb->s_blocksize / dev->data_bytes_per_chunk);
2581         } else {
2582                 buf->f_blocks =
2583                     (dev->param.end_block - dev->param.start_block + 1) *
2584                     dev->param.chunks_per_block *
2585                     (dev->data_bytes_per_chunk / sb->s_blocksize);
2586
2587                 buf->f_bfree =
2588                     yaffs_get_n_free_chunks(dev) *
2589                     (dev->data_bytes_per_chunk / sb->s_blocksize);
2590         }
2591
2592         buf->f_files = 0;
2593         buf->f_ffree = 0;
2594         buf->f_bavail = buf->f_bfree;
2595
2596         yaffs_gross_unlock(dev);
2597         return 0;
2598 }
2599
2600
2601
2602 static int yaffs_do_sync_fs(struct super_block *sb, int request_checkpoint)
2603 {
2604
2605         struct yaffs_dev *dev = yaffs_super_to_dev(sb);
2606         unsigned int oneshot_checkpoint = (yaffs_auto_checkpoint & 4);
2607         unsigned gc_urgent = yaffs_bg_gc_urgency(dev);
2608         int do_checkpoint;
2609         int dirty = yaffs_check_super_dirty(dev);
2610
2611         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
2612                 "yaffs_do_sync_fs: gc-urgency %d %s %s%s",
2613                 gc_urgent,
2614                 dirty ? "dirty" : "clean",
2615                 request_checkpoint ? "checkpoint requested" : "no checkpoint",
2616                 oneshot_checkpoint ? " one-shot" : "");
2617
2618         yaffs_gross_lock(dev);
2619         do_checkpoint = ((request_checkpoint && !gc_urgent) ||
2620                          oneshot_checkpoint) && !dev->is_checkpointed;
2621
2622         if (dirty || do_checkpoint) {
2623                 yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint);
2624                 yaffs_clear_super_dirty(dev);
2625                 if (oneshot_checkpoint)
2626                         yaffs_auto_checkpoint &= ~4;
2627         }
2628         yaffs_gross_unlock(dev);
2629
2630         return 0;
2631 }
2632
2633
2634 #ifdef YAFFS_HAS_WRITE_SUPER
2635 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2636 static void yaffs_write_super(struct super_block *sb)
2637 #else
2638 static int yaffs_write_super(struct super_block *sb)
2639 #endif
2640 {
2641         unsigned request_checkpoint = (yaffs_auto_checkpoint >= 2);
2642
2643         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
2644                 "yaffs_write_super %s",
2645                 request_checkpoint ? " checkpt" : "");
2646
2647         yaffs_do_sync_fs(sb, request_checkpoint);
2648
2649 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
2650         return 0;
2651 #endif
2652 }
2653 #endif
2654
2655 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2656 static int yaffs_sync_fs(struct super_block *sb, int wait)
2657 #else
2658 static int yaffs_sync_fs(struct super_block *sb)
2659 #endif
2660 {
2661         unsigned request_checkpoint = (yaffs_auto_checkpoint >= 1);
2662
2663         yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
2664                 "yaffs_sync_fs%s", request_checkpoint ? " checkpt" : "");
2665
2666         yaffs_do_sync_fs(sb, request_checkpoint);
2667
2668         return 0;
2669 }
2670
2671 /* the function only is used to change dev->read_only when this file system
2672  * is remounted.
2673  */
2674 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
2675 {
2676         int read_only = 0;
2677         struct mtd_info *mtd;
2678         struct yaffs_dev *dev = 0;
2679
2680         /* Get the device */
2681         mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
2682         if (!mtd) {
2683                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2684                         "MTD device #%u doesn't appear to exist",
2685                         MINOR(sb->s_dev));
2686                 return 1;
2687         }
2688
2689         /* Check it's NAND */
2690         if (mtd->type != MTD_NANDFLASH) {
2691                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2692                         "MTD device is not NAND it's type %d",
2693                         mtd->type);
2694                 return 1;
2695         }
2696
2697         read_only = ((*flags & MS_RDONLY) != 0);
2698         if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
2699                 read_only = 1;
2700                 printk(KERN_INFO
2701                         "yaffs: mtd is read only, setting superblock read only");
2702                 *flags |= MS_RDONLY;
2703         }
2704
2705         dev = sb->s_fs_info;
2706         dev->read_only = read_only;
2707
2708         return 0;
2709 }
2710
2711 static const struct super_operations yaffs_super_ops = {
2712         .statfs = yaffs_statfs,
2713
2714 #ifndef YAFFS_USE_OWN_IGET
2715         .read_inode = yaffs_read_inode,
2716 #endif
2717 #ifdef YAFFS_HAS_PUT_INODE
2718         .put_inode = yaffs_put_inode,
2719 #endif
2720         .put_super = yaffs_put_super,
2721 #ifdef YAFFS_HAS_EVICT_INODE
2722         .evict_inode = yaffs_evict_inode,
2723 #else
2724         .delete_inode = yaffs_delete_inode,
2725         .clear_inode = yaffs_clear_inode,
2726 #endif
2727         .sync_fs = yaffs_sync_fs,
2728 #ifdef YAFFS_HAS_WRITE_SUPER
2729         .write_super = yaffs_write_super,
2730 #endif
2731         .remount_fs = yaffs_remount_fs,
2732 };
2733
2734 struct yaffs_options {
2735         int inband_tags;
2736         int skip_checkpoint_read;
2737         int skip_checkpoint_write;
2738         int no_cache;
2739         int tags_ecc_on;
2740         int tags_ecc_overridden;
2741         int lazy_loading_enabled;
2742         int lazy_loading_overridden;
2743         int empty_lost_and_found;
2744         int empty_lost_and_found_overridden;
2745         int disable_summary;
2746 };
2747
2748 #define MAX_OPT_LEN 30
2749 static int yaffs_parse_options(struct yaffs_options *options,
2750                                const char *options_str)
2751 {
2752         char cur_opt[MAX_OPT_LEN + 1];
2753         int p;
2754         int error = 0;
2755
2756         /* Parse through the options which is a comma seperated list */
2757
2758         while (options_str && *options_str && !error) {
2759                 memset(cur_opt, 0, MAX_OPT_LEN + 1);
2760                 p = 0;
2761
2762                 while (*options_str == ',')
2763                         options_str++;
2764
2765                 while (*options_str && *options_str != ',') {
2766                         if (p < MAX_OPT_LEN) {
2767                                 cur_opt[p] = *options_str;
2768                                 p++;
2769                         }
2770                         options_str++;
2771                 }
2772
2773                 if (!strcmp(cur_opt, "inband-tags")) {
2774                         options->inband_tags = 1;
2775                 } else if (!strcmp(cur_opt, "tags-ecc-off")) {
2776                         options->tags_ecc_on = 0;
2777                         options->tags_ecc_overridden = 1;
2778                 } else if (!strcmp(cur_opt, "tags-ecc-on")) {
2779                         options->tags_ecc_on = 1;
2780                         options->tags_ecc_overridden = 1;
2781                 } else if (!strcmp(cur_opt, "lazy-loading-off")) {
2782                         options->lazy_loading_enabled = 0;
2783                         options->lazy_loading_overridden = 1;
2784                 } else if (!strcmp(cur_opt, "lazy-loading-on")) {
2785                         options->lazy_loading_enabled = 1;
2786                         options->lazy_loading_overridden = 1;
2787                 } else if (!strcmp(cur_opt, "disable-summary")) {
2788                         options->disable_summary = 1;
2789                 } else if (!strcmp(cur_opt, "empty-lost-and-found-off")) {
2790                         options->empty_lost_and_found = 0;
2791                         options->empty_lost_and_found_overridden = 1;
2792                 } else if (!strcmp(cur_opt, "empty-lost-and-found-on")) {
2793                         options->empty_lost_and_found = 1;
2794                         options->empty_lost_and_found_overridden = 1;
2795                 } else if (!strcmp(cur_opt, "no-cache")) {
2796                         options->no_cache = 1;
2797                 } else if (!strcmp(cur_opt, "no-checkpoint-read")) {
2798                         options->skip_checkpoint_read = 1;
2799                 } else if (!strcmp(cur_opt, "no-checkpoint-write")) {
2800                         options->skip_checkpoint_write = 1;
2801                 } else if (!strcmp(cur_opt, "no-checkpoint")) {
2802                         options->skip_checkpoint_read = 1;
2803                         options->skip_checkpoint_write = 1;
2804                 } else {
2805                         printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
2806                                cur_opt);
2807                         error = 1;
2808                 }
2809         }
2810
2811         return error;
2812 }
2813
2814
2815 static struct dentry *yaffs_make_root(struct inode *inode)
2816 {
2817 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
2818         struct dentry *root = d_alloc_root(inode);
2819
2820         if (!root)
2821                 iput(inode);
2822
2823         return root;
2824 #else
2825         return d_make_root(inode);
2826 #endif
2827 }
2828
2829
2830
2831
2832 static struct super_block *yaffs_internal_read_super(int yaffs_version,
2833                                                      struct super_block *sb,
2834                                                      void *data, int silent)
2835 {
2836         int n_blocks;
2837         struct inode *inode = NULL;
2838         struct dentry *root;
2839         struct yaffs_dev *dev = 0;
2840         char devname_buf[BDEVNAME_SIZE + 1];
2841         struct mtd_info *mtd;
2842         int err;
2843         char *data_str = (char *)data;
2844         struct yaffs_linux_context *context = NULL;
2845         struct yaffs_param *param;
2846
2847         int read_only = 0;
2848         int inband_tags = 0;
2849
2850         struct yaffs_options options;
2851
2852         unsigned mount_id;
2853         int found;
2854         struct yaffs_linux_context *context_iterator;
2855         struct list_head *l;
2856
2857         if (!sb) {
2858                 printk(KERN_INFO "yaffs: sb is NULL\n");
2859                 return NULL;
2860         }
2861
2862         sb->s_magic = YAFFS_MAGIC;
2863         sb->s_op = &yaffs_super_ops;
2864         sb->s_flags |= MS_NOATIME;
2865
2866         read_only = ((sb->s_flags & MS_RDONLY) != 0);
2867
2868 #ifdef YAFFS_COMPILE_EXPORTFS
2869         sb->s_export_op = &yaffs_export_ops;
2870 #endif
2871
2872         if (!sb->s_dev)
2873                 printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
2874         else if (!yaffs_devname(sb, devname_buf))
2875                 printk(KERN_INFO "yaffs: devname is NULL\n");
2876         else
2877                 printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
2878                        sb->s_dev,
2879                        yaffs_devname(sb, devname_buf), read_only ? "ro" : "rw");
2880
2881         if (!data_str)
2882                 data_str = "";
2883
2884         printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
2885
2886         memset(&options, 0, sizeof(options));
2887
2888         if (yaffs_parse_options(&options, data_str)) {
2889                 /* Option parsing failed */
2890                 return NULL;
2891         }
2892
2893         sb->s_blocksize = PAGE_CACHE_SIZE;
2894         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
2895
2896         yaffs_trace(YAFFS_TRACE_OS,
2897                 "yaffs_read_super: Using yaffs%d", yaffs_version);
2898         yaffs_trace(YAFFS_TRACE_OS,
2899                 "yaffs_read_super: block size %d", (int)(sb->s_blocksize));
2900
2901         yaffs_trace(YAFFS_TRACE_ALWAYS,
2902                 "yaffs: Attempting MTD mount of %u.%u,\"%s\"",
2903                 MAJOR(sb->s_dev), MINOR(sb->s_dev),
2904                 yaffs_devname(sb, devname_buf));
2905
2906         /* Get the device */
2907         mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
2908         if (IS_ERR(mtd)) {
2909                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2910                         "yaffs: MTD device %u either not valid or unavailable",
2911                         MINOR(sb->s_dev));
2912                 return NULL;
2913         }
2914
2915         if (yaffs_auto_select && yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) {
2916                 yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs2");
2917                 yaffs_version = 2;
2918         }
2919
2920         /* Added NCB 26/5/2006 for completeness */
2921         if (yaffs_version == 2 && !options.inband_tags
2922             && WRITE_SIZE(mtd) == 512) {
2923                 yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1");
2924                 yaffs_version = 1;
2925         }
2926
2927         if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) ||
2928             options.inband_tags)
2929                 inband_tags = 1;
2930
2931         if(yaffs_verify_mtd(mtd, yaffs_version, inband_tags) < 0)
2932                 return NULL;
2933
2934         /* OK, so if we got here, we have an MTD that's NAND and looks
2935          * like it has the right capabilities
2936          * Set the struct yaffs_dev up for mtd
2937          */
2938
2939         if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
2940                 read_only = 1;
2941                 printk(KERN_INFO
2942                        "yaffs: mtd is read only, setting superblock read only\n"
2943                 );
2944                 sb->s_flags |= MS_RDONLY;
2945         }
2946
2947         dev = kmalloc(sizeof(struct yaffs_dev), GFP_KERNEL);
2948         context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
2949
2950         if (!dev || !context) {
2951                 kfree(dev);
2952                 kfree(context);
2953                 dev = NULL;
2954                 context = NULL;
2955
2956                 /* Deep shit could not allocate device structure */
2957                 yaffs_trace(YAFFS_TRACE_ALWAYS,
2958                         "yaffs_read_super: Failed trying to allocate struct yaffs_dev."
2959                 );
2960                 return NULL;
2961         }
2962         memset(dev, 0, sizeof(struct yaffs_dev));
2963         param = &(dev->param);
2964
2965         memset(context, 0, sizeof(struct yaffs_linux_context));
2966         dev->os_context = context;
2967         INIT_LIST_HEAD(&(context->context_list));
2968         context->dev = dev;
2969         context->super = sb;
2970
2971         dev->read_only = read_only;
2972
2973 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2974         sb->s_fs_info = dev;
2975 #else
2976         sb->u.generic_sbp = dev;
2977 #endif
2978
2979
2980         dev->driver_context = mtd;
2981         param->name = mtd->name;
2982
2983         /* Set up the memory size parameters.... */
2984
2985
2986         param->n_reserved_blocks = 5;
2987         param->n_caches = (options.no_cache) ? 0 : 10;
2988         param->inband_tags = inband_tags;
2989
2990         param->enable_xattr = 1;
2991         if (options.lazy_loading_overridden)
2992                 param->disable_lazy_load = !options.lazy_loading_enabled;
2993
2994         param->defered_dir_update = 1;
2995
2996         if (options.tags_ecc_overridden)
2997                 param->no_tags_ecc = !options.tags_ecc_on;
2998
2999         param->empty_lost_n_found = 1;
3000         param->refresh_period = 500;
3001         param->disable_summary = options.disable_summary;
3002
3003
3004 #ifdef CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING
3005         param->disable_bad_block_marking  = 1;
3006 #endif
3007         if (options.empty_lost_and_found_overridden)
3008                 param->empty_lost_n_found = options.empty_lost_and_found;
3009
3010         /* ... and the functions. */
3011         if (yaffs_version == 2) {
3012                 param->is_yaffs2 = 1;
3013 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3014                 param->total_bytes_per_chunk = mtd->writesize;
3015                 param->chunks_per_block = mtd->erasesize / mtd->writesize;
3016 #else
3017                 param->total_bytes_per_chunk = mtd->oobblock;
3018                 param->chunks_per_block = mtd->erasesize / mtd->oobblock;
3019 #endif
3020                 n_blocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
3021
3022                 param->start_block = 0;
3023                 param->end_block = n_blocks - 1;
3024         } else {
3025                 param->is_yaffs2 = 0;
3026                 n_blocks = YCALCBLOCKS(mtd->size,
3027                              YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
3028
3029                 param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
3030                 param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
3031         }
3032
3033         param->start_block = 0;
3034         param->end_block = n_blocks - 1;
3035
3036         yaffs_mtd_drv_install(dev);
3037
3038         param->sb_dirty_fn = yaffs_set_super_dirty;
3039         param->gc_control_fn = yaffs_gc_control_callback;
3040
3041         yaffs_dev_to_lc(dev)->super = sb;
3042
3043         param->use_nand_ecc = 1;
3044
3045         param->skip_checkpt_rd = options.skip_checkpoint_read;
3046         param->skip_checkpt_wr = options.skip_checkpoint_write;
3047
3048         mutex_lock(&yaffs_context_lock);
3049         /* Get a mount id */
3050         found = 0;
3051         for (mount_id = 0; !found; mount_id++) {
3052                 found = 1;
3053                 list_for_each(l, &yaffs_context_list) {
3054                         context_iterator =
3055                             list_entry(l, struct yaffs_linux_context,
3056                                        context_list);
3057                         if (context_iterator->mount_id == mount_id)
3058                                 found = 0;
3059                 }
3060         }
3061         context->mount_id = mount_id;
3062
3063         list_add_tail(&(yaffs_dev_to_lc(dev)->context_list),
3064                       &yaffs_context_list);
3065         mutex_unlock(&yaffs_context_lock);
3066
3067         /* Directory search handling... */
3068         INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->search_contexts));
3069         param->remove_obj_fn = yaffs_remove_obj_callback;
3070
3071         mutex_init(&(yaffs_dev_to_lc(dev)->gross_lock));
3072
3073         yaffs_gross_lock(dev);
3074
3075         err = yaffs_guts_initialise(dev);
3076
3077         yaffs_trace(YAFFS_TRACE_OS,
3078                 "yaffs_read_super: guts initialised %s",
3079                 (err == YAFFS_OK) ? "OK" : "FAILED");
3080
3081         if (err == YAFFS_OK)
3082                 yaffs_bg_start(dev);
3083
3084         if (!context->bg_thread)
3085                 param->defered_dir_update = 0;
3086
3087         sb->s_maxbytes = yaffs_max_file_size(dev);
3088
3089         /* Release lock before yaffs_get_inode() */
3090         yaffs_gross_unlock(dev);
3091
3092         /* Create root inode */
3093         if (err == YAFFS_OK)
3094                 inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_root(dev));
3095
3096         if (!inode)
3097                 return NULL;
3098
3099         inode->i_op = &yaffs_dir_inode_operations;
3100         inode->i_fop = &yaffs_dir_operations;
3101
3102         yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode");
3103
3104         root = yaffs_make_root(inode);
3105
3106         if (!root)
3107                 return NULL;
3108
3109         sb->s_root = root;
3110         if(!dev->is_checkpointed)
3111                 yaffs_set_super_dirty(dev);
3112
3113         yaffs_trace(YAFFS_TRACE_ALWAYS,
3114                 "yaffs_read_super: is_checkpointed %d",
3115                 dev->is_checkpointed);
3116
3117         yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: done");
3118         return sb;
3119 }
3120
3121 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3122 static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
3123                                          int silent)
3124 {
3125         return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
3126 }
3127
3128 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3129 static struct dentry *yaffs_mount(struct file_system_type *fs_type, int flags,
3130         const char *dev_name, void *data)
3131 {
3132     return mount_bdev(fs_type, flags, dev_name, data, yaffs_internal_read_super_mtd);
3133 }
3134 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3135 static int yaffs_read_super(struct file_system_type *fs,
3136                             int flags, const char *dev_name,
3137                             void *data, struct vfsmount *mnt)
3138 {
3139
3140         return get_sb_bdev(fs, flags, dev_name, data,
3141                            yaffs_internal_read_super_mtd, mnt);
3142 }
3143 #else
3144 static struct super_block *yaffs_read_super(struct file_system_type *fs,
3145                                             int flags, const char *dev_name,
3146                                             void *data)
3147 {
3148
3149         return get_sb_bdev(fs, flags, dev_name, data,
3150                            yaffs_internal_read_super_mtd);
3151 }
3152 #endif
3153
3154 static struct file_system_type yaffs_fs_type = {
3155         .owner = THIS_MODULE,
3156         .name = "yaffs",
3157 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3158         .mount = yaffs_mount,
3159 #else
3160         .get_sb = yaffs_read_super,
3161 #endif
3162         .kill_sb = kill_block_super,
3163         .fs_flags = FS_REQUIRES_DEV,
3164 };
3165 #else
3166 static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
3167                                             int silent)
3168 {
3169         return yaffs_internal_read_super(1, sb, data, silent);
3170 }
3171
3172 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
3173                       FS_REQUIRES_DEV);
3174 #endif
3175
3176
3177 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3178 static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
3179                                           int silent)
3180 {
3181         return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
3182 }
3183
3184 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3185 static struct dentry *yaffs2_mount(struct file_system_type *fs_type, int flags,
3186         const char *dev_name, void *data)
3187 {
3188         return mount_bdev(fs_type, flags, dev_name, data, yaffs2_internal_read_super_mtd);
3189 }
3190 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3191 static int yaffs2_read_super(struct file_system_type *fs,
3192                              int flags, const char *dev_name, void *data,
3193                              struct vfsmount *mnt)
3194 {
3195         return get_sb_bdev(fs, flags, dev_name, data,
3196                            yaffs2_internal_read_super_mtd, mnt);
3197 }
3198 #else
3199 static struct super_block *yaffs2_read_super(struct file_system_type *fs,
3200                                              int flags, const char *dev_name,
3201                                              void *data)
3202 {
3203
3204         return get_sb_bdev(fs, flags, dev_name, data,
3205                            yaffs2_internal_read_super_mtd);
3206 }
3207 #endif
3208
3209 static struct file_system_type yaffs2_fs_type = {
3210         .owner = THIS_MODULE,
3211         .name = "yaffs2",
3212 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
3213         .mount = yaffs2_mount,
3214 #else
3215         .get_sb = yaffs2_read_super,
3216 #endif
3217         .kill_sb = kill_block_super,
3218         .fs_flags = FS_REQUIRES_DEV,
3219 };
3220 #else
3221 static struct super_block *yaffs2_read_super(struct super_block *sb,
3222                                              void *data, int silent)
3223 {
3224         return yaffs_internal_read_super(2, sb, data, silent);
3225 }
3226
3227 static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
3228                       FS_REQUIRES_DEV);
3229 #endif
3230
3231
3232 static struct proc_dir_entry *my_proc_entry;
3233
3234 static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
3235 {
3236         struct yaffs_param *param = &dev->param;
3237         int bs[10];
3238
3239         yaffs_count_blocks_by_state(dev,bs);
3240
3241         buf += sprintf(buf, "start_block.......... %d\n", param->start_block);
3242         buf += sprintf(buf, "end_block............ %d\n", param->end_block);
3243         buf += sprintf(buf, "total_bytes_per_chunk %d\n",
3244                                 param->total_bytes_per_chunk);
3245         buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc);
3246         buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
3247         buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2);
3248         buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags);
3249         buf += sprintf(buf, "empty_lost_n_found... %d\n",
3250                                 param->empty_lost_n_found);
3251         buf += sprintf(buf, "disable_lazy_load.... %d\n",
3252                                 param->disable_lazy_load);
3253         buf += sprintf(buf, "disable_bad_block_mrk %d\n",
3254                                 param->disable_bad_block_marking);
3255         buf += sprintf(buf, "refresh_period....... %d\n",
3256                                 param->refresh_period);
3257         buf += sprintf(buf, "n_caches............. %d\n", param->n_caches);
3258         buf += sprintf(buf, "n_reserved_blocks.... %d\n",
3259                                 param->n_reserved_blocks);
3260         buf += sprintf(buf, "always_check_erased.. %d\n",
3261                                 param->always_check_erased);
3262         buf += sprintf(buf, "\n");
3263         buf += sprintf(buf, "block count by state\n");
3264         buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
3265                                 bs[0], bs[1], bs[2], bs[3], bs[4]);
3266         buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
3267                                 bs[5], bs[6], bs[7], bs[8], bs[9]);
3268
3269         return buf;
3270 }
3271
3272 static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
3273 {
3274         buf += sprintf(buf, "max file size....... %lld\n",
3275                                 (long long) yaffs_max_file_size(dev));
3276         buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
3277                                 dev->data_bytes_per_chunk);
3278         buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
3279         buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
3280         buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
3281         buf += sprintf(buf, "blocks_in_checkpt.... %d\n",
3282                                 dev->blocks_in_checkpt);
3283         buf += sprintf(buf, "\n");
3284         buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
3285         buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
3286         buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
3287         buf += sprintf(buf, "\n");
3288         buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
3289         buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
3290         buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
3291         buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
3292         buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
3293         buf += sprintf(buf, "passive_gc_count..... %u\n",
3294                                 dev->passive_gc_count);
3295         buf += sprintf(buf, "oldest_dirty_gc_count %u\n",
3296                                 dev->oldest_dirty_gc_count);
3297         buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
3298         buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
3299         buf += sprintf(buf, "n_retried_writes..... %u\n",
3300                                 dev->n_retried_writes);
3301         buf += sprintf(buf, "n_retired_blocks..... %u\n",
3302                                 dev->n_retired_blocks);
3303         buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
3304         buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
3305         buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n",
3306                                 dev->n_tags_ecc_fixed);
3307         buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n",
3308                                 dev->n_tags_ecc_unfixed);
3309         buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
3310         buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
3311         buf += sprintf(buf, "n_unlinked_files..... %u\n",
3312                                 dev->n_unlinked_files);
3313         buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
3314         buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
3315         buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used);
3316         buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used);
3317
3318         return buf;
3319 }
3320
3321 static int yaffs_proc_read(char *page,
3322                            char **start,
3323                            off_t offset, int count, int *eof, void *data)
3324 {
3325         struct list_head *item;
3326         char *buf = page;
3327         int step = offset;
3328         int n = 0;
3329
3330         /* Get proc_file_read() to step 'offset' by one on each sucessive call.
3331          * We use 'offset' (*ppos) to indicate where we are in dev_list.
3332          * This also assumes the user has posted a read buffer large
3333          * enough to hold the complete output; but that's life in /proc.
3334          */
3335
3336         *(int *)start = 1;
3337
3338         /* Print header first */
3339         if (step == 0)
3340                 buf +=
3341                     sprintf(buf, "Multi-version YAFFS\n");
3342         else if (step == 1)
3343                 buf += sprintf(buf, "\n");
3344         else {
3345                 step -= 2;
3346
3347                 mutex_lock(&yaffs_context_lock);
3348
3349                 /* Locate and print the Nth entry.  Order N-squared but N is small. */
3350                 list_for_each(item, &yaffs_context_list) {
3351                         struct yaffs_linux_context *dc =
3352                             list_entry(item, struct yaffs_linux_context,
3353                                        context_list);
3354                         struct yaffs_dev *dev = dc->dev;
3355
3356                         if (n < (step & ~1)) {
3357                                 n += 2;
3358                                 continue;
3359                         }
3360                         if ((step & 1) == 0) {
3361                                 buf +=
3362                                     sprintf(buf, "\nDevice %d \"%s\"\n", n,
3363                                             dev->param.name);
3364                                 buf = yaffs_dump_dev_part0(buf, dev);
3365                         } else {
3366                                 buf = yaffs_dump_dev_part1(buf, dev);
3367                         }
3368
3369                         break;
3370                 }
3371                 mutex_unlock(&yaffs_context_lock);
3372         }
3373
3374         return buf - page < count ? buf - page : count;
3375 }
3376
3377 /**
3378  * Set the verbosity of the warnings and error messages.
3379  *
3380  * Note that the names can only be a..z or _ with the current code.
3381  */
3382
3383 static struct {
3384         char *mask_name;
3385         unsigned mask_bitfield;
3386 } mask_flags[] = {
3387         {"allocate", YAFFS_TRACE_ALLOCATE},
3388         {"always", YAFFS_TRACE_ALWAYS},
3389         {"background", YAFFS_TRACE_BACKGROUND},
3390         {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
3391         {"buffers", YAFFS_TRACE_BUFFERS},
3392         {"bug", YAFFS_TRACE_BUG},
3393         {"checkpt", YAFFS_TRACE_CHECKPOINT},
3394         {"deletion", YAFFS_TRACE_DELETION},
3395         {"erase", YAFFS_TRACE_ERASE},
3396         {"error", YAFFS_TRACE_ERROR},
3397         {"gc_detail", YAFFS_TRACE_GC_DETAIL},
3398         {"gc", YAFFS_TRACE_GC},
3399         {"lock", YAFFS_TRACE_LOCK},
3400         {"mtd", YAFFS_TRACE_MTD},
3401         {"nandaccess", YAFFS_TRACE_NANDACCESS},
3402         {"os", YAFFS_TRACE_OS},
3403         {"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
3404         {"scan", YAFFS_TRACE_SCAN},
3405         {"mount", YAFFS_TRACE_MOUNT},
3406         {"tracing", YAFFS_TRACE_TRACING},
3407         {"sync", YAFFS_TRACE_SYNC},
3408         {"write", YAFFS_TRACE_WRITE},
3409         {"verify", YAFFS_TRACE_VERIFY},
3410         {"verify_nand", YAFFS_TRACE_VERIFY_NAND},
3411         {"verify_full", YAFFS_TRACE_VERIFY_FULL},
3412         {"verify_all", YAFFS_TRACE_VERIFY_ALL},
3413         {"all", 0xffffffff},
3414         {"none", 0},
3415         {NULL, 0},
3416 };
3417
3418 #define MAX_MASK_NAME_LENGTH 40
3419 static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
3420                                           unsigned long count)
3421 {
3422         unsigned rg = 0, mask_bitfield;
3423         char *end;
3424         char *mask_name;
3425         const char *x;
3426         char substring[MAX_MASK_NAME_LENGTH + 1];
3427         int i;
3428         int done = 0;
3429         int add, len = 0;
3430         int pos = 0;
3431
3432         rg = yaffs_trace_mask;
3433
3434         while (!done && (pos < count)) {
3435                 done = 1;
3436                 while ((pos < count) && isspace(buf[pos]))
3437                         pos++;
3438
3439                 switch (buf[pos]) {
3440                 case '+':
3441                 case '-':
3442                 case '=':
3443                         add = buf[pos];
3444                         pos++;
3445                         break;
3446
3447                 default:
3448                         add = ' ';
3449                         break;
3450                 }
3451                 mask_name = NULL;
3452
3453                 mask_bitfield = simple_strtoul(buf + pos, &end, 0);
3454
3455                 if (end > buf + pos) {
3456                         mask_name = "numeral";
3457                         len = end - (buf + pos);
3458                         pos += len;
3459                         done = 0;
3460                 } else {
3461                         for (x = buf + pos, i = 0;
3462                              (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
3463                              i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
3464                                 substring[i] = *x;
3465                         substring[i] = '\0';
3466
3467                         for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3468                                 if (strcmp(substring, mask_flags[i].mask_name)
3469                                     == 0) {
3470                                         mask_name = mask_flags[i].mask_name;
3471                                         mask_bitfield =
3472                                             mask_flags[i].mask_bitfield;
3473                                         done = 0;
3474                                         break;
3475                                 }
3476                         }
3477                 }
3478
3479                 if (mask_name != NULL) {
3480                         done = 0;
3481                         switch (add) {
3482                         case '-':
3483                                 rg &= ~mask_bitfield;
3484                                 break;
3485                         case '+':
3486                                 rg |= mask_bitfield;
3487                                 break;
3488                         case '=':
3489                                 rg = mask_bitfield;
3490                                 break;
3491                         default:
3492                                 rg |= mask_bitfield;
3493                                 break;
3494                         }
3495                 }
3496         }
3497
3498         yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS;
3499
3500         printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask);
3501
3502         if (rg & YAFFS_TRACE_ALWAYS) {
3503                 for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3504                         char flag;
3505                         flag = ((rg & mask_flags[i].mask_bitfield) ==
3506                                 mask_flags[i].mask_bitfield) ? '+' : '-';
3507                         printk(KERN_DEBUG "%c%s\n", flag,
3508                                mask_flags[i].mask_name);
3509                 }
3510         }
3511
3512         return count;
3513 }
3514
3515 /* Debug strings are of the form:
3516  * .bnnn         print info on block n
3517  * .cobjn,chunkn print nand chunk id for objn:chunkn
3518  */
3519
3520 static int yaffs_proc_debug_write(struct file *file, const char *buf,
3521                                           unsigned long count)
3522 {
3523
3524         char str[100];
3525         char *p0;
3526         char *p1;
3527         long p1_val;
3528         long p0_val;
3529         char cmd;
3530         struct list_head *item;
3531
3532         memset(str, 0, sizeof(str));
3533         memcpy(str, buf, min((size_t)count, sizeof(str) -1));
3534
3535         cmd = str[1];
3536
3537         p0 = str + 2;
3538
3539         p1 = p0;
3540
3541         while (*p1 && *p1 != ',') {
3542                 p1++;
3543         }
3544         *p1 = '\0';
3545         p1++;
3546
3547         p0_val = simple_strtol(p0, NULL, 0);
3548         p1_val = simple_strtol(p1, NULL, 0);
3549
3550
3551         mutex_lock(&yaffs_context_lock);
3552
3553         /* Locate and print the Nth entry.  Order N-squared but N is small. */
3554         list_for_each(item, &yaffs_context_list) {
3555                 struct yaffs_linux_context *dc =
3556                     list_entry(item, struct yaffs_linux_context,
3557                                context_list);
3558                 struct yaffs_dev *dev = dc->dev;
3559
3560                 if (cmd == 'b') {
3561                         struct yaffs_block_info *bi;
3562
3563                         bi = yaffs_get_block_info(dev,p0_val);
3564
3565                         if(bi) {
3566                                 printk("Block %d: state %d, retire %d, use %d, seq %d\n",
3567                                         (int)p0_val, bi->block_state,
3568                                         bi->needs_retiring, bi->pages_in_use,
3569                                         bi->seq_number);
3570                         }
3571                 } else if (cmd == 'c') {
3572                         struct yaffs_obj *obj;
3573                         int nand_chunk;
3574
3575                         obj = yaffs_find_by_number(dev, p0_val);
3576                         if (!obj)
3577                                 printk("No obj %d\n", (int)p0_val);
3578                         else {
3579                                 if(p1_val == 0)
3580                                         nand_chunk = obj->hdr_chunk;
3581                                 else
3582                                         nand_chunk =
3583                                                 yaffs_find_chunk_in_file(obj,
3584                                                         p1_val, NULL);
3585                                 printk("Nand chunk for %d:%d is %d\n",
3586                                         (int)p0_val, (int)p1_val, nand_chunk);
3587                         }
3588                 }
3589         }
3590
3591         mutex_unlock(&yaffs_context_lock);
3592
3593         return count;
3594 }
3595
3596
3597 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
3598 static int yaffs_proc_write(struct file *file, const char *buf,
3599                             unsigned long count, void *ppos)
3600 #else
3601 static ssize_t yaffs_proc_write(struct file *file, const char __user *buf,
3602                             size_t count, loff_t *ppos)
3603 #endif
3604 {
3605         if (buf[0] == '.')
3606                 return yaffs_proc_debug_write(file, buf, count);
3607         return yaffs_proc_write_trace_options(file, buf, count);
3608 }
3609
3610 /* Stuff to handle installation of file systems */
3611 struct file_system_to_install {
3612         struct file_system_type *fst;
3613         int installed;
3614 };
3615
3616 static struct file_system_to_install fs_to_install[] = {
3617         {&yaffs_fs_type, 0},
3618         {&yaffs2_fs_type, 0},
3619         {NULL, 0}
3620 };
3621
3622
3623 #ifdef YAFFS_NEW_PROCFS
3624 static int yaffs_proc_show(struct seq_file *m, void *v)
3625 {
3626         /* FIXME: Unify in a better way? */
3627         char buffer[512];
3628         char *start;
3629         int len;
3630
3631         len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL);
3632         seq_puts(m, buffer);
3633         return 0;
3634 }
3635
3636 static int yaffs_proc_open(struct inode *inode, struct file *file)
3637 {
3638         return single_open(file, yaffs_proc_show, NULL);
3639 }
3640
3641 static struct file_operations procfs_ops = {
3642         .owner = THIS_MODULE,
3643         .open  = yaffs_proc_open,
3644         .read  = seq_read,
3645         .write = yaffs_proc_write,
3646 };
3647
3648 static int yaffs_procfs_init(void)
3649 {
3650         /* Install the proc_fs entries */
3651         my_proc_entry = proc_create("yaffs",
3652                                     S_IRUGO | S_IFREG,
3653                                     YPROC_ROOT,
3654                                     &procfs_ops);
3655
3656         if (my_proc_entry) {
3657                 return 0;
3658         } else {
3659                 return -ENOMEM;
3660         }
3661 }
3662
3663 #else
3664
3665
3666 static int yaffs_procfs_init(void)
3667 {
3668         /* Install the proc_fs entries */
3669         my_proc_entry = create_proc_entry("yaffs",
3670                                           S_IRUGO | S_IFREG, YPROC_ROOT);
3671
3672         if (my_proc_entry) {
3673                 my_proc_entry->write_proc = yaffs_proc_write;
3674                 my_proc_entry->read_proc = yaffs_proc_read;
3675                 my_proc_entry->data = NULL;
3676                 return 0;
3677         } else {
3678                 return -ENOMEM;
3679         }
3680 }
3681
3682 #endif
3683
3684
3685 static int __init init_yaffs_fs(void)
3686 {
3687         int error = 0;
3688         struct file_system_to_install *fsinst;
3689
3690         yaffs_trace(YAFFS_TRACE_ALWAYS,
3691                 "yaffs Installing.");
3692
3693         mutex_init(&yaffs_context_lock);
3694
3695         error = yaffs_procfs_init();
3696         if (error)
3697                 return error;
3698
3699         /* Now add the file system entries */
3700
3701         fsinst = fs_to_install;
3702
3703         while (fsinst->fst && !error) {
3704                 error = register_filesystem(fsinst->fst);
3705                 if (!error)
3706                         fsinst->installed = 1;
3707                 fsinst++;
3708         }
3709
3710         /* Any errors? uninstall  */
3711         if (error) {
3712                 fsinst = fs_to_install;
3713
3714                 while (fsinst->fst) {
3715                         if (fsinst->installed) {
3716                                 unregister_filesystem(fsinst->fst);
3717                                 fsinst->installed = 0;
3718                         }
3719                         fsinst++;
3720                 }
3721         }
3722
3723         return error;
3724 }
3725
3726 static void __exit exit_yaffs_fs(void)
3727 {
3728
3729         struct file_system_to_install *fsinst;
3730
3731         yaffs_trace(YAFFS_TRACE_ALWAYS,
3732                 "yaffs removing.");
3733
3734         remove_proc_entry("yaffs", YPROC_ROOT);
3735
3736         fsinst = fs_to_install;
3737
3738         while (fsinst->fst) {
3739                 if (fsinst->installed) {
3740                         unregister_filesystem(fsinst->fst);
3741                         fsinst->installed = 0;
3742                 }
3743                 fsinst++;
3744         }
3745 }
3746
3747 module_init(init_yaffs_fs)
3748     module_exit(exit_yaffs_fs)
3749
3750     MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
3751 MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2011");
3752 MODULE_LICENSE("GPL");