2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2010 Aleph One Ltd.
5 * for Toby Churchill Ltd and Brightstar Engineering
7 * Created by Charles Manning <charles@aleph1.co.uk>
9 * Luc van OostenRyck for numerous patches.
10 * Nick Bane for numerous patches.
11 * Nick Bane for 2.5/2.6 integration.
12 * Andras Toth for mknod rdev issue.
13 * Michael Fischer for finding the problem with inode inconsistency.
14 * Some code bodily lifted from JFFS
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
23 * This is the file system front-end to YAFFS that hooks it up to
27 * >> 2.4: sb->u.generic_sbp points to the struct yaffs_dev associated with
29 * >> 2.6: sb->s_fs_info points to the struct yaffs_dev associated with this
31 * >> inode->u.generic_ip points to the associated struct yaffs_obj.
35 * NB There are two variants of Linux VFS glue code. This variant supports
36 * a single version and should not include any multi-version code.
38 #include <linux/version.h>
40 #include <linux/kernel.h>
41 #include <linux/module.h>
42 #include <linux/slab.h>
43 #include <linux/init.h>
45 #include <linux/proc_fs.h>
46 #include <linux/smp_lock.h>
47 #include <linux/pagemap.h>
48 #include <linux/mtd/mtd.h>
49 #include <linux/interrupt.h>
50 #include <linux/string.h>
51 #include <linux/ctype.h>
52 #include <linux/namei.h>
53 #include <linux/exportfs.h>
54 #include <linux/kthread.h>
55 #include <linux/delay.h>
56 #include <linux/freezer.h>
58 #include <asm/div64.h>
60 #include <linux/statfs.h>
62 #define UnlockPage(p) unlock_page(p)
63 #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)
65 #define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf)
67 #define YPROC_ROOT NULL
69 #define Y_INIT_TIMER(a) init_timer_on_stack(a)
71 #define WRITE_SIZE_STR "writesize"
72 #define WRITE_SIZE(mtd) ((mtd)->writesize)
74 static uint32_t YCALCBLOCKS(uint64_t partition_size
, uint32_t block_size
)
76 uint64_t result
= partition_size
;
77 do_div(result
, block_size
);
78 return (uint32_t) result
;
81 #include <linux/uaccess.h>
82 #include <linux/mtd/mtd.h>
85 #include "yaffs_trace.h"
86 #include "yaffs_guts.h"
87 #include "yaffs_attribs.h"
89 #include "yaffs_linux.h"
91 #include "yaffs_mtdif.h"
92 #include "yaffs_mtdif1.h"
93 #include "yaffs_mtdif2.h"
95 unsigned int yaffs_trace_mask
= YAFFS_TRACE_BAD_BLOCKS
| YAFFS_TRACE_ALWAYS
;
96 unsigned int yaffs_wr_attempts
= YAFFS_WR_ATTEMPTS
;
97 unsigned int yaffs_auto_checkpoint
= 1;
98 unsigned int yaffs_gc_control
= 1;
99 unsigned int yaffs_bg_enable
= 1;
101 /* Module Parameters */
102 module_param(yaffs_trace_mask
, uint
, 0644);
103 module_param(yaffs_wr_attempts
, uint
, 0644);
104 module_param(yaffs_auto_checkpoint
, uint
, 0644);
105 module_param(yaffs_gc_control
, uint
, 0644);
106 module_param(yaffs_bg_enable
, uint
, 0644);
109 #define yaffs_inode_to_obj_lv(iptr) ((iptr)->i_private)
110 #define yaffs_inode_to_obj(iptr) ((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr)))
111 #define yaffs_dentry_to_obj(dptr) yaffs_inode_to_obj((dptr)->d_inode)
112 #define yaffs_super_to_dev(sb) ((struct yaffs_dev *)sb->s_fs_info)
114 #define update_dir_time(dir) do {\
115 (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
119 static unsigned yaffs_gc_control_callback(struct yaffs_dev
*dev
)
121 return yaffs_gc_control
;
124 static void yaffs_gross_lock(struct yaffs_dev
*dev
)
126 yaffs_trace(YAFFS_TRACE_LOCK
, "yaffs locking %p", current
);
127 mutex_lock(&(yaffs_dev_to_lc(dev
)->gross_lock
));
128 yaffs_trace(YAFFS_TRACE_LOCK
, "yaffs locked %p", current
);
131 static void yaffs_gross_unlock(struct yaffs_dev
*dev
)
133 yaffs_trace(YAFFS_TRACE_LOCK
, "yaffs unlocking %p", current
);
134 mutex_unlock(&(yaffs_dev_to_lc(dev
)->gross_lock
));
137 static void yaffs_fill_inode_from_obj(struct inode
*inode
,
138 struct yaffs_obj
*obj
);
140 static struct inode
*yaffs_iget(struct super_block
*sb
, unsigned long ino
)
143 struct yaffs_obj
*obj
;
144 struct yaffs_dev
*dev
= yaffs_super_to_dev(sb
);
146 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_iget for %lu", ino
);
148 inode
= iget_locked(sb
, ino
);
150 return ERR_PTR(-ENOMEM
);
151 if (!(inode
->i_state
& I_NEW
))
154 /* NB This is called as a side effect of other functions, but
155 * we had to release the lock to prevent deadlocks, so
156 * need to lock again.
159 yaffs_gross_lock(dev
);
161 obj
= yaffs_find_by_number(dev
, inode
->i_ino
);
163 yaffs_fill_inode_from_obj(inode
, obj
);
165 yaffs_gross_unlock(dev
);
167 unlock_new_inode(inode
);
171 struct inode
*yaffs_get_inode(struct super_block
*sb
, int mode
, int dev
,
172 struct yaffs_obj
*obj
)
177 yaffs_trace(YAFFS_TRACE_OS
,
178 "yaffs_get_inode for NULL super_block!!");
184 yaffs_trace(YAFFS_TRACE_OS
,
185 "yaffs_get_inode for NULL object!!");
190 yaffs_trace(YAFFS_TRACE_OS
,
191 "yaffs_get_inode for object %d",
194 inode
= yaffs_iget(sb
, obj
->obj_id
);
198 /* NB Side effect: iget calls back to yaffs_read_inode(). */
199 /* iget also increments the inode's i_count */
200 /* NB You can't be holding gross_lock or deadlock will happen! */
205 static int yaffs_mknod(struct inode
*dir
, struct dentry
*dentry
, int mode
,
210 struct yaffs_obj
*obj
= NULL
;
211 struct yaffs_dev
*dev
;
213 struct yaffs_obj
*parent
= yaffs_inode_to_obj(dir
);
216 uid_t uid
= current
->cred
->fsuid
;
218 (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->cred
->fsgid
;
220 if ((dir
->i_mode
& S_ISGID
) && S_ISDIR(mode
))
224 yaffs_trace(YAFFS_TRACE_OS
,
225 "yaffs_mknod: parent object %d type %d",
226 parent
->obj_id
, parent
->variant_type
);
228 yaffs_trace(YAFFS_TRACE_OS
,
229 "yaffs_mknod: could not get parent object");
233 yaffs_trace(YAFFS_TRACE_OS
,
234 "yaffs_mknod: making oject for %s, mode %x dev %x",
235 dentry
->d_name
.name
, mode
, rdev
);
237 dev
= parent
->my_dev
;
239 yaffs_gross_lock(dev
);
241 switch (mode
& S_IFMT
) {
243 /* Special (socket, fifo, device...) */
244 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_mknod: making special");
246 yaffs_create_special(parent
, dentry
->d_name
.name
, mode
, uid
,
247 gid
, old_encode_dev(rdev
));
249 case S_IFREG
: /* file */
250 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_mknod: making file");
251 obj
= yaffs_create_file(parent
, dentry
->d_name
.name
, mode
, uid
,
254 case S_IFDIR
: /* directory */
255 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_mknod: making directory");
256 obj
= yaffs_create_dir(parent
, dentry
->d_name
.name
, mode
,
259 case S_IFLNK
: /* symlink */
260 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_mknod: making symlink");
261 obj
= NULL
; /* Do we ever get here? */
265 /* Can not call yaffs_get_inode() with gross lock held */
266 yaffs_gross_unlock(dev
);
269 inode
= yaffs_get_inode(dir
->i_sb
, mode
, rdev
, obj
);
270 d_instantiate(dentry
, inode
);
271 update_dir_time(dir
);
272 yaffs_trace(YAFFS_TRACE_OS
,
273 "yaffs_mknod created object %d count = %d",
274 obj
->obj_id
, atomic_read(&inode
->i_count
));
276 yaffs_fill_inode_from_obj(dir
, parent
);
278 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_mknod failed making object");
285 static int yaffs_mkdir(struct inode
*dir
, struct dentry
*dentry
, int mode
)
287 return yaffs_mknod(dir
, dentry
, mode
| S_IFDIR
, 0);
290 static int yaffs_create(struct inode
*dir
, struct dentry
*dentry
, int mode
,
293 return yaffs_mknod(dir
, dentry
, mode
| S_IFREG
, 0);
296 static int yaffs_link(struct dentry
*old_dentry
, struct inode
*dir
,
297 struct dentry
*dentry
)
299 struct inode
*inode
= old_dentry
->d_inode
;
300 struct yaffs_obj
*obj
= NULL
;
301 struct yaffs_obj
*link
= NULL
;
302 struct yaffs_dev
*dev
;
304 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_link");
306 obj
= yaffs_inode_to_obj(inode
);
309 yaffs_gross_lock(dev
);
311 if (!S_ISDIR(inode
->i_mode
)) /* Don't link directories */
313 yaffs_link_obj(yaffs_inode_to_obj(dir
), dentry
->d_name
.name
,
317 old_dentry
->d_inode
->i_nlink
= yaffs_get_obj_link_count(obj
);
318 d_instantiate(dentry
, old_dentry
->d_inode
);
319 atomic_inc(&old_dentry
->d_inode
->i_count
);
320 yaffs_trace(YAFFS_TRACE_OS
,
321 "yaffs_link link count %d i_count %d",
322 old_dentry
->d_inode
->i_nlink
,
323 atomic_read(&old_dentry
->d_inode
->i_count
));
326 yaffs_gross_unlock(dev
);
329 update_dir_time(dir
);
336 static int yaffs_symlink(struct inode
*dir
, struct dentry
*dentry
,
339 struct yaffs_obj
*obj
;
340 struct yaffs_dev
*dev
;
341 uid_t uid
= current
->cred
->fsuid
;
343 (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->cred
->fsgid
;
345 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_symlink");
347 dev
= yaffs_inode_to_obj(dir
)->my_dev
;
348 yaffs_gross_lock(dev
);
349 obj
= yaffs_create_symlink(yaffs_inode_to_obj(dir
), dentry
->d_name
.name
,
350 S_IFLNK
| S_IRWXUGO
, uid
, gid
, symname
);
351 yaffs_gross_unlock(dev
);
356 inode
= yaffs_get_inode(dir
->i_sb
, obj
->yst_mode
, 0, obj
);
357 d_instantiate(dentry
, inode
);
358 update_dir_time(dir
);
359 yaffs_trace(YAFFS_TRACE_OS
, "symlink created OK");
362 yaffs_trace(YAFFS_TRACE_OS
, "symlink not created");
368 static struct dentry
*yaffs_lookup(struct inode
*dir
, struct dentry
*dentry
,
371 struct yaffs_obj
*obj
;
372 struct inode
*inode
= NULL
;
374 struct yaffs_dev
*dev
= yaffs_inode_to_obj(dir
)->my_dev
;
376 if (current
!= yaffs_dev_to_lc(dev
)->readdir_process
)
377 yaffs_gross_lock(dev
);
379 yaffs_trace(YAFFS_TRACE_OS
,
380 "yaffs_lookup for %d:%s",
381 yaffs_inode_to_obj(dir
)->obj_id
, dentry
->d_name
.name
);
383 obj
= yaffs_find_by_name(yaffs_inode_to_obj(dir
), dentry
->d_name
.name
);
385 obj
= yaffs_get_equivalent_obj(obj
); /* in case it was a hardlink */
387 /* Can't hold gross lock when calling yaffs_get_inode() */
388 if (current
!= yaffs_dev_to_lc(dev
)->readdir_process
)
389 yaffs_gross_unlock(dev
);
392 yaffs_trace(YAFFS_TRACE_OS
,
393 "yaffs_lookup found %d", obj
->obj_id
);
395 inode
= yaffs_get_inode(dir
->i_sb
, obj
->yst_mode
, 0, obj
);
398 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_loookup dentry");
399 d_add(dentry
, inode
);
405 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_lookup not found");
409 d_add(dentry
, inode
);
414 static int yaffs_unlink(struct inode
*dir
, struct dentry
*dentry
)
418 struct yaffs_dev
*dev
;
419 struct yaffs_obj
*obj
;
421 yaffs_trace(YAFFS_TRACE_OS
,
422 "yaffs_unlink %d:%s",
423 (int)(dir
->i_ino
), dentry
->d_name
.name
);
424 obj
= yaffs_inode_to_obj(dir
);
427 yaffs_gross_lock(dev
);
429 ret_val
= yaffs_unlinker(obj
, dentry
->d_name
.name
);
431 if (ret_val
== YAFFS_OK
) {
432 dentry
->d_inode
->i_nlink
--;
434 yaffs_gross_unlock(dev
);
435 mark_inode_dirty(dentry
->d_inode
);
436 update_dir_time(dir
);
439 yaffs_gross_unlock(dev
);
443 static int yaffs_sync_object(struct file
*file
, int datasync
)
446 struct yaffs_obj
*obj
;
447 struct yaffs_dev
*dev
;
448 struct dentry
*dentry
= file
->f_path
.dentry
;
450 obj
= yaffs_dentry_to_obj(dentry
);
454 yaffs_trace(YAFFS_TRACE_OS
| YAFFS_TRACE_SYNC
, "yaffs_sync_object");
455 yaffs_gross_lock(dev
);
456 yaffs_flush_file(obj
, 1, datasync
);
457 yaffs_gross_unlock(dev
);
461 * The VFS layer already does all the dentry stuff for rename.
463 * NB: POSIX says you can rename an object over an old object of the same name
465 static int yaffs_rename(struct inode
*old_dir
, struct dentry
*old_dentry
,
466 struct inode
*new_dir
, struct dentry
*new_dentry
)
468 struct yaffs_dev
*dev
;
469 int ret_val
= YAFFS_FAIL
;
470 struct yaffs_obj
*target
;
472 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_rename");
473 dev
= yaffs_inode_to_obj(old_dir
)->my_dev
;
475 yaffs_gross_lock(dev
);
477 /* Check if the target is an existing directory that is not empty. */
478 target
= yaffs_find_by_name(yaffs_inode_to_obj(new_dir
),
479 new_dentry
->d_name
.name
);
481 if (target
&& target
->variant_type
== YAFFS_OBJECT_TYPE_DIRECTORY
&&
482 !list_empty(&target
->variant
.dir_variant
.children
)) {
484 yaffs_trace(YAFFS_TRACE_OS
, "target is non-empty dir");
486 ret_val
= YAFFS_FAIL
;
488 /* Now does unlinking internally using shadowing mechanism */
489 yaffs_trace(YAFFS_TRACE_OS
, "calling yaffs_rename_obj");
491 ret_val
= yaffs_rename_obj(yaffs_inode_to_obj(old_dir
),
492 old_dentry
->d_name
.name
,
493 yaffs_inode_to_obj(new_dir
),
494 new_dentry
->d_name
.name
);
496 yaffs_gross_unlock(dev
);
498 if (ret_val
== YAFFS_OK
) {
500 new_dentry
->d_inode
->i_nlink
--;
501 mark_inode_dirty(new_dentry
->d_inode
);
504 update_dir_time(old_dir
);
505 if (old_dir
!= new_dir
)
506 update_dir_time(new_dir
);
513 static int yaffs_setattr(struct dentry
*dentry
, struct iattr
*attr
)
515 struct inode
*inode
= dentry
->d_inode
;
517 struct yaffs_dev
*dev
;
519 yaffs_trace(YAFFS_TRACE_OS
,
520 "yaffs_setattr of object %d",
521 yaffs_inode_to_obj(inode
)->obj_id
);
523 /* Fail if a requested resize >= 2GB */
524 if (attr
->ia_valid
& ATTR_SIZE
&& (attr
->ia_size
>> 31))
528 error
= inode_change_ok(inode
, attr
);
532 setattr_copy(inode
, attr
);
533 yaffs_trace(YAFFS_TRACE_OS
, "inode_setattr called");
534 if (attr
->ia_valid
& ATTR_SIZE
) {
535 truncate_setsize(inode
, attr
->ia_size
);
536 inode
->i_blocks
= (inode
->i_size
+ 511) >> 9;
539 dev
= yaffs_inode_to_obj(inode
)->my_dev
;
540 if (attr
->ia_valid
& ATTR_SIZE
) {
541 yaffs_trace(YAFFS_TRACE_OS
, "resize to %d(%x)",
542 (int)(attr
->ia_size
),
543 (int)(attr
->ia_size
));
545 yaffs_gross_lock(dev
);
546 result
= yaffs_set_attribs(yaffs_inode_to_obj(inode
), attr
);
547 if (result
== YAFFS_OK
) {
552 yaffs_gross_unlock(dev
);
556 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_setattr done returning %d", error
);
561 #ifdef CONFIG_YAFFS_XATTR
562 static int yaffs_setxattr(struct dentry
*dentry
, const char *name
,
563 const void *value
, size_t size
, int flags
)
565 struct inode
*inode
= dentry
->d_inode
;
567 struct yaffs_dev
*dev
;
568 struct yaffs_obj
*obj
= yaffs_inode_to_obj(inode
);
570 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_setxattr of object %d", obj
->obj_id
);
575 yaffs_gross_lock(dev
);
576 result
= yaffs_set_xattrib(obj
, name
, value
, size
, flags
);
577 if (result
== YAFFS_OK
)
581 yaffs_gross_unlock(dev
);
584 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_setxattr done returning %d", error
);
589 static ssize_t
yaffs_getxattr(struct dentry
* dentry
, const char *name
, void *buff
,
592 struct inode
*inode
= dentry
->d_inode
;
594 struct yaffs_dev
*dev
;
595 struct yaffs_obj
*obj
= yaffs_inode_to_obj(inode
);
597 yaffs_trace(YAFFS_TRACE_OS
,
598 "yaffs_getxattr \"%s\" from object %d",
603 yaffs_gross_lock(dev
);
604 error
= yaffs_get_xattrib(obj
, name
, buff
, size
);
605 yaffs_gross_unlock(dev
);
608 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_getxattr done returning %d", error
);
613 static int yaffs_removexattr(struct dentry
*dentry
, const char *name
)
615 struct inode
*inode
= dentry
->d_inode
;
617 struct yaffs_dev
*dev
;
618 struct yaffs_obj
*obj
= yaffs_inode_to_obj(inode
);
620 yaffs_trace(YAFFS_TRACE_OS
,
621 "yaffs_removexattr of object %d", obj
->obj_id
);
626 yaffs_gross_lock(dev
);
627 result
= yaffs_remove_xattrib(obj
, name
);
628 if (result
== YAFFS_OK
)
632 yaffs_gross_unlock(dev
);
635 yaffs_trace(YAFFS_TRACE_OS
,
636 "yaffs_removexattr done returning %d", error
);
641 static ssize_t
yaffs_listxattr(struct dentry
* dentry
, char *buff
, size_t size
)
643 struct inode
*inode
= dentry
->d_inode
;
645 struct yaffs_dev
*dev
;
646 struct yaffs_obj
*obj
= yaffs_inode_to_obj(inode
);
648 yaffs_trace(YAFFS_TRACE_OS
,
649 "yaffs_listxattr of object %d", obj
->obj_id
);
653 yaffs_gross_lock(dev
);
654 error
= yaffs_list_xattrib(obj
, buff
, size
);
655 yaffs_gross_unlock(dev
);
658 yaffs_trace(YAFFS_TRACE_OS
,
659 "yaffs_listxattr done returning %d", error
);
666 static const struct inode_operations yaffs_dir_inode_operations
= {
667 .create
= yaffs_create
,
668 .lookup
= yaffs_lookup
,
670 .unlink
= yaffs_unlink
,
671 .symlink
= yaffs_symlink
,
672 .mkdir
= yaffs_mkdir
,
673 .rmdir
= yaffs_unlink
,
674 .mknod
= yaffs_mknod
,
675 .rename
= yaffs_rename
,
676 .setattr
= yaffs_setattr
,
677 #ifdef CONFIG_YAFFS_XATTR
678 .setxattr
= yaffs_setxattr
,
679 .getxattr
= yaffs_getxattr
,
680 .listxattr
= yaffs_listxattr
,
681 .removexattr
= yaffs_removexattr
,
684 /*-----------------------------------------------------------------*/
685 /* Directory search context allows us to unlock access to yaffs during
686 * filldir without causing problems with the directory being modified.
687 * This is similar to the tried and tested mechanism used in yaffs direct.
689 * A search context iterates along a doubly linked list of siblings in the
690 * directory. If the iterating object is deleted then this would corrupt
691 * the list iteration, likely causing a crash. The search context avoids
692 * this by using the remove_obj_fn to move the search context to the
693 * next object before the object is deleted.
695 * Many readdirs (and thus seach conexts) may be alive simulateously so
696 * each struct yaffs_dev has a list of these.
698 * A seach context lives for the duration of a readdir.
700 * All these functions must be called while yaffs is locked.
703 struct yaffs_search_context
{
704 struct yaffs_dev
*dev
;
705 struct yaffs_obj
*dir_obj
;
706 struct yaffs_obj
*next_return
;
707 struct list_head others
;
711 * yaffs_new_search() creates a new search context, initialises it and
712 * adds it to the device's search context list.
714 * Called at start of readdir.
716 static struct yaffs_search_context
*yaffs_new_search(struct yaffs_obj
*dir
)
718 struct yaffs_dev
*dev
= dir
->my_dev
;
719 struct yaffs_search_context
*sc
=
720 kmalloc(sizeof(struct yaffs_search_context
), GFP_NOFS
);
724 if (list_empty(&sc
->dir_obj
->variant
.dir_variant
.children
))
725 sc
->next_return
= NULL
;
728 list_entry(dir
->variant
.dir_variant
.children
.next
,
729 struct yaffs_obj
, siblings
);
730 INIT_LIST_HEAD(&sc
->others
);
731 list_add(&sc
->others
, &(yaffs_dev_to_lc(dev
)->search_contexts
));
737 * yaffs_search_end() disposes of a search context and cleans up.
739 static void yaffs_search_end(struct yaffs_search_context
*sc
)
742 list_del(&sc
->others
);
748 * yaffs_search_advance() moves a search context to the next object.
749 * Called when the search iterates or when an object removal causes
750 * the search context to be moved to the next object.
752 static void yaffs_search_advance(struct yaffs_search_context
*sc
)
757 if (sc
->next_return
== NULL
||
758 list_empty(&sc
->dir_obj
->variant
.dir_variant
.children
))
759 sc
->next_return
= NULL
;
761 struct list_head
*next
= sc
->next_return
->siblings
.next
;
763 if (next
== &sc
->dir_obj
->variant
.dir_variant
.children
)
764 sc
->next_return
= NULL
; /* end of list */
767 list_entry(next
, struct yaffs_obj
, siblings
);
772 * yaffs_remove_obj_callback() is called when an object is unlinked.
773 * We check open search contexts and advance any which are currently
774 * on the object being iterated.
776 static void yaffs_remove_obj_callback(struct yaffs_obj
*obj
)
780 struct yaffs_search_context
*sc
;
781 struct list_head
*search_contexts
=
782 &(yaffs_dev_to_lc(obj
->my_dev
)->search_contexts
);
784 /* Iterate through the directory search contexts.
785 * If any are currently on the object being removed, then advance
786 * the search context to the next object to prevent a hanging pointer.
788 list_for_each(i
, search_contexts
) {
790 sc
= list_entry(i
, struct yaffs_search_context
, others
);
791 if (sc
->next_return
== obj
)
792 yaffs_search_advance(sc
);
798 static int yaffs_readdir(struct file
*f
, void *dirent
, filldir_t filldir
)
800 struct yaffs_obj
*obj
;
801 struct yaffs_dev
*dev
;
802 struct yaffs_search_context
*sc
;
803 struct inode
*inode
= f
->f_dentry
->d_inode
;
804 unsigned long offset
, curoffs
;
808 char name
[YAFFS_MAX_NAME_LENGTH
+ 1];
810 obj
= yaffs_dentry_to_obj(f
->f_dentry
);
813 yaffs_gross_lock(dev
);
815 yaffs_dev_to_lc(dev
)->readdir_process
= current
;
819 sc
= yaffs_new_search(obj
);
825 yaffs_trace(YAFFS_TRACE_OS
,
826 "yaffs_readdir: starting at %d", (int)offset
);
829 yaffs_trace(YAFFS_TRACE_OS
,
830 "yaffs_readdir: entry . ino %d",
832 yaffs_gross_unlock(dev
);
833 if (filldir(dirent
, ".", 1, offset
, inode
->i_ino
, DT_DIR
) < 0) {
834 yaffs_gross_lock(dev
);
837 yaffs_gross_lock(dev
);
842 yaffs_trace(YAFFS_TRACE_OS
,
843 "yaffs_readdir: entry .. ino %d",
844 (int)f
->f_dentry
->d_parent
->d_inode
->i_ino
);
845 yaffs_gross_unlock(dev
);
846 if (filldir(dirent
, "..", 2, offset
,
847 f
->f_dentry
->d_parent
->d_inode
->i_ino
,
849 yaffs_gross_lock(dev
);
852 yaffs_gross_lock(dev
);
859 /* If the directory has changed since the open or last call to
860 readdir, rewind to after the 2 canned entries. */
861 if (f
->f_version
!= inode
->i_version
) {
864 f
->f_version
= inode
->i_version
;
867 while (sc
->next_return
) {
870 if (curoffs
>= offset
) {
871 int this_inode
= yaffs_get_obj_inode(l
);
872 int this_type
= yaffs_get_obj_type(l
);
874 yaffs_get_obj_name(l
, name
, YAFFS_MAX_NAME_LENGTH
+ 1);
875 yaffs_trace(YAFFS_TRACE_OS
,
876 "yaffs_readdir: %s inode %d",
877 name
, yaffs_get_obj_inode(l
));
879 yaffs_gross_unlock(dev
);
884 offset
, this_inode
, this_type
) < 0) {
885 yaffs_gross_lock(dev
);
889 yaffs_gross_lock(dev
);
894 yaffs_search_advance(sc
);
898 yaffs_search_end(sc
);
899 yaffs_dev_to_lc(dev
)->readdir_process
= NULL
;
900 yaffs_gross_unlock(dev
);
905 static const struct file_operations yaffs_dir_operations
= {
906 .read
= generic_read_dir
,
907 .readdir
= yaffs_readdir
,
908 .fsync
= yaffs_sync_object
,
909 .llseek
= generic_file_llseek
,
914 static int yaffs_file_flush(struct file
*file
, fl_owner_t id
)
916 struct yaffs_obj
*obj
= yaffs_dentry_to_obj(file
->f_dentry
);
918 struct yaffs_dev
*dev
= obj
->my_dev
;
920 yaffs_trace(YAFFS_TRACE_OS
,
921 "yaffs_file_flush object %d (%s)",
922 obj
->obj_id
, obj
->dirty
? "dirty" : "clean");
924 yaffs_gross_lock(dev
);
926 yaffs_flush_file(obj
, 1, 0);
928 yaffs_gross_unlock(dev
);
933 static const struct file_operations yaffs_file_operations
= {
934 .read
= do_sync_read
,
935 .write
= do_sync_write
,
936 .aio_read
= generic_file_aio_read
,
937 .aio_write
= generic_file_aio_write
,
938 .mmap
= generic_file_mmap
,
939 .flush
= yaffs_file_flush
,
940 .fsync
= yaffs_sync_object
,
941 .splice_read
= generic_file_splice_read
,
942 .splice_write
= generic_file_splice_write
,
943 .llseek
= generic_file_llseek
,
947 /* ExportFS support */
948 static struct inode
*yaffs2_nfs_get_inode(struct super_block
*sb
, uint64_t ino
,
951 return yaffs_iget(sb
, ino
);
954 static struct dentry
*yaffs2_fh_to_dentry(struct super_block
*sb
,
955 struct fid
*fid
, int fh_len
,
958 return generic_fh_to_dentry(sb
, fid
, fh_len
, fh_type
,
959 yaffs2_nfs_get_inode
);
962 static struct dentry
*yaffs2_fh_to_parent(struct super_block
*sb
,
963 struct fid
*fid
, int fh_len
,
966 return generic_fh_to_parent(sb
, fid
, fh_len
, fh_type
,
967 yaffs2_nfs_get_inode
);
970 struct dentry
*yaffs2_get_parent(struct dentry
*dentry
)
973 struct super_block
*sb
= dentry
->d_inode
->i_sb
;
974 struct dentry
*parent
= ERR_PTR(-ENOENT
);
976 unsigned long parent_ino
;
977 struct yaffs_obj
*d_obj
;
978 struct yaffs_obj
*parent_obj
;
980 d_obj
= yaffs_inode_to_obj(dentry
->d_inode
);
983 parent_obj
= d_obj
->parent
;
985 parent_ino
= yaffs_get_obj_inode(parent_obj
);
986 inode
= yaffs_iget(sb
, parent_ino
);
989 parent
= ERR_CAST(inode
);
991 parent
= d_obtain_alias(inode
);
992 if (!IS_ERR(parent
)) {
993 parent
= ERR_PTR(-ENOMEM
);
1003 /* Just declare a zero structure as a NULL value implies
1004 * using the default functions of exportfs.
1007 static struct export_operations yaffs_export_ops
= {
1008 .fh_to_dentry
= yaffs2_fh_to_dentry
,
1009 .fh_to_parent
= yaffs2_fh_to_parent
,
1010 .get_parent
= yaffs2_get_parent
,
1014 /*-----------------------------------------------------------------*/
1016 static int yaffs_readlink(struct dentry
*dentry
, char __user
* buffer
,
1019 unsigned char *alias
;
1022 struct yaffs_dev
*dev
= yaffs_dentry_to_obj(dentry
)->my_dev
;
1024 yaffs_gross_lock(dev
);
1026 alias
= yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry
));
1028 yaffs_gross_unlock(dev
);
1033 ret
= vfs_readlink(dentry
, buffer
, buflen
, alias
);
1038 static void *yaffs_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
1040 unsigned char *alias
;
1042 struct yaffs_dev
*dev
= yaffs_dentry_to_obj(dentry
)->my_dev
;
1044 yaffs_gross_lock(dev
);
1046 alias
= yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry
));
1047 yaffs_gross_unlock(dev
);
1050 ret
= ERR_PTR(-ENOMEM
);
1054 nd_set_link(nd
, alias
);
1055 ret
= (void *)alias
;
1060 void yaffs_put_link(struct dentry
*dentry
, struct nameidata
*nd
, void *alias
)
1066 static void yaffs_unstitch_obj(struct inode
*inode
, struct yaffs_obj
*obj
)
1068 /* Clear the association between the inode and
1069 * the struct yaffs_obj.
1071 obj
->my_inode
= NULL
;
1072 yaffs_inode_to_obj_lv(inode
) = NULL
;
1074 /* If the object freeing was deferred, then the real
1076 * This should fix the inode inconsistency problem.
1078 yaffs_handle_defered_free(obj
);
1081 /* yaffs_evict_inode combines into one operation what was previously done in
1082 * yaffs_clear_inode() and yaffs_delete_inode()
1085 static void yaffs_evict_inode(struct inode
*inode
)
1087 struct yaffs_obj
*obj
;
1088 struct yaffs_dev
*dev
;
1091 obj
= yaffs_inode_to_obj(inode
);
1093 yaffs_trace(YAFFS_TRACE_OS
,
1094 "yaffs_evict_inode: ino %d, count %d %s",
1096 atomic_read(&inode
->i_count
),
1097 obj
? "object exists" : "null object");
1099 if (!inode
->i_nlink
&& !is_bad_inode(inode
))
1101 truncate_inode_pages(&inode
->i_data
, 0);
1102 end_writeback(inode
);
1104 if (deleteme
&& obj
) {
1106 yaffs_gross_lock(dev
);
1108 yaffs_gross_unlock(dev
);
1112 yaffs_gross_lock(dev
);
1113 yaffs_unstitch_obj(inode
, obj
);
1114 yaffs_gross_unlock(dev
);
1119 static void yaffs_touch_super(struct yaffs_dev
*dev
)
1121 struct super_block
*sb
= yaffs_dev_to_lc(dev
)->super
;
1123 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_touch_super() sb = %p", sb
);
1128 static int yaffs_readpage_nolock(struct file
*f
, struct page
*pg
)
1130 /* Lifted from jffs2 */
1132 struct yaffs_obj
*obj
;
1133 unsigned char *pg_buf
;
1136 struct yaffs_dev
*dev
;
1138 yaffs_trace(YAFFS_TRACE_OS
,
1139 "yaffs_readpage_nolock at %08x, size %08x",
1140 (unsigned)(pg
->index
<< PAGE_CACHE_SHIFT
),
1141 (unsigned)PAGE_CACHE_SIZE
);
1143 obj
= yaffs_dentry_to_obj(f
->f_dentry
);
1147 BUG_ON(!PageLocked(pg
));
1150 /* FIXME: Can kmap fail? */
1152 yaffs_gross_lock(dev
);
1154 ret
= yaffs_file_rd(obj
, pg_buf
,
1155 pg
->index
<< PAGE_CACHE_SHIFT
, PAGE_CACHE_SIZE
);
1157 yaffs_gross_unlock(dev
);
1163 ClearPageUptodate(pg
);
1166 SetPageUptodate(pg
);
1170 flush_dcache_page(pg
);
1173 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_readpage_nolock done");
1177 static int yaffs_readpage_unlock(struct file
*f
, struct page
*pg
)
1179 int ret
= yaffs_readpage_nolock(f
, pg
);
1184 static int yaffs_readpage(struct file
*f
, struct page
*pg
)
1188 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_readpage");
1189 ret
= yaffs_readpage_unlock(f
, pg
);
1190 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_readpage done");
1194 /* writepage inspired by/stolen from smbfs */
1196 static int yaffs_writepage(struct page
*page
, struct writeback_control
*wbc
)
1198 struct yaffs_dev
*dev
;
1199 struct address_space
*mapping
= page
->mapping
;
1200 struct inode
*inode
;
1201 unsigned long end_index
;
1203 struct yaffs_obj
*obj
;
1210 inode
= mapping
->host
;
1213 i_size
= i_size_read(inode
);
1215 end_index
= i_size
>> PAGE_CACHE_SHIFT
;
1217 if (page
->index
< end_index
)
1218 n_bytes
= PAGE_CACHE_SIZE
;
1220 n_bytes
= i_size
& (PAGE_CACHE_SIZE
- 1);
1222 if (page
->index
> end_index
|| !n_bytes
) {
1223 yaffs_trace(YAFFS_TRACE_OS
,
1224 "yaffs_writepage at %08x, inode size = %08x!!!",
1225 (unsigned)(page
->index
<< PAGE_CACHE_SHIFT
),
1226 (unsigned)inode
->i_size
);
1227 yaffs_trace(YAFFS_TRACE_OS
,
1228 " -> don't care!!");
1230 zero_user_segment(page
, 0, PAGE_CACHE_SIZE
);
1231 set_page_writeback(page
);
1233 end_page_writeback(page
);
1238 if (n_bytes
!= PAGE_CACHE_SIZE
)
1239 zero_user_segment(page
, n_bytes
, PAGE_CACHE_SIZE
);
1243 buffer
= kmap(page
);
1245 obj
= yaffs_inode_to_obj(inode
);
1247 yaffs_gross_lock(dev
);
1249 yaffs_trace(YAFFS_TRACE_OS
,
1250 "yaffs_writepage at %08x, size %08x",
1251 (unsigned)(page
->index
<< PAGE_CACHE_SHIFT
), n_bytes
);
1252 yaffs_trace(YAFFS_TRACE_OS
,
1253 "writepag0: obj = %05x, ino = %05x",
1254 (int)obj
->variant
.file_variant
.file_size
, (int)inode
->i_size
);
1256 n_written
= yaffs_wr_file(obj
, buffer
,
1257 page
->index
<< PAGE_CACHE_SHIFT
, n_bytes
, 0);
1259 yaffs_touch_super(dev
);
1261 yaffs_trace(YAFFS_TRACE_OS
,
1262 "writepag1: obj = %05x, ino = %05x",
1263 (int)obj
->variant
.file_variant
.file_size
, (int)inode
->i_size
);
1265 yaffs_gross_unlock(dev
);
1268 set_page_writeback(page
);
1270 end_page_writeback(page
);
1273 return (n_written
== n_bytes
) ? 0 : -ENOSPC
;
1276 /* Space holding and freeing is done to ensure we have space available for
1278 * For now we just assume few parallel writes and check against a small
1280 * Todo: need to do this with a counter to handle parallel reads better.
1283 static ssize_t
yaffs_hold_space(struct file
*f
)
1285 struct yaffs_obj
*obj
;
1286 struct yaffs_dev
*dev
;
1290 obj
= yaffs_dentry_to_obj(f
->f_dentry
);
1294 yaffs_gross_lock(dev
);
1296 n_free_chunks
= yaffs_get_n_free_chunks(dev
);
1298 yaffs_gross_unlock(dev
);
1300 return (n_free_chunks
> 20) ? 1 : 0;
1303 static void yaffs_release_space(struct file
*f
)
1305 struct yaffs_obj
*obj
;
1306 struct yaffs_dev
*dev
;
1308 obj
= yaffs_dentry_to_obj(f
->f_dentry
);
1312 yaffs_gross_lock(dev
);
1314 yaffs_gross_unlock(dev
);
1317 static int yaffs_write_begin(struct file
*filp
, struct address_space
*mapping
,
1318 loff_t pos
, unsigned len
, unsigned flags
,
1319 struct page
**pagep
, void **fsdata
)
1321 struct page
*pg
= NULL
;
1322 pgoff_t index
= pos
>> PAGE_CACHE_SHIFT
;
1328 pg
= grab_cache_page_write_begin(mapping
, index
, flags
);
1335 yaffs_trace(YAFFS_TRACE_OS
,
1336 "start yaffs_write_begin index %d(%x) uptodate %d",
1337 (int)index
, (int)index
, Page_Uptodate(pg
) ? 1 : 0);
1340 space_held
= yaffs_hold_space(filp
);
1347 /* Update page if required */
1349 if (!Page_Uptodate(pg
))
1350 ret
= yaffs_readpage_nolock(filp
, pg
);
1355 /* Happy path return */
1356 yaffs_trace(YAFFS_TRACE_OS
, "end yaffs_write_begin - ok");
1361 yaffs_trace(YAFFS_TRACE_OS
,
1362 "end yaffs_write_begin fail returning %d", ret
);
1364 yaffs_release_space(filp
);
1367 page_cache_release(pg
);
1372 static ssize_t
yaffs_file_write(struct file
*f
, const char *buf
, size_t n
,
1375 struct yaffs_obj
*obj
;
1376 int n_written
, ipos
;
1377 struct inode
*inode
;
1378 struct yaffs_dev
*dev
;
1380 obj
= yaffs_dentry_to_obj(f
->f_dentry
);
1384 yaffs_gross_lock(dev
);
1386 inode
= f
->f_dentry
->d_inode
;
1388 if (!S_ISBLK(inode
->i_mode
) && f
->f_flags
& O_APPEND
)
1389 ipos
= inode
->i_size
;
1394 yaffs_trace(YAFFS_TRACE_OS
,
1395 "yaffs_file_write: hey obj is null!");
1397 yaffs_trace(YAFFS_TRACE_OS
,
1398 "yaffs_file_write about to write writing %u(%x) bytes to object %d at %d(%x)",
1399 (unsigned)n
, (unsigned)n
, obj
->obj_id
, ipos
, ipos
);
1401 n_written
= yaffs_wr_file(obj
, buf
, ipos
, n
, 0);
1403 yaffs_touch_super(dev
);
1405 yaffs_trace(YAFFS_TRACE_OS
,
1406 "yaffs_file_write: %d(%x) bytes written",
1407 (unsigned)n
, (unsigned)n
);
1409 if (n_written
> 0) {
1412 if (ipos
> inode
->i_size
) {
1413 inode
->i_size
= ipos
;
1414 inode
->i_blocks
= (ipos
+ 511) >> 9;
1416 yaffs_trace(YAFFS_TRACE_OS
,
1417 "yaffs_file_write size updated to %d bytes, %d blocks",
1418 ipos
, (int)(inode
->i_blocks
));
1422 yaffs_gross_unlock(dev
);
1423 return (n_written
== 0) && (n
> 0) ? -ENOSPC
: n_written
;
1426 static int yaffs_write_end(struct file
*filp
, struct address_space
*mapping
,
1427 loff_t pos
, unsigned len
, unsigned copied
,
1428 struct page
*pg
, void *fsdadata
)
1432 uint32_t offset_into_page
= pos
& (PAGE_CACHE_SIZE
- 1);
1435 addr
= kva
+ offset_into_page
;
1437 yaffs_trace(YAFFS_TRACE_OS
,
1438 "yaffs_write_end addr %p pos %x n_bytes %d",
1439 addr
, (unsigned)pos
, copied
);
1441 ret
= yaffs_file_write(filp
, addr
, copied
, &pos
);
1443 if (ret
!= copied
) {
1444 yaffs_trace(YAFFS_TRACE_OS
,
1445 "yaffs_write_end not same size ret %d copied %d",
1452 yaffs_release_space(filp
);
1454 page_cache_release(pg
);
1458 static int yaffs_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
1460 struct yaffs_dev
*dev
= yaffs_dentry_to_obj(dentry
)->my_dev
;
1461 struct super_block
*sb
= dentry
->d_sb
;
1463 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_statfs");
1465 yaffs_gross_lock(dev
);
1467 buf
->f_type
= YAFFS_MAGIC
;
1468 buf
->f_bsize
= sb
->s_blocksize
;
1469 buf
->f_namelen
= 255;
1471 if (dev
->data_bytes_per_chunk
& (dev
->data_bytes_per_chunk
- 1)) {
1472 /* Do this if chunk size is not a power of 2 */
1474 uint64_t bytes_in_dev
;
1475 uint64_t bytes_free
;
1479 ((dev
->param
.end_block
- dev
->param
.start_block
+
1480 1))) * ((uint64_t) (dev
->param
.chunks_per_block
*
1481 dev
->data_bytes_per_chunk
));
1483 do_div(bytes_in_dev
, sb
->s_blocksize
); /* bytes_in_dev becomes the number of blocks */
1484 buf
->f_blocks
= bytes_in_dev
;
1486 bytes_free
= ((uint64_t) (yaffs_get_n_free_chunks(dev
))) *
1487 ((uint64_t) (dev
->data_bytes_per_chunk
));
1489 do_div(bytes_free
, sb
->s_blocksize
);
1491 buf
->f_bfree
= bytes_free
;
1493 } else if (sb
->s_blocksize
> dev
->data_bytes_per_chunk
) {
1496 (dev
->param
.end_block
- dev
->param
.start_block
+ 1) *
1497 dev
->param
.chunks_per_block
/
1498 (sb
->s_blocksize
/ dev
->data_bytes_per_chunk
);
1500 yaffs_get_n_free_chunks(dev
) /
1501 (sb
->s_blocksize
/ dev
->data_bytes_per_chunk
);
1504 (dev
->param
.end_block
- dev
->param
.start_block
+ 1) *
1505 dev
->param
.chunks_per_block
*
1506 (dev
->data_bytes_per_chunk
/ sb
->s_blocksize
);
1509 yaffs_get_n_free_chunks(dev
) *
1510 (dev
->data_bytes_per_chunk
/ sb
->s_blocksize
);
1515 buf
->f_bavail
= buf
->f_bfree
;
1517 yaffs_gross_unlock(dev
);
1521 static void yaffs_flush_inodes(struct super_block
*sb
)
1524 struct yaffs_obj
*obj
;
1526 list_for_each_entry(iptr
, &sb
->s_inodes
, i_sb_list
) {
1527 obj
= yaffs_inode_to_obj(iptr
);
1529 yaffs_trace(YAFFS_TRACE_OS
,
1530 "flushing obj %d", obj
->obj_id
);
1531 yaffs_flush_file(obj
, 1, 0);
1536 static void yaffs_flush_super(struct super_block
*sb
, int do_checkpoint
)
1538 struct yaffs_dev
*dev
= yaffs_super_to_dev(sb
);
1542 yaffs_flush_inodes(sb
);
1543 yaffs_update_dirty_dirs(dev
);
1544 yaffs_flush_whole_cache(dev
);
1546 yaffs_checkpoint_save(dev
);
1549 static unsigned yaffs_bg_gc_urgency(struct yaffs_dev
*dev
)
1551 unsigned erased_chunks
=
1552 dev
->n_erased_blocks
* dev
->param
.chunks_per_block
;
1553 struct yaffs_linux_context
*context
= yaffs_dev_to_lc(dev
);
1554 unsigned scattered
= 0; /* Free chunks not in an erased block */
1556 if (erased_chunks
< dev
->n_free_chunks
)
1557 scattered
= (dev
->n_free_chunks
- erased_chunks
);
1559 if (!context
->bg_running
)
1561 else if (scattered
< (dev
->param
.chunks_per_block
* 2))
1563 else if (erased_chunks
> dev
->n_free_chunks
/ 2)
1565 else if (erased_chunks
> dev
->n_free_chunks
/ 4)
1571 static int yaffs_do_sync_fs(struct super_block
*sb
, int request_checkpoint
)
1574 struct yaffs_dev
*dev
= yaffs_super_to_dev(sb
);
1575 unsigned int oneshot_checkpoint
= (yaffs_auto_checkpoint
& 4);
1576 unsigned gc_urgent
= yaffs_bg_gc_urgency(dev
);
1579 yaffs_trace(YAFFS_TRACE_OS
| YAFFS_TRACE_SYNC
| YAFFS_TRACE_BACKGROUND
,
1580 "yaffs_do_sync_fs: gc-urgency %d %s %s%s",
1582 sb
->s_dirt
? "dirty" : "clean",
1583 request_checkpoint
? "checkpoint requested" : "no checkpoint",
1584 oneshot_checkpoint
? " one-shot" : "");
1586 yaffs_gross_lock(dev
);
1587 do_checkpoint
= ((request_checkpoint
&& !gc_urgent
) ||
1588 oneshot_checkpoint
) && !dev
->is_checkpointed
;
1590 if (sb
->s_dirt
|| do_checkpoint
) {
1591 yaffs_flush_super(sb
, !dev
->is_checkpointed
&& do_checkpoint
);
1593 if (oneshot_checkpoint
)
1594 yaffs_auto_checkpoint
&= ~4;
1596 yaffs_gross_unlock(dev
);
1602 * yaffs background thread functions .
1603 * yaffs_bg_thread_fn() the thread function
1604 * yaffs_bg_start() launches the background thread.
1605 * yaffs_bg_stop() cleans up the background thread.
1608 * The thread should only run after the yaffs is initialised
1609 * The thread should be stopped before yaffs is unmounted.
1610 * The thread should not do any writing while the fs is in read only.
1613 void yaffs_background_waker(unsigned long data
)
1615 wake_up_process((struct task_struct
*)data
);
1618 static int yaffs_bg_thread_fn(void *data
)
1620 struct yaffs_dev
*dev
= (struct yaffs_dev
*)data
;
1621 struct yaffs_linux_context
*context
= yaffs_dev_to_lc(dev
);
1622 unsigned long now
= jiffies
;
1623 unsigned long next_dir_update
= now
;
1624 unsigned long next_gc
= now
;
1625 unsigned long expires
;
1626 unsigned int urgency
;
1629 struct timer_list timer
;
1631 yaffs_trace(YAFFS_TRACE_BACKGROUND
,
1632 "yaffs_background starting for dev %p", (void *)dev
);
1635 while (context
->bg_running
) {
1636 yaffs_trace(YAFFS_TRACE_BACKGROUND
, "yaffs_background");
1638 if (kthread_should_stop())
1641 if (try_to_freeze())
1644 yaffs_gross_lock(dev
);
1648 if (time_after(now
, next_dir_update
) && yaffs_bg_enable
) {
1649 yaffs_update_dirty_dirs(dev
);
1650 next_dir_update
= now
+ HZ
;
1653 if (time_after(now
, next_gc
) && yaffs_bg_enable
) {
1654 if (!dev
->is_checkpointed
) {
1655 urgency
= yaffs_bg_gc_urgency(dev
);
1656 gc_result
= yaffs_bg_gc(dev
, urgency
);
1658 next_gc
= now
+ HZ
/ 20 + 1;
1659 else if (urgency
> 0)
1660 next_gc
= now
+ HZ
/ 10 + 1;
1662 next_gc
= now
+ HZ
* 2;
1665 * gc not running so set to next_dir_update
1666 * to cut down on wake ups
1668 next_gc
= next_dir_update
;
1671 yaffs_gross_unlock(dev
);
1672 expires
= next_dir_update
;
1673 if (time_before(next_gc
, expires
))
1675 if (time_before(expires
, now
))
1678 Y_INIT_TIMER(&timer
);
1679 timer
.expires
= expires
+ 1;
1680 timer
.data
= (unsigned long)current
;
1681 timer
.function
= yaffs_background_waker
;
1683 set_current_state(TASK_INTERRUPTIBLE
);
1686 del_timer_sync(&timer
);
1692 static int yaffs_bg_start(struct yaffs_dev
*dev
)
1695 struct yaffs_linux_context
*context
= yaffs_dev_to_lc(dev
);
1700 context
->bg_running
= 1;
1702 context
->bg_thread
= kthread_run(yaffs_bg_thread_fn
,
1703 (void *)dev
, "yaffs-bg-%d",
1706 if (IS_ERR(context
->bg_thread
)) {
1707 retval
= PTR_ERR(context
->bg_thread
);
1708 context
->bg_thread
= NULL
;
1709 context
->bg_running
= 0;
1714 static void yaffs_bg_stop(struct yaffs_dev
*dev
)
1716 struct yaffs_linux_context
*ctxt
= yaffs_dev_to_lc(dev
);
1718 ctxt
->bg_running
= 0;
1720 if (ctxt
->bg_thread
) {
1721 kthread_stop(ctxt
->bg_thread
);
1722 ctxt
->bg_thread
= NULL
;
1726 static void yaffs_write_super(struct super_block
*sb
)
1728 unsigned request_checkpoint
= (yaffs_auto_checkpoint
>= 2);
1730 yaffs_trace(YAFFS_TRACE_OS
| YAFFS_TRACE_SYNC
| YAFFS_TRACE_BACKGROUND
,
1731 "yaffs_write_super%s",
1732 request_checkpoint
? " checkpt" : "");
1734 yaffs_do_sync_fs(sb
, request_checkpoint
);
1738 static int yaffs_sync_fs(struct super_block
*sb
, int wait
)
1740 unsigned request_checkpoint
= (yaffs_auto_checkpoint
>= 1);
1742 yaffs_trace(YAFFS_TRACE_OS
| YAFFS_TRACE_SYNC
,
1743 "yaffs_sync_fs%s", request_checkpoint
? " checkpt" : "");
1745 yaffs_do_sync_fs(sb
, request_checkpoint
);
1751 static LIST_HEAD(yaffs_context_list
);
1752 struct mutex yaffs_context_lock
;
1756 struct yaffs_options
{
1758 int skip_checkpoint_read
;
1759 int skip_checkpoint_write
;
1762 int tags_ecc_overridden
;
1763 int lazy_loading_enabled
;
1764 int lazy_loading_overridden
;
1765 int empty_lost_and_found
;
1766 int empty_lost_and_found_overridden
;
1769 #define MAX_OPT_LEN 30
1770 static int yaffs_parse_options(struct yaffs_options
*options
,
1771 const char *options_str
)
1773 char cur_opt
[MAX_OPT_LEN
+ 1];
1777 /* Parse through the options which is a comma seperated list */
1779 while (options_str
&& *options_str
&& !error
) {
1780 memset(cur_opt
, 0, MAX_OPT_LEN
+ 1);
1783 while (*options_str
== ',')
1786 while (*options_str
&& *options_str
!= ',') {
1787 if (p
< MAX_OPT_LEN
) {
1788 cur_opt
[p
] = *options_str
;
1794 if (!strcmp(cur_opt
, "inband-tags")) {
1795 options
->inband_tags
= 1;
1796 } else if (!strcmp(cur_opt
, "tags-ecc-off")) {
1797 options
->tags_ecc_on
= 0;
1798 options
->tags_ecc_overridden
= 1;
1799 } else if (!strcmp(cur_opt
, "tags-ecc-on")) {
1800 options
->tags_ecc_on
= 1;
1801 options
->tags_ecc_overridden
= 1;
1802 } else if (!strcmp(cur_opt
, "lazy-loading-off")) {
1803 options
->lazy_loading_enabled
= 0;
1804 options
->lazy_loading_overridden
= 1;
1805 } else if (!strcmp(cur_opt
, "lazy-loading-on")) {
1806 options
->lazy_loading_enabled
= 1;
1807 options
->lazy_loading_overridden
= 1;
1808 } else if (!strcmp(cur_opt
, "empty-lost-and-found-off")) {
1809 options
->empty_lost_and_found
= 0;
1810 options
->empty_lost_and_found_overridden
= 1;
1811 } else if (!strcmp(cur_opt
, "empty-lost-and-found-on")) {
1812 options
->empty_lost_and_found
= 1;
1813 options
->empty_lost_and_found_overridden
= 1;
1814 } else if (!strcmp(cur_opt
, "no-cache")) {
1815 options
->no_cache
= 1;
1816 } else if (!strcmp(cur_opt
, "no-checkpoint-read")) {
1817 options
->skip_checkpoint_read
= 1;
1818 } else if (!strcmp(cur_opt
, "no-checkpoint-write")) {
1819 options
->skip_checkpoint_write
= 1;
1820 } else if (!strcmp(cur_opt
, "no-checkpoint")) {
1821 options
->skip_checkpoint_read
= 1;
1822 options
->skip_checkpoint_write
= 1;
1824 printk(KERN_INFO
"yaffs: Bad mount option \"%s\"\n",
1833 static struct address_space_operations yaffs_file_address_operations
= {
1834 .readpage
= yaffs_readpage
,
1835 .writepage
= yaffs_writepage
,
1836 .write_begin
= yaffs_write_begin
,
1837 .write_end
= yaffs_write_end
,
1842 static const struct inode_operations yaffs_file_inode_operations
= {
1843 .setattr
= yaffs_setattr
,
1844 #ifdef CONFIG_YAFFS_XATTR
1845 .setxattr
= yaffs_setxattr
,
1846 .getxattr
= yaffs_getxattr
,
1847 .listxattr
= yaffs_listxattr
,
1848 .removexattr
= yaffs_removexattr
,
1852 static const struct inode_operations yaffs_symlink_inode_operations
= {
1853 .readlink
= yaffs_readlink
,
1854 .follow_link
= yaffs_follow_link
,
1855 .put_link
= yaffs_put_link
,
1856 .setattr
= yaffs_setattr
,
1857 #ifdef CONFIG_YAFFS_XATTR
1858 .setxattr
= yaffs_setxattr
,
1859 .getxattr
= yaffs_getxattr
,
1860 .listxattr
= yaffs_listxattr
,
1861 .removexattr
= yaffs_removexattr
,
1865 static void yaffs_fill_inode_from_obj(struct inode
*inode
,
1866 struct yaffs_obj
*obj
)
1870 /* Check mode against the variant type and attempt to repair if broken. */
1871 u32 mode
= obj
->yst_mode
;
1872 switch (obj
->variant_type
) {
1873 case YAFFS_OBJECT_TYPE_FILE
:
1874 if (!S_ISREG(mode
)) {
1875 obj
->yst_mode
&= ~S_IFMT
;
1876 obj
->yst_mode
|= S_IFREG
;
1880 case YAFFS_OBJECT_TYPE_SYMLINK
:
1881 if (!S_ISLNK(mode
)) {
1882 obj
->yst_mode
&= ~S_IFMT
;
1883 obj
->yst_mode
|= S_IFLNK
;
1887 case YAFFS_OBJECT_TYPE_DIRECTORY
:
1888 if (!S_ISDIR(mode
)) {
1889 obj
->yst_mode
&= ~S_IFMT
;
1890 obj
->yst_mode
|= S_IFDIR
;
1894 case YAFFS_OBJECT_TYPE_UNKNOWN
:
1895 case YAFFS_OBJECT_TYPE_HARDLINK
:
1896 case YAFFS_OBJECT_TYPE_SPECIAL
:
1902 inode
->i_flags
|= S_NOATIME
;
1904 inode
->i_ino
= obj
->obj_id
;
1905 inode
->i_mode
= obj
->yst_mode
;
1906 inode
->i_uid
= obj
->yst_uid
;
1907 inode
->i_gid
= obj
->yst_gid
;
1909 inode
->i_rdev
= old_decode_dev(obj
->yst_rdev
);
1911 inode
->i_atime
.tv_sec
= (time_t) (obj
->yst_atime
);
1912 inode
->i_atime
.tv_nsec
= 0;
1913 inode
->i_mtime
.tv_sec
= (time_t) obj
->yst_mtime
;
1914 inode
->i_mtime
.tv_nsec
= 0;
1915 inode
->i_ctime
.tv_sec
= (time_t) obj
->yst_ctime
;
1916 inode
->i_ctime
.tv_nsec
= 0;
1917 inode
->i_size
= yaffs_get_obj_length(obj
);
1918 inode
->i_blocks
= (inode
->i_size
+ 511) >> 9;
1920 inode
->i_nlink
= yaffs_get_obj_link_count(obj
);
1922 yaffs_trace(YAFFS_TRACE_OS
,
1923 "yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
1924 inode
->i_mode
, inode
->i_uid
, inode
->i_gid
,
1925 (int)inode
->i_size
, atomic_read(&inode
->i_count
));
1927 switch (obj
->yst_mode
& S_IFMT
) {
1928 default: /* fifo, device or socket */
1929 init_special_inode(inode
, obj
->yst_mode
,
1930 old_decode_dev(obj
->yst_rdev
));
1932 case S_IFREG
: /* file */
1933 inode
->i_op
= &yaffs_file_inode_operations
;
1934 inode
->i_fop
= &yaffs_file_operations
;
1935 inode
->i_mapping
->a_ops
=
1936 &yaffs_file_address_operations
;
1938 case S_IFDIR
: /* directory */
1939 inode
->i_op
= &yaffs_dir_inode_operations
;
1940 inode
->i_fop
= &yaffs_dir_operations
;
1942 case S_IFLNK
: /* symlink */
1943 inode
->i_op
= &yaffs_symlink_inode_operations
;
1947 yaffs_inode_to_obj_lv(inode
) = obj
;
1949 obj
->my_inode
= inode
;
1952 yaffs_trace(YAFFS_TRACE_OS
,
1953 "yaffs_fill_inode invalid parameters");
1957 static void yaffs_put_super(struct super_block
*sb
)
1959 struct yaffs_dev
*dev
= yaffs_super_to_dev(sb
);
1961 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_put_super");
1963 yaffs_trace(YAFFS_TRACE_OS
| YAFFS_TRACE_BACKGROUND
,
1964 "Shutting down yaffs background thread");
1966 yaffs_trace(YAFFS_TRACE_OS
| YAFFS_TRACE_BACKGROUND
,
1967 "yaffs background thread shut down");
1969 yaffs_gross_lock(dev
);
1971 yaffs_flush_super(sb
, 1);
1973 if (yaffs_dev_to_lc(dev
)->put_super_fn
)
1974 yaffs_dev_to_lc(dev
)->put_super_fn(sb
);
1976 yaffs_deinitialise(dev
);
1978 yaffs_gross_unlock(dev
);
1979 mutex_lock(&yaffs_context_lock
);
1980 list_del_init(&(yaffs_dev_to_lc(dev
)->context_list
));
1981 mutex_unlock(&yaffs_context_lock
);
1983 if (yaffs_dev_to_lc(dev
)->spare_buffer
) {
1984 kfree(yaffs_dev_to_lc(dev
)->spare_buffer
);
1985 yaffs_dev_to_lc(dev
)->spare_buffer
= NULL
;
1991 static void yaffs_mtd_put_super(struct super_block
*sb
)
1993 struct mtd_info
*mtd
= yaffs_dev_to_mtd(yaffs_super_to_dev(sb
));
1998 put_mtd_device(mtd
);
2001 static const struct super_operations yaffs_super_ops
= {
2002 .statfs
= yaffs_statfs
,
2003 .put_super
= yaffs_put_super
,
2004 .evict_inode
= yaffs_evict_inode
,
2005 .sync_fs
= yaffs_sync_fs
,
2006 .write_super
= yaffs_write_super
,
2009 static struct super_block
*yaffs_internal_read_super(int yaffs_version
,
2010 struct super_block
*sb
,
2011 void *data
, int silent
)
2014 struct inode
*inode
= NULL
;
2015 struct dentry
*root
;
2016 struct yaffs_dev
*dev
= 0;
2017 char devname_buf
[BDEVNAME_SIZE
+ 1];
2018 struct mtd_info
*mtd
;
2020 char *data_str
= (char *)data
;
2021 struct yaffs_linux_context
*context
= NULL
;
2022 struct yaffs_param
*param
;
2026 struct yaffs_options options
;
2030 struct yaffs_linux_context
*context_iterator
;
2031 struct list_head
*l
;
2033 sb
->s_magic
= YAFFS_MAGIC
;
2034 sb
->s_op
= &yaffs_super_ops
;
2035 sb
->s_flags
|= MS_NOATIME
;
2037 read_only
= ((sb
->s_flags
& MS_RDONLY
) != 0);
2039 sb
->s_export_op
= &yaffs_export_ops
;
2042 printk(KERN_INFO
"yaffs: sb is NULL\n");
2043 else if (!sb
->s_dev
)
2044 printk(KERN_INFO
"yaffs: sb->s_dev is NULL\n");
2045 else if (!yaffs_devname(sb
, devname_buf
))
2046 printk(KERN_INFO
"yaffs: devname is NULL\n");
2048 printk(KERN_INFO
"yaffs: dev is %d name is \"%s\" %s\n",
2050 yaffs_devname(sb
, devname_buf
), read_only
? "ro" : "rw");
2055 printk(KERN_INFO
"yaffs: passed flags \"%s\"\n", data_str
);
2057 memset(&options
, 0, sizeof(options
));
2059 if (yaffs_parse_options(&options
, data_str
)) {
2060 /* Option parsing failed */
2064 sb
->s_blocksize
= PAGE_CACHE_SIZE
;
2065 sb
->s_blocksize_bits
= PAGE_CACHE_SHIFT
;
2067 yaffs_trace(YAFFS_TRACE_OS
,
2068 "yaffs_read_super: Using yaffs%d", yaffs_version
);
2069 yaffs_trace(YAFFS_TRACE_OS
,
2070 "yaffs_read_super: block size %d", (int)(sb
->s_blocksize
));
2072 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2073 "Attempting MTD mount of %u.%u,\"%s\"",
2074 MAJOR(sb
->s_dev
), MINOR(sb
->s_dev
),
2075 yaffs_devname(sb
, devname_buf
));
2077 /* Check it's an mtd device..... */
2078 if (MAJOR(sb
->s_dev
) != MTD_BLOCK_MAJOR
)
2079 return NULL
; /* This isn't an mtd device */
2081 /* Get the device */
2082 mtd
= get_mtd_device(NULL
, MINOR(sb
->s_dev
));
2084 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2085 "MTD device #%u doesn't appear to exist",
2089 /* Check it's NAND */
2090 if (mtd
->type
!= MTD_NANDFLASH
) {
2091 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2092 "MTD device is not NAND it's type %d",
2097 yaffs_trace(YAFFS_TRACE_OS
, " erase %p", mtd
->erase
);
2098 yaffs_trace(YAFFS_TRACE_OS
, " read %p", mtd
->read
);
2099 yaffs_trace(YAFFS_TRACE_OS
, " write %p", mtd
->write
);
2100 yaffs_trace(YAFFS_TRACE_OS
, " readoob %p", mtd
->read_oob
);
2101 yaffs_trace(YAFFS_TRACE_OS
, " writeoob %p", mtd
->write_oob
);
2102 yaffs_trace(YAFFS_TRACE_OS
, " block_isbad %p", mtd
->block_isbad
);
2103 yaffs_trace(YAFFS_TRACE_OS
, " block_markbad %p", mtd
->block_markbad
);
2104 yaffs_trace(YAFFS_TRACE_OS
, " %s %d", WRITE_SIZE_STR
, WRITE_SIZE(mtd
));
2105 yaffs_trace(YAFFS_TRACE_OS
, " oobsize %d", mtd
->oobsize
);
2106 yaffs_trace(YAFFS_TRACE_OS
, " erasesize %d", mtd
->erasesize
);
2107 yaffs_trace(YAFFS_TRACE_OS
, " size %lld", mtd
->size
);
2109 #ifdef CONFIG_YAFFS_AUTO_YAFFS2
2111 if (yaffs_version
== 1 && WRITE_SIZE(mtd
) >= 2048) {
2112 yaffs_trace(YAFFS_TRACE_ALWAYS
, "auto selecting yaffs2");
2116 /* Added NCB 26/5/2006 for completeness */
2117 if (yaffs_version
== 2 && !options
.inband_tags
2118 && WRITE_SIZE(mtd
) == 512) {
2119 yaffs_trace(YAFFS_TRACE_ALWAYS
, "auto selecting yaffs1");
2124 if (yaffs_version
== 2) {
2125 /* Check for version 2 style functions */
2127 !mtd
->block_isbad
||
2128 !mtd
->block_markbad
||
2130 !mtd
->write
|| !mtd
->read_oob
|| !mtd
->write_oob
) {
2131 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2132 "MTD device does not support required functions");
2136 if ((WRITE_SIZE(mtd
) < YAFFS_MIN_YAFFS2_CHUNK_SIZE
||
2137 mtd
->oobsize
< YAFFS_MIN_YAFFS2_SPARE_SIZE
) &&
2138 !options
.inband_tags
) {
2139 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2140 "MTD device does not have the right page sizes");
2144 /* Check for V1 style functions */
2147 !mtd
->write
|| !mtd
->read_oob
|| !mtd
->write_oob
) {
2148 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2149 "MTD device does not support required functions");
2153 if (WRITE_SIZE(mtd
) < YAFFS_BYTES_PER_CHUNK
||
2154 mtd
->oobsize
!= YAFFS_BYTES_PER_SPARE
) {
2155 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2156 "MTD device does not support have the right page sizes");
2161 /* OK, so if we got here, we have an MTD that's NAND and looks
2162 * like it has the right capabilities
2163 * Set the struct yaffs_dev up for mtd
2166 if (!read_only
&& !(mtd
->flags
& MTD_WRITEABLE
)) {
2169 "yaffs: mtd is read only, setting superblock read only");
2170 sb
->s_flags
|= MS_RDONLY
;
2173 dev
= kmalloc(sizeof(struct yaffs_dev
), GFP_KERNEL
);
2174 context
= kmalloc(sizeof(struct yaffs_linux_context
), GFP_KERNEL
);
2176 if (!dev
|| !context
) {
2186 /* Deep shit could not allocate device structure */
2187 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2188 "yaffs_read_super failed trying to allocate yaffs_dev");
2191 memset(dev
, 0, sizeof(struct yaffs_dev
));
2192 param
= &(dev
->param
);
2194 memset(context
, 0, sizeof(struct yaffs_linux_context
));
2195 dev
->os_context
= context
;
2196 INIT_LIST_HEAD(&(context
->context_list
));
2198 context
->super
= sb
;
2200 dev
->read_only
= read_only
;
2202 sb
->s_fs_info
= dev
;
2204 dev
->driver_context
= mtd
;
2205 param
->name
= mtd
->name
;
2207 /* Set up the memory size parameters.... */
2210 YCALCBLOCKS(mtd
->size
,
2211 (YAFFS_CHUNKS_PER_BLOCK
* YAFFS_BYTES_PER_CHUNK
));
2213 param
->start_block
= 0;
2214 param
->end_block
= n_blocks
- 1;
2215 param
->chunks_per_block
= YAFFS_CHUNKS_PER_BLOCK
;
2216 param
->total_bytes_per_chunk
= YAFFS_BYTES_PER_CHUNK
;
2217 param
->n_reserved_blocks
= 5;
2218 param
->n_caches
= (options
.no_cache
) ? 0 : 10;
2219 param
->inband_tags
= options
.inband_tags
;
2221 #ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
2222 param
->disable_lazy_load
= 1;
2224 #ifdef CONFIG_YAFFS_XATTR
2225 param
->enable_xattr
= 1;
2227 if (options
.lazy_loading_overridden
)
2228 param
->disable_lazy_load
= !options
.lazy_loading_enabled
;
2230 #ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
2231 param
->no_tags_ecc
= 1;
2234 #ifdef CONFIG_YAFFS_DISABLE_BACKGROUND
2236 param
->defered_dir_update
= 1;
2239 if (options
.tags_ecc_overridden
)
2240 param
->no_tags_ecc
= !options
.tags_ecc_on
;
2242 #ifdef CONFIG_YAFFS_EMPTY_LOST_AND_FOUND
2243 param
->empty_lost_n_found
= 1;
2246 #ifdef CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING
2247 param
->refresh_period
= 0;
2249 param
->refresh_period
= 500;
2252 #ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
2253 param
->always_check_erased
= 1;
2256 if (options
.empty_lost_and_found_overridden
)
2257 param
->empty_lost_n_found
= options
.empty_lost_and_found
;
2259 /* ... and the functions. */
2260 if (yaffs_version
== 2) {
2261 param
->write_chunk_tags_fn
= nandmtd2_write_chunk_tags
;
2262 param
->read_chunk_tags_fn
= nandmtd2_read_chunk_tags
;
2263 param
->bad_block_fn
= nandmtd2_mark_block_bad
;
2264 param
->query_block_fn
= nandmtd2_query_block
;
2265 yaffs_dev_to_lc(dev
)->spare_buffer
=
2266 kmalloc(mtd
->oobsize
, GFP_NOFS
);
2267 param
->is_yaffs2
= 1;
2268 param
->total_bytes_per_chunk
= mtd
->writesize
;
2269 param
->chunks_per_block
= mtd
->erasesize
/ mtd
->writesize
;
2270 n_blocks
= YCALCBLOCKS(mtd
->size
, mtd
->erasesize
);
2272 param
->start_block
= 0;
2273 param
->end_block
= n_blocks
- 1;
2275 /* use the MTD interface in yaffs_mtdif1.c */
2276 param
->write_chunk_tags_fn
= nandmtd1_write_chunk_tags
;
2277 param
->read_chunk_tags_fn
= nandmtd1_read_chunk_tags
;
2278 param
->bad_block_fn
= nandmtd1_mark_block_bad
;
2279 param
->query_block_fn
= nandmtd1_query_block
;
2280 param
->is_yaffs2
= 0;
2282 /* ... and common functions */
2283 param
->erase_fn
= nandmtd_erase_block
;
2284 param
->initialise_flash_fn
= nandmtd_initialise
;
2286 yaffs_dev_to_lc(dev
)->put_super_fn
= yaffs_mtd_put_super
;
2288 param
->sb_dirty_fn
= yaffs_touch_super
;
2289 param
->gc_control
= yaffs_gc_control_callback
;
2291 yaffs_dev_to_lc(dev
)->super
= sb
;
2293 #ifndef CONFIG_YAFFS_DOES_ECC
2294 param
->use_nand_ecc
= 1;
2297 param
->skip_checkpt_rd
= options
.skip_checkpoint_read
;
2298 param
->skip_checkpt_wr
= options
.skip_checkpoint_write
;
2300 mutex_lock(&yaffs_context_lock
);
2301 /* Get a mount id */
2303 for (mount_id
= 0; !found
; mount_id
++) {
2305 list_for_each(l
, &yaffs_context_list
) {
2307 list_entry(l
, struct yaffs_linux_context
,
2309 if (context_iterator
->mount_id
== mount_id
)
2313 context
->mount_id
= mount_id
;
2315 list_add_tail(&(yaffs_dev_to_lc(dev
)->context_list
),
2316 &yaffs_context_list
);
2317 mutex_unlock(&yaffs_context_lock
);
2319 /* Directory search handling... */
2320 INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev
)->search_contexts
));
2321 param
->remove_obj_fn
= yaffs_remove_obj_callback
;
2323 mutex_init(&(yaffs_dev_to_lc(dev
)->gross_lock
));
2325 yaffs_gross_lock(dev
);
2327 err
= yaffs_guts_initialise(dev
);
2329 yaffs_trace(YAFFS_TRACE_OS
,
2330 "yaffs_read_super: guts initialised %s",
2331 (err
== YAFFS_OK
) ? "OK" : "FAILED");
2333 if (err
== YAFFS_OK
)
2334 yaffs_bg_start(dev
);
2336 if (!context
->bg_thread
)
2337 param
->defered_dir_update
= 0;
2339 /* Release lock before yaffs_get_inode() */
2340 yaffs_gross_unlock(dev
);
2342 /* Create root inode */
2343 if (err
== YAFFS_OK
)
2344 inode
= yaffs_get_inode(sb
, S_IFDIR
| 0755, 0, yaffs_root(dev
));
2349 inode
->i_op
= &yaffs_dir_inode_operations
;
2350 inode
->i_fop
= &yaffs_dir_operations
;
2352 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_read_super: got root inode");
2354 root
= d_alloc_root(inode
);
2356 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_read_super: d_alloc_root done");
2363 sb
->s_dirt
= !dev
->is_checkpointed
;
2364 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2365 "yaffs_read_super: is_checkpointed %d",
2366 dev
->is_checkpointed
);
2368 yaffs_trace(YAFFS_TRACE_OS
, "yaffs_read_super: done");
2372 static int yaffs_internal_read_super_mtd(struct super_block
*sb
, void *data
,
2375 return yaffs_internal_read_super(1, sb
, data
, silent
) ? 0 : -EINVAL
;
2378 static int yaffs_read_super(struct file_system_type
*fs
,
2379 int flags
, const char *dev_name
,
2380 void *data
, struct vfsmount
*mnt
)
2383 return get_sb_bdev(fs
, flags
, dev_name
, data
,
2384 yaffs_internal_read_super_mtd
, mnt
);
2387 static struct file_system_type yaffs_fs_type
= {
2388 .owner
= THIS_MODULE
,
2390 .get_sb
= yaffs_read_super
,
2391 .kill_sb
= kill_block_super
,
2392 .fs_flags
= FS_REQUIRES_DEV
,
2395 #ifdef CONFIG_YAFFS_YAFFS2
2397 static int yaffs2_internal_read_super_mtd(struct super_block
*sb
, void *data
,
2400 return yaffs_internal_read_super(2, sb
, data
, silent
) ? 0 : -EINVAL
;
2403 static int yaffs2_read_super(struct file_system_type
*fs
,
2404 int flags
, const char *dev_name
, void *data
,
2405 struct vfsmount
*mnt
)
2407 return get_sb_bdev(fs
, flags
, dev_name
, data
,
2408 yaffs2_internal_read_super_mtd
, mnt
);
2411 static struct file_system_type yaffs2_fs_type
= {
2412 .owner
= THIS_MODULE
,
2414 .get_sb
= yaffs2_read_super
,
2415 .kill_sb
= kill_block_super
,
2416 .fs_flags
= FS_REQUIRES_DEV
,
2418 #endif /* CONFIG_YAFFS_YAFFS2 */
2420 static struct proc_dir_entry
*my_proc_entry
;
2422 static char *yaffs_dump_dev_part0(char *buf
, struct yaffs_dev
*dev
)
2424 struct yaffs_param
*param
= &dev
->param
;
2425 buf
+= sprintf(buf
, "start_block........... %d\n", param
->start_block
);
2426 buf
+= sprintf(buf
, "end_block............. %d\n", param
->end_block
);
2427 buf
+= sprintf(buf
, "total_bytes_per_chunk. %d\n",
2428 param
->total_bytes_per_chunk
);
2429 buf
+= sprintf(buf
, "use_nand_ecc.......... %d\n",
2430 param
->use_nand_ecc
);
2431 buf
+= sprintf(buf
, "no_tags_ecc........... %d\n", param
->no_tags_ecc
);
2432 buf
+= sprintf(buf
, "is_yaffs2............. %d\n", param
->is_yaffs2
);
2433 buf
+= sprintf(buf
, "inband_tags........... %d\n", param
->inband_tags
);
2434 buf
+= sprintf(buf
, "empty_lost_n_found.... %d\n",
2435 param
->empty_lost_n_found
);
2436 buf
+= sprintf(buf
, "disable_lazy_load..... %d\n",
2437 param
->disable_lazy_load
);
2438 buf
+= sprintf(buf
, "refresh_period........ %d\n",
2439 param
->refresh_period
);
2440 buf
+= sprintf(buf
, "n_caches.............. %d\n", param
->n_caches
);
2441 buf
+= sprintf(buf
, "n_reserved_blocks..... %d\n",
2442 param
->n_reserved_blocks
);
2443 buf
+= sprintf(buf
, "always_check_erased... %d\n",
2444 param
->always_check_erased
);
2449 static char *yaffs_dump_dev_part1(char *buf
, struct yaffs_dev
*dev
)
2452 sprintf(buf
, "data_bytes_per_chunk.. %d\n",
2453 dev
->data_bytes_per_chunk
);
2454 buf
+= sprintf(buf
, "chunk_grp_bits........ %d\n", dev
->chunk_grp_bits
);
2455 buf
+= sprintf(buf
, "chunk_grp_size........ %d\n", dev
->chunk_grp_size
);
2457 sprintf(buf
, "n_erased_blocks....... %d\n", dev
->n_erased_blocks
);
2459 sprintf(buf
, "blocks_in_checkpt..... %d\n", dev
->blocks_in_checkpt
);
2460 buf
+= sprintf(buf
, "\n");
2461 buf
+= sprintf(buf
, "n_tnodes.............. %d\n", dev
->n_tnodes
);
2462 buf
+= sprintf(buf
, "n_obj................. %d\n", dev
->n_obj
);
2463 buf
+= sprintf(buf
, "n_free_chunks......... %d\n", dev
->n_free_chunks
);
2464 buf
+= sprintf(buf
, "\n");
2465 buf
+= sprintf(buf
, "n_page_writes......... %u\n", dev
->n_page_writes
);
2466 buf
+= sprintf(buf
, "n_page_reads.......... %u\n", dev
->n_page_reads
);
2467 buf
+= sprintf(buf
, "n_erasures............ %u\n", dev
->n_erasures
);
2468 buf
+= sprintf(buf
, "n_gc_copies........... %u\n", dev
->n_gc_copies
);
2469 buf
+= sprintf(buf
, "all_gcs............... %u\n", dev
->all_gcs
);
2471 sprintf(buf
, "passive_gc_count...... %u\n", dev
->passive_gc_count
);
2473 sprintf(buf
, "oldest_dirty_gc_count. %u\n",
2474 dev
->oldest_dirty_gc_count
);
2475 buf
+= sprintf(buf
, "n_gc_blocks........... %u\n", dev
->n_gc_blocks
);
2476 buf
+= sprintf(buf
, "bg_gcs................ %u\n", dev
->bg_gcs
);
2478 sprintf(buf
, "n_retired_writes...... %u\n", dev
->n_retired_writes
);
2480 sprintf(buf
, "n_retired_blocks...... %u\n", dev
->n_retired_blocks
);
2481 buf
+= sprintf(buf
, "n_ecc_fixed........... %u\n", dev
->n_ecc_fixed
);
2482 buf
+= sprintf(buf
, "n_ecc_unfixed......... %u\n", dev
->n_ecc_unfixed
);
2484 sprintf(buf
, "n_tags_ecc_fixed...... %u\n", dev
->n_tags_ecc_fixed
);
2486 sprintf(buf
, "n_tags_ecc_unfixed.... %u\n",
2487 dev
->n_tags_ecc_unfixed
);
2488 buf
+= sprintf(buf
, "cache_hits............ %u\n", dev
->cache_hits
);
2490 sprintf(buf
, "n_deleted_files....... %u\n", dev
->n_deleted_files
);
2492 sprintf(buf
, "n_unlinked_files...... %u\n", dev
->n_unlinked_files
);
2493 buf
+= sprintf(buf
, "refresh_count......... %u\n", dev
->refresh_count
);
2494 buf
+= sprintf(buf
, "n_bg_deletions........ %u\n", dev
->n_bg_deletions
);
2499 static int yaffs_proc_read(char *page
,
2501 off_t offset
, int count
, int *eof
, void *data
)
2503 struct list_head
*item
;
2508 /* Get proc_file_read() to step 'offset' by one on each sucessive call.
2509 * We use 'offset' (*ppos) to indicate where we are in dev_list.
2510 * This also assumes the user has posted a read buffer large
2511 * enough to hold the complete output; but that's life in /proc.
2516 /* Print header first */
2518 buf
+= sprintf(buf
, "YAFFS built:" __DATE__
" " __TIME__
"\n");
2520 buf
+= sprintf(buf
, "\n");
2524 mutex_lock(&yaffs_context_lock
);
2526 /* Locate and print the Nth entry. Order N-squared but N is small. */
2527 list_for_each(item
, &yaffs_context_list
) {
2528 struct yaffs_linux_context
*dc
=
2529 list_entry(item
, struct yaffs_linux_context
,
2531 struct yaffs_dev
*dev
= dc
->dev
;
2533 if (n
< (step
& ~1)) {
2537 if ((step
& 1) == 0) {
2539 sprintf(buf
, "\nDevice %d \"%s\"\n", n
,
2541 buf
= yaffs_dump_dev_part0(buf
, dev
);
2543 buf
= yaffs_dump_dev_part1(buf
, dev
);
2548 mutex_unlock(&yaffs_context_lock
);
2551 return buf
- page
< count
? buf
- page
: count
;
2556 * Set the verbosity of the warnings and error messages.
2558 * Note that the names can only be a..z or _ with the current code.
2563 unsigned mask_bitfield
;
2565 {"allocate", YAFFS_TRACE_ALLOCATE
},
2566 {"always", YAFFS_TRACE_ALWAYS
},
2567 {"background", YAFFS_TRACE_BACKGROUND
},
2568 {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS
},
2569 {"buffers", YAFFS_TRACE_BUFFERS
},
2570 {"bug", YAFFS_TRACE_BUG
},
2571 {"checkpt", YAFFS_TRACE_CHECKPOINT
},
2572 {"deletion", YAFFS_TRACE_DELETION
},
2573 {"erase", YAFFS_TRACE_ERASE
},
2574 {"error", YAFFS_TRACE_ERROR
},
2575 {"gc_detail", YAFFS_TRACE_GC_DETAIL
},
2576 {"gc", YAFFS_TRACE_GC
},
2577 {"lock", YAFFS_TRACE_LOCK
},
2578 {"mtd", YAFFS_TRACE_MTD
},
2579 {"nandaccess", YAFFS_TRACE_NANDACCESS
},
2580 {"os", YAFFS_TRACE_OS
},
2581 {"scan_debug", YAFFS_TRACE_SCAN_DEBUG
},
2582 {"scan", YAFFS_TRACE_SCAN
},
2583 {"mount", YAFFS_TRACE_MOUNT
},
2584 {"tracing", YAFFS_TRACE_TRACING
},
2585 {"sync", YAFFS_TRACE_SYNC
},
2586 {"write", YAFFS_TRACE_WRITE
},
2587 {"verify", YAFFS_TRACE_VERIFY
},
2588 {"verify_nand", YAFFS_TRACE_VERIFY_NAND
},
2589 {"verify_full", YAFFS_TRACE_VERIFY_FULL
},
2590 {"verify_all", YAFFS_TRACE_VERIFY_ALL
},
2591 {"all", 0xffffffff},
2596 #define MAX_MASK_NAME_LENGTH 40
2597 static int yaffs_proc_write_trace_options(struct file
*file
, const char *buf
,
2598 unsigned long count
, void *data
)
2600 unsigned rg
= 0, mask_bitfield
;
2604 char substring
[MAX_MASK_NAME_LENGTH
+ 1];
2610 rg
= yaffs_trace_mask
;
2612 while (!done
&& (pos
< count
)) {
2614 while ((pos
< count
) && isspace(buf
[pos
]))
2631 mask_bitfield
= simple_strtoul(buf
+ pos
, &end
, 0);
2633 if (end
> buf
+ pos
) {
2634 mask_name
= "numeral";
2635 len
= end
- (buf
+ pos
);
2639 for (x
= buf
+ pos
, i
= 0;
2640 (*x
== '_' || (*x
>= 'a' && *x
<= 'z')) &&
2641 i
< MAX_MASK_NAME_LENGTH
; x
++, i
++, pos
++)
2643 substring
[i
] = '\0';
2645 for (i
= 0; mask_flags
[i
].mask_name
!= NULL
; i
++) {
2646 if (strcmp(substring
, mask_flags
[i
].mask_name
)
2648 mask_name
= mask_flags
[i
].mask_name
;
2650 mask_flags
[i
].mask_bitfield
;
2657 if (mask_name
!= NULL
) {
2661 rg
&= ~mask_bitfield
;
2664 rg
|= mask_bitfield
;
2670 rg
|= mask_bitfield
;
2676 yaffs_trace_mask
= rg
| YAFFS_TRACE_ALWAYS
;
2678 printk(KERN_DEBUG
"new trace = 0x%08X\n", yaffs_trace_mask
);
2680 if (rg
& YAFFS_TRACE_ALWAYS
) {
2681 for (i
= 0; mask_flags
[i
].mask_name
!= NULL
; i
++) {
2683 flag
= ((rg
& mask_flags
[i
].mask_bitfield
) ==
2684 mask_flags
[i
].mask_bitfield
) ? '+' : '-';
2685 printk(KERN_DEBUG
"%c%s\n", flag
,
2686 mask_flags
[i
].mask_name
);
2693 static int yaffs_proc_write(struct file
*file
, const char *buf
,
2694 unsigned long count
, void *data
)
2696 return yaffs_proc_write_trace_options(file
, buf
, count
, data
);
2699 /* Stuff to handle installation of file systems */
2700 struct file_system_to_install
{
2701 struct file_system_type
*fst
;
2705 static struct file_system_to_install fs_to_install
[] = {
2706 {&yaffs_fs_type
, 0},
2707 {&yaffs2_fs_type
, 0},
2711 static int __init
init_yaffs_fs(void)
2714 struct file_system_to_install
*fsinst
;
2716 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2717 "yaffs built " __DATE__
" " __TIME__
" Installing.");
2719 #ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
2720 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2721 "\n\nYAFFS-WARNING CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED selected.\n\n\n");
2724 mutex_init(&yaffs_context_lock
);
2726 /* Install the proc_fs entries */
2727 my_proc_entry
= create_proc_entry("yaffs",
2728 S_IRUGO
| S_IFREG
, YPROC_ROOT
);
2730 if (my_proc_entry
) {
2731 my_proc_entry
->write_proc
= yaffs_proc_write
;
2732 my_proc_entry
->read_proc
= yaffs_proc_read
;
2733 my_proc_entry
->data
= NULL
;
2739 /* Now add the file system entries */
2741 fsinst
= fs_to_install
;
2743 while (fsinst
->fst
&& !error
) {
2744 error
= register_filesystem(fsinst
->fst
);
2746 fsinst
->installed
= 1;
2750 /* Any errors? uninstall */
2752 fsinst
= fs_to_install
;
2754 while (fsinst
->fst
) {
2755 if (fsinst
->installed
) {
2756 unregister_filesystem(fsinst
->fst
);
2757 fsinst
->installed
= 0;
2766 static void __exit
exit_yaffs_fs(void)
2769 struct file_system_to_install
*fsinst
;
2771 yaffs_trace(YAFFS_TRACE_ALWAYS
,
2772 "yaffs built " __DATE__
" " __TIME__
" removing.");
2774 remove_proc_entry("yaffs", YPROC_ROOT
);
2776 fsinst
= fs_to_install
;
2778 while (fsinst
->fst
) {
2779 if (fsinst
->installed
) {
2780 unregister_filesystem(fsinst
->fst
);
2781 fsinst
->installed
= 0;
2787 module_init(init_yaffs_fs
)
2788 module_exit(exit_yaffs_fs
)
2790 MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
2791 MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2010");
2792 MODULE_LICENSE("GPL");