Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
1a4c1b9e
Commit
1a4c1b9e
authored
Jul 29, 2002
by
David Woodhouse
Browse files
Options
Browse Files
Download
Plain Diff
Merge hch's addition of generic_file_sendfile into jffs2_file_operations.
parents
ff42067b
70d06792
Changes
30
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
763 additions
and
996 deletions
+763
-996
fs/jffs2/LICENCE
fs/jffs2/LICENCE
+35
-0
fs/jffs2/TODO
fs/jffs2/TODO
+23
-3
fs/jffs2/background.c
fs/jffs2/background.c
+27
-32
fs/jffs2/build.c
fs/jffs2/build.c
+6
-26
fs/jffs2/compr.c
fs/jffs2/compr.c
+2
-26
fs/jffs2/compr_rtime.c
fs/jffs2/compr_rtime.c
+2
-26
fs/jffs2/compr_rubin.c
fs/jffs2/compr_rubin.c
+2
-26
fs/jffs2/compr_zlib.c
fs/jffs2/compr_zlib.c
+7
-31
fs/jffs2/dir.c
fs/jffs2/dir.c
+53
-45
fs/jffs2/erase.c
fs/jffs2/erase.c
+15
-38
fs/jffs2/file.c
fs/jffs2/file.c
+31
-59
fs/jffs2/fs.c
fs/jffs2/fs.c
+52
-154
fs/jffs2/gc.c
fs/jffs2/gc.c
+35
-33
fs/jffs2/ioctl.c
fs/jffs2/ioctl.c
+2
-26
fs/jffs2/malloc.c
fs/jffs2/malloc.c
+2
-26
fs/jffs2/nodelist.c
fs/jffs2/nodelist.c
+10
-42
fs/jffs2/nodelist.h
fs/jffs2/nodelist.h
+9
-27
fs/jffs2/nodemgmt.c
fs/jffs2/nodemgmt.c
+157
-34
fs/jffs2/os-linux.h
fs/jffs2/os-linux.h
+6
-26
fs/jffs2/pushpull.h
fs/jffs2/pushpull.h
+2
-26
fs/jffs2/read.c
fs/jffs2/read.c
+2
-26
fs/jffs2/readinode.c
fs/jffs2/readinode.c
+7
-26
fs/jffs2/scan.c
fs/jffs2/scan.c
+129
-49
fs/jffs2/super.c
fs/jffs2/super.c
+32
-44
fs/jffs2/symlink.c
fs/jffs2/symlink.c
+5
-29
fs/jffs2/wbuf.c
fs/jffs2/wbuf.c
+84
-28
fs/jffs2/write.c
fs/jffs2/write.c
+12
-30
fs/jffs2/writev.c
fs/jffs2/writev.c
+2
-26
include/linux/jffs2.h
include/linux/jffs2.h
+3
-26
include/linux/jffs2_fs_sb.h
include/linux/jffs2_fs_sb.h
+9
-6
No files found.
fs/jffs2/LICENCE
0 → 100644
View file @
1a4c1b9e
The files in this directory and elsewhere which refer to this LICENCE
file are part of JFFS2, the Journalling Flash File System v2.
Copyright (C) 2001, 2002 Red Hat, Inc.
JFFS2 is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 or (at your option) any later
version.
JFFS2 is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with JFFS2; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from these files, or you compile these
files and link them with other works to produce a work based on these
files, these files do not by themselves cause the resulting work to be
covered by the GNU General Public License. However the source code for
these files must still be made available in accordance with section (3)
of the GNU General Public License.
This exception does not invalidate any other reasons why a work based on
this file might be covered by the GNU General Public License.
For information on obtaining alternative licences for JFFS2, see
http://sources.redhat.com/jffs2/jffs2-licence.html
$Id: LICENCE,v 1.1 2002/05/20 14:56:37 dwmw2 Exp $
fs/jffs2/TODO
View file @
1a4c1b9e
$Id: TODO,v 1.
7 2002/03/11 12:36:59
dwmw2 Exp $
$Id: TODO,v 1.
9 2002/07/11 10:39:04
dwmw2 Exp $
- Locking audit. Even more so now 2.5 took away the BKL.
- disable compression in commit_write()?
- fine-tune the allocation / GC thresholds
- chattr support - turning on/off and tuning compression per-inode
...
...
@@ -9,7 +8,6 @@ $Id: TODO,v 1.7 2002/03/11 12:36:59 dwmw2 Exp $
mount doesn't have to read the flash twice for large files.
Make this a per-inode option, changable with chattr, so you can
decide which inodes should be in-core immediately after mount.
- stop it depending on a block device.
- test, test, test
- NAND flash support:
...
...
@@ -22,3 +20,25 @@ $Id: TODO,v 1.7 2002/03/11 12:36:59 dwmw2 Exp $
- timed flush of old wbuf
- fix magical second arg of jffs2_flush_wbuf(). Split into two or more functions instead.
- Optimisations:
- Stop GC from decompressing and immediately recompressing nodes which could
just be copied intact.
- Furthermore, in the case where it could be copied intact we don't even need
to call iget() for it -- if we use (raw_node_raw->flash_offset & 2) as a flag
to show a node can be copied intact and it's _not_ in icache, we could just do
it, fix up the next_in_ino list and move on. We would need a way to find out
_whether_ it's in icache though -- if it's in icache we also need to do the
fragment lists, etc. P'raps a flag or pointer in the jffs2_inode_cache could
help.
- Stop keeping name in-core with struct jffs2_full_dirent. If we keep the hash in
the full dirent, we only need to go to the flash in lookup() when we think we've
got a match, and in readdir().
- Doubly-linked next_in_ino list to allow us to free obsoleted raw_node_refs immediately?
- Remove totlen from jffs2_raw_node_ref? Need to have totlen passed into
jffs2_mark_node_obsolete(). Can all callers work it out?
- Don't check data CRC on node scan during mount. We don't really need to know
yet. This means we can't build up node fragment lists, and hence can't
build accurate clean/dirty information. But we don't _need_ that for reading,
only for writing. And in fact we don't even need it for writing until we
start to need GC.
fs/jffs2/background.c
View file @
1a4c1b9e
...
...
@@ -5,45 +5,21 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: background.c,v 1.23 2002/03/06 12:37:08 dwmw2 Exp $
* $Id: background.c,v 1.29 2002/06/07 10:04:28 dwmw2 Exp $
*
*/
#define __KERNEL_SYSCALLS__
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <linux/jffs2.h>
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/mtd/compatmac.h>
/* recalc_sigpending() */
#include <linux/unistd.h>
#include "nodelist.h"
...
...
@@ -86,6 +62,13 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
void
jffs2_stop_garbage_collect_thread
(
struct
jffs2_sb_info
*
c
)
{
if
(
c
->
mtd
->
type
==
MTD_NANDFLASH
)
{
/* stop a eventually scheduled wbuf flush timer */
del_timer_sync
(
&
c
->
wbuf_timer
);
/* make sure, that a scheduled wbuf flush task is completed */
flush_scheduled_tasks
();
}
spin_lock_bh
(
&
c
->
erase_completion_lock
);
if
(
c
->
gc_task
)
{
D1
(
printk
(
KERN_DEBUG
"jffs2: Killing GC task %d
\n
"
,
c
->
gc_task
->
pid
));
...
...
@@ -171,11 +154,23 @@ static int jffs2_garbage_collect_thread(void *_c)
static
int
thread_should_wake
(
struct
jffs2_sb_info
*
c
)
{
D1
(
printk
(
KERN_DEBUG
"thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x
\n
"
,
c
->
nr_free_blocks
,
c
->
nr_erasing_blocks
,
c
->
dirty_size
));
uint32_t
gcnodeofs
=
0
;
int
ret
;
/* Don't count any progress we've already made through the gcblock
as dirty space, for the purposes of this calculation */
if
(
c
->
gcblock
&&
c
->
gcblock
->
gc_node
)
gcnodeofs
=
c
->
gcblock
->
gc_node
->
flash_offset
&
~
3
&
(
c
->
sector_size
-
1
);
if
(
c
->
nr_free_blocks
+
c
->
nr_erasing_blocks
<
JFFS2_RESERVED_BLOCKS_GCTRIGGER
&&
c
->
dirty_size
>
c
->
sector_size
)
ret
urn
1
;
(
c
->
dirty_size
-
gcnodeofs
)
>
c
->
sector_size
)
ret
=
1
;
else
return
0
;
ret
=
0
;
D1
(
printk
(
KERN_DEBUG
"thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x (mod 0x%x): %s
\n
"
,
c
->
nr_free_blocks
,
c
->
nr_erasing_blocks
,
c
->
dirty_size
,
c
->
dirty_size
-
gcnodeofs
,
ret
?
"yes"
:
"no"
));
return
ret
;
}
fs/jffs2/build.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: build.c,v 1.32 2002/03/08 15:11:24 dwmw2 Exp $
* $Id: build.c,v 1.35 2002/05/20 14:56:37 dwmw2 Exp $
*
*/
...
...
@@ -124,6 +100,9 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
}
D1
(
printk
(
KERN_DEBUG
"Pass 3 complete
\n
"
));
/* Rotate the lists by some number to ensure wear levelling */
jffs2_rotate_lists
(
c
);
return
ret
;
}
...
...
@@ -304,6 +283,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
spin_lock_init
(
&
c
->
inocache_lock
);
INIT_LIST_HEAD
(
&
c
->
clean_list
);
INIT_LIST_HEAD
(
&
c
->
very_dirty_list
);
INIT_LIST_HEAD
(
&
c
->
dirty_list
);
INIT_LIST_HEAD
(
&
c
->
erasable_list
);
INIT_LIST_HEAD
(
&
c
->
erasing_list
);
...
...
fs/jffs2/compr.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by Arjan van de Ven <arjanv@redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: compr.c,v 1.23 2002/01/25 01:49:26 dwmw2 Exp $
* $Id: compr.c,v 1.24 2002/05/20 14:56:37 dwmw2 Exp $
*
*/
...
...
fs/jffs2/compr_rtime.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by Arjan van de Ven <arjanv@redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: compr_rtime.c,v 1.8 2002/01/25 01:49:26 dwmw2 Exp $
* $Id: compr_rtime.c,v 1.9 2002/05/20 14:56:37 dwmw2 Exp $
*
*
* Very simple lz77-ish encoder.
...
...
fs/jffs2/compr_rubin.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by Arjan van de Ven <arjanv@redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: compr_rubin.c,v 1.16 2002/01/25 01:49:26 dwmw2 Exp $
* $Id: compr_rubin.c,v 1.17 2002/05/20 14:56:37 dwmw2 Exp $
*
*/
...
...
fs/jffs2/compr_zlib.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: compr_zlib.c,v 1.15 2002/03/04 09:35:48 dwmw2 Exp $
* $Id: compr_zlib.c,v 1.18 2002/05/20 14:56:37 dwmw2 Exp $
*
*/
...
...
@@ -65,21 +41,21 @@ int __init jffs2_zlib_init(void)
{
deflate_workspace
=
vmalloc
(
zlib_deflate_workspacesize
());
if
(
!
deflate_workspace
)
{
printk
(
"Failed to allocate %d bytes for deflate workspace
\n
"
,
zlib_deflate_workspacesize
());
printk
(
KERN_WARNING
"Failed to allocate %d bytes for deflate workspace
\n
"
,
zlib_deflate_workspacesize
());
return
-
ENOMEM
;
}
D1
(
printk
(
"Allocated %d bytes for deflate workspace
\n
"
,
zlib_deflate_workspacesize
()));
D1
(
printk
(
KERN_DEBUG
"Allocated %d bytes for deflate workspace
\n
"
,
zlib_deflate_workspacesize
()));
inflate_workspace
=
vmalloc
(
zlib_inflate_workspacesize
());
if
(
!
inflate_workspace
)
{
printk
(
"Failed to allocate %d bytes for inflate workspace
\n
"
,
zlib_inflate_workspacesize
());
printk
(
KERN_WARNING
"Failed to allocate %d bytes for inflate workspace
\n
"
,
zlib_inflate_workspacesize
());
vfree
(
deflate_workspace
);
return
-
ENOMEM
;
}
D1
(
printk
(
"Allocated %d bytes for inflate workspace
\n
"
,
zlib_inflate_workspacesize
()));
D1
(
printk
(
KERN_DEBUG
"Allocated %d bytes for inflate workspace
\n
"
,
zlib_inflate_workspacesize
()));
return
0
;
}
void
__exit
jffs2_zlib_exit
(
void
)
void
jffs2_zlib_exit
(
void
)
{
vfree
(
deflate_workspace
);
vfree
(
inflate_workspace
);
...
...
fs/jffs2/dir.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: dir.c,v 1.68 2002/03/11 12:36:59 dwmw2 Exp $
* $Id: dir.c,v 1.71 2002/07/23 17:00:45 dwmw2 Exp $
*
*/
...
...
@@ -45,7 +21,6 @@
#include <linux/jffs2_fs_i.h>
#include <linux/jffs2_fs_sb.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
#include "nodelist.h"
static
int
jffs2_readdir
(
struct
file
*
,
void
*
,
filldir_t
);
...
...
@@ -63,25 +38,25 @@ static int jffs2_rename (struct inode *, struct dentry *,
struct
file_operations
jffs2_dir_operations
=
{
read:
generic_read_dir
,
readdir:
jffs2_readdir
,
ioctl:
jffs2_ioctl
,
fsync:
jffs2_fsync
.
read
=
generic_read_dir
,
.
readdir
=
jffs2_readdir
,
.
ioctl
=
jffs2_ioctl
,
.
fsync
=
jffs2_fsync
};
struct
inode_operations
jffs2_dir_inode_operations
=
{
create:
jffs2_create
,
lookup:
jffs2_lookup
,
link:
jffs2_link
,
unlink:
jffs2_unlink
,
symlink:
jffs2_symlink
,
mkdir:
jffs2_mkdir
,
rmdir:
jffs2_rmdir
,
mknod:
jffs2_mknod
,
rename:
jffs2_rename
,
setattr:
jffs2_setattr
,
.
create
=
jffs2_create
,
.
lookup
=
jffs2_lookup
,
.
link
=
jffs2_link
,
.
unlink
=
jffs2_unlink
,
.
symlink
=
jffs2_symlink
,
.
mkdir
=
jffs2_mkdir
,
.
rmdir
=
jffs2_rmdir
,
.
mknod
=
jffs2_mknod
,
.
rename
=
jffs2_rename
,
.
setattr
=
jffs2_setattr
,
};
/***********************************************************************/
...
...
@@ -144,8 +119,6 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
D1
(
printk
(
KERN_DEBUG
"jffs2_readdir() for dir_i #%lu
\n
"
,
filp
->
f_dentry
->
d_inode
->
i_ino
));
lock_kernel
();
f
=
JFFS2_INODE_INFO
(
inode
);
c
=
JFFS2_SB_INFO
(
inode
->
i_sb
);
...
...
@@ -189,7 +162,6 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
up
(
&
f
->
sem
);
out:
filp
->
f_pos
=
offset
;
unlock_kernel
();
return
0
;
}
...
...
@@ -744,8 +716,30 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
{
int
ret
;
struct
jffs2_sb_info
*
c
=
JFFS2_SB_INFO
(
old_dir_i
->
i_sb
);
struct
jffs2_inode_info
*
victim_f
=
NULL
;
uint8_t
type
;
/* The VFS will check for us and prevent trying to rename a
* file over a directory and vice versa, but if it's a directory,
* the VFS can't check whether the victim is empty. The filesystem
* needs to do that for itself.
*/
if
(
new_dentry
->
d_inode
)
{
victim_f
=
JFFS2_INODE_INFO
(
new_dentry
->
d_inode
);
if
(
S_ISDIR
(
new_dentry
->
d_inode
->
i_mode
))
{
struct
jffs2_full_dirent
*
fd
;
down
(
&
victim_f
->
sem
);
for
(
fd
=
victim_f
->
dents
;
fd
;
fd
=
fd
->
next
)
{
if
(
fd
->
ino
)
{
up
(
&
victim_f
->
sem
);
return
-
ENOTEMPTY
;
}
}
up
(
&
victim_f
->
sem
);
}
}
/* XXX: We probably ought to alloc enough space for
both nodes at the same time. Writing the new link,
then getting -ENOSPC, is quite bad :)
...
...
@@ -764,7 +758,21 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
if
(
ret
)
return
ret
;
if
(
S_ISDIR
(
old_dentry
->
d_inode
->
i_mode
))
if
(
victim_f
)
{
/* There was a victim. Kill it off nicely */
new_dentry
->
d_inode
->
i_nlink
--
;
/* Don't oops if the victim was a dirent pointing to an
inode which didn't exist. */
if
(
victim_f
->
inocache
)
{
down
(
&
victim_f
->
sem
);
victim_f
->
inocache
->
nlink
--
;
up
(
&
victim_f
->
sem
);
}
}
/* If it was a directory we moved, and there was no victim,
increase i_nlink on its new parent */
if
(
S_ISDIR
(
old_dentry
->
d_inode
->
i_mode
)
&&
!
victim_f
)
new_dir_i
->
i_nlink
++
;
/* Unlink the original */
...
...
fs/jffs2/erase.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: erase.c,v 1.35 2002/03/08 15:11:24 dwmw2 Exp $
* $Id: erase.c,v 1.39 2002/07/23 17:00:45 dwmw2 Exp $
*
*/
...
...
@@ -286,20 +262,12 @@ void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
void
jffs2_mark_erased_blocks
(
struct
jffs2_sb_info
*
c
)
{
static
struct
jffs2_unknown_node
marker
=
{
magic:
JFFS2_MAGIC_BITMASK
,
nodetype:
JFFS2_NODETYPE_CLEANMARKER
,
totlen:
sizeof
(
struct
jffs2_unknown_node
)
};
struct
jffs2_eraseblock
*
jeb
;
struct
jffs2_raw_node_ref
*
marker_ref
=
NULL
;
unsigned
char
*
ebuf
;
size_t
retlen
;
int
ret
;
if
(
unlikely
(
!
marker
.
hdr_crc
))
marker
.
hdr_crc
=
crc32
(
0
,
&
marker
,
sizeof
(
struct
jffs2_unknown_node
)
-
4
);
spin_lock_bh
(
&
c
->
erase_completion_lock
);
while
(
!
list_empty
(
&
c
->
erase_complete_list
))
{
jeb
=
list_entry
(
c
->
erase_complete_list
.
next
,
struct
jffs2_eraseblock
,
list
);
...
...
@@ -359,6 +327,7 @@ void jffs2_mark_erased_blocks(struct jffs2_sb_info *c)
}
}
ofs
+=
readlen
;
cond_resched
();
}
kfree
(
ebuf
);
}
...
...
@@ -376,22 +345,30 @@ void jffs2_mark_erased_blocks(struct jffs2_sb_info *c)
jeb
->
used_size
=
0
;
jeb
->
dirty_size
=
0
;
}
else
{
ret
=
jffs2_flash_write
(
c
,
jeb
->
offset
,
sizeof
(
marker
),
&
retlen
,
(
char
*
)
&
marker
);
struct
jffs2_unknown_node
marker
=
{
.
magic
=
JFFS2_MAGIC_BITMASK
,
.
nodetype
=
JFFS2_NODETYPE_CLEANMARKER
,
.
totlen
=
c
->
cleanmarker_size
};
marker
.
hdr_crc
=
crc32
(
0
,
&
marker
,
marker
.
totlen
-
4
);
ret
=
jffs2_flash_write
(
c
,
jeb
->
offset
,
marker
.
totlen
,
&
retlen
,
(
char
*
)
&
marker
);
if
(
ret
)
{
printk
(
KERN_WARNING
"Write clean marker to block at 0x%08x failed: %d
\n
"
,
jeb
->
offset
,
ret
);
goto
bad2
;
}
if
(
retlen
!=
sizeof
(
marker
)
)
{
if
(
retlen
!=
marker
.
totlen
)
{
printk
(
KERN_WARNING
"Short write to newly-erased block at 0x%08x: Wanted %d, got %d
\n
"
,
jeb
->
offset
,
sizeof
(
marker
)
,
retlen
);
jeb
->
offset
,
marker
.
totlen
,
retlen
);
goto
bad2
;
}
marker_ref
->
next_in_ino
=
NULL
;
marker_ref
->
next_phys
=
NULL
;
marker_ref
->
flash_offset
=
jeb
->
offset
;
marker_ref
->
totlen
=
PAD
(
sizeof
(
marker
)
);
marker_ref
->
totlen
=
PAD
(
marker
.
totlen
);
jeb
->
first_node
=
jeb
->
last_node
=
marker_ref
;
...
...
fs/jffs2/file.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: file.c,v 1.70 2002/03/05 09:55:07 dwmw2 Exp $
* $Id: file.c,v 1.76 2002/07/29 08:25:35 dwmw2 Exp $
*
*/
...
...
@@ -43,7 +19,6 @@
#include <linux/pagemap.h>
#include <linux/crc32.h>
#include <linux/jffs2.h>
#include <linux/smp_lock.h>
#include "nodelist.h"
extern
int
generic_file_open
(
struct
inode
*
,
struct
file
*
)
__attribute__
((
weak
));
...
...
@@ -66,37 +41,41 @@ int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
* maybe we have to think about it to find a smarter
* solution.
*/
down
(
&
c
->
alloc_sem
);
down
(
&
f
->
sem
);
jffs2_flush_wbuf
(
c
,
2
);
up
(
&
f
->
sem
);
up
(
&
c
->
alloc_sem
);
return
0
;
}
struct
file_operations
jffs2_file_operations
=
{
llseek:
generic_file_llseek
,
open:
generic_file_open
,
read:
generic_file_read
,
write:
generic_file_write
,
ioctl:
jffs2_ioctl
,
mmap:
generic_file_mmap
,
fsync:
jffs2_fsync
sendfile:
generic_file_sendfile
,
.
llseek
=
generic_file_llseek
,
.
open
=
generic_file_open
,
.
read
=
generic_file_read
,
.
write
=
generic_file_write
,
.
ioctl
=
jffs2_ioctl
,
.
mmap
=
generic_file_mmap
,
.
fsync
=
jffs2_fsync
,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,29)
.
sendfile
=
generic_file_sendfile
#endif
};
/* jffs2_file_inode_operations */
struct
inode_operations
jffs2_file_inode_operations
=
{
setattr:
jffs2_setattr
.
setattr
=
jffs2_setattr
};
struct
address_space_operations
jffs2_file_address_operations
=
{
readpage:
jffs2_readpage
,
prepare_write:
jffs2_prepare_write
,
commit_write:
jffs2_commit_write
.
readpage
=
jffs2_readpage
,
.
prepare_write
=
jffs2_prepare_write
,
.
commit_write
=
jffs2_commit_write
};
int
jffs2_setattr
(
struct
dentry
*
dentry
,
struct
iattr
*
iattr
)
...
...
@@ -111,12 +90,11 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
int
mdatalen
=
0
;
unsigned
int
ivalid
;
uint32_t
phys_ofs
,
alloclen
;
int
ret
=
0
;
lock_kernel
();
int
ret
;
D1
(
printk
(
KERN_DEBUG
"jffs2_setattr(): ino #%lu
\n
"
,
inode
->
i_ino
));
ret
=
inode_change_ok
(
inode
,
iattr
);
if
(
ret
)
goto
ou
t
;
return
re
t
;
/* Special cases - we don't want more than one data node
for these types on the medium at any time. So setattr
...
...
@@ -133,14 +111,12 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
}
else
if
(
S_ISLNK
(
inode
->
i_mode
))
{
mdatalen
=
f
->
metadata
->
size
;
mdata
=
kmalloc
(
f
->
metadata
->
size
,
GFP_USER
);
if
(
!
mdata
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
if
(
!
mdata
)
return
-
ENOMEM
;
ret
=
jffs2_read_dnode
(
c
,
f
->
metadata
,
mdata
,
0
,
mdatalen
);
if
(
ret
)
{
kfree
(
mdata
);
goto
ou
t
;
return
re
t
;
}
D1
(
printk
(
KERN_DEBUG
"jffs2_setattr(): Writing %d bytes of symlink target
\n
"
,
mdatalen
));
}
...
...
@@ -149,8 +125,7 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
if
(
!
ri
)
{
if
(
S_ISLNK
(
inode
->
i_mode
))
kfree
(
mdata
);
ret
=
-
ENOMEM
;
goto
out
;
return
-
ENOMEM
;
}
ret
=
jffs2_reserve_space
(
c
,
sizeof
(
*
ri
)
+
mdatalen
,
&
phys_ofs
,
&
alloclen
,
ALLOC_NORMAL
);
...
...
@@ -158,7 +133,7 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
jffs2_free_raw_inode
(
ri
);
if
(
S_ISLNK
(
inode
->
i_mode
&
S_IFMT
))
kfree
(
mdata
);
goto
ou
t
;
return
re
t
;
}
down
(
&
f
->
sem
);
ivalid
=
iattr
->
ia_valid
;
...
...
@@ -207,8 +182,7 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
jffs2_complete_reservation
(
c
);
jffs2_free_raw_inode
(
ri
);
up
(
&
f
->
sem
);
ret
=
PTR_ERR
(
new_metadata
);
goto
out
;
return
PTR_ERR
(
new_metadata
);
}
/* It worked. Update the inode */
inode
->
i_atime
=
ri
->
atime
;
...
...
@@ -242,9 +216,7 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
up
(
&
f
->
sem
);
jffs2_complete_reservation
(
c
);
out:
unlock_kernel
();
return
ret
;
return
0
;
}
int
jffs2_do_readpage_nolock
(
struct
inode
*
inode
,
struct
page
*
pg
)
...
...
@@ -289,18 +261,18 @@ int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg)
int
jffs2_readpage
(
struct
file
*
filp
,
struct
page
*
pg
)
{
struct
jffs2_inode_info
*
f
=
JFFS2_INODE_INFO
(
filp
->
f_dentry
->
d_inode
);
struct
jffs2_inode_info
*
f
=
JFFS2_INODE_INFO
(
pg
->
mapping
->
host
);
int
ret
;
down
(
&
f
->
sem
);
ret
=
jffs2_do_readpage_unlock
(
filp
->
f_dentry
->
d_inode
,
pg
);
ret
=
jffs2_do_readpage_unlock
(
pg
->
mapping
->
host
,
pg
);
up
(
&
f
->
sem
);
return
ret
;
}
int
jffs2_prepare_write
(
struct
file
*
filp
,
struct
page
*
pg
,
unsigned
start
,
unsigned
end
)
{
struct
inode
*
inode
=
filp
->
f_dentry
->
d_inode
;
struct
inode
*
inode
=
pg
->
mapping
->
host
;
struct
jffs2_inode_info
*
f
=
JFFS2_INODE_INFO
(
inode
);
uint32_t
pageofs
=
pg
->
index
<<
PAGE_CACHE_SHIFT
;
int
ret
=
0
;
...
...
@@ -384,7 +356,7 @@ int jffs2_commit_write (struct file *filp, struct page *pg, unsigned start, unsi
/* Actually commit the write from the page cache page we're looking at.
* For now, we write the full page out each time. It sucks, but it's simple
*/
struct
inode
*
inode
=
filp
->
f_dentry
->
d_inode
;
struct
inode
*
inode
=
pg
->
mapping
->
host
;
struct
jffs2_inode_info
*
f
=
JFFS2_INODE_INFO
(
inode
);
struct
jffs2_sb_info
*
c
=
JFFS2_SB_INFO
(
inode
->
i_sb
);
struct
jffs2_raw_inode
*
ri
;
...
...
fs/jffs2/fs.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: fs.c,v 1.4 2002/03/11 12:36:59 dwmw2 Exp $
* $Id: fs.c,v 1.13 2002/07/02 22:48:24 dwmw2 Exp $
*
*/
...
...
@@ -44,7 +20,6 @@
#include <linux/mtd/mtd.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include "nodelist.h"
int
jffs2_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
)
...
...
@@ -69,122 +44,10 @@ int jffs2_statfs(struct super_block *sb, struct statfs *buf)
buf
->
f_bavail
=
buf
->
f_bfree
=
avail
>>
PAGE_SHIFT
;
#if CONFIG_JFFS2_FS_DEBUG > 0
printk
(
KERN_DEBUG
"STATFS:
\n
"
);
printk
(
KERN_DEBUG
"flash_size: %08x
\n
"
,
c
->
flash_size
);
printk
(
KERN_DEBUG
"used_size: %08x
\n
"
,
c
->
used_size
);
printk
(
KERN_DEBUG
"dirty_size: %08x
\n
"
,
c
->
dirty_size
);
printk
(
KERN_DEBUG
"free_size: %08x
\n
"
,
c
->
free_size
);
printk
(
KERN_DEBUG
"erasing_size: %08x
\n
"
,
c
->
erasing_size
);
printk
(
KERN_DEBUG
"bad_size: %08x
\n
"
,
c
->
bad_size
);
printk
(
KERN_DEBUG
"sector_size: %08x
\n
"
,
c
->
sector_size
);
printk
(
KERN_DEBUG
"jffs2_reserved_blocks size: %08x
\n
"
,
c
->
sector_size
*
JFFS2_RESERVED_BLOCKS_WRITE
);
if
(
c
->
nextblock
)
{
printk
(
KERN_DEBUG
"nextblock: 0x%08x
\n
"
,
c
->
nextblock
->
offset
);
}
else
{
printk
(
KERN_DEBUG
"nextblock: NULL
\n
"
);
}
if
(
c
->
gcblock
)
{
printk
(
KERN_DEBUG
"gcblock: 0x%08x
\n
"
,
c
->
gcblock
->
offset
);
}
else
{
printk
(
KERN_DEBUG
"gcblock: NULL
\n
"
);
}
if
(
list_empty
(
&
c
->
clean_list
))
{
printk
(
KERN_DEBUG
"clean_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
clean_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"clean_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
dirty_list
))
{
printk
(
KERN_DEBUG
"dirty_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
dirty_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"dirty_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
erasable_list
))
{
printk
(
KERN_DEBUG
"erasable_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erasable_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erasable_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
erasing_list
))
{
printk
(
KERN_DEBUG
"erasing_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erasing_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erasing_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
erase_pending_list
))
{
printk
(
KERN_DEBUG
"erase_pending_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erase_pending_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erase_pending_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
erasable_pending_wbuf_list
))
{
printk
(
KERN_DEBUG
"erasable_pending_wbuf_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erasable_pending_wbuf_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erase_pending_wbuf_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
free_list
))
{
printk
(
KERN_DEBUG
"free_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
free_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"free_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
bad_list
))
{
printk
(
KERN_DEBUG
"bad_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
bad_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"bad_list: %08x
\n
"
,
jeb
->
offset
);
}
}
if
(
list_empty
(
&
c
->
bad_used_list
))
{
printk
(
KERN_DEBUG
"bad_used_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
bad_used_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"bad_used_list: %08x
\n
"
,
jeb
->
offset
);
}
}
#endif
/* CONFIG_JFFS2_FS_DEBUG */
D1
(
jffs2_dump_block_lists
(
c
));
spin_unlock_bh
(
&
c
->
erase_completion_lock
);
return
0
;
}
...
...
@@ -275,9 +138,9 @@ void jffs2_read_inode (struct inode *inode)
if
(
jffs2_read_dnode
(
c
,
f
->
metadata
,
(
char
*
)
&
rdev
,
0
,
sizeof
(
rdev
))
<
0
)
{
/* Eep */
printk
(
KERN_NOTICE
"Read device numbers for inode %lu failed
\n
"
,
(
unsigned
long
)
inode
->
i_ino
);
up
(
&
f
->
sem
);
jffs2_do_clear_inode
(
c
,
f
);
make_bad_inode
(
inode
);
up
(
&
f
->
sem
);
return
;
}
...
...
@@ -321,21 +184,24 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
void
jffs2_write_super
(
struct
super_block
*
sb
)
{
struct
jffs2_sb_info
*
c
=
JFFS2_SB_INFO
(
sb
);
lock_kernel
();
sb
->
s_dirt
=
0
;
if
(
sb
->
s_flags
&
MS_RDONLY
)
{
unlock_kernel
();
if
(
sb
->
s_flags
&
MS_RDONLY
)
return
;
}
D1
(
printk
(
"jffs2_write_super(): flush_wbuf before gc-trigger
\n
"
));
jffs2_flush_wbuf
(
c
,
2
);
D1
(
printk
(
KERN_DEBUG
"jffs2_write_super(): flush_wbuf before gc-trigger
\n
"
));
jffs2_garbage_collect_trigger
(
c
);
jffs2_erase_pending_blocks
(
c
);
jffs2_mark_erased_blocks
(
c
);
unlock_kernel
();
/* Eep. If we lock this here, we deadlock with jffs2_reserve_space() when
* it locks the alloc_sem and jffs2_do_reserve_space() waits for erases
* to happen. I think the erases and/or the flush_wbuf want doing from
*
*/
if
(
!
down_trylock
(
&
c
->
alloc_sem
))
{
jffs2_flush_wbuf
(
c
,
2
);
up
(
&
c
->
alloc_sem
);
}
// else it stays dirty. FIXME.
}
...
...
@@ -400,33 +266,61 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
{
struct
jffs2_sb_info
*
c
;
struct
inode
*
root_i
;
int
ret
;
c
=
JFFS2_SB_INFO
(
sb
);
c
->
sector_size
=
c
->
mtd
->
erasesize
;
c
->
flash_size
=
c
->
mtd
->
size
;
#if 0
if (c->sector_size < 0x10000) {
printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using 64KiB instead\n",
c->sector_size / 1024);
c->sector_size = 0x10000;
}
#endif
if
(
c
->
flash_size
<
5
*
c
->
sector_size
)
{
printk
(
KERN_ERR
"jffs2: Too few erase blocks (%d)
\n
"
,
c
->
flash_size
/
c
->
sector_size
);
return
-
EINVAL
;
}
c
->
cleanmarker_size
=
sizeof
(
struct
jffs2_unknown_node
);
/* Jrn -- stick alignment for weird 8-byte-page flash here */
if
(
jffs2_cleanmarker_oob
(
c
))
{
/* Cleanmarker is out-of-band, so inline size zero */
c
->
cleanmarker_size
=
0
;
}
if
(
c
->
mtd
->
type
==
MTD_NANDFLASH
)
{
/* Initialise write buffer */
c
->
wbuf_pagesize
=
c
->
mtd
->
oobblock
;
c
->
wbuf_ofs
=
0xFFFFFFFF
;
c
->
wbuf
=
kmalloc
(
c
->
wbuf_pagesize
,
GFP_KERNEL
);
if
(
!
c
->
wbuf
)
goto
out_mtd
;
return
-
ENOMEM
;
/* Initialize process for timed wbuf flush */
INIT_TQUEUE
(
&
c
->
wbuf_task
,(
void
*
)
jffs2_wbuf_process
,
(
void
*
)
c
);
/* Initialize timer for timed wbuf flush */
init_timer
(
&
c
->
wbuf_timer
);
c
->
wbuf_timer
.
function
=
jffs2_wbuf_timeout
;
c
->
wbuf_timer
.
data
=
(
unsigned
long
)
c
;
}
if
(
jffs2_do_mount_fs
(
c
))
goto
out_mtd
;
c
->
inocache_list
=
kmalloc
(
INOCACHE_HASHSIZE
*
sizeof
(
struct
jffs2_inode_cache
*
),
GFP_KERNEL
);
if
(
!
c
->
inocache_list
)
{
ret
=
-
ENOMEM
;
goto
out_wbuf
;
}
memset
(
c
->
inocache_list
,
0
,
INOCACHE_HASHSIZE
*
sizeof
(
struct
jffs2_inode_cache
*
));
if
((
ret
=
jffs2_do_mount_fs
(
c
)))
goto
out_inohash
;
ret
=
-
EINVAL
;
D1
(
printk
(
KERN_DEBUG
"jffs2_do_fill_super(): Getting root inode
\n
"
));
root_i
=
iget
(
sb
,
1
);
...
...
@@ -456,6 +350,10 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
jffs2_free_ino_caches
(
c
);
jffs2_free_raw_node_refs
(
c
);
kfree
(
c
->
blocks
);
out_mtd:
return
-
EINVAL
;
out_inohash:
kfree
(
c
->
inocache_list
);
out_wbuf:
if
(
c
->
wbuf
)
kfree
(
c
->
wbuf
);
return
ret
;
}
fs/jffs2/gc.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: gc.c,v 1.68 2002/03/08 15:11:24 dwmw2 Exp $
* $Id: gc.c,v 1.74 2002/05/20 14:56:38 dwmw2 Exp $
*
*/
...
...
@@ -65,14 +41,21 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
/* Pick an eraseblock to garbage collect next. This is where we'll
put the clever wear-levelling algorithms. Eventually. */
/* We possibly want to favour the dirtier blocks more when the
number of free blocks is low. */
if
(
!
list_empty
(
&
c
->
bad_used_list
)
&&
c
->
nr_free_blocks
>
JFFS2_RESERVED_BLOCKS_GCBAD
)
{
D1
(
printk
(
KERN_DEBUG
"Picking block from bad_used_list to GC next
\n
"
));
nextlist
=
&
c
->
bad_used_list
;
}
else
if
(
n
<
100
&&
!
list_empty
(
&
c
->
erasable_list
))
{
}
else
if
(
n
<
50
&&
!
list_empty
(
&
c
->
erasable_list
))
{
/* Note that most of them will have gone directly to be erased.
So don't favour the erasable_list _too_ much. */
D1
(
printk
(
KERN_DEBUG
"Picking block from erasable_list to GC next
\n
"
));
nextlist
=
&
c
->
erasable_list
;
}
else
if
(
n
<
110
&&
!
list_empty
(
&
c
->
very_dirty_list
))
{
/* Most of the time, pick one off the very_dirty list */
D1
(
printk
(
KERN_DEBUG
"Picking block from very_dirty_list to GC next
\n
"
));
nextlist
=
&
c
->
very_dirty_list
;
}
else
if
(
n
<
126
&&
!
list_empty
(
&
c
->
dirty_list
))
{
/* Most of the time, pick one off the dirty list */
D1
(
printk
(
KERN_DEBUG
"Picking block from dirty_list to GC next
\n
"
));
nextlist
=
&
c
->
dirty_list
;
}
else
if
(
!
list_empty
(
&
c
->
clean_list
))
{
...
...
@@ -82,12 +65,15 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
D1
(
printk
(
KERN_DEBUG
"Picking block from dirty_list to GC next (clean_list was empty)
\n
"
));
nextlist
=
&
c
->
dirty_list
;
}
else
if
(
!
list_empty
(
&
c
->
very_dirty_list
))
{
D1
(
printk
(
KERN_DEBUG
"Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)
\n
"
));
nextlist
=
&
c
->
very_dirty_list
;
}
else
if
(
!
list_empty
(
&
c
->
erasable_list
))
{
D1
(
printk
(
KERN_DEBUG
"Picking block from erasable_list to GC next (clean_list and dirty_list were empty)
\n
"
));
D1
(
printk
(
KERN_DEBUG
"Picking block from erasable_list to GC next (clean_list and
{very_,}
dirty_list were empty)
\n
"
));
nextlist
=
&
c
->
erasable_list
;
}
else
{
/* Eep.
Both
were empty */
/* Eep.
All
were empty */
printk
(
KERN_NOTICE
"jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?
\n
"
);
return
NULL
;
}
...
...
@@ -100,6 +86,8 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
printk
(
KERN_WARNING
"Eep. ret->gc_node for block at 0x%08x is NULL
\n
"
,
ret
->
offset
);
BUG
();
}
D1
(
jffs2_dump_block_lists
(
c
));
return
ret
;
}
...
...
@@ -138,7 +126,9 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
return
-
EIO
;
}
D1
(
printk
(
KERN_DEBUG
"garbage collect from block at phys 0x%08x
\n
"
,
jeb
->
offset
));
D1
(
printk
(
KERN_DEBUG
"GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
));
D1
(
if
(
c
->
nextblock
)
printk
(
KERN_DEBUG
"Nextblock at %08x, used_size %08x, dirty_size %08x, free_size %08x
\n
"
,
c
->
nextblock
->
offset
,
c
->
nextblock
->
used_size
,
c
->
nextblock
->
dirty_size
,
c
->
nextblock
->
free_size
));
if
(
!
jeb
->
used_size
)
goto
eraseit
;
...
...
@@ -606,9 +596,21 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
jffs2_mark_node_obsolete
(
c
,
f
->
metadata
->
raw
);
jffs2_free_full_dnode
(
f
->
metadata
);
f
->
metadata
=
NULL
;
return
0
;
}
return
0
;
}
/*
* We should only get here in the case where the node we are
* replacing had more than one frag, so we kept the same version
* number as before. (Except in case of error -- see 'goto fill;'
* above.)
*/
D1
(
if
(
unlikely
(
fn
->
frags
<=
1
))
{
printk
(
KERN_WARNING
"jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d
\n
"
,
fn
->
frags
,
ri
.
version
,
f
->
highest_version
,
ri
.
ino
);
});
for
(
frag
=
f
->
fraglist
;
frag
;
frag
=
frag
->
next
)
{
if
(
frag
->
ofs
>
fn
->
size
+
fn
->
ofs
)
break
;
...
...
@@ -760,7 +762,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
kunmap
(
pg
);
/* XXX: Does the page get freed automatically? */
/* AAA: Judging by the unmount getting stuck in __wait_on_page
_locked
, nope. */
/* AAA: Judging by the unmount getting stuck in __wait_on_page, nope. */
page_cache_release
(
pg
);
return
ret
;
}
...
...
fs/jffs2/ioctl.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: ioctl.c,v 1.5 2001/03/15 15:38:24 dwmw2 Exp $
* $Id: ioctl.c,v 1.6 2002/05/20 14:56:38 dwmw2 Exp $
*
*/
...
...
fs/jffs2/malloc.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: malloc.c,v 1.21 2002/03/12 17:36:55 dwmw2 Exp $
* $Id: malloc.c,v 1.22 2002/05/20 14:56:38 dwmw2 Exp $
*
*/
...
...
fs/jffs2/nodelist.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: nodelist.c,v 1.42 2002/03/11 11:17:29 dwmw2 Exp $
* $Id: nodelist.c,v 1.47 2002/06/26 01:25:30 dwmw2 Exp $
*
*/
...
...
@@ -69,7 +45,7 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new
*
prev
=
new
;
out:
D
1
(
while
(
*
list
)
{
D
2
(
while
(
*
list
)
{
printk
(
KERN_DEBUG
"Dirent
\"
%s
\"
(hash 0x%08x, ino #%u
\n
"
,
(
*
list
)
->
name
,
(
*
list
)
->
nhash
,
(
*
list
)
->
ino
);
list
=
&
(
*
list
)
->
next
;
});
...
...
@@ -311,9 +287,6 @@ struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, int ino)
D2
(
printk
(
KERN_DEBUG
"jffs2_get_ino_cache(): ino %u
\n
"
,
ino
));
spin_lock
(
&
c
->
inocache_lock
);
if
(
c
->
inocache_last
&&
c
->
inocache_last
->
ino
==
ino
)
{
ret
=
c
->
inocache_last
;
}
else
{
ret
=
c
->
inocache_list
[
ino
%
INOCACHE_HASHSIZE
];
while
(
ret
&&
ret
->
ino
<
ino
)
{
ret
=
ret
->
next
;
...
...
@@ -321,7 +294,7 @@ struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, int ino)
if
(
ret
&&
ret
->
ino
!=
ino
)
ret
=
NULL
;
}
spin_unlock
(
&
c
->
inocache_lock
);
D2
(
printk
(
KERN_DEBUG
"jffs2_get_ino_cache found %p for ino %u
\n
"
,
ret
,
ino
));
...
...
@@ -342,8 +315,6 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
new
->
next
=
*
prev
;
*
prev
=
new
;
c
->
inocache_last
=
new
;
spin_unlock
(
&
c
->
inocache_lock
);
}
...
...
@@ -361,8 +332,6 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
if
((
*
prev
)
==
old
)
{
*
prev
=
old
->
next
;
}
if
(
c
->
inocache_last
==
old
)
c
->
inocache_last
=
NULL
;
spin_unlock
(
&
c
->
inocache_lock
);
}
...
...
@@ -382,7 +351,6 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
}
c
->
inocache_list
[
i
]
=
NULL
;
}
c
->
inocache_last
=
NULL
;
}
void
jffs2_free_raw_node_refs
(
struct
jffs2_sb_info
*
c
)
...
...
fs/jffs2/nodelist.h
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: nodelist.h,v 1.68 2002/03/08 11:27:19 dwmw2 Exp $
* $Id: nodelist.h,v 1.74 2002/06/26 01:20:43 dwmw2 Exp $
*
*/
...
...
@@ -117,6 +93,8 @@ struct jffs2_inode_cache {
int
nlink
;
};
#define INOCACHE_HASHSIZE 128
struct
jffs2_scan_info
{
struct
jffs2_full_dirent
*
dents
;
struct
jffs2_tmp_dnode_info
*
tmpnodes
;
...
...
@@ -172,7 +150,6 @@ struct jffs2_node_frag
struct
jffs2_full_dnode
*
node
;
/* NULL for holes */
uint32_t
size
;
uint32_t
ofs
;
/* Don't really need this, but optimisation */
uint32_t
node_ofs
;
/* offset within the physical node */
};
struct
jffs2_eraseblock
...
...
@@ -240,6 +217,9 @@ struct jffs2_eraseblock
#define JFFS2_RESERVED_BLOCKS_GCMERGE (JFFS2_RESERVED_BLOCKS_BASE)
/* ... merge pages when garbage collecting */
/* How much dirty space before it goes on the very_dirty_list */
#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2))
#define PAD(x) (((x)+3)&~3)
static
inline
int
jffs2_raw_ref_to_inum
(
struct
jffs2_raw_node_ref
*
raw
)
...
...
@@ -271,6 +251,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
int
jffs2_add_physical_node_ref
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_raw_node_ref
*
new
,
uint32_t
len
,
int
dirty
);
void
jffs2_complete_reservation
(
struct
jffs2_sb_info
*
c
);
void
jffs2_mark_node_obsolete
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_raw_node_ref
*
raw
);
void
jffs2_dump_block_lists
(
struct
jffs2_sb_info
*
c
);
/* write.c */
int
jffs2_do_new_inode
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_inode_info
*
f
,
uint32_t
mode
,
struct
jffs2_raw_inode
*
ri
);
...
...
@@ -331,6 +312,7 @@ int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
/* scan.c */
int
jffs2_scan_medium
(
struct
jffs2_sb_info
*
c
);
void
jffs2_rotate_lists
(
struct
jffs2_sb_info
*
c
);
/* build.c */
int
jffs2_do_mount_fs
(
struct
jffs2_sb_info
*
c
);
...
...
fs/jffs2/nodemgmt.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: nodemgmt.c,v 1.63 2002/03/08 14:54:09 dwmw2 Exp $
* $Id: nodemgmt.c,v 1.70 2002/07/02 22:48:24 dwmw2 Exp $
*
*/
...
...
@@ -158,9 +134,15 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ui
c
->
free_size
-=
jeb
->
free_size
;
jeb
->
dirty_size
+=
jeb
->
free_size
;
jeb
->
free_size
=
0
;
if
(
VERYDIRTY
(
c
,
jeb
->
dirty_size
))
{
D1
(
printk
(
KERN_DEBUG
"Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x
\n
"
,
jeb
->
offset
,
jeb
->
free_size
,
jeb
->
dirty_size
,
jeb
->
used_size
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
very_dirty_list
);
}
else
{
D1
(
printk
(
KERN_DEBUG
"Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x
\n
"
,
jeb
->
offset
,
jeb
->
free_size
,
jeb
->
dirty_size
,
jeb
->
used_size
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
dirty_list
);
}
c
->
nextblock
=
jeb
=
NULL
;
}
...
...
@@ -180,6 +162,7 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ui
list_del
(
&
ejeb
->
list
);
list_add_tail
(
&
ejeb
->
list
,
&
c
->
erase_pending_list
);
c
->
nr_erasing_blocks
++
;
jffs2_erase_pending_trigger
(
c
);
D1
(
printk
(
KERN_DEBUG
"jffs2_do_reserve_space: Triggering erase of erasable block at 0x%08x
\n
"
,
ejeb
->
offset
));
}
...
...
@@ -232,10 +215,7 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ui
c
->
nextblock
=
jeb
=
list_entry
(
next
,
struct
jffs2_eraseblock
,
list
);
c
->
nr_free_blocks
--
;
/* On NAND free_size == sector_size, cleanmarker is in spare area !*/
if
(
jeb
->
free_size
!=
c
->
sector_size
-
(
jffs2_cleanmarker_oob
(
c
))
?
0
:
sizeof
(
struct
jffs2_unknown_node
))
{
if
(
jeb
->
free_size
!=
c
->
sector_size
-
c
->
cleanmarker_size
)
{
printk
(
KERN_WARNING
"Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!
\n
"
,
jeb
->
offset
,
jeb
->
free_size
);
goto
restart
;
}
...
...
@@ -420,9 +400,20 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
BUG
();
}
}
else
{
if
(
jiffies
&
127
)
{
/* Most of the time, we just erase it immediately. Otherwise we
spend ages scanning it on mount, etc. */
D1
(
printk
(
KERN_DEBUG
"...and adding to erase_pending_list
\n
"
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
erase_pending_list
);
c
->
nr_erasing_blocks
++
;
jffs2_erase_pending_trigger
(
c
);
}
else
{
/* Sometimes, however, we leave it elsewhere so it doesn't get
immediately reused, and we spread the load a bit. */
D1
(
printk
(
KERN_DEBUG
"...and adding to erasable_list
\n
"
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
erasable_list
);
}
}
D1
(
printk
(
KERN_DEBUG
"Done OK
\n
"
));
}
else
if
(
jeb
==
c
->
gcblock
)
{
D2
(
printk
(
KERN_DEBUG
"Not moving gcblock 0x%08x to dirty_list
\n
"
,
jeb
->
offset
));
...
...
@@ -431,6 +422,12 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
list_del
(
&
jeb
->
list
);
D1
(
printk
(
KERN_DEBUG
"...and adding to dirty_list
\n
"
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
dirty_list
);
}
else
if
(
VERYDIRTY
(
c
,
jeb
->
dirty_size
)
&&
!
VERYDIRTY
(
c
,
jeb
->
dirty_size
-
ref
->
totlen
))
{
D1
(
printk
(
KERN_DEBUG
"Eraseblock at 0x%08x is now very dirty. Removing from dirty list...
\n
"
,
jeb
->
offset
));
list_del
(
&
jeb
->
list
);
D1
(
printk
(
KERN_DEBUG
"...and adding to very_dirty_list
\n
"
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
very_dirty_list
);
}
spin_unlock_bh
(
&
c
->
erase_completion_lock
);
...
...
@@ -469,3 +466,129 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
return
;
}
}
#if CONFIG_JFFS2_FS_DEBUG > 0
void
jffs2_dump_block_lists
(
struct
jffs2_sb_info
*
c
)
{
printk
(
KERN_DEBUG
"jffs2_dump_block_lists:
\n
"
);
printk
(
KERN_DEBUG
"flash_size: %08x
\n
"
,
c
->
flash_size
);
printk
(
KERN_DEBUG
"used_size: %08x
\n
"
,
c
->
used_size
);
printk
(
KERN_DEBUG
"dirty_size: %08x
\n
"
,
c
->
dirty_size
);
printk
(
KERN_DEBUG
"free_size: %08x
\n
"
,
c
->
free_size
);
printk
(
KERN_DEBUG
"erasing_size: %08x
\n
"
,
c
->
erasing_size
);
printk
(
KERN_DEBUG
"bad_size: %08x
\n
"
,
c
->
bad_size
);
printk
(
KERN_DEBUG
"sector_size: %08x
\n
"
,
c
->
sector_size
);
printk
(
KERN_DEBUG
"jffs2_reserved_blocks size: %08x
\n
"
,
c
->
sector_size
*
JFFS2_RESERVED_BLOCKS_WRITE
);
if
(
c
->
nextblock
)
{
printk
(
KERN_DEBUG
"nextblock: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
c
->
nextblock
->
offset
,
c
->
nextblock
->
used_size
,
c
->
nextblock
->
dirty_size
,
c
->
nextblock
->
free_size
);
}
else
{
printk
(
KERN_DEBUG
"nextblock: NULL
\n
"
);
}
if
(
c
->
gcblock
)
{
printk
(
KERN_DEBUG
"gcblock: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
c
->
gcblock
->
offset
,
c
->
gcblock
->
used_size
,
c
->
gcblock
->
dirty_size
,
c
->
gcblock
->
free_size
);
}
else
{
printk
(
KERN_DEBUG
"gcblock: NULL
\n
"
);
}
if
(
list_empty
(
&
c
->
clean_list
))
{
printk
(
KERN_DEBUG
"clean_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
clean_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"clean_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
very_dirty_list
))
{
printk
(
KERN_DEBUG
"very_dirty_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
very_dirty_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"very_dirty_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
dirty_list
))
{
printk
(
KERN_DEBUG
"dirty_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
dirty_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"dirty_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
erasable_list
))
{
printk
(
KERN_DEBUG
"erasable_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erasable_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erasable_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
erasing_list
))
{
printk
(
KERN_DEBUG
"erasing_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erasing_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erasing_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
erase_pending_list
))
{
printk
(
KERN_DEBUG
"erase_pending_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erase_pending_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erase_pending_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
erasable_pending_wbuf_list
))
{
printk
(
KERN_DEBUG
"erasable_pending_wbuf_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
erasable_pending_wbuf_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"erase_pending_wbuf_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
free_list
))
{
printk
(
KERN_DEBUG
"free_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
free_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"free_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
bad_list
))
{
printk
(
KERN_DEBUG
"bad_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
bad_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"bad_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
if
(
list_empty
(
&
c
->
bad_used_list
))
{
printk
(
KERN_DEBUG
"bad_used_list: empty
\n
"
);
}
else
{
struct
list_head
*
this
;
list_for_each
(
this
,
&
c
->
bad_used_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
printk
(
KERN_DEBUG
"bad_used_list: %08x (used %08x, dirty %08x, free %08x)
\n
"
,
jeb
->
offset
,
jeb
->
used_size
,
jeb
->
dirty_size
,
jeb
->
free_size
);
}
}
}
#endif
/* CONFIG_JFFS2_FS_DEBUG */
fs/jffs2/os-linux.h
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: os-linux.h,v 1.16 2002/03/17 10:18:42 dwmw2 Exp $
* $Id: os-linux.h,v 1.19 2002/05/20 14:56:38 dwmw2 Exp $
*
*/
...
...
@@ -101,6 +77,8 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
#define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0)
#define jffs2_write_nand_badblock(c,jeb) do { ; } while(0)
#define jffs2_flash_writev jffs2_flash_direct_writev
#define jffs2_wbuf_timeout NULL
#define jffs2_wbuf_process NULL
#else
/* NAND support present */
...
...
@@ -119,6 +97,8 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
int
jffs2_check_nand_cleanmarker
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_eraseblock
*
jeb
);
int
jffs2_write_nand_cleanmarker
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_eraseblock
*
jeb
);
int
jffs2_write_nand_badblock
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_eraseblock
*
jeb
);
void
jffs2_wbuf_timeout
(
unsigned
long
data
);
void
jffs2_wbuf_process
(
void
*
data
);
#endif
/* NAND */
/* background.c */
...
...
fs/jffs2/pushpull.h
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: pushpull.h,v 1.7 2002/03/06 12:37:08 dwmw2 Exp $
* $Id: pushpull.h,v 1.8 2002/05/20 14:56:38 dwmw2 Exp $
*
*/
...
...
fs/jffs2/read.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: read.c,v 1.22 2002/03/02 22:08:27 dwmw2 Exp $
* $Id: read.c,v 1.23 2002/05/20 14:56:38 dwmw2 Exp $
*
*/
...
...
fs/jffs2/readinode.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: readinode.c,v 1.71 2002/03/06 12:25:59 dwmw2 Exp $
* $Id: readinode.c,v 1.73 2002/05/20 14:56:38 dwmw2 Exp $
*
*/
...
...
@@ -337,6 +313,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
printk
(
KERN_NOTICE
"MTD read in jffs2_do_read_inode() failed: Returned %d, %ld of %d bytes read
\n
"
,
ret
,
(
long
)
retlen
,
sizeof
(
*
latest_node
));
/* FIXME: If this fails, there seems to be a memory leak. Find it. */
up
(
&
f
->
sem
);
jffs2_do_clear_inode
(
c
,
f
);
return
ret
?
ret
:-
EIO
;
}
...
...
@@ -344,6 +321,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
crc
=
crc32
(
0
,
latest_node
,
sizeof
(
*
latest_node
)
-
8
);
if
(
crc
!=
latest_node
->
node_crc
)
{
printk
(
KERN_NOTICE
"CRC failed for read_inode of inode %u at physical location 0x%x
\n
"
,
ino
,
fn
->
raw
->
flash_offset
&
~
3
);
up
(
&
f
->
sem
);
jffs2_do_clear_inode
(
c
,
f
);
return
-
EIO
;
}
...
...
@@ -378,11 +356,13 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
kept as the metadata node */
if
(
f
->
metadata
)
{
printk
(
KERN_WARNING
"Argh. Special inode #%u with mode 0%o had metadata node
\n
"
,
ino
,
latest_node
->
mode
);
up
(
&
f
->
sem
);
jffs2_do_clear_inode
(
c
,
f
);
return
-
EIO
;
}
if
(
!
f
->
fraglist
)
{
printk
(
KERN_WARNING
"Argh. Special inode #%u with mode 0%o has no fragments
\n
"
,
ino
,
latest_node
->
mode
);
up
(
&
f
->
sem
);
jffs2_do_clear_inode
(
c
,
f
);
return
-
EIO
;
}
...
...
@@ -390,6 +370,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
if
(
f
->
fraglist
->
next
)
{
printk
(
KERN_WARNING
"Argh. Special inode #%u with mode 0%o had more than one node
\n
"
,
ino
,
latest_node
->
mode
);
/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
up
(
&
f
->
sem
);
jffs2_do_clear_inode
(
c
,
f
);
return
-
EIO
;
}
...
...
fs/jffs2/scan.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: scan.c,v 1.69 2002/03/08 11:03:23 dwmw2 Exp $
* $Id: scan.c,v 1.79 2002/07/25 20:48:51 dwmw2 Exp $
*
*/
#include <linux/kernel.h>
...
...
@@ -62,7 +38,6 @@
} while(0)
static
uint32_t
pseudo_random
;
static
void
jffs2_rotate_lists
(
struct
jffs2_sb_info
*
c
);
static
int
jffs2_scan_eraseblock
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_eraseblock
*
jeb
);
...
...
@@ -141,14 +116,24 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
not the one with most free space.
*/
if
(
jeb
->
free_size
>
2
*
sizeof
(
struct
jffs2_raw_inode
)
&&
(
jffs2_can_mark_obsolete
(
c
)
||
jeb
->
free_size
>
c
->
wbuf_pagesize
)
&&
(
!
c
->
nextblock
||
c
->
nextblock
->
free_size
<
jeb
->
free_size
))
{
/* Better candidate for the next writes to go to */
if
(
c
->
nextblock
)
if
(
c
->
nextblock
)
{
if
(
VERYDIRTY
(
c
,
c
->
nextblock
->
dirty_size
))
{
list_add
(
&
c
->
nextblock
->
list
,
&
c
->
very_dirty_list
);
}
else
{
list_add
(
&
c
->
nextblock
->
list
,
&
c
->
dirty_list
);
}
}
c
->
nextblock
=
jeb
;
}
else
{
if
(
VERYDIRTY
(
c
,
jeb
->
dirty_size
))
{
list_add
(
&
jeb
->
list
,
&
c
->
very_dirty_list
);
}
else
{
list_add
(
&
jeb
->
list
,
&
c
->
dirty_list
);
}
}
break
;
case
BLK_STATE_ALLDIRTY
:
...
...
@@ -167,14 +152,26 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
bad_blocks
++
;
break
;
default:
printk
(
"jffs2_scan_medium(): unknown block state
\n
"
);
printk
(
KERN_WARNING
"jffs2_scan_medium(): unknown block state
\n
"
);
BUG
();
}
}
/* Rotate the lists by some number to ensure wear levelling */
jffs2_rotate_lists
(
c
);
if
(
!
jffs2_can_mark_obsolete
(
c
)
&&
c
->
nextblock
&&
(
c
->
nextblock
->
free_size
&
(
c
->
wbuf_pagesize
-
1
)))
{
/* If we're going to start writing into a block which already
contains data, and the end of the data isn't page-aligned,
skip a little and align it. */
uint32_t
skip
=
c
->
nextblock
->
free_size
&
(
c
->
wbuf_pagesize
-
1
);
D1
(
printk
(
KERN_DEBUG
"jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment
\n
"
,
skip
));
c
->
nextblock
->
dirty_size
+=
skip
;
c
->
dirty_size
+=
skip
;
c
->
nextblock
->
free_size
-=
skip
;
c
->
free_size
-=
skip
;
}
if
(
c
->
nr_erasing_blocks
)
{
if
(
!
c
->
used_size
&&
((
empty_blocks
+
bad_blocks
)
!=
c
->
nr_blocks
||
bad_blocks
==
c
->
nr_blocks
)
)
{
printk
(
KERN_NOTICE
"Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes
\n
"
);
...
...
@@ -246,6 +243,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
size_t
retlen
;
ACCT_PARANOIA_CHECK
(
jeb
);
cond_resched
();
if
(
ofs
&
3
)
{
printk
(
KERN_WARNING
"Eep. ofs 0x%08x not word-aligned!
\n
"
,
ofs
);
ofs
=
(
ofs
+
3
)
&~
3
;
...
...
@@ -323,6 +322,16 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
continue
;
}
if
(
ofs
+
node
.
totlen
>
jeb
->
offset
+
c
->
sector_size
)
{
/* Eep. Node goes over the end of the erase block. */
printk
(
KERN_WARNING
"Node at 0x%08x with length 0x%08x would run over the end of the erase block
\n
"
,
ofs
,
node
.
totlen
);
printk
(
KERN_WARNING
"Perhaps the file system was created with the wrong erase size?
\n
"
);
DIRTY_SPACE
(
4
);
ofs
+=
4
;
continue
;
}
if
(
!
(
node
.
nodetype
&
JFFS2_NODE_ACCURATE
))
{
/* Wheee. This is an obsoleted node */
D2
(
printk
(
KERN_DEBUG
"Node at 0x%08x is obsolete. Skipping
\n
"
,
ofs
));
...
...
@@ -343,9 +352,9 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
break
;
case
JFFS2_NODETYPE_CLEANMARKER
:
if
(
node
.
totlen
!=
sizeof
(
struct
jffs2_unknown_node
)
)
{
if
(
node
.
totlen
!=
c
->
cleanmarker_size
)
{
printk
(
KERN_NOTICE
"CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x
\n
"
,
ofs
,
node
.
totlen
,
sizeof
(
struct
jffs2_unknown_node
)
);
ofs
,
node
.
totlen
,
c
->
cleanmarker_size
);
DIRTY_SPACE
(
PAD
(
sizeof
(
struct
jffs2_unknown_node
)));
}
else
if
(
jeb
->
first_node
)
{
printk
(
KERN_NOTICE
"CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)
\n
"
,
ofs
,
jeb
->
offset
);
...
...
@@ -369,6 +378,11 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
ofs
+=
PAD
(
sizeof
(
struct
jffs2_unknown_node
));
break
;
case
JFFS2_NODETYPE_PADDING
:
DIRTY_SPACE
(
PAD
(
node
.
totlen
));
ofs
+=
PAD
(
node
.
totlen
);
break
;
default:
switch
(
node
.
nodetype
&
JFFS2_COMPAT_MASK
)
{
case
JFFS2_FEATURE_ROCOMPAT
:
...
...
@@ -378,7 +392,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
return
-
EROFS
;
DIRTY_SPACE
(
PAD
(
node
.
totlen
));
ofs
+=
PAD
(
node
.
totlen
);
continue
;
break
;
case
JFFS2_FEATURE_INCOMPAT
:
printk
(
KERN_NOTICE
"Incompatible feature node (0x%04x) found at offset 0x%08x
\n
"
,
node
.
nodetype
,
ofs
);
...
...
@@ -650,7 +664,11 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
tn
->
version
=
ri
.
version
;
USED_SPACE
(
PAD
(
ri
.
totlen
));
jffs2_add_tn_to_list
(
tn
,
&
ic
->
scan
->
tmpnodes
);
/* No need to scan from the beginning of the list again.
We can start from tn_list instead (Thanks Jocke) */
jffs2_add_tn_to_list
(
tn
,
tn_list
);
/* Make sure the one we just added is the _last_ in the list
with this version number, so the older ones get obsoleted */
while
(
tn
->
next
&&
tn
->
next
->
version
==
tn
->
version
)
{
...
...
@@ -813,22 +831,84 @@ static void rotate_list(struct list_head *head, uint32_t count)
list_add
(
head
,
n
);
}
static
void
jffs2_rotate_lists
(
struct
jffs2_sb_info
*
c
)
void
jffs2_rotate_lists
(
struct
jffs2_sb_info
*
c
)
{
uint32_t
x
;
uint32_t
rotateby
;
x
=
count_list
(
&
c
->
clean_list
);
if
(
x
)
rotate_list
((
&
c
->
clean_list
),
pseudo_random
%
x
);
if
(
x
)
{
rotateby
=
pseudo_random
%
x
;
D1
(
printk
(
KERN_DEBUG
"Rotating clean_list by %d
\n
"
,
rotateby
));
rotate_list
((
&
c
->
clean_list
),
rotateby
);
D1
(
printk
(
KERN_DEBUG
"Erase block at front of clean_list is at %08x
\n
"
,
list_entry
(
c
->
clean_list
.
next
,
struct
jffs2_eraseblock
,
list
)
->
offset
));
}
else
{
D1
(
printk
(
KERN_DEBUG
"Not rotating empty clean_list
\n
"
));
}
x
=
count_list
(
&
c
->
very_dirty_list
);
if
(
x
)
{
rotateby
=
pseudo_random
%
x
;
D1
(
printk
(
KERN_DEBUG
"Rotating very_dirty_list by %d
\n
"
,
rotateby
));
rotate_list
((
&
c
->
very_dirty_list
),
rotateby
);
D1
(
printk
(
KERN_DEBUG
"Erase block at front of very_dirty_list is at %08x
\n
"
,
list_entry
(
c
->
very_dirty_list
.
next
,
struct
jffs2_eraseblock
,
list
)
->
offset
));
}
else
{
D1
(
printk
(
KERN_DEBUG
"Not rotating empty very_dirty_list
\n
"
));
}
x
=
count_list
(
&
c
->
dirty_list
);
if
(
x
)
rotate_list
((
&
c
->
dirty_list
),
pseudo_random
%
x
);
if
(
x
)
{
rotateby
=
pseudo_random
%
x
;
D1
(
printk
(
KERN_DEBUG
"Rotating dirty_list by %d
\n
"
,
rotateby
));
rotate_list
((
&
c
->
dirty_list
),
rotateby
);
D1
(
printk
(
KERN_DEBUG
"Erase block at front of dirty_list is at %08x
\n
"
,
list_entry
(
c
->
dirty_list
.
next
,
struct
jffs2_eraseblock
,
list
)
->
offset
));
}
else
{
D1
(
printk
(
KERN_DEBUG
"Not rotating empty dirty_list
\n
"
));
}
if
(
c
->
nr_erasing_blocks
)
rotate_list
((
&
c
->
erase_pending_list
),
pseudo_random
%
c
->
nr_erasing_blocks
);
x
=
count_list
(
&
c
->
erasable_list
);
if
(
x
)
{
rotateby
=
pseudo_random
%
x
;
D1
(
printk
(
KERN_DEBUG
"Rotating erasable_list by %d
\n
"
,
rotateby
));
if
(
c
->
nr_free_blocks
)
/* Not that it should ever be zero */
rotate_list
((
&
c
->
free_list
),
pseudo_random
%
c
->
nr_free_blocks
);
rotate_list
((
&
c
->
erasable_list
),
rotateby
);
D1
(
printk
(
KERN_DEBUG
"Erase block at front of erasable_list is at %08x
\n
"
,
list_entry
(
c
->
erasable_list
.
next
,
struct
jffs2_eraseblock
,
list
)
->
offset
));
}
else
{
D1
(
printk
(
KERN_DEBUG
"Not rotating empty erasable_list
\n
"
));
}
if
(
c
->
nr_erasing_blocks
)
{
rotateby
=
pseudo_random
%
c
->
nr_erasing_blocks
;
D1
(
printk
(
KERN_DEBUG
"Rotating erase_pending_list by %d
\n
"
,
rotateby
));
rotate_list
((
&
c
->
erase_pending_list
),
rotateby
);
D1
(
printk
(
KERN_DEBUG
"Erase block at front of erase_pending_list is at %08x
\n
"
,
list_entry
(
c
->
erase_pending_list
.
next
,
struct
jffs2_eraseblock
,
list
)
->
offset
));
}
else
{
D1
(
printk
(
KERN_DEBUG
"Not rotating empty erase_pending_list
\n
"
));
}
if
(
c
->
nr_free_blocks
)
{
rotateby
=
pseudo_random
%
c
->
nr_free_blocks
;
D1
(
printk
(
KERN_DEBUG
"Rotating free_list by %d
\n
"
,
rotateby
));
rotate_list
((
&
c
->
free_list
),
rotateby
);
D1
(
printk
(
KERN_DEBUG
"Erase block at front of free_list is at %08x
\n
"
,
list_entry
(
c
->
free_list
.
next
,
struct
jffs2_eraseblock
,
list
)
->
offset
));
}
else
{
D1
(
printk
(
KERN_DEBUG
"Not rotating empty free_list
\n
"
));
}
}
fs/jffs2/super.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: super.c,v 1.64 2002/03/17 10:18:42 dwmw2 Exp $
* $Id: super.c,v 1.73 2002/07/23 17:00:45 dwmw2 Exp $
*
*/
...
...
@@ -43,12 +19,12 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/jffs2.h>
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
#include <linux/ctype.h>
#include <linux/namei.h>
#include "nodelist.h"
void
jffs2_put_super
(
struct
super_block
*
);
...
...
@@ -83,14 +59,14 @@ static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long f
static
struct
super_operations
jffs2_super_operations
=
{
alloc_inode:
jffs2_alloc_inode
,
destroy_inode:
jffs2_destroy_inode
,
read_inode:
jffs2_read_inode
,
put_super:
jffs2_put_super
,
write_super:
jffs2_write_super
,
statfs:
jffs2_statfs
,
remount_fs:
jffs2_remount_fs
,
clear_inode:
jffs2_clear_inode
.
alloc_inode
=
jffs2_alloc_inode
,
.
destroy_inode
=
jffs2_destroy_inode
,
.
read_inode
=
jffs2_read_inode
,
.
put_super
=
jffs2_put_super
,
.
write_super
=
jffs2_write_super
,
.
statfs
=
jffs2_statfs
,
.
remount_fs
=
jffs2_remount_fs
,
.
clear_inode
=
jffs2_clear_inode
};
static
int
jffs2_sb_compare
(
struct
super_block
*
sb
,
void
*
data
)
...
...
@@ -101,11 +77,11 @@ static int jffs2_sb_compare(struct super_block *sb, void *data)
/* The superblocks are considered to be equivalent if the underlying MTD
device is the same one */
if
(
c
->
mtd
==
p
->
mtd
)
{
D1
(
printk
(
KERN_DEBUG
"jffs2_sb_compare: match on device %d (
\"
%s
\"
)
\n
"
,
mtd
->
index
,
mtd
->
name
));
D1
(
printk
(
KERN_DEBUG
"jffs2_sb_compare: match on device %d (
\"
%s
\"
)
\n
"
,
p
->
mtd
->
index
,
p
->
mtd
->
name
));
return
1
;
}
else
{
D1
(
printk
(
KERN_DEBUG
"jffs2_sb_compare: No match, device %d (
\"
%s
\"
), device %d (
\"
%s
\"
)
\n
"
,
c
->
mtd
->
index
,
c
->
mtd
->
name
,
mtd
->
index
,
mtd
->
name
));
c
->
mtd
->
index
,
c
->
mtd
->
name
,
p
->
mtd
->
index
,
p
->
mtd
->
name
));
return
0
;
}
}
...
...
@@ -282,10 +258,15 @@ void jffs2_put_super (struct super_block *sb)
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
jffs2_stop_garbage_collect_thread
(
c
);
down
(
&
c
->
alloc_sem
);
jffs2_flush_wbuf
(
c
,
1
);
up
(
&
c
->
alloc_sem
);
jffs2_free_ino_caches
(
c
);
jffs2_free_raw_node_refs
(
c
);
kfree
(
c
->
blocks
);
if
(
c
->
wbuf
)
kfree
(
c
->
wbuf
);
kfree
(
c
->
inocache_list
);
if
(
c
->
mtd
->
sync
)
c
->
mtd
->
sync
(
c
->
mtd
);
...
...
@@ -301,10 +282,10 @@ static void jffs2_kill_sb(struct super_block *sb)
}
static
struct
file_system_type
jffs2_fs_type
=
{
owner:
THIS_MODULE
,
name:
"jffs2"
,
get_sb:
jffs2_get_sb
,
kill_sb:
jffs2_kill_sb
,
.
owner
=
THIS_MODULE
,
.
name
=
"jffs2"
,
.
get_sb
=
jffs2_get_sb
,
.
kill_sb
=
jffs2_kill_sb
,
};
...
...
@@ -326,18 +307,25 @@ static int __init init_jffs2_fs(void)
ret
=
jffs2_zlib_init
();
if
(
ret
)
{
printk
(
KERN_ERR
"JFFS2 error: Failed to initialise zlib workspaces
\n
"
);
return
re
t
;
goto
ou
t
;
}
ret
=
jffs2_create_slab_caches
();
if
(
ret
)
{
printk
(
KERN_ERR
"JFFS2 error: Failed to initialise slab caches
\n
"
);
return
ret
;
goto
out_zlib
;
}
ret
=
register_filesystem
(
&
jffs2_fs_type
);
if
(
ret
)
{
printk
(
KERN_ERR
"JFFS2 error: Failed to register filesystem
\n
"
);
jffs2_destroy_slab_caches
()
;
goto
out_slab
;
}
return
0
;
out_slab:
jffs2_destroy_slab_caches
();
out_zlib:
jffs2_zlib_exit
();
out:
return
ret
;
}
...
...
fs/jffs2/symlink.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: symlink.c,v 1.9 2002/01/10 09:29:53 dwmw2 Exp $
* $Id: symlink.c,v 1.11 2002/07/23 17:00:45 dwmw2 Exp $
*
*/
...
...
@@ -46,9 +22,9 @@ int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
struct
inode_operations
jffs2_symlink_inode_operations
=
{
readlink:
jffs2_readlink
,
follow_link:
jffs2_follow_link
,
setattr:
jffs2_setattr
.
readlink
=
jffs2_readlink
,
.
follow_link
=
jffs2_follow_link
,
.
setattr
=
jffs2_setattr
};
int
jffs2_readlink
(
struct
dentry
*
dentry
,
char
*
buffer
,
int
buflen
)
...
...
fs/jffs2/wbuf.c
View file @
1a4c1b9e
...
...
@@ -5,34 +5,10 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: wbuf.c,v 1.7 2002/03/08 11:27:59 dwmw2 Exp $
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: wbuf.c,v 1.12 2002/05/20 14:56:39 dwmw2 Exp $
* -- with the NAND definitions added back pending MTD update for 2.5.
*/
#include <linux/kernel.h>
...
...
@@ -51,26 +27,101 @@
#define NAND_JFFS2_OOB8_FSDALEN 2
#define NAND_JFFS2_OOB16_FSDALEN 8
/* max. erase failures before we mark a block bad */
#define MAX_ERASE_FAILURES 5
/* two seconds timeout for timed wbuf-flushing */
#define WBUF_FLUSH_TIMEOUT 2 * HZ
static
inline
void
jffs2_refile_wbuf_blocks
(
struct
jffs2_sb_info
*
c
)
{
struct
list_head
*
this
,
*
next
;
static
int
n
;
if
(
list_empty
(
&
c
->
erasable_pending_wbuf_list
))
return
;
list_for_each_safe
(
this
,
next
,
&
c
->
erasable_pending_wbuf_list
)
{
struct
jffs2_eraseblock
*
jeb
=
list_entry
(
this
,
struct
jffs2_eraseblock
,
list
);
D1
(
printk
(
KERN_DEBUG
"Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...
\n
"
,
jeb
->
offset
));
list_del
(
this
);
list_add_tail
(
this
,
&
c
->
erasable_list
);
if
((
jiffies
+
(
n
++
))
&
127
)
{
/* Most of the time, we just erase it immediately. Otherwise we
spend ages scanning it on mount, etc. */
D1
(
printk
(
KERN_DEBUG
"...and adding to erase_pending_list
\n
"
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
erase_pending_list
);
c
->
nr_erasing_blocks
++
;
jffs2_erase_pending_trigger
(
c
);
}
else
{
/* Sometimes, however, we leave it elsewhere so it doesn't get
immediately reused, and we spread the load a bit. */
D1
(
printk
(
KERN_DEBUG
"...and adding to erasable_list
\n
"
));
list_add_tail
(
&
jeb
->
list
,
&
c
->
erasable_list
);
}
}
}
/*
* Timed flushing of wbuf. If we have no consecutive write to wbuf, within
* the specified time, we flush the contents with padding !
*/
void
jffs2_wbuf_timeout
(
unsigned
long
data
)
{
struct
jffs2_sb_info
*
c
=
(
struct
jffs2_sb_info
*
)
data
;
/*
* Wake up the flush process, we need process context to have the right
* to sleep on flash write
*/
D1
(
printk
(
KERN_DEBUG
"jffs2_wbuf_timeout(): timer expired
\n
"
));
schedule_task
(
&
c
->
wbuf_task
);
}
/*
* Process for timed wbuf flush
*
* FIXME What happens, if we have a write failure there ????
*/
void
jffs2_wbuf_process
(
void
*
data
)
{
struct
jffs2_sb_info
*
c
=
(
struct
jffs2_sb_info
*
)
data
;
D1
(
printk
(
KERN_DEBUG
"jffs2_wbuf_process() entered
\n
"
));
if
(
!
down_trylock
(
&
c
->
alloc_sem
))
{
D1
(
printk
(
KERN_DEBUG
"jffs2_wbuf_process() alloc_sem got
\n
"
));
if
(
!
c
->
nextblock
||
(
c
->
nextblock
->
free_size
<
(
c
->
wbuf_pagesize
-
c
->
wbuf_len
)))
jffs2_flush_wbuf
(
c
,
1
);
/* pad only */
else
jffs2_flush_wbuf
(
c
,
2
);
/* pad and adjust nextblock */
up
(
&
c
->
alloc_sem
);
}
else
{
D1
(
printk
(
KERN_DEBUG
"jffs2_wbuf_process() alloc_sem already occupied
\n
"
));
}
}
/* Meaning of pad argument:
0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway.
1: Pad, do not adjust nextblock free_size
2: Pad, adjust nextblock free_size
*/
int
jffs2_flush_wbuf
(
struct
jffs2_sb_info
*
c
,
int
pad
)
{
int
ret
;
size_t
retlen
;
if
(
!
down_trylock
(
&
c
->
alloc_sem
))
{
up
(
&
c
->
alloc_sem
);
printk
(
KERN_CRIT
"jffs2_flush_wbuf() called with alloc_sem not locked!
\n
"
);
BUG
();
}
/* delete a eventually started timed wbuf flush */
del_timer_sync
(
&
c
->
wbuf_timer
);
if
(
!
c
->
wbuf
||
!
c
->
wbuf_len
)
return
0
;
...
...
@@ -339,6 +390,11 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *invecs, unsi
alldone:
*
retlen
=
donelen
;
/* Setup timed wbuf flush, if buffer len != 0 */
if
(
c
->
wbuf_len
)
{
D1
(
printk
(
KERN_DEBUG
"jffs2_flash_writev: mod wbuf_timer
\n
"
));
mod_timer
(
&
c
->
wbuf_timer
,
jiffies
+
WBUF_FLUSH_TIMEOUT
);
}
return
0
;
}
...
...
fs/jffs2/write.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: write.c,v 1.52 2002/03/08 11:01:43 dwmw2 Exp $
* $Id: write.c,v 1.56 2002/07/10 14:05:16 dwmw2 Exp $
*
*/
...
...
@@ -89,7 +65,7 @@ static void writecheck(struct jffs2_sb_info *c, uint32_t ofs)
ret
=
1
;
}
if
(
ret
)
{
printk
(
KERN_WARNING
"ARGH. About to write node to 0x%08x on flash, but there
's
data already there:
\n
"
,
ofs
);
printk
(
KERN_WARNING
"ARGH. About to write node to 0x%08x on flash, but there
are
data already there:
\n
"
,
ofs
);
printk
(
KERN_WARNING
"0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
ofs
,
buf
[
0
],
buf
[
1
],
buf
[
2
],
buf
[
3
],
buf
[
4
],
buf
[
5
],
buf
[
6
],
buf
[
7
],
...
...
@@ -386,8 +362,10 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
*/
ret
=
jffs2_reserve_space
(
c
,
sizeof
(
*
ri
),
&
phys_ofs
,
&
alloclen
,
ALLOC_NORMAL
);
D1
(
printk
(
KERN_DEBUG
"jffs2_do_create(): reserved 0x%x bytes
\n
"
,
alloclen
));
if
(
ret
)
if
(
ret
)
{
up
(
&
f
->
sem
);
return
ret
;
}
ri
->
data_crc
=
0
;
ri
->
node_crc
=
crc32
(
0
,
ri
,
sizeof
(
*
ri
)
-
8
);
...
...
@@ -472,7 +450,8 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
}
int
jffs2_do_unlink
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_inode_info
*
dir_f
,
const
char
*
name
,
int
namelen
,
struct
jffs2_inode_info
*
dead_f
)
int
jffs2_do_unlink
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_inode_info
*
dir_f
,
const
char
*
name
,
int
namelen
,
struct
jffs2_inode_info
*
dead_f
)
{
struct
jffs2_raw_dirent
*
rd
;
struct
jffs2_full_dirent
*
fd
;
...
...
@@ -522,7 +501,10 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, con
jffs2_complete_reservation
(
c
);
up
(
&
dir_f
->
sem
);
if
(
dead_f
)
{
/* Null if this was a rename not a real unlink */
/* dead_f is NULL if this was a rename not a real unlink */
/* Also catch the !f->inocache case, where there was a dirent
pointing to an inode which didn't exist. */
if
(
dead_f
&&
dead_f
->
inocache
)
{
down
(
&
dead_f
->
sem
);
...
...
fs/jffs2/writev.c
View file @
1a4c1b9e
...
...
@@ -5,33 +5,9 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
* For licensing information, see the file 'LICENCE' in this directory.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: writev.c,v 1.1 2002/03/08 11:27:59 dwmw2 Exp $
* $Id: writev.c,v 1.2 2002/05/20 14:56:39 dwmw2 Exp $
*
*/
...
...
include/linux/jffs2.h
View file @
1a4c1b9e
...
...
@@ -5,33 +5,10 @@
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
*
The original JFFS, from which the design for JFFS2 was derived,
*
was designed and implemented by Axis Communications AB
.
*
For licensing information, see the file 'LICENCE' in the
*
jffs2 directory
.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: jffs2.h,v 1.23 2002/02/21 17:03:45 dwmw2 Exp $
* $Id: jffs2.h,v 1.24 2002/05/20 14:56:37 dwmw2 Exp $
*
*/
...
...
include/linux/jffs2_fs_sb.h
View file @
1a4c1b9e
/* $Id: jffs2_fs_sb.h,v 1.
26 2002/03/17 10:18:42
dwmw2 Exp $ */
/* $Id: jffs2_fs_sb.h,v 1.
32 2002/07/23 14:35:34
dwmw2 Exp $ */
#ifndef _JFFS2_FS_SB
#define _JFFS2_FS_SB
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/tqueue.h>
#include <linux/completion.h>
#include <asm/semaphore.h>
#include <linux/list.h>
#define INOCACHE_HASHSIZE 14
#define JFFS2_SB_FLAG_RO 1
#define JFFS2_SB_FLAG_MOUNTING 2
...
...
@@ -33,6 +32,9 @@ struct jffs2_sb_info {
out-of-order writing of nodes.
And GC.
*/
uint32_t
cleanmarker_size
;
/* Size of an _inline_ CLEANMARKER
(i.e. zero for OOB CLEANMARKER */
uint32_t
flash_size
;
uint32_t
used_size
;
uint32_t
dirty_size
;
...
...
@@ -52,6 +54,7 @@ struct jffs2_sb_info {
struct
jffs2_eraseblock
*
gcblock
;
/* The block we're currently garbage-collecting */
struct
list_head
clean_list
;
/* Blocks 100% full of clean data */
struct
list_head
very_dirty_list
;
/* Blocks with lots of dirty space */
struct
list_head
dirty_list
;
/* Blocks with some dirty space */
struct
list_head
erasable_list
;
/* Blocks which are completely dirty, and need erasing */
struct
list_head
erasable_pending_wbuf_list
;
/* Blocks which need erasing but only after the current wbuf is flushed */
...
...
@@ -66,10 +69,8 @@ struct jffs2_sb_info {
against erase completion handler */
wait_queue_head_t
erase_wait
;
/* For waiting for erases to complete */
struct
jffs2_inode_cache
*
inocache_list
[
INOCACHE_HASHSIZE
]
;
struct
jffs2_inode_cache
*
*
inocache_list
;
spinlock_t
inocache_lock
;
/* This _really_ speeds up mounts. */
struct
jffs2_inode_cache
*
inocache_last
;
/* Sem to allow jffs2_garbage_collect_deletion_dirent to
drop the erase_completion_lock while it's holding a pointer
...
...
@@ -81,6 +82,8 @@ struct jffs2_sb_info {
uint32_t
wbuf_ofs
;
uint32_t
wbuf_len
;
uint32_t
wbuf_pagesize
;
struct
tq_struct
wbuf_task
;
/* task for timed wbuf flush */
struct
timer_list
wbuf_timer
;
/* timer for flushing wbuf */
/* OS-private pointer for getting back to master superblock info */
void
*
os_priv
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment