mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 04:42:12 +00:00
[JFFS2] Clean up trailing white spaces
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
97894cda57
commit
182ec4eee3
10
fs/Kconfig
10
fs/Kconfig
@ -1084,10 +1084,10 @@ config JFFS2_ZLIB
|
||||
default y
|
||||
help
|
||||
Zlib is designed to be a free, general-purpose, legally unencumbered,
|
||||
lossless data-compression library for use on virtually any computer
|
||||
lossless data-compression library for use on virtually any computer
|
||||
hardware and operating system. See <http://www.gzip.org/zlib/> for
|
||||
further information.
|
||||
|
||||
|
||||
Say 'Y' if unsure.
|
||||
|
||||
config JFFS2_RTIME
|
||||
@ -1109,7 +1109,7 @@ choice
|
||||
default JFFS2_CMODE_PRIORITY
|
||||
depends on JFFS2_FS
|
||||
help
|
||||
You can set here the default compression mode of JFFS2 from
|
||||
You can set here the default compression mode of JFFS2 from
|
||||
the available compression modes. Don't touch if unsure.
|
||||
|
||||
config JFFS2_CMODE_NONE
|
||||
@ -1120,13 +1120,13 @@ config JFFS2_CMODE_NONE
|
||||
config JFFS2_CMODE_PRIORITY
|
||||
bool "priority"
|
||||
help
|
||||
Tries the compressors in a predefinied order and chooses the first
|
||||
Tries the compressors in a predefinied order and chooses the first
|
||||
successful one.
|
||||
|
||||
config JFFS2_CMODE_SIZE
|
||||
bool "size (EXPERIMENTAL)"
|
||||
help
|
||||
Tries all compressors and chooses the one which has the smallest
|
||||
Tries all compressors and chooses the one which has the smallest
|
||||
result.
|
||||
|
||||
endchoice
|
||||
|
@ -51,7 +51,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
|
||||
D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
|
||||
wait_for_completion(&c->gc_thread_start);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ static int jffs2_garbage_collect_thread(void *_c)
|
||||
|
||||
cond_resched();
|
||||
|
||||
/* Put_super will send a SIGKILL and then wait on the sem.
|
||||
/* Put_super will send a SIGKILL and then wait on the sem.
|
||||
*/
|
||||
while (signal_pending(current)) {
|
||||
siginfo_t info;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: build.c,v 1.84 2005/09/27 13:40:49 dedekind Exp $
|
||||
* $Id: build.c,v 1.85 2005/11/07 11:14:38 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -129,10 +129,10 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
|
||||
for_each_inode(i, c, ic) {
|
||||
if (ic->nlink)
|
||||
continue;
|
||||
|
||||
|
||||
jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
dbg_fsbuild("pass 2a starting\n");
|
||||
|
||||
@ -149,7 +149,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
|
||||
|
||||
dbg_fsbuild("pass 2a complete\n");
|
||||
dbg_fsbuild("freeing temporary data structures\n");
|
||||
|
||||
|
||||
/* Finally, we can scan again and free the dirent structs */
|
||||
for_each_inode(i, c, ic) {
|
||||
while(ic->scan_dents) {
|
||||
@ -161,7 +161,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
|
||||
cond_resched();
|
||||
}
|
||||
c->flags &= ~JFFS2_SB_FLAG_BUILDING;
|
||||
|
||||
|
||||
dbg_fsbuild("FS build complete\n");
|
||||
|
||||
/* Rotate the lists by some number to ensure wear levelling */
|
||||
@ -191,7 +191,7 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
|
||||
struct jffs2_full_dirent *fd;
|
||||
|
||||
dbg_fsbuild("removing ino #%u with nlink == zero.\n", ic->ino);
|
||||
|
||||
|
||||
raw = ic->nodes;
|
||||
while (raw != (void *)ic) {
|
||||
struct jffs2_raw_node_ref *next = raw->next_in_ino;
|
||||
@ -220,7 +220,7 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
|
||||
whinged = 1;
|
||||
|
||||
dbg_fsbuild("removing child \"%s\", ino #%u\n", fd->name, fd->ino);
|
||||
|
||||
|
||||
child_ic = jffs2_get_ino_cache(c, fd->ino);
|
||||
if (!child_ic) {
|
||||
dbg_fsbuild("cannot remove child \"%s\", ino #%u, because it doesn't exist\n",
|
||||
@ -229,11 +229,11 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Reduce nlink of the child. If it's now zero, stick it on the
|
||||
/* Reduce nlink of the child. If it's now zero, stick it on the
|
||||
dead_fds list to be cleaned up later. Else just free the fd */
|
||||
|
||||
child_ic->nlink--;
|
||||
|
||||
|
||||
if (!child_ic->nlink) {
|
||||
dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n",
|
||||
fd->ino, fd->name);
|
||||
@ -248,7 +248,7 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
|
||||
}
|
||||
|
||||
/*
|
||||
We don't delete the inocache from the hash list and free it yet.
|
||||
We don't delete the inocache from the hash list and free it yet.
|
||||
The erase code will do that, when all the nodes are completely gone.
|
||||
*/
|
||||
}
|
||||
@ -262,7 +262,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
|
||||
because there's not enough free space... */
|
||||
c->resv_blocks_deletion = 2;
|
||||
|
||||
/* Be conservative about how much space we need before we allow writes.
|
||||
/* Be conservative about how much space we need before we allow writes.
|
||||
On top of that which is required for deletia, require an extra 2%
|
||||
of the medium to be available, for overhead caused by nodes being
|
||||
split across blocks, etc. */
|
||||
@ -277,7 +277,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
|
||||
|
||||
c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
|
||||
|
||||
/* When do we allow garbage collection to merge nodes to make
|
||||
/* When do we allow garbage collection to merge nodes to make
|
||||
long-term progress at the expense of short-term space exhaustion? */
|
||||
c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
|
||||
|
||||
@ -303,7 +303,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
|
||||
c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
|
||||
dbg_fsbuild("Amount of dirty space required to GC: %d bytes\n",
|
||||
c->nospc_dirty_size);
|
||||
}
|
||||
}
|
||||
|
||||
int jffs2_do_mount_fs(struct jffs2_sb_info *c)
|
||||
{
|
||||
@ -355,7 +355,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
|
||||
#ifndef __ECOS
|
||||
if (jffs2_blocks_use_vmalloc(c))
|
||||
vfree(c->blocks);
|
||||
else
|
||||
else
|
||||
#endif
|
||||
kfree(c->blocks);
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: compr.c,v 1.45 2005/07/26 13:24:40 havasi Exp $
|
||||
* $Id: compr.c,v 1.46 2005/11/07 11:14:38 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -36,16 +36,16 @@ static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_co
|
||||
* data.
|
||||
*
|
||||
* Returns: Lower byte to be stored with data indicating compression type used.
|
||||
* Zero is used to show that the data could not be compressed - the
|
||||
* Zero is used to show that the data could not be compressed - the
|
||||
* compressed version was actually larger than the original.
|
||||
* Upper byte will be used later. (soon)
|
||||
*
|
||||
* If the cdata buffer isn't large enough to hold all the uncompressed data,
|
||||
* jffs2_compress should compress as much as will fit, and should set
|
||||
* jffs2_compress should compress as much as will fit, and should set
|
||||
* *datalen accordingly to show the amount of data which were compressed.
|
||||
*/
|
||||
uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
unsigned char *data_in, unsigned char **cpage_out,
|
||||
unsigned char *data_in, unsigned char **cpage_out,
|
||||
uint32_t *datalen, uint32_t *cdatalen)
|
||||
{
|
||||
int ret = JFFS2_COMPR_NONE;
|
||||
@ -164,7 +164,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
}
|
||||
|
||||
int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
uint16_t comprtype, unsigned char *cdata_in,
|
||||
uint16_t comprtype, unsigned char *cdata_in,
|
||||
unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
|
||||
{
|
||||
struct jffs2_compressor *this;
|
||||
@ -298,7 +298,7 @@ char *jffs2_stats(void)
|
||||
|
||||
act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n");
|
||||
act_buf += sprintf(act_buf,"%10s ","none");
|
||||
act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks,
|
||||
act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks,
|
||||
none_stat_compr_size, none_stat_decompr_blocks);
|
||||
spin_lock(&jffs2_compressor_list_lock);
|
||||
list_for_each_entry(this, &jffs2_compressor_list, list) {
|
||||
@ -307,8 +307,8 @@ char *jffs2_stats(void)
|
||||
act_buf += sprintf(act_buf,"- ");
|
||||
else
|
||||
act_buf += sprintf(act_buf,"+ ");
|
||||
act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks,
|
||||
this->stat_compr_new_size, this->stat_compr_orig_size,
|
||||
act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks,
|
||||
this->stat_compr_new_size, this->stat_compr_orig_size,
|
||||
this->stat_decompr_blocks);
|
||||
act_buf += sprintf(act_buf,"\n");
|
||||
}
|
||||
@ -317,7 +317,7 @@ char *jffs2_stats(void)
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *jffs2_get_compression_mode_name(void)
|
||||
char *jffs2_get_compression_mode_name(void)
|
||||
{
|
||||
switch (jffs2_compression_mode) {
|
||||
case JFFS2_COMPR_MODE_NONE:
|
||||
@ -330,7 +330,7 @@ char *jffs2_get_compression_mode_name(void)
|
||||
return "unkown";
|
||||
}
|
||||
|
||||
int jffs2_set_compression_mode_name(const char *name)
|
||||
int jffs2_set_compression_mode_name(const char *name)
|
||||
{
|
||||
if (!strcmp("none",name)) {
|
||||
jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
|
||||
@ -355,7 +355,7 @@ static int jffs2_compressor_Xable(const char *name, int disabled)
|
||||
if (!strcmp(this->name, name)) {
|
||||
this->disabled = disabled;
|
||||
spin_unlock(&jffs2_compressor_list_lock);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
spin_unlock(&jffs2_compressor_list_lock);
|
||||
@ -385,7 +385,7 @@ int jffs2_set_compressor_priority(const char *name, int priority)
|
||||
}
|
||||
}
|
||||
spin_unlock(&jffs2_compressor_list_lock);
|
||||
printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name);
|
||||
printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name);
|
||||
return 1;
|
||||
reinsert:
|
||||
/* list is sorted in the order of priority, so if
|
||||
@ -412,7 +412,7 @@ void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
|
||||
kfree(comprbuf);
|
||||
}
|
||||
|
||||
int jffs2_compressors_init(void)
|
||||
int jffs2_compressors_init(void)
|
||||
{
|
||||
/* Registering compressors */
|
||||
#ifdef CONFIG_JFFS2_ZLIB
|
||||
@ -440,7 +440,7 @@ int jffs2_compressors_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jffs2_compressors_exit(void)
|
||||
int jffs2_compressors_exit(void)
|
||||
{
|
||||
/* Unregistering compressors */
|
||||
#ifdef CONFIG_JFFS2_RUBIN
|
||||
|
@ -4,10 +4,10 @@
|
||||
* Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
|
||||
* University of Szeged, Hungary
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in the
|
||||
* For licensing information, see the file 'LICENCE' in the
|
||||
* jffs2 directory.
|
||||
*
|
||||
* $Id: compr.h,v 1.8 2005/07/26 13:24:40 havasi Exp $
|
||||
* $Id: compr.h,v 1.9 2005/11/07 11:14:38 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/jffs2.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/jffs2.h>
|
||||
#include "compr.h"
|
||||
|
||||
/* _compress returns the compressed size, -1 if bigger */
|
||||
@ -38,19 +38,19 @@ static int jffs2_rtime_compress(unsigned char *data_in,
|
||||
int outpos = 0;
|
||||
int pos=0;
|
||||
|
||||
memset(positions,0,sizeof(positions));
|
||||
|
||||
memset(positions,0,sizeof(positions));
|
||||
|
||||
while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
|
||||
int backpos, runlen=0;
|
||||
unsigned char value;
|
||||
|
||||
|
||||
value = data_in[pos];
|
||||
|
||||
cpage_out[outpos++] = data_in[pos++];
|
||||
|
||||
|
||||
backpos = positions[value];
|
||||
positions[value]=pos;
|
||||
|
||||
|
||||
while ((backpos < pos) && (pos < (*sourcelen)) &&
|
||||
(data_in[pos]==data_in[backpos++]) && (runlen<255)) {
|
||||
pos++;
|
||||
@ -63,12 +63,12 @@ static int jffs2_rtime_compress(unsigned char *data_in,
|
||||
/* We failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Tell the caller how much we managed to compress, and how much space it took */
|
||||
*sourcelen = pos;
|
||||
*dstlen = outpos;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int jffs2_rtime_decompress(unsigned char *data_in,
|
||||
@ -79,19 +79,19 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
|
||||
short positions[256];
|
||||
int outpos = 0;
|
||||
int pos=0;
|
||||
|
||||
memset(positions,0,sizeof(positions));
|
||||
|
||||
|
||||
memset(positions,0,sizeof(positions));
|
||||
|
||||
while (outpos<destlen) {
|
||||
unsigned char value;
|
||||
int backoffs;
|
||||
int repeat;
|
||||
|
||||
|
||||
value = data_in[pos++];
|
||||
cpage_out[outpos++] = value; /* first the verbatim copied byte */
|
||||
repeat = data_in[pos++];
|
||||
backoffs = positions[value];
|
||||
|
||||
|
||||
positions[value]=outpos;
|
||||
if (repeat) {
|
||||
if (backoffs + repeat >= outpos) {
|
||||
@ -101,12 +101,12 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
|
||||
}
|
||||
} else {
|
||||
memcpy(&cpage_out[outpos],&cpage_out[backoffs],repeat);
|
||||
outpos+=repeat;
|
||||
outpos+=repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct jffs2_compressor jffs2_rtime_comp = {
|
||||
.priority = JFFS2_RTIME_PRIORITY,
|
||||
|
@ -11,7 +11,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/jffs2.h>
|
||||
@ -20,7 +19,7 @@
|
||||
#include "compr.h"
|
||||
|
||||
static void init_rubin(struct rubin_state *rs, int div, int *bits)
|
||||
{
|
||||
{
|
||||
int c;
|
||||
|
||||
rs->q = 0;
|
||||
@ -40,7 +39,7 @@ static int encode(struct rubin_state *rs, long A, long B, int symbol)
|
||||
|
||||
while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) {
|
||||
rs->bit_number++;
|
||||
|
||||
|
||||
ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -68,7 +67,7 @@ static int encode(struct rubin_state *rs, long A, long B, int symbol)
|
||||
|
||||
|
||||
static void end_rubin(struct rubin_state *rs)
|
||||
{
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
@ -82,7 +81,7 @@ static void end_rubin(struct rubin_state *rs)
|
||||
|
||||
static void init_decode(struct rubin_state *rs, int div, int *bits)
|
||||
{
|
||||
init_rubin(rs, div, bits);
|
||||
init_rubin(rs, div, bits);
|
||||
|
||||
/* behalve lower */
|
||||
rs->rec_q = 0;
|
||||
@ -188,7 +187,7 @@ static int in_byte(struct rubin_state *rs)
|
||||
|
||||
|
||||
|
||||
static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
|
||||
static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
|
||||
unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen)
|
||||
{
|
||||
int outpos = 0;
|
||||
@ -198,31 +197,31 @@ static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
|
||||
init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32);
|
||||
|
||||
init_rubin(&rs, bit_divider, bits);
|
||||
|
||||
|
||||
while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos]))
|
||||
pos++;
|
||||
|
||||
|
||||
end_rubin(&rs);
|
||||
|
||||
if (outpos > pos) {
|
||||
/* We failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Tell the caller how much we managed to compress,
|
||||
|
||||
/* Tell the caller how much we managed to compress,
|
||||
* and how much space it took */
|
||||
|
||||
|
||||
outpos = (pushedbits(&rs.pp)+7)/8;
|
||||
|
||||
|
||||
if (outpos >= pos)
|
||||
return -1; /* We didn't actually compress */
|
||||
*sourcelen = pos;
|
||||
*dstlen = outpos;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* _compress returns the compressed size, -1 if bigger */
|
||||
int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
uint32_t *sourcelen, uint32_t *dstlen, void *model)
|
||||
{
|
||||
return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
|
||||
@ -277,7 +276,7 @@ static int jffs2_dynrubin_compress(unsigned char *data_in,
|
||||
}
|
||||
|
||||
ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, &mydstlen);
|
||||
if (ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Add back the 8 bytes we took for the probabilities */
|
||||
@ -293,19 +292,19 @@ static int jffs2_dynrubin_compress(unsigned char *data_in,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
|
||||
static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
|
||||
unsigned char *page_out, uint32_t srclen, uint32_t destlen)
|
||||
{
|
||||
int outpos = 0;
|
||||
struct rubin_state rs;
|
||||
|
||||
|
||||
init_pushpull(&rs.pp, cdata_in, srclen, 0, 0);
|
||||
init_decode(&rs, bit_divider, bits);
|
||||
|
||||
|
||||
while (outpos < destlen) {
|
||||
page_out[outpos++] = in_byte(&rs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int jffs2_rubinmips_decompress(unsigned char *data_in,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Rubin encoder/decoder header */
|
||||
/* work started at : aug 3, 1994 */
|
||||
/* last modification : aug 15, 1994 */
|
||||
/* $Id: compr_rubin.h,v 1.6 2002/01/25 01:49:26 dwmw2 Exp $ */
|
||||
/* $Id: compr_rubin.h,v 1.7 2005/11/07 11:14:38 gleixner Exp $ */
|
||||
|
||||
#include "pushpull.h"
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
|
||||
|
||||
struct rubin_state {
|
||||
unsigned long p;
|
||||
unsigned long q;
|
||||
unsigned long p;
|
||||
unsigned long q;
|
||||
unsigned long rec_q;
|
||||
long bit_number;
|
||||
struct pushpull pp;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $
|
||||
* $Id: compr_zlib.c,v 1.32 2005/11/07 11:14:38 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,11 +24,11 @@
|
||||
#include "nodelist.h"
|
||||
#include "compr.h"
|
||||
|
||||
/* Plan: call deflate() with avail_in == *sourcelen,
|
||||
avail_out = *dstlen - 12 and flush == Z_FINISH.
|
||||
/* Plan: call deflate() with avail_in == *sourcelen,
|
||||
avail_out = *dstlen - 12 and flush == Z_FINISH.
|
||||
If it doesn't manage to finish, call it again with
|
||||
avail_in == 0 and avail_out set to the remaining 12
|
||||
bytes for it to clean up.
|
||||
bytes for it to clean up.
|
||||
Q: Is 12 bytes sufficient?
|
||||
*/
|
||||
#define STREAM_END_SPACE 12
|
||||
@ -89,7 +89,7 @@ static int jffs2_zlib_compress(unsigned char *data_in,
|
||||
|
||||
def_strm.next_in = data_in;
|
||||
def_strm.total_in = 0;
|
||||
|
||||
|
||||
def_strm.next_out = cpage_out;
|
||||
def_strm.total_out = 0;
|
||||
|
||||
@ -99,7 +99,7 @@ static int jffs2_zlib_compress(unsigned char *data_in,
|
||||
D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
|
||||
def_strm.avail_in, def_strm.avail_out));
|
||||
ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH);
|
||||
D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
|
||||
D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
|
||||
def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out));
|
||||
if (ret != Z_OK) {
|
||||
D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret));
|
||||
@ -150,7 +150,7 @@ static int jffs2_zlib_decompress(unsigned char *data_in,
|
||||
inf_strm.next_in = data_in;
|
||||
inf_strm.avail_in = srclen;
|
||||
inf_strm.total_in = 0;
|
||||
|
||||
|
||||
inf_strm.next_out = cpage_out;
|
||||
inf_strm.avail_out = destlen;
|
||||
inf_strm.total_out = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: comprtest.c,v 1.5 2002/01/03 15:20:44 dwmw2 Exp $ */
|
||||
/* $Id: comprtest.c,v 1.6 2005/11/07 11:14:38 gleixner Exp $ */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
@ -265,9 +265,9 @@ static unsigned char testdata[TESTDATA_LEN] = {
|
||||
static unsigned char comprbuf[TESTDATA_LEN];
|
||||
static unsigned char decomprbuf[TESTDATA_LEN];
|
||||
|
||||
int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
|
||||
int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
|
||||
unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
|
||||
unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
uint32_t *datalen, uint32_t *cdatalen);
|
||||
|
||||
int init_module(void ) {
|
||||
@ -276,10 +276,10 @@ int init_module(void ) {
|
||||
int ret;
|
||||
|
||||
printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
testdata[0],testdata[1],testdata[2],testdata[3],
|
||||
testdata[4],testdata[5],testdata[6],testdata[7],
|
||||
testdata[8],testdata[9],testdata[10],testdata[11],
|
||||
testdata[12],testdata[13],testdata[14],testdata[15]);
|
||||
testdata[0],testdata[1],testdata[2],testdata[3],
|
||||
testdata[4],testdata[5],testdata[6],testdata[7],
|
||||
testdata[8],testdata[9],testdata[10],testdata[11],
|
||||
testdata[12],testdata[13],testdata[14],testdata[15]);
|
||||
d = TESTDATA_LEN;
|
||||
c = TESTDATA_LEN;
|
||||
comprtype = jffs2_compress(testdata, comprbuf, &d, &c);
|
||||
@ -287,18 +287,18 @@ int init_module(void ) {
|
||||
printk("jffs2_compress used compression type %d. Compressed size %d, uncompressed size %d\n",
|
||||
comprtype, c, d);
|
||||
printk("Compressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
comprbuf[0],comprbuf[1],comprbuf[2],comprbuf[3],
|
||||
comprbuf[4],comprbuf[5],comprbuf[6],comprbuf[7],
|
||||
comprbuf[8],comprbuf[9],comprbuf[10],comprbuf[11],
|
||||
comprbuf[12],comprbuf[13],comprbuf[14],comprbuf[15]);
|
||||
comprbuf[0],comprbuf[1],comprbuf[2],comprbuf[3],
|
||||
comprbuf[4],comprbuf[5],comprbuf[6],comprbuf[7],
|
||||
comprbuf[8],comprbuf[9],comprbuf[10],comprbuf[11],
|
||||
comprbuf[12],comprbuf[13],comprbuf[14],comprbuf[15]);
|
||||
|
||||
ret = jffs2_decompress(comprtype, comprbuf, decomprbuf, c, d);
|
||||
printk("jffs2_decompress returned %d\n", ret);
|
||||
printk("Decompressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
decomprbuf[0],decomprbuf[1],decomprbuf[2],decomprbuf[3],
|
||||
decomprbuf[4],decomprbuf[5],decomprbuf[6],decomprbuf[7],
|
||||
decomprbuf[8],decomprbuf[9],decomprbuf[10],decomprbuf[11],
|
||||
decomprbuf[12],decomprbuf[13],decomprbuf[14],decomprbuf[15]);
|
||||
decomprbuf[0],decomprbuf[1],decomprbuf[2],decomprbuf[3],
|
||||
decomprbuf[4],decomprbuf[5],decomprbuf[6],decomprbuf[7],
|
||||
decomprbuf[8],decomprbuf[9],decomprbuf[10],decomprbuf[11],
|
||||
decomprbuf[12],decomprbuf[13],decomprbuf[14],decomprbuf[15]);
|
||||
if (memcmp(decomprbuf, testdata, d))
|
||||
printk("Compression and decompression corrupted data\n");
|
||||
else
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: debug.c,v 1.11 2005/09/21 13:28:35 dedekind Exp $
|
||||
* $Id: debug.c,v 1.12 2005/11/07 11:14:39 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
@ -67,7 +67,7 @@ __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
|
||||
__jffs2_dbg_fragtree_paranoia_check_nolock(f);
|
||||
up(&f->sem);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
|
||||
{
|
||||
@ -165,7 +165,7 @@ __jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
|
||||
__jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
|
||||
struct jffs2_eraseblock *jeb)
|
||||
@ -237,7 +237,7 @@ error:
|
||||
__jffs2_dbg_dump_jeb_nolock(jeb);
|
||||
__jffs2_dbg_dump_block_lists_nolock(c);
|
||||
BUG();
|
||||
|
||||
|
||||
}
|
||||
#endif /* JFFS2_DBG_PARANOIA_CHECKS */
|
||||
|
||||
@ -321,7 +321,7 @@ void
|
||||
__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
|
||||
{
|
||||
printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
|
||||
|
||||
|
||||
printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
|
||||
printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
|
||||
printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
|
||||
@ -577,15 +577,15 @@ __jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
|
||||
{
|
||||
int skip;
|
||||
int i;
|
||||
|
||||
|
||||
printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
|
||||
offs, offs + len, len);
|
||||
i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
|
||||
offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
|
||||
|
||||
|
||||
if (skip != 0)
|
||||
printk(JFFS2_DBG "%#08x: ", offs);
|
||||
|
||||
|
||||
while (skip--)
|
||||
printk(" ");
|
||||
|
||||
@ -598,7 +598,7 @@ __jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
|
||||
}
|
||||
|
||||
printk("%02x ", buf[i]);
|
||||
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
@ -616,7 +616,7 @@ __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
|
||||
size_t retlen;
|
||||
uint32_t crc;
|
||||
int ret;
|
||||
|
||||
|
||||
printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
|
||||
|
||||
ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
|
||||
@ -630,13 +630,13 @@ __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
|
||||
printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
|
||||
printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
|
||||
printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
|
||||
|
||||
|
||||
crc = crc32(0, &node.u, sizeof(node.u) - 4);
|
||||
if (crc != je32_to_cpu(node.u.hdr_crc)) {
|
||||
JFFS2_ERROR("wrong common header CRC.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
|
||||
je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
|
||||
{
|
||||
@ -668,7 +668,7 @@ __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
|
||||
printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
|
||||
printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
|
||||
|
||||
crc = crc32(0, &node.i, sizeof(node.i) - 8);
|
||||
crc = crc32(0, &node.i, sizeof(node.i) - 8);
|
||||
if (crc != je32_to_cpu(node.i.node_crc)) {
|
||||
JFFS2_ERROR("wrong node header CRC.\n");
|
||||
return;
|
||||
@ -686,11 +686,11 @@ __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
|
||||
printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
|
||||
printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
|
||||
printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
|
||||
|
||||
|
||||
node.d.name[node.d.nsize] = '\0';
|
||||
printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
|
||||
|
||||
crc = crc32(0, &node.d, sizeof(node.d) - 8);
|
||||
crc = crc32(0, &node.d, sizeof(node.d) - 8);
|
||||
if (crc != je32_to_cpu(node.d.node_crc)) {
|
||||
JFFS2_ERROR("wrong node header CRC.\n");
|
||||
return;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: debug.h,v 1.20 2005/10/24 16:22:34 dedekind Exp $
|
||||
* $Id: debug.h,v 1.21 2005/11/07 11:14:39 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
#ifndef _JFFS2_DEBUG_H_
|
||||
@ -24,7 +24,7 @@
|
||||
#define JFFS2_DBG_PARANOIA_CHECKS
|
||||
#define JFFS2_DBG_DUMPS
|
||||
|
||||
/*
|
||||
/*
|
||||
* By defining/undefining the below macros one may select debugging messages
|
||||
* fro specific JFFS2 subsystems.
|
||||
*/
|
||||
@ -45,7 +45,7 @@
|
||||
/* Sanity checks are supposed to be light-weight and enabled by default */
|
||||
#define JFFS2_DBG_SANITY_CHECKS
|
||||
|
||||
/*
|
||||
/*
|
||||
* Dx() are mainly used for debugging messages, they must go away and be
|
||||
* superseded by nicer dbg_xxx() macros...
|
||||
*/
|
||||
@ -91,7 +91,7 @@
|
||||
" (%d) %s: " fmt, current->pid, \
|
||||
__FUNCTION__, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define JFFS2_NOTICE(fmt, ...) \
|
||||
do { \
|
||||
printk(JFFS2_NOTICE_MSG_PREFIX \
|
||||
@ -106,7 +106,7 @@
|
||||
__FUNCTION__, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
/*
|
||||
* We split our debugging messages on several parts, depending on the JFFS2
|
||||
* subsystem the message belongs to.
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: dir.c,v 1.89 2005/09/07 08:34:54 havasi Exp $
|
||||
* $Id: dir.c,v 1.90 2005/11/07 11:14:39 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -64,7 +64,7 @@ struct inode_operations jffs2_dir_inode_operations =
|
||||
|
||||
|
||||
/* We keep the dirent list sorted in increasing order of name hash,
|
||||
and we use the same hash function as the dentries. Makes this
|
||||
and we use the same hash function as the dentries. Makes this
|
||||
nice and simple
|
||||
*/
|
||||
static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
|
||||
@ -85,7 +85,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
|
||||
|
||||
/* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
|
||||
for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) {
|
||||
if (fd_list->nhash == target->d_name.hash &&
|
||||
if (fd_list->nhash == target->d_name.hash &&
|
||||
(!fd || fd_list->version > fd->version) &&
|
||||
strlen(fd_list->name) == target->d_name.len &&
|
||||
!strncmp(fd_list->name, target->d_name.name, target->d_name.len)) {
|
||||
@ -147,7 +147,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
curofs++;
|
||||
/* First loop: curofs = 2; offset = 2 */
|
||||
if (curofs < offset) {
|
||||
D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
|
||||
D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
|
||||
fd->name, fd->ino, fd->type, curofs, offset));
|
||||
continue;
|
||||
}
|
||||
@ -182,7 +182,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
|
||||
ri = jffs2_alloc_raw_inode();
|
||||
if (!ri)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
c = JFFS2_SB_INFO(dir_i->i_sb);
|
||||
|
||||
D1(printk(KERN_DEBUG "jffs2_create()\n"));
|
||||
@ -203,7 +203,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
|
||||
f = JFFS2_INODE_INFO(inode);
|
||||
dir_f = JFFS2_INODE_INFO(dir_i);
|
||||
|
||||
ret = jffs2_do_create(c, dir_f, f, ri,
|
||||
ret = jffs2_do_create(c, dir_f, f, ri,
|
||||
dentry->d_name.name, dentry->d_name.len);
|
||||
|
||||
if (ret) {
|
||||
@ -234,7 +234,7 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
|
||||
int ret;
|
||||
uint32_t now = get_seconds();
|
||||
|
||||
ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
|
||||
ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
|
||||
dentry->d_name.len, dead_f, now);
|
||||
if (dead_f->inocache)
|
||||
dentry->d_inode->i_nlink = dead_f->inocache->nlink;
|
||||
@ -303,11 +303,11 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
|
||||
|
||||
if (!ri)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
c = JFFS2_SB_INFO(dir_i->i_sb);
|
||||
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
*/
|
||||
namelen = dentry->d_name.len;
|
||||
ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen,
|
||||
@ -338,7 +338,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
|
||||
ri->compr = JFFS2_COMPR_NONE;
|
||||
ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
|
||||
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
|
||||
|
||||
|
||||
fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
jffs2_free_raw_inode(ri);
|
||||
@ -364,7 +364,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
|
||||
memcpy(f->target, target, targetlen + 1);
|
||||
D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target));
|
||||
|
||||
/* No data here. Only a metadata node, which will be
|
||||
/* No data here. Only a metadata node, which will be
|
||||
obsoleted by the first data write
|
||||
*/
|
||||
f->metadata = fn;
|
||||
@ -407,7 +407,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
|
||||
fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
if (IS_ERR(fd)) {
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
as if it were the final unlink() */
|
||||
jffs2_complete_reservation(c);
|
||||
jffs2_free_raw_dirent(rd);
|
||||
@ -450,11 +450,11 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
|
||||
ri = jffs2_alloc_raw_inode();
|
||||
if (!ri)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
c = JFFS2_SB_INFO(dir_i->i_sb);
|
||||
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
*/
|
||||
namelen = dentry->d_name.len;
|
||||
ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL,
|
||||
@ -482,7 +482,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
|
||||
|
||||
ri->data_crc = cpu_to_je32(0);
|
||||
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
|
||||
|
||||
|
||||
fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
jffs2_free_raw_inode(ri);
|
||||
@ -494,7 +494,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
|
||||
jffs2_clear_inode(inode);
|
||||
return PTR_ERR(fn);
|
||||
}
|
||||
/* No data here. Only a metadata node, which will be
|
||||
/* No data here. Only a metadata node, which will be
|
||||
obsoleted by the first data write
|
||||
*/
|
||||
f->metadata = fn;
|
||||
@ -508,7 +508,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
|
||||
jffs2_clear_inode(inode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
rd = jffs2_alloc_raw_dirent();
|
||||
if (!rd) {
|
||||
/* Argh. Now we treat it like a normal delete */
|
||||
@ -535,9 +535,9 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
|
||||
rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
|
||||
|
||||
fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
|
||||
if (IS_ERR(fd)) {
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
as if it were the final unlink() */
|
||||
jffs2_complete_reservation(c);
|
||||
jffs2_free_raw_dirent(rd);
|
||||
@ -599,16 +599,16 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
|
||||
ri = jffs2_alloc_raw_inode();
|
||||
if (!ri)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
c = JFFS2_SB_INFO(dir_i->i_sb);
|
||||
|
||||
|
||||
if (S_ISBLK(mode) || S_ISCHR(mode)) {
|
||||
dev = cpu_to_je16(old_encode_dev(rdev));
|
||||
devlen = sizeof(dev);
|
||||
}
|
||||
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
*/
|
||||
namelen = dentry->d_name.len;
|
||||
ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen,
|
||||
@ -638,7 +638,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
|
||||
ri->compr = JFFS2_COMPR_NONE;
|
||||
ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
|
||||
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
|
||||
|
||||
|
||||
fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
jffs2_free_raw_inode(ri);
|
||||
@ -650,7 +650,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
|
||||
jffs2_clear_inode(inode);
|
||||
return PTR_ERR(fn);
|
||||
}
|
||||
/* No data here. Only a metadata node, which will be
|
||||
/* No data here. Only a metadata node, which will be
|
||||
obsoleted by the first data write
|
||||
*/
|
||||
f->metadata = fn;
|
||||
@ -694,9 +694,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
|
||||
rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
|
||||
|
||||
fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
|
||||
if (IS_ERR(fd)) {
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
as if it were the final unlink() */
|
||||
jffs2_complete_reservation(c);
|
||||
jffs2_free_raw_dirent(rd);
|
||||
@ -730,7 +730,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
|
||||
uint8_t type;
|
||||
uint32_t now;
|
||||
|
||||
/* The VFS will check for us and prevent trying to rename a
|
||||
/* 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.
|
||||
@ -752,18 +752,18 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
|
||||
}
|
||||
|
||||
/* XXX: We probably ought to alloc enough space for
|
||||
both nodes at the same time. Writing the new link,
|
||||
both nodes at the same time. Writing the new link,
|
||||
then getting -ENOSPC, is quite bad :)
|
||||
*/
|
||||
|
||||
/* Make a hard link */
|
||||
|
||||
|
||||
/* XXX: This is ugly */
|
||||
type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
|
||||
if (!type) type = DT_REG;
|
||||
|
||||
now = get_seconds();
|
||||
ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
|
||||
ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
|
||||
old_dentry->d_inode->i_ino, type,
|
||||
new_dentry->d_name.name, new_dentry->d_name.len, now);
|
||||
|
||||
@ -782,13 +782,13 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
|
||||
}
|
||||
}
|
||||
|
||||
/* If it was a directory we moved, and there was no victim,
|
||||
/* 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 */
|
||||
ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
|
||||
ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
|
||||
old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
|
||||
|
||||
/* We don't touch inode->i_nlink */
|
||||
|
@ -24,7 +24,7 @@ struct erase_priv_struct {
|
||||
struct jffs2_eraseblock *jeb;
|
||||
struct jffs2_sb_info *c;
|
||||
};
|
||||
|
||||
|
||||
#ifndef __ECOS
|
||||
static void jffs2_erase_callback(struct erase_info *);
|
||||
#endif
|
||||
@ -71,7 +71,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
|
||||
instr->callback = jffs2_erase_callback;
|
||||
instr->priv = (unsigned long)(&instr[1]);
|
||||
instr->fail_addr = 0xffffffff;
|
||||
|
||||
|
||||
((struct erase_priv_struct *)instr->priv)->jeb = jeb;
|
||||
((struct erase_priv_struct *)instr->priv)->c = c;
|
||||
|
||||
@ -96,7 +96,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret == -EROFS)
|
||||
if (ret == -EROFS)
|
||||
printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset);
|
||||
else
|
||||
printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret);
|
||||
@ -197,7 +197,7 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
|
||||
c->nr_erasing_blocks--;
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
wake_up(&c->erase_wait);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __ECOS
|
||||
static void jffs2_erase_callback(struct erase_info *instr)
|
||||
@ -209,7 +209,7 @@ static void jffs2_erase_callback(struct erase_info *instr)
|
||||
jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr);
|
||||
} else {
|
||||
jffs2_erase_succeeded(priv->c, priv->jeb);
|
||||
}
|
||||
}
|
||||
kfree(instr);
|
||||
}
|
||||
#endif /* !__ECOS */
|
||||
@ -227,13 +227,13 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
|
||||
/* Walk the inode's list once, removing any nodes from this eraseblock */
|
||||
while (1) {
|
||||
if (!(*prev)->next_in_ino) {
|
||||
/* We're looking at the jffs2_inode_cache, which is
|
||||
/* We're looking at the jffs2_inode_cache, which is
|
||||
at the end of the linked list. Stash it and continue
|
||||
from the beginning of the list */
|
||||
ic = (struct jffs2_inode_cache *)(*prev);
|
||||
prev = &ic->nodes;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
|
||||
/* It's in the block we're erasing */
|
||||
@ -267,7 +267,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
|
||||
printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG);
|
||||
|
||||
this = ic->nodes;
|
||||
|
||||
|
||||
while(this) {
|
||||
printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this));
|
||||
if (++i == 5) {
|
||||
@ -290,7 +290,7 @@ static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_erase
|
||||
while(jeb->first_node) {
|
||||
ref = jeb->first_node;
|
||||
jeb->first_node = ref->next_phys;
|
||||
|
||||
|
||||
/* Remove from the inode-list */
|
||||
if (ref->next_in_ino)
|
||||
jffs2_remove_node_refs_from_ino_list(c, ref, jeb);
|
||||
@ -307,7 +307,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
|
||||
uint32_t ofs;
|
||||
size_t retlen;
|
||||
int ret = -EIO;
|
||||
|
||||
|
||||
ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!ebuf) {
|
||||
printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);
|
||||
@ -361,7 +361,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
|
||||
case -EIO: goto filebad;
|
||||
}
|
||||
|
||||
/* Write the erase complete marker */
|
||||
/* Write the erase complete marker */
|
||||
D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));
|
||||
bad_offset = jeb->offset;
|
||||
|
||||
@ -399,7 +399,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
|
||||
vecs[0].iov_base = (unsigned char *) ▮
|
||||
vecs[0].iov_len = sizeof(marker);
|
||||
ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
|
||||
|
||||
|
||||
if (ret || retlen != sizeof(marker)) {
|
||||
if (ret)
|
||||
printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
|
||||
@ -416,9 +416,9 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
|
||||
marker_ref->next_phys = NULL;
|
||||
marker_ref->flash_offset = jeb->offset | REF_NORMAL;
|
||||
marker_ref->__totlen = c->cleanmarker_size;
|
||||
|
||||
|
||||
jeb->first_node = jeb->last_node = marker_ref;
|
||||
|
||||
|
||||
jeb->free_size = c->sector_size - c->cleanmarker_size;
|
||||
jeb->used_size = c->cleanmarker_size;
|
||||
jeb->dirty_size = 0;
|
||||
|
@ -34,8 +34,8 @@ int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
|
||||
|
||||
/* Trigger GC to flush any pending writes for this inode */
|
||||
jffs2_flush_wbuf_gc(c, inode->i_ino);
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct file_operations jffs2_file_operations =
|
||||
@ -107,7 +107,7 @@ static int jffs2_readpage (struct file *filp, struct page *pg)
|
||||
{
|
||||
struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host);
|
||||
int ret;
|
||||
|
||||
|
||||
down(&f->sem);
|
||||
ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
|
||||
up(&f->sem);
|
||||
@ -130,7 +130,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
|
||||
struct jffs2_raw_inode ri;
|
||||
struct jffs2_full_dnode *fn;
|
||||
uint32_t phys_ofs, alloc_len;
|
||||
|
||||
|
||||
D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
|
||||
(unsigned int)inode->i_size, pageofs));
|
||||
|
||||
@ -160,7 +160,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
|
||||
ri.compr = JFFS2_COMPR_ZERO;
|
||||
ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
|
||||
ri.data_crc = cpu_to_je32(0);
|
||||
|
||||
|
||||
fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
if (IS_ERR(fn)) {
|
||||
@ -187,7 +187,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
|
||||
inode->i_size = pageofs;
|
||||
up(&f->sem);
|
||||
}
|
||||
|
||||
|
||||
/* Read in the page if it wasn't already present, unless it's a whole page */
|
||||
if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
|
||||
down(&f->sem);
|
||||
@ -218,7 +218,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
|
||||
if (!start && end == PAGE_CACHE_SIZE) {
|
||||
/* We need to avoid deadlock with page_cache_read() in
|
||||
jffs2_garbage_collect_pass(). So we have to mark the
|
||||
page up to date, to prevent page_cache_read() from
|
||||
page up to date, to prevent page_cache_read() from
|
||||
trying to re-lock it. */
|
||||
SetPageUptodate(pg);
|
||||
}
|
||||
@ -252,7 +252,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
|
||||
/* There was an error writing. */
|
||||
SetPageError(pg);
|
||||
}
|
||||
|
||||
|
||||
/* Adjust writtenlen for the padding we did, so we don't confuse our caller */
|
||||
if (writtenlen < (start&3))
|
||||
writtenlen = 0;
|
||||
@ -263,7 +263,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
|
||||
if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
|
||||
inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
|
||||
inode->i_blocks = (inode->i_size + 511) >> 9;
|
||||
|
||||
|
||||
inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
|
||||
}
|
||||
}
|
||||
@ -272,7 +272,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
|
||||
|
||||
if (start+writtenlen < end) {
|
||||
/* generic_file_write has written more to the page cache than we've
|
||||
actually written to the medium. Mark the page !Uptodate so that
|
||||
actually written to the medium. Mark the page !Uptodate so that
|
||||
it gets reread */
|
||||
D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n"));
|
||||
SetPageError(pg);
|
||||
|
@ -40,7 +40,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
|
||||
int ret;
|
||||
D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
|
||||
ret = inode_change_ok(inode, iattr);
|
||||
if (ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Special cases - we don't want more than one data node
|
||||
@ -73,7 +73,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
|
||||
kfree(mdata);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen,
|
||||
ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
|
||||
if (ret) {
|
||||
@ -84,7 +84,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
|
||||
}
|
||||
down(&f->sem);
|
||||
ivalid = iattr->ia_valid;
|
||||
|
||||
|
||||
ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
|
||||
ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
|
||||
ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
|
||||
@ -100,7 +100,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
|
||||
if (iattr->ia_mode & S_ISGID &&
|
||||
!in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
|
||||
ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
|
||||
else
|
||||
else
|
||||
ri->mode = cpu_to_jemode(iattr->ia_mode);
|
||||
else
|
||||
ri->mode = cpu_to_jemode(inode->i_mode);
|
||||
@ -129,7 +129,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
|
||||
new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
|
||||
if (S_ISLNK(inode->i_mode))
|
||||
kfree(mdata);
|
||||
|
||||
|
||||
if (IS_ERR(new_metadata)) {
|
||||
jffs2_complete_reservation(c);
|
||||
jffs2_free_raw_inode(ri);
|
||||
@ -167,7 +167,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
|
||||
jffs2_complete_reservation(c);
|
||||
|
||||
/* We have to do the vmtruncate() without f->sem held, since
|
||||
some pages may be locked and waiting for it in readpage().
|
||||
some pages may be locked and waiting for it in readpage().
|
||||
We are protected from a simultaneous write() extending i_size
|
||||
back past iattr->ia_size, because do_truncate() holds the
|
||||
generic inode semaphore. */
|
||||
@ -210,12 +210,12 @@ int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
|
||||
|
||||
void jffs2_clear_inode (struct inode *inode)
|
||||
{
|
||||
/* We can forget about this inode for now - drop all
|
||||
/* We can forget about this inode for now - drop all
|
||||
* the nodelists associated with it, etc.
|
||||
*/
|
||||
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
|
||||
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
|
||||
|
||||
|
||||
D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
|
||||
|
||||
jffs2_do_clear_inode(c, f);
|
||||
@ -234,7 +234,7 @@ void jffs2_read_inode (struct inode *inode)
|
||||
c = JFFS2_SB_INFO(inode->i_sb);
|
||||
|
||||
jffs2_init_inode_info(f);
|
||||
|
||||
|
||||
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
|
||||
|
||||
if (ret) {
|
||||
@ -254,14 +254,14 @@ void jffs2_read_inode (struct inode *inode)
|
||||
|
||||
inode->i_blksize = PAGE_SIZE;
|
||||
inode->i_blocks = (inode->i_size + 511) >> 9;
|
||||
|
||||
|
||||
switch (inode->i_mode & S_IFMT) {
|
||||
jint16_t rdev;
|
||||
|
||||
case S_IFLNK:
|
||||
inode->i_op = &jffs2_symlink_inode_operations;
|
||||
break;
|
||||
|
||||
|
||||
case S_IFDIR:
|
||||
{
|
||||
struct jffs2_full_dirent *fd;
|
||||
@ -298,7 +298,7 @@ void jffs2_read_inode (struct inode *inode)
|
||||
jffs2_do_clear_inode(c, f);
|
||||
make_bad_inode(inode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
case S_IFSOCK:
|
||||
case S_IFIFO:
|
||||
@ -354,11 +354,11 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
|
||||
down(&c->alloc_sem);
|
||||
jffs2_flush_wbuf_pad(c);
|
||||
up(&c->alloc_sem);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*flags & MS_RDONLY))
|
||||
jffs2_start_garbage_collect_thread(c);
|
||||
|
||||
|
||||
*flags |= MS_NOATIME;
|
||||
|
||||
return 0;
|
||||
@ -392,9 +392,9 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
|
||||
D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
|
||||
|
||||
c = JFFS2_SB_INFO(sb);
|
||||
|
||||
|
||||
inode = new_inode(sb);
|
||||
|
||||
|
||||
if (!inode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -458,14 +458,14 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
|
||||
#endif
|
||||
|
||||
c->flash_size = c->mtd->size;
|
||||
c->sector_size = c->mtd->erasesize;
|
||||
c->sector_size = c->mtd->erasesize;
|
||||
blocks = c->flash_size / c->sector_size;
|
||||
|
||||
/*
|
||||
* Size alignment check
|
||||
*/
|
||||
if ((c->sector_size * blocks) != c->flash_size) {
|
||||
c->flash_size = c->sector_size * blocks;
|
||||
c->flash_size = c->sector_size * blocks;
|
||||
printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n",
|
||||
c->flash_size / 1024);
|
||||
}
|
||||
@ -543,16 +543,16 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_cache *ic;
|
||||
if (!nlink) {
|
||||
/* The inode has zero nlink but its nodes weren't yet marked
|
||||
obsolete. This has to be because we're still waiting for
|
||||
obsolete. This has to be because we're still waiting for
|
||||
the final (close() and) iput() to happen.
|
||||
|
||||
There's a possibility that the final iput() could have
|
||||
There's a possibility that the final iput() could have
|
||||
happened while we were contemplating. In order to ensure
|
||||
that we don't cause a new read_inode() (which would fail)
|
||||
for the inode in question, we use ilookup() in this case
|
||||
instead of iget().
|
||||
|
||||
The nlink can't _become_ zero at this point because we're
|
||||
The nlink can't _become_ zero at this point because we're
|
||||
holding the alloc_sem, and jffs2_do_unlink() would also
|
||||
need that while decrementing nlink on any inode.
|
||||
*/
|
||||
@ -599,19 +599,19 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
|
||||
return JFFS2_INODE_INFO(inode);
|
||||
}
|
||||
|
||||
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_info *f,
|
||||
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_info *f,
|
||||
unsigned long offset,
|
||||
unsigned long *priv)
|
||||
{
|
||||
struct inode *inode = OFNI_EDONI_2SFFJ(f);
|
||||
struct page *pg;
|
||||
|
||||
pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
|
||||
pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
|
||||
(void *)jffs2_do_readpage_unlock, inode);
|
||||
if (IS_ERR(pg))
|
||||
return (void *)pg;
|
||||
|
||||
|
||||
*priv = (unsigned long)pg;
|
||||
return kmap(pg);
|
||||
}
|
||||
@ -628,7 +628,7 @@ void jffs2_gc_release_page(struct jffs2_sb_info *c,
|
||||
|
||||
static int jffs2_flash_setup(struct jffs2_sb_info *c) {
|
||||
int ret = 0;
|
||||
|
||||
|
||||
if (jffs2_cleanmarker_oob(c)) {
|
||||
/* NAND flash... do setup accordingly */
|
||||
ret = jffs2_nand_flash_setup(c);
|
||||
@ -642,7 +642,7 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) {
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* and Dataflash */
|
||||
if (jffs2_dataflash(c)) {
|
||||
ret = jffs2_dataflash_setup(c);
|
||||
@ -670,7 +670,7 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
|
||||
if (jffs2_nor_ecc(c)) {
|
||||
jffs2_nor_ecc_flash_cleanup(c);
|
||||
}
|
||||
|
||||
|
||||
/* and DataFlash */
|
||||
if (jffs2_dataflash(c)) {
|
||||
jffs2_dataflash_cleanup(c);
|
||||
|
112
fs/jffs2/gc.c
112
fs/jffs2/gc.c
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: gc.c,v 1.154 2005/09/07 08:34:54 havasi Exp $
|
||||
* $Id: gc.c,v 1.155 2005/11/07 11:14:39 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -21,14 +21,14 @@
|
||||
#include "nodelist.h"
|
||||
#include "compr.h"
|
||||
|
||||
static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
|
||||
static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_cache *ic,
|
||||
struct jffs2_raw_node_ref *raw);
|
||||
static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_inode_info *f, struct jffs2_full_dnode *fd);
|
||||
static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
|
||||
static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
|
||||
static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
|
||||
@ -55,7 +55,7 @@ again:
|
||||
D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
|
||||
nextlist = &c->bad_used_list;
|
||||
} else if (n < 50 && !list_empty(&c->erasable_list)) {
|
||||
/* Note that most of them will have gone directly to be erased.
|
||||
/* 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;
|
||||
@ -101,7 +101,7 @@ again:
|
||||
printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset);
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
/* Have we accidentally picked a clean block with wasted space ? */
|
||||
if (ret->wasted_size) {
|
||||
D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size));
|
||||
@ -136,7 +136,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
|
||||
|
||||
/* We can't start doing GC yet. We haven't finished checking
|
||||
the node CRCs etc. Do it now. */
|
||||
|
||||
|
||||
/* checked_ino is protected by the alloc_sem */
|
||||
if (c->checked_ino > c->highest_ino) {
|
||||
printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
|
||||
@ -178,7 +178,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
|
||||
|
||||
case INO_STATE_READING:
|
||||
/* We need to wait for it to finish, lest we move on
|
||||
and trigger the BUG() above while we haven't yet
|
||||
and trigger the BUG() above while we haven't yet
|
||||
finished checking all its nodes */
|
||||
D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
|
||||
up(&c->alloc_sem);
|
||||
@ -228,13 +228,13 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
|
||||
}
|
||||
|
||||
raw = jeb->gc_node;
|
||||
|
||||
|
||||
while(ref_obsolete(raw)) {
|
||||
D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw)));
|
||||
raw = raw->next_phys;
|
||||
if (unlikely(!raw)) {
|
||||
printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");
|
||||
printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
|
||||
printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
|
||||
jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
|
||||
jeb->gc_node = raw;
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
@ -259,7 +259,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
|
||||
ic = jffs2_raw_ref_to_ic(raw);
|
||||
|
||||
/* We need to hold the inocache. Either the erase_completion_lock or
|
||||
the inocache_lock are sufficient; we trade down since the inocache_lock
|
||||
the inocache_lock are sufficient; we trade down since the inocache_lock
|
||||
causes less contention. */
|
||||
spin_lock(&c->inocache_lock);
|
||||
|
||||
@ -278,14 +278,14 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
|
||||
|
||||
switch(ic->state) {
|
||||
case INO_STATE_CHECKEDABSENT:
|
||||
/* It's been checked, but it's not currently in-core.
|
||||
/* It's been checked, but it's not currently in-core.
|
||||
We can just copy any pristine nodes, but have
|
||||
to prevent anyone else from doing read_inode() while
|
||||
we're at it, so we set the state accordingly */
|
||||
if (ref_flags(raw) == REF_PRISTINE)
|
||||
ic->state = INO_STATE_GC;
|
||||
else {
|
||||
D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
|
||||
D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
|
||||
ic->ino));
|
||||
}
|
||||
break;
|
||||
@ -298,8 +298,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
|
||||
case INO_STATE_CHECKING:
|
||||
case INO_STATE_GC:
|
||||
/* Should never happen. We should have finished checking
|
||||
by the time we actually start doing any GC, and since
|
||||
we're holding the alloc_sem, no other garbage collection
|
||||
by the time we actually start doing any GC, and since
|
||||
we're holding the alloc_sem, no other garbage collection
|
||||
can happen.
|
||||
*/
|
||||
printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
|
||||
@ -319,21 +319,21 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
|
||||
D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",
|
||||
ic->ino, ic->state));
|
||||
sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
|
||||
/* And because we dropped the alloc_sem we must start again from the
|
||||
/* And because we dropped the alloc_sem we must start again from the
|
||||
beginning. Ponder chance of livelock here -- we're returning success
|
||||
without actually making any progress.
|
||||
|
||||
Q: What are the chances that the inode is back in INO_STATE_READING
|
||||
Q: What are the chances that the inode is back in INO_STATE_READING
|
||||
again by the time we next enter this function? And that this happens
|
||||
enough times to cause a real delay?
|
||||
|
||||
A: Small enough that I don't care :)
|
||||
A: Small enough that I don't care :)
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the
|
||||
node intact, and we don't have to muck about with the fragtree etc.
|
||||
node intact, and we don't have to muck about with the fragtree etc.
|
||||
because we know it's not in-core. If it _was_ in-core, we go through
|
||||
all the iget() crap anyway */
|
||||
|
||||
@ -453,7 +453,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
|
||||
if (!ret) {
|
||||
/* Urgh. Return it sensibly. */
|
||||
frag->node->raw = f->inocache->nodes;
|
||||
}
|
||||
}
|
||||
if (ret != -EBADFD)
|
||||
goto upnout;
|
||||
}
|
||||
@ -467,7 +467,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
|
||||
}
|
||||
goto upnout;
|
||||
}
|
||||
|
||||
|
||||
/* Wasn't a dnode. Try dirent */
|
||||
for (fd = f->dents; fd; fd=fd->next) {
|
||||
if (fd->raw == raw)
|
||||
@ -494,7 +494,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
|
||||
static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_cache *ic,
|
||||
struct jffs2_raw_node_ref *raw)
|
||||
{
|
||||
@ -580,7 +580,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
|
||||
printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
|
||||
ref_offset(raw), je16_to_cpu(node->u.nodetype));
|
||||
goto bail;
|
||||
}
|
||||
@ -621,7 +621,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
|
||||
retried = 1;
|
||||
|
||||
D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n"));
|
||||
|
||||
|
||||
jffs2_dbg_acct_sanity_check(c,jeb);
|
||||
jffs2_dbg_acct_paranoia_check(c, jeb);
|
||||
|
||||
@ -669,7 +669,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
|
||||
goto out_node;
|
||||
}
|
||||
|
||||
static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
|
||||
{
|
||||
struct jffs2_full_dnode *new_fn;
|
||||
@ -684,7 +684,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
|
||||
S_ISCHR(JFFS2_F_I_MODE(f)) ) {
|
||||
/* For these, we don't actually need to read the old node */
|
||||
/* FIXME: for minor or major > 255. */
|
||||
dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
|
||||
dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
|
||||
JFFS2_F_I_RDEV_MIN(f)));
|
||||
mdata = (char *)&dev;
|
||||
mdatalen = sizeof(dev);
|
||||
@ -705,7 +705,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
|
||||
D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen));
|
||||
|
||||
}
|
||||
|
||||
|
||||
ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen,
|
||||
JFFS2_SUMMARY_INODE_SIZE);
|
||||
if (ret) {
|
||||
@ -713,7 +713,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
|
||||
sizeof(ri)+ mdatalen, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
last_frag = frag_last(&f->fragtree);
|
||||
if (last_frag)
|
||||
/* Fetch the inode length from the fragtree rather then
|
||||
@ -721,7 +721,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
|
||||
ilen = last_frag->ofs + last_frag->size;
|
||||
else
|
||||
ilen = JFFS2_F_I_SIZE(f);
|
||||
|
||||
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
|
||||
ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
|
||||
@ -760,7 +760,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
|
||||
{
|
||||
struct jffs2_full_dirent *new_fd;
|
||||
@ -781,12 +781,12 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
|
||||
so refrain from splatting them. */
|
||||
if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f))
|
||||
rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f));
|
||||
else
|
||||
else
|
||||
rd.mctime = cpu_to_je32(0);
|
||||
rd.type = fd->type;
|
||||
rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
|
||||
rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
|
||||
|
||||
|
||||
ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen,
|
||||
JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize));
|
||||
if (ret) {
|
||||
@ -804,7 +804,7 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
|
||||
{
|
||||
struct jffs2_full_dirent **fdp = &f->dents;
|
||||
@ -843,7 +843,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
|
||||
if (ref_totlen(c, NULL, raw) != rawlen)
|
||||
continue;
|
||||
|
||||
/* Doesn't matter if there's one in the same erase block. We're going to
|
||||
/* Doesn't matter if there's one in the same erase block. We're going to
|
||||
delete it too at the same time. */
|
||||
if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
|
||||
continue;
|
||||
@ -895,7 +895,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
|
||||
kfree(rd);
|
||||
}
|
||||
|
||||
/* FIXME: If we're deleting a dirent which contains the current mtime and ctime,
|
||||
/* FIXME: If we're deleting a dirent which contains the current mtime and ctime,
|
||||
we should update the metadata node with those times accordingly */
|
||||
|
||||
/* No need for it any more. Just mark it obsolete and remove it from the list */
|
||||
@ -927,13 +927,13 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
|
||||
|
||||
D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
|
||||
f->inocache->ino, start, end));
|
||||
|
||||
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
|
||||
if(fn->frags > 1) {
|
||||
size_t readlen;
|
||||
uint32_t crc;
|
||||
/* It's partially obsoleted by a later write. So we have to
|
||||
/* It's partially obsoleted by a later write. So we have to
|
||||
write it out again with the _same_ version as before */
|
||||
ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);
|
||||
if (readlen != sizeof(ri) || ret) {
|
||||
@ -955,16 +955,16 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
|
||||
crc = crc32(0, &ri, sizeof(ri)-8);
|
||||
if (crc != je32_to_cpu(ri.node_crc)) {
|
||||
printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",
|
||||
ref_offset(fn->raw),
|
||||
ref_offset(fn->raw),
|
||||
je32_to_cpu(ri.node_crc), crc);
|
||||
/* FIXME: We could possibly deal with this by writing new holes for each frag */
|
||||
printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
|
||||
printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
|
||||
start, end, f->inocache->ino);
|
||||
goto fill;
|
||||
}
|
||||
if (ri.compr != JFFS2_COMPR_ZERO) {
|
||||
printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw));
|
||||
printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
|
||||
printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
|
||||
start, end, f->inocache->ino);
|
||||
goto fill;
|
||||
}
|
||||
@ -982,7 +982,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
|
||||
ri.csize = cpu_to_je32(0);
|
||||
ri.compr = JFFS2_COMPR_ZERO;
|
||||
}
|
||||
|
||||
|
||||
frag = frag_last(&f->fragtree);
|
||||
if (frag)
|
||||
/* Fetch the inode length from the fragtree rather then
|
||||
@ -1024,10 +1024,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
|
||||
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;'
|
||||
* number as before. (Except in case of error -- see 'goto fill;'
|
||||
* above.)
|
||||
*/
|
||||
D1(if(unlikely(fn->frags <= 1)) {
|
||||
@ -1039,7 +1039,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
|
||||
/* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */
|
||||
mark_ref_normal(new_fn->raw);
|
||||
|
||||
for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
|
||||
for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
|
||||
frag; frag = frag_next(frag)) {
|
||||
if (frag->ofs > fn->size + fn->ofs)
|
||||
break;
|
||||
@ -1057,10 +1057,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
|
||||
printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
jffs2_mark_node_obsolete(c, fn->raw);
|
||||
jffs2_free_full_dnode(fn);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1070,12 +1070,12 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
|
||||
{
|
||||
struct jffs2_full_dnode *new_fn;
|
||||
struct jffs2_raw_inode ri;
|
||||
uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
|
||||
uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
|
||||
int ret = 0;
|
||||
unsigned char *comprbuf = NULL, *writebuf;
|
||||
unsigned long pg;
|
||||
unsigned char *pg_ptr;
|
||||
|
||||
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
|
||||
D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n",
|
||||
@ -1087,8 +1087,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
|
||||
if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) {
|
||||
/* Attempt to do some merging. But only expand to cover logically
|
||||
adjacent frags if the block containing them is already considered
|
||||
to be dirty. Otherwise we end up with GC just going round in
|
||||
circles dirtying the nodes it already wrote out, especially
|
||||
to be dirty. Otherwise we end up with GC just going round in
|
||||
circles dirtying the nodes it already wrote out, especially
|
||||
on NAND where we have small eraseblocks and hence a much higher
|
||||
chance of nodes having to be split to cross boundaries. */
|
||||
|
||||
@ -1122,7 +1122,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
|
||||
break;
|
||||
} else {
|
||||
|
||||
/* OK, it's a frag which extends to the beginning of the page. Does it live
|
||||
/* OK, it's a frag which extends to the beginning of the page. Does it live
|
||||
in a block which is still considered clean? If so, don't obsolete it.
|
||||
If not, cover it anyway. */
|
||||
|
||||
@ -1172,7 +1172,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
|
||||
break;
|
||||
} else {
|
||||
|
||||
/* OK, it's a frag which extends to the beginning of the page. Does it live
|
||||
/* OK, it's a frag which extends to the beginning of the page. Does it live
|
||||
in a block which is still considered clean? If so, don't obsolete it.
|
||||
If not, cover it anyway. */
|
||||
|
||||
@ -1199,14 +1199,14 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
|
||||
break;
|
||||
}
|
||||
}
|
||||
D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
|
||||
D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
|
||||
orig_start, orig_end, start, end));
|
||||
|
||||
D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size));
|
||||
BUG_ON(end < orig_end);
|
||||
BUG_ON(start > orig_start);
|
||||
}
|
||||
|
||||
|
||||
/* First, use readpage() to read the appropriate page into the page cache */
|
||||
/* Q: What happens if we actually try to GC the _same_ page for which commit_write()
|
||||
* triggered garbage collection in the first place?
|
||||
@ -1263,7 +1263,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
|
||||
ri.usercompr = (comprtype >> 8) & 0xff;
|
||||
ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
|
||||
ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
|
||||
|
||||
|
||||
new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC);
|
||||
|
||||
jffs2_free_comprbuf(comprbuf, writebuf);
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* This file provides the bit-probabilities for the input file */
|
||||
#define BIT_DIVIDER 629
|
||||
#define BIT_DIVIDER 629
|
||||
static int bits[9] = { 179,167,183,165,159,198,178,119,}; /* ia32 .so files */
|
||||
|
@ -1,2 +1,2 @@
|
||||
#define BIT_DIVIDER_MIPS 1043
|
||||
#define BIT_DIVIDER_MIPS 1043
|
||||
static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */
|
||||
|
@ -7,17 +7,17 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: ioctl.c,v 1.9 2004/11/16 20:36:11 dwmw2 Exp $
|
||||
* $Id: ioctl.c,v 1.10 2005/11/07 11:14:40 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
/* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which
|
||||
will include compression support etc. */
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: malloc.c,v 1.30 2005/09/20 14:27:34 dedekind Exp $
|
||||
* $Id: malloc.c,v 1.31 2005/11/07 11:14:40 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -29,7 +29,7 @@ static kmem_cache_t *inode_cache_slab;
|
||||
|
||||
int __init jffs2_create_slab_caches(void)
|
||||
{
|
||||
full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
|
||||
full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
|
||||
sizeof(struct jffs2_full_dnode),
|
||||
0, 0, NULL, NULL);
|
||||
if (!full_dnode_slab)
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: nodelist.c,v 1.114 2005/09/21 13:28:35 dedekind Exp $
|
||||
* $Id: nodelist.c,v 1.115 2005/11/07 11:14:40 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
|
||||
{
|
||||
struct jffs2_full_dirent **prev = list;
|
||||
|
||||
|
||||
dbg_dentlist("add dirent \"%s\", ino #%u\n", new->name, new->ino);
|
||||
|
||||
while ((*prev) && (*prev)->nhash <= new->nhash) {
|
||||
@ -75,14 +75,14 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
/*
|
||||
* If the last fragment starts at the RAM page boundary, it is
|
||||
* REF_PRISTINE irrespective of its size.
|
||||
*/
|
||||
frag = frag_last(list);
|
||||
if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) {
|
||||
dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n",
|
||||
frag->ofs, frag->ofs + frag->size);
|
||||
frag->ofs, frag->ofs + frag->size);
|
||||
frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE;
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,7 @@ void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *t
|
||||
ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, this->node->frags);
|
||||
mark_ref_normal(this->node->raw);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
jffs2_free_node_frag(this);
|
||||
}
|
||||
@ -117,7 +117,7 @@ static void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_
|
||||
while (*link) {
|
||||
parent = *link;
|
||||
base = rb_entry(parent, struct jffs2_node_frag, rb);
|
||||
|
||||
|
||||
if (newfrag->ofs > base->ofs)
|
||||
link = &base->rb.rb_right;
|
||||
else if (newfrag->ofs < base->ofs)
|
||||
@ -137,7 +137,7 @@ static void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_
|
||||
static inline struct jffs2_node_frag * new_fragment(struct jffs2_full_dnode *fn, uint32_t ofs, uint32_t size)
|
||||
{
|
||||
struct jffs2_node_frag *newfrag;
|
||||
|
||||
|
||||
newfrag = jffs2_alloc_node_frag();
|
||||
if (likely(newfrag)) {
|
||||
newfrag->ofs = ofs;
|
||||
@ -169,7 +169,7 @@ static int no_overlapping_node(struct jffs2_sb_info *c, struct rb_root *root,
|
||||
}
|
||||
|
||||
if (this) {
|
||||
/* By definition, the 'this' node has no right-hand child,
|
||||
/* By definition, the 'this' node has no right-hand child,
|
||||
because there are no frags with offset greater than it.
|
||||
So that's where we want to put the hole */
|
||||
dbg_fragtree2("add hole frag %#04x-%#04x on the right of the new frag.\n",
|
||||
@ -183,13 +183,13 @@ static int no_overlapping_node(struct jffs2_sb_info *c, struct rb_root *root,
|
||||
rb_insert_color(&holefrag->rb, root);
|
||||
this = holefrag;
|
||||
}
|
||||
|
||||
|
||||
if (this) {
|
||||
/* By definition, the 'this' node has no right-hand child,
|
||||
/* By definition, the 'this' node has no right-hand child,
|
||||
because there are no frags with offset greater than it.
|
||||
So that's where we want to put new fragment */
|
||||
dbg_fragtree2("add the new node at the right\n");
|
||||
rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
|
||||
rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
|
||||
} else {
|
||||
dbg_fragtree2("insert the new node at the root of the tree\n");
|
||||
rb_link_node(&newfrag->rb, NULL, &root->rb_node);
|
||||
@ -216,7 +216,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
dbg_fragtree2("lookup gave no frag\n");
|
||||
lastend = 0;
|
||||
}
|
||||
|
||||
|
||||
/* See if we ran off the end of the fragtree */
|
||||
if (lastend <= newfrag->ofs) {
|
||||
/* We did */
|
||||
@ -243,7 +243,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
this->ofs, this->ofs + this->size);
|
||||
|
||||
/* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
|
||||
* - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
|
||||
* - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
|
||||
*/
|
||||
if (newfrag->ofs > this->ofs) {
|
||||
/* This node isn't completely obsoleted. The start of it remains valid */
|
||||
@ -261,10 +261,10 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
if (this->node)
|
||||
dbg_fragtree2("split old frag 0x%04x-0x%04x, phys 0x%08x\n",
|
||||
this->ofs, this->ofs+this->size, ref_offset(this->node->raw));
|
||||
else
|
||||
else
|
||||
dbg_fragtree2("split old hole frag 0x%04x-0x%04x\n",
|
||||
this->ofs, this->ofs+this->size);
|
||||
|
||||
|
||||
/* New second frag pointing to this's node */
|
||||
newfrag2 = new_fragment(this->node, newfrag->ofs + newfrag->size,
|
||||
this->ofs + this->size - newfrag->ofs - newfrag->size);
|
||||
@ -284,10 +284,10 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
from newfrag to insert newfrag2. */
|
||||
jffs2_fragtree_insert(newfrag, this);
|
||||
rb_insert_color(&newfrag->rb, root);
|
||||
|
||||
|
||||
jffs2_fragtree_insert(newfrag2, newfrag);
|
||||
rb_insert_color(&newfrag2->rb, root);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* New node just reduces 'this' frag in size, doesn't split it */
|
||||
@ -297,13 +297,13 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
jffs2_fragtree_insert(newfrag, this);
|
||||
rb_insert_color(&newfrag->rb, root);
|
||||
} else {
|
||||
/* New frag starts at the same point as 'this' used to. Replace
|
||||
/* New frag starts at the same point as 'this' used to. Replace
|
||||
it in the tree without doing a delete and insertion */
|
||||
dbg_fragtree2("inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
|
||||
newfrag, newfrag->ofs, newfrag->ofs+newfrag->size, this, this->ofs, this->ofs+this->size);
|
||||
|
||||
|
||||
rb_replace_node(&this->rb, &newfrag->rb, root);
|
||||
|
||||
|
||||
if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
|
||||
dbg_fragtree2("obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size);
|
||||
jffs2_obsolete_node_frag(c, this);
|
||||
@ -317,7 +317,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
}
|
||||
}
|
||||
/* OK, now we have newfrag added in the correct place in the tree, but
|
||||
frag_next(newfrag) may be a fragment which is overlapped by it
|
||||
frag_next(newfrag) may be a fragment which is overlapped by it
|
||||
*/
|
||||
while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
|
||||
/* 'this' frag is obsoleted completely. */
|
||||
@ -326,7 +326,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
rb_erase(&this->rb, root);
|
||||
jffs2_obsolete_node_frag(c, this);
|
||||
}
|
||||
/* Now we're pointing at the first frag which isn't totally obsoleted by
|
||||
/* Now we're pointing at the first frag which isn't totally obsoleted by
|
||||
the new frag */
|
||||
|
||||
if (!this || newfrag->ofs + newfrag->size == this->ofs)
|
||||
@ -344,7 +344,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Given an inode, probably with existing tree of fragments, add the new node
|
||||
* to the fragment tree.
|
||||
*/
|
||||
@ -363,7 +363,7 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in
|
||||
|
||||
dbg_fragtree("adding node %#04x-%#04x @0x%08x on flash, newfrag *%p\n",
|
||||
fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
|
||||
|
||||
|
||||
ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
@ -374,14 +374,14 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in
|
||||
struct jffs2_node_frag *prev = frag_prev(newfrag);
|
||||
|
||||
mark_ref_normal(fn->raw);
|
||||
/* If we don't start at zero there's _always_ a previous */
|
||||
/* If we don't start at zero there's _always_ a previous */
|
||||
if (prev->node)
|
||||
mark_ref_normal(prev->node->raw);
|
||||
}
|
||||
|
||||
if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
|
||||
struct jffs2_node_frag *next = frag_next(newfrag);
|
||||
|
||||
|
||||
if (next) {
|
||||
mark_ref_normal(fn->raw);
|
||||
if (next->node)
|
||||
@ -412,7 +412,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
|
||||
|
||||
if (!jffs2_is_writebuffered(c))
|
||||
goto adj_acc;
|
||||
|
||||
|
||||
/* Calculate how many bytes were already checked */
|
||||
ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode);
|
||||
len = ofs % c->wbuf_pagesize;
|
||||
@ -424,13 +424,13 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
|
||||
ref_offset(ref), tn->csize, ofs);
|
||||
goto adj_acc;
|
||||
}
|
||||
|
||||
|
||||
ofs += len;
|
||||
len = tn->csize - len;
|
||||
|
||||
|
||||
dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
|
||||
ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);
|
||||
|
||||
|
||||
#ifndef __ECOS
|
||||
/* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
|
||||
* adding and jffs2_flash_read_end() interface. */
|
||||
@ -445,12 +445,12 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
|
||||
pointed = 1; /* succefully pointed to device */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (!pointed) {
|
||||
buffer = kmalloc(len, GFP_KERNEL);
|
||||
if (unlikely(!buffer))
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
/* TODO: this is very frequent pattern, make it a separate
|
||||
* routine */
|
||||
err = jffs2_flash_read(c, ofs, len, &retlen, buffer);
|
||||
@ -458,7 +458,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
|
||||
JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err);
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
|
||||
if (retlen != len) {
|
||||
JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ofs, retlen, len);
|
||||
err = -EIO;
|
||||
@ -485,7 +485,7 @@ adj_acc:
|
||||
jeb = &c->blocks[ref->flash_offset / c->sector_size];
|
||||
len = ref_totlen(c, jeb, ref);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Mark the node as having been checked and fix the
|
||||
* accounting accordingly.
|
||||
*/
|
||||
@ -516,13 +516,13 @@ free_out:
|
||||
static inline int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
BUG_ON(ref_obsolete(tn->fn->raw));
|
||||
|
||||
/* We only check the data CRC of unchecked nodes */
|
||||
if (ref_flags(tn->fn->raw) != REF_UNCHECKED)
|
||||
return 0;
|
||||
|
||||
|
||||
dbg_fragtree2("check node %#04x-%#04x, phys offs %#08x.\n",
|
||||
tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw));
|
||||
|
||||
@ -538,7 +538,7 @@ static inline int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Helper function for jffs2_add_older_frag_to_fragtree().
|
||||
*
|
||||
* Called when the new fragment that is being inserted
|
||||
@ -551,31 +551,31 @@ static int split_hole(struct jffs2_sb_info *c, struct rb_root *root,
|
||||
newfrag->ofs, newfrag->ofs + newfrag->size, hole->ofs, hole->ofs + hole->size);
|
||||
|
||||
if (hole->ofs == newfrag->ofs) {
|
||||
/*
|
||||
/*
|
||||
* Well, the new fragment actually starts at the same offset as
|
||||
* the hole.
|
||||
*/
|
||||
if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) {
|
||||
/*
|
||||
/*
|
||||
* We replace the overlapped left part of the hole by
|
||||
* the new node.
|
||||
*/
|
||||
|
||||
|
||||
dbg_fragtree2("insert fragment %#04x-%#04x and cut the left part of the hole\n",
|
||||
newfrag->ofs, newfrag->ofs + newfrag->size);
|
||||
rb_replace_node(&hole->rb, &newfrag->rb, root);
|
||||
|
||||
|
||||
hole->ofs += newfrag->size;
|
||||
hole->size -= newfrag->size;
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
* We know that 'hole' should be the right hand
|
||||
* fragment.
|
||||
*/
|
||||
jffs2_fragtree_insert(hole, newfrag);
|
||||
rb_insert_color(&hole->rb, root);
|
||||
} else {
|
||||
/*
|
||||
/*
|
||||
* Ah, the new fragment is of the same size as the hole.
|
||||
* Relace the hole by it.
|
||||
*/
|
||||
@ -586,7 +586,7 @@ static int split_hole(struct jffs2_sb_info *c, struct rb_root *root,
|
||||
}
|
||||
} else {
|
||||
/* The new fragment lefts some hole space at the left */
|
||||
|
||||
|
||||
struct jffs2_node_frag * newfrag2 = NULL;
|
||||
|
||||
if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) {
|
||||
@ -606,7 +606,7 @@ static int split_hole(struct jffs2_sb_info *c, struct rb_root *root,
|
||||
|
||||
jffs2_fragtree_insert(newfrag, hole);
|
||||
rb_insert_color(&newfrag->rb, root);
|
||||
|
||||
|
||||
if (newfrag2) {
|
||||
dbg_fragtree2("left the hole %#04x-%#04x at the right\n",
|
||||
newfrag2->ofs, newfrag2->ofs + newfrag2->size);
|
||||
@ -654,18 +654,18 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
lastend = this->ofs + this->size;
|
||||
else
|
||||
lastend = 0;
|
||||
|
||||
|
||||
/* Detect the preliminary type of node */
|
||||
if (fn->size >= PAGE_CACHE_SIZE)
|
||||
ref_flag = REF_PRISTINE;
|
||||
else
|
||||
ref_flag = REF_NORMAL;
|
||||
|
||||
|
||||
/* See if we ran off the end of the root */
|
||||
if (lastend <= fn_ofs) {
|
||||
/* We did */
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
* We are going to insert the new node into the
|
||||
* fragment tree, so check it.
|
||||
*/
|
||||
@ -691,21 +691,21 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
fn->frags = 0;
|
||||
|
||||
while (1) {
|
||||
/*
|
||||
/*
|
||||
* Here we have:
|
||||
* fn_ofs < this->ofs + this->size && fn_ofs >= this->ofs.
|
||||
*
|
||||
*
|
||||
* Remember, 'this' has higher version, any non-hole node
|
||||
* which is already in the fragtree is newer then the newly
|
||||
* inserted.
|
||||
*/
|
||||
if (!this->node) {
|
||||
/*
|
||||
/*
|
||||
* 'this' is the hole fragment, so at least the
|
||||
* beginning of the new fragment is valid.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
* We are going to insert the new node into the
|
||||
* fragment tree, so check it.
|
||||
*/
|
||||
@ -715,7 +715,7 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
return err;
|
||||
checked = 1;
|
||||
}
|
||||
|
||||
|
||||
if (this->ofs + this->size >= fn_ofs + fn_size) {
|
||||
/* We split the hole on two parts */
|
||||
|
||||
@ -730,7 +730,7 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
goto out_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* The beginning of the new fragment is valid since it
|
||||
* overlaps the hole node.
|
||||
*/
|
||||
@ -742,9 +742,9 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
this->ofs + this->size - fn_ofs);
|
||||
if (unlikely(!newfrag))
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
if (fn_ofs == this->ofs) {
|
||||
/*
|
||||
/*
|
||||
* The new node starts at the same offset as
|
||||
* the hole and supersieds the hole.
|
||||
*/
|
||||
@ -754,21 +754,21 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
rb_replace_node(&this->rb, &newfrag->rb, root);
|
||||
jffs2_free_node_frag(this);
|
||||
} else {
|
||||
/*
|
||||
/*
|
||||
* The hole becomes shorter as its right part
|
||||
* is supersieded by the new fragment.
|
||||
*/
|
||||
dbg_fragtree2("reduce size of hole %#04x-%#04x to %#04x-%#04x\n",
|
||||
this->ofs, this->ofs + this->size, this->ofs, this->ofs + this->size - newfrag->size);
|
||||
|
||||
|
||||
dbg_fragtree2("add new fragment %#04x-%#04x, refcnt %d\n", fn_ofs,
|
||||
fn_ofs + this->ofs + this->size - fn_ofs, fn->frags);
|
||||
|
||||
|
||||
this->size -= newfrag->size;
|
||||
jffs2_fragtree_insert(newfrag, this);
|
||||
rb_insert_color(&newfrag->rb, root);
|
||||
}
|
||||
|
||||
|
||||
fn_ofs += newfrag->size;
|
||||
fn_size -= newfrag->size;
|
||||
this = rb_entry(rb_next(&newfrag->rb),
|
||||
@ -778,7 +778,7 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
this->ofs, this->ofs + this->size, this->node ? "(data)" : "(hole)");
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 'This' node is not the hole so it obsoletes the new fragment
|
||||
* either fully or partially.
|
||||
*/
|
||||
@ -791,19 +791,19 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
goto out_ok;
|
||||
} else {
|
||||
struct jffs2_node_frag *new_this;
|
||||
|
||||
|
||||
/* 'This' node obsoletes the beginning of the new node */
|
||||
dbg_fragtree2("the beginning %#04x-%#04x is obsolete\n", fn_ofs, this->ofs + this->size);
|
||||
|
||||
ref_flag = REF_NORMAL;
|
||||
|
||||
|
||||
fn_size -= this->ofs + this->size - fn_ofs;
|
||||
fn_ofs = this->ofs + this->size;
|
||||
dbg_fragtree2("now considering %#04x-%#04x\n", fn_ofs, fn_ofs + fn_size);
|
||||
|
||||
|
||||
new_this = rb_entry(rb_next(&this->rb), struct jffs2_node_frag, rb);
|
||||
if (!new_this) {
|
||||
/*
|
||||
/*
|
||||
* There is no next fragment. Add the rest of
|
||||
* the new node as the right-hand child.
|
||||
*/
|
||||
@ -813,7 +813,7 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
return err;
|
||||
checked = 1;
|
||||
}
|
||||
|
||||
|
||||
fn->frags += 1;
|
||||
newfrag = new_fragment(fn, fn_ofs, fn_size);
|
||||
if (unlikely(!newfrag))
|
||||
@ -821,7 +821,7 @@ int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode
|
||||
|
||||
dbg_fragtree2("there are no more fragments, insert %#04x-%#04x\n",
|
||||
newfrag->ofs, newfrag->ofs + newfrag->size);
|
||||
rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
|
||||
rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
|
||||
rb_insert_color(&newfrag->rb, root);
|
||||
goto out_ok;
|
||||
} else {
|
||||
@ -862,9 +862,9 @@ void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache
|
||||
|
||||
/* During mount, this needs no locking. During normal operation, its
|
||||
callers want to do other stuff while still holding the inocache_lock.
|
||||
Rather than introducing special case get_ino_cache functions or
|
||||
Rather than introducing special case get_ino_cache functions or
|
||||
callbacks, we just let the caller do the locking itself. */
|
||||
|
||||
|
||||
struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
|
||||
{
|
||||
struct jffs2_inode_cache *ret;
|
||||
@ -873,7 +873,7 @@ struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t
|
||||
while (ret && ret->ino < ino) {
|
||||
ret = ret->next;
|
||||
}
|
||||
|
||||
|
||||
if (ret && ret->ino != ino)
|
||||
ret = NULL;
|
||||
|
||||
@ -907,9 +907,9 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
|
||||
|
||||
dbg_inocache("del %p (ino #%u)\n", old, old->ino);
|
||||
spin_lock(&c->inocache_lock);
|
||||
|
||||
|
||||
prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
|
||||
|
||||
|
||||
while ((*prev) && (*prev)->ino < old->ino) {
|
||||
prev = &(*prev)->next;
|
||||
}
|
||||
@ -919,7 +919,7 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
|
||||
|
||||
/* Free it now unless it's in READING or CLEARING state, which
|
||||
are the transitions upon read_inode() and clear_inode(). The
|
||||
rest of the time we know nobody else is looking at it, and
|
||||
rest of the time we know nobody else is looking at it, and
|
||||
if it's held by read_inode() or clear_inode() they'll free it
|
||||
for themselves. */
|
||||
if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
|
||||
@ -932,7 +932,7 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
|
||||
{
|
||||
int i;
|
||||
struct jffs2_inode_cache *this, *next;
|
||||
|
||||
|
||||
for (i=0; i<INOCACHE_HASHSIZE; i++) {
|
||||
this = c->inocache_list[i];
|
||||
while (this) {
|
||||
@ -959,10 +959,10 @@ void jffs2_free_raw_node_refs(struct jffs2_sb_info *c)
|
||||
c->blocks[i].first_node = c->blocks[i].last_node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
|
||||
{
|
||||
/* The common case in lookup is that there will be a node
|
||||
/* The common case in lookup is that there will be a node
|
||||
which precisely matches. So we go looking for that first */
|
||||
struct rb_node *next;
|
||||
struct jffs2_node_frag *prev = NULL;
|
||||
@ -993,9 +993,9 @@ struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_
|
||||
if (prev)
|
||||
dbg_fragtree2("no match. Returning frag %#04x-%#04x, closest previous\n",
|
||||
prev->ofs, prev->ofs+prev->size);
|
||||
else
|
||||
else
|
||||
dbg_fragtree2("returning NULL, empty fragtree\n");
|
||||
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
@ -1010,7 +1010,7 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
|
||||
return;
|
||||
|
||||
dbg_fragtree("killing\n");
|
||||
|
||||
|
||||
frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
|
||||
while(frag) {
|
||||
if (frag->rb.rb_left) {
|
||||
@ -1023,18 +1023,18 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
|
||||
}
|
||||
|
||||
if (frag->node && !(--frag->node->frags)) {
|
||||
/* Not a hole, and it's the final remaining frag
|
||||
/* Not a hole, and it's the final remaining frag
|
||||
of this node. Free the node */
|
||||
if (c)
|
||||
jffs2_mark_node_obsolete(c, frag->node->raw);
|
||||
|
||||
|
||||
jffs2_free_full_dnode(frag->node);
|
||||
}
|
||||
parent = frag_parent(frag);
|
||||
if (parent) {
|
||||
if (frag_left(parent) == frag)
|
||||
parent->rb.rb_left = NULL;
|
||||
else
|
||||
else
|
||||
parent->rb.rb_right = NULL;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@
|
||||
#define je16_to_cpu(x) (le16_to_cpu(x.v16))
|
||||
#define je32_to_cpu(x) (le32_to_cpu(x.v32))
|
||||
#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m)))
|
||||
#else
|
||||
#else
|
||||
#error wibble
|
||||
#endif
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
/*
|
||||
This is all we need to keep in-core for each raw node during normal
|
||||
operation. As and when we do read_inode on a particular inode, we can
|
||||
scan the nodes which are listed for it and build up a proper map of
|
||||
scan the nodes which are listed for it and build up a proper map of
|
||||
which nodes are currently valid. JFFSv1 always used to keep that whole
|
||||
map in core for each inode.
|
||||
*/
|
||||
@ -85,7 +85,7 @@ struct jffs2_raw_node_ref
|
||||
|
||||
/* flash_offset & 3 always has to be zero, because nodes are
|
||||
always aligned at 4 bytes. So we have a couple of extra bits
|
||||
to play with, which indicate the node's status; see below: */
|
||||
to play with, which indicate the node's status; see below: */
|
||||
#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */
|
||||
#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */
|
||||
#define REF_PRISTINE 2 /* Completely clean. GC without looking */
|
||||
@ -98,7 +98,7 @@ struct jffs2_raw_node_ref
|
||||
/* For each inode in the filesystem, we need to keep a record of
|
||||
nlink, because it would be a PITA to scan the whole directory tree
|
||||
at read_inode() time to calculate it, and to keep sufficient information
|
||||
in the raw_node_ref (basically both parent and child inode number for
|
||||
in the raw_node_ref (basically both parent and child inode number for
|
||||
dirent nodes) would take more space than this does. We also keep
|
||||
a pointer to the first physical node which is part of this inode, too.
|
||||
*/
|
||||
@ -128,7 +128,7 @@ struct jffs2_inode_cache {
|
||||
#define INOCACHE_HASHSIZE 128
|
||||
|
||||
/*
|
||||
Larger representation of a raw node, kept in-core only when the
|
||||
Larger representation of a raw node, kept in-core only when the
|
||||
struct inode for this particular ino is instantiated.
|
||||
*/
|
||||
|
||||
@ -138,11 +138,11 @@ struct jffs2_full_dnode
|
||||
uint32_t ofs; /* The offset to which the data of this node belongs */
|
||||
uint32_t size;
|
||||
uint32_t frags; /* Number of fragments which currently refer
|
||||
to this node. When this reaches zero,
|
||||
to this node. When this reaches zero,
|
||||
the node is obsolete. */
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
Even larger representation of a raw node, kept in-core only while
|
||||
we're actually building up the original map of which nodes go where,
|
||||
in read_inode()
|
||||
@ -155,7 +155,7 @@ struct jffs2_tmp_dnode_info
|
||||
uint32_t data_crc;
|
||||
uint32_t partial_crc;
|
||||
uint32_t csize;
|
||||
};
|
||||
};
|
||||
|
||||
struct jffs2_full_dirent
|
||||
{
|
||||
@ -169,7 +169,7 @@ struct jffs2_full_dirent
|
||||
};
|
||||
|
||||
/*
|
||||
Fragments - used to build a map of which raw node to obtain
|
||||
Fragments - used to build a map of which raw node to obtain
|
||||
data from for each part of the ino
|
||||
*/
|
||||
struct jffs2_node_frag
|
||||
@ -209,7 +209,7 @@ static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
|
||||
struct jffs2_raw_node_ref *ref)
|
||||
{
|
||||
uint32_t ref_end;
|
||||
|
||||
|
||||
if (ref->next_phys)
|
||||
ref_end = ref_offset(ref->next_phys);
|
||||
else {
|
||||
@ -264,7 +264,7 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
|
||||
#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2))
|
||||
|
||||
/* check if dirty space is more than 255 Byte */
|
||||
#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
|
||||
#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
|
||||
|
||||
#define PAD(x) (((x)+3)&~3)
|
||||
|
||||
@ -341,7 +341,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
|
||||
struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode);
|
||||
struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode);
|
||||
int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
struct jffs2_raw_inode *ri, unsigned char *buf,
|
||||
struct jffs2_raw_inode *ri, unsigned char *buf,
|
||||
uint32_t offset, uint32_t writelen, uint32_t *retlen);
|
||||
int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen);
|
||||
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, uint32_t time);
|
||||
@ -349,7 +349,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
|
||||
|
||||
|
||||
/* readinode.c */
|
||||
int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
uint32_t ino, struct jffs2_raw_inode *latest_node);
|
||||
int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
|
||||
void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
|
||||
|
@ -88,12 +88,12 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
|
||||
up(&c->alloc_sem);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
||||
/* Calc possibly available space. Possibly available means that we
|
||||
* don't know, if unchecked size contains obsoleted nodes, which could give us some
|
||||
* more usable space. This will affect the sum only once, as gc first finishes checking
|
||||
* of nodes.
|
||||
+ Return -ENOSPC, if the maximum possibly available space is less or equal than
|
||||
+ Return -ENOSPC, if the maximum possibly available space is less or equal than
|
||||
* blocksneeded * sector_size.
|
||||
* This blocks endless gc looping on a filesystem, which is nearly full, even if
|
||||
* the check above passes.
|
||||
@ -118,7 +118,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
|
||||
c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size,
|
||||
c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
|
||||
|
||||
ret = jffs2_garbage_collect_pass(c);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -183,7 +183,7 @@ static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblo
|
||||
jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
|
||||
list_add_tail(&jeb->list, &c->dirty_list);
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_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->clean_list);
|
||||
@ -197,7 +197,7 @@ static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblo
|
||||
static int jffs2_find_nextblock(struct jffs2_sb_info *c)
|
||||
{
|
||||
struct list_head *next;
|
||||
|
||||
|
||||
/* Take the next block off the 'free' list */
|
||||
|
||||
if (list_empty(&c->free_list)) {
|
||||
@ -229,8 +229,8 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c)
|
||||
if (!c->nr_erasing_blocks) {
|
||||
/* Ouch. We're in GC, or we wouldn't have got here.
|
||||
And there's no space left. At all. */
|
||||
printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
|
||||
c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
|
||||
printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
|
||||
c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
|
||||
list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
|
||||
return -ENOSPC;
|
||||
}
|
||||
@ -250,7 +250,7 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c)
|
||||
list_del(next);
|
||||
c->nextblock = list_entry(next, struct jffs2_eraseblock, list);
|
||||
c->nr_free_blocks--;
|
||||
|
||||
|
||||
jffs2_sum_reset_collected(c->summary); /* reset collected summary */
|
||||
|
||||
D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset));
|
||||
@ -354,9 +354,9 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
|
||||
|
||||
if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
|
||||
!jeb->first_node->next_in_ino) {
|
||||
/* Only node in it beforehand was a CLEANMARKER node (we think).
|
||||
/* Only node in it beforehand was a CLEANMARKER node (we think).
|
||||
So mark it obsolete now that there's going to be another node
|
||||
in the block. This will reduce used_size to zero but We've
|
||||
in the block. This will reduce used_size to zero but We've
|
||||
already set c->nextblock so that jffs2_mark_node_obsolete()
|
||||
won't try to refile it to the dirty_list.
|
||||
*/
|
||||
@ -376,12 +376,12 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
|
||||
* @len: length of this physical node
|
||||
* @dirty: dirty flag for new node
|
||||
*
|
||||
* Should only be used to report nodes for which space has been allocated
|
||||
* Should only be used to report nodes for which space has been allocated
|
||||
* by jffs2_reserve_space.
|
||||
*
|
||||
* Must be called with the alloc_sem held.
|
||||
*/
|
||||
|
||||
|
||||
int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new)
|
||||
{
|
||||
struct jffs2_eraseblock *jeb;
|
||||
@ -488,8 +488,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
|
||||
if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
|
||||
!(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
|
||||
/* Hm. This may confuse static lock analysis. If any of the above
|
||||
three conditions is false, we're going to return from this
|
||||
/* Hm. This may confuse static lock analysis. If any of the above
|
||||
three conditions is false, we're going to return from this
|
||||
function without actually obliterating any nodes or freeing
|
||||
any jffs2_raw_node_refs. So we don't need to stop erases from
|
||||
happening, or protect against people holding an obsolete
|
||||
@ -546,17 +546,17 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
D1(printk(KERN_DEBUG "Wasting\n"));
|
||||
addedsize = 0;
|
||||
jeb->wasted_size += ref_totlen(c, jeb, ref);
|
||||
c->wasted_size += ref_totlen(c, jeb, ref);
|
||||
c->wasted_size += ref_totlen(c, jeb, ref);
|
||||
}
|
||||
ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
|
||||
|
||||
|
||||
jffs2_dbg_acct_sanity_check_nolock(c, jeb);
|
||||
jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
|
||||
|
||||
if (c->flags & JFFS2_SB_FLAG_SCANNING) {
|
||||
/* Flash scanning is in progress. Don't muck about with the block
|
||||
lists because they're not ready yet, and don't actually
|
||||
obliterate nodes that look obsolete. If they weren't
|
||||
obliterate nodes that look obsolete. If they weren't
|
||||
marked obsolete on the flash at the time they _became_
|
||||
obsolete, there was probably a reason for that. */
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
@ -590,7 +590,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
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) {
|
||||
@ -608,8 +608,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
list_add_tail(&jeb->list, &c->very_dirty_list);
|
||||
} else {
|
||||
D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
|
||||
jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
|
||||
}
|
||||
jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
|
||||
}
|
||||
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
|
||||
@ -656,11 +656,11 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
|
||||
/* Nodes which have been marked obsolete no longer need to be
|
||||
associated with any inode. Remove them from the per-inode list.
|
||||
|
||||
Note we can't do this for NAND at the moment because we need
|
||||
|
||||
Note we can't do this for NAND at the moment because we need
|
||||
obsolete dirent nodes to stay on the lists, because of the
|
||||
horridness in jffs2_garbage_collect_deletion_dirent(). Also
|
||||
because we delete the inocache, and on NAND we need that to
|
||||
because we delete the inocache, and on NAND we need that to
|
||||
stay around until all the nodes are actually erased, in order
|
||||
to stop us from giving the same inode number to another newly
|
||||
created inode. */
|
||||
@ -689,7 +689,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
if (ref->next_phys && ref_obsolete(ref->next_phys) &&
|
||||
!ref->next_phys->next_in_ino) {
|
||||
struct jffs2_raw_node_ref *n = ref->next_phys;
|
||||
|
||||
|
||||
spin_lock(&c->erase_completion_lock);
|
||||
|
||||
ref->__totlen += n->__totlen;
|
||||
@ -703,7 +703,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
|
||||
jffs2_free_raw_node_ref(n);
|
||||
}
|
||||
|
||||
|
||||
/* Also merge with the previous node in the list, if there is one
|
||||
and that one is obsolete */
|
||||
if (ref != jeb->first_node ) {
|
||||
@ -713,7 +713,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
|
||||
while (p->next_phys != ref)
|
||||
p = p->next_phys;
|
||||
|
||||
|
||||
if (ref_obsolete(p) && !ref->next_in_ino) {
|
||||
p->__totlen += ref->__totlen;
|
||||
if (jeb->last_node == ref) {
|
||||
@ -753,11 +753,11 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c)
|
||||
*/
|
||||
dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size;
|
||||
|
||||
if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
|
||||
(dirty > c->nospc_dirty_size))
|
||||
if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
|
||||
(dirty > c->nospc_dirty_size))
|
||||
ret = 1;
|
||||
|
||||
D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
|
||||
D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
|
||||
c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no"));
|
||||
|
||||
return ret;
|
||||
|
@ -191,18 +191,18 @@ void jffs2_gc_release_inode(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
|
||||
int inum, int nlink);
|
||||
|
||||
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_info *f,
|
||||
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_info *f,
|
||||
unsigned long offset,
|
||||
unsigned long *priv);
|
||||
void jffs2_gc_release_page(struct jffs2_sb_info *c,
|
||||
unsigned char *pg,
|
||||
unsigned long *priv);
|
||||
void jffs2_flash_cleanup(struct jffs2_sb_info *c);
|
||||
|
||||
|
||||
|
||||
/* writev.c */
|
||||
int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
|
||||
int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
|
||||
unsigned long count, loff_t to, size_t *retlen);
|
||||
int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
|
||||
size_t *retlen, const u_char *buf);
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: read.c,v 1.41 2005/07/22 10:32:08 dedekind Exp $
|
||||
* $Id: read.c,v 1.42 2005/11/07 11:14:41 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -43,7 +43,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
}
|
||||
if (readlen != sizeof(*ri)) {
|
||||
jffs2_free_raw_inode(ri);
|
||||
printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
|
||||
printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
|
||||
ref_offset(fd->raw), sizeof(*ri), readlen);
|
||||
return -EIO;
|
||||
}
|
||||
@ -61,7 +61,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
}
|
||||
/* There was a bug where we wrote hole nodes out with csize/dsize
|
||||
swapped. Deal with it */
|
||||
if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
|
||||
if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
|
||||
je32_to_cpu(ri->csize)) {
|
||||
ri->dsize = ri->csize;
|
||||
ri->csize = cpu_to_je32(0);
|
||||
@ -74,7 +74,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
goto out_ri;
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (ri->compr == JFFS2_COMPR_ZERO) {
|
||||
memset(buf, 0, len);
|
||||
goto out_ri;
|
||||
@ -82,8 +82,8 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
|
||||
/* Cases:
|
||||
Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
|
||||
Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
|
||||
Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
|
||||
Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
|
||||
Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
|
||||
Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
|
||||
*/
|
||||
if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) {
|
||||
@ -129,7 +129,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
|
||||
if (ri->compr != JFFS2_COMPR_NONE) {
|
||||
D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n",
|
||||
je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
|
||||
je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
|
||||
ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
|
||||
@ -191,7 +191,7 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
} else {
|
||||
uint32_t readlen;
|
||||
uint32_t fragofs; /* offset within the frag to start reading */
|
||||
|
||||
|
||||
fragofs = offset - frag->ofs;
|
||||
readlen = min(frag->size - fragofs, end - offset);
|
||||
D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n",
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: readinode.c,v 1.142 2005/09/20 14:27:34 dedekind Exp $
|
||||
* $Id: readinode.c,v 1.143 2005/11/07 11:14:41 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -116,19 +116,19 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
|
||||
uint32_t *latest_mctime, uint32_t *mctime_ver)
|
||||
{
|
||||
struct jffs2_full_dirent *fd;
|
||||
|
||||
|
||||
/* The direntry nodes are checked during the flash scanning */
|
||||
BUG_ON(ref_flags(ref) == REF_UNCHECKED);
|
||||
/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
|
||||
BUG_ON(ref_obsolete(ref));
|
||||
|
||||
|
||||
/* Sanity check */
|
||||
if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
|
||||
JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
|
||||
ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
fd = jffs2_alloc_full_dirent(rd->nsize + 1);
|
||||
if (unlikely(!fd))
|
||||
return -ENOMEM;
|
||||
@ -144,39 +144,39 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
|
||||
*latest_mctime = je32_to_cpu(rd->mctime);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copy as much of the name as possible from the raw
|
||||
* dirent we've already read from the flash.
|
||||
*/
|
||||
if (read > sizeof(*rd))
|
||||
memcpy(&fd->name[0], &rd->name[0],
|
||||
min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) ));
|
||||
|
||||
|
||||
/* Do we need to copy any more of the name directly from the flash? */
|
||||
if (rd->nsize + sizeof(*rd) > read) {
|
||||
/* FIXME: point() */
|
||||
int err;
|
||||
int already = read - sizeof(*rd);
|
||||
|
||||
err = jffs2_flash_read(c, (ref_offset(ref)) + read,
|
||||
|
||||
err = jffs2_flash_read(c, (ref_offset(ref)) + read,
|
||||
rd->nsize - already, &read, &fd->name[already]);
|
||||
if (unlikely(read != rd->nsize - already) && likely(!err))
|
||||
return -EIO;
|
||||
|
||||
|
||||
if (unlikely(err)) {
|
||||
JFFS2_ERROR("read remainder of name: error %d\n", err);
|
||||
jffs2_free_full_dirent(fd);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fd->nhash = full_name_hash(fd->name, rd->nsize);
|
||||
fd->next = NULL;
|
||||
fd->name[rd->nsize] = '\0';
|
||||
|
||||
|
||||
/*
|
||||
* Wheee. We now have a complete jffs2_full_dirent structure, with
|
||||
* the name in it and everything. Link it into the list
|
||||
* the name in it and everything. Link it into the list
|
||||
*/
|
||||
jffs2_add_fd_to_list(c, fd, fdp);
|
||||
|
||||
@ -198,7 +198,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
struct jffs2_tmp_dnode_info *tn;
|
||||
uint32_t len, csize;
|
||||
int ret = 1;
|
||||
|
||||
|
||||
/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
|
||||
BUG_ON(ref_obsolete(ref));
|
||||
|
||||
@ -210,7 +210,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
|
||||
tn->partial_crc = 0;
|
||||
csize = je32_to_cpu(rd->csize);
|
||||
|
||||
|
||||
/* If we've never checked the CRCs on this node, check them now */
|
||||
if (ref_flags(ref) == REF_UNCHECKED) {
|
||||
uint32_t crc;
|
||||
@ -221,7 +221,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
|
||||
/* Sanity checks */
|
||||
if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
|
||||
unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
|
||||
@ -313,13 +313,13 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
ret = -ENOMEM;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
|
||||
tn->version = je32_to_cpu(rd->version);
|
||||
tn->fn->ofs = je32_to_cpu(rd->offset);
|
||||
tn->data_crc = je32_to_cpu(rd->data_crc);
|
||||
tn->csize = csize;
|
||||
tn->fn->raw = ref;
|
||||
|
||||
|
||||
/* There was a bug where we wrote hole nodes out with
|
||||
csize/dsize swapped. Deal with it */
|
||||
if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize)
|
||||
@ -329,7 +329,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
|
||||
|
||||
dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n",
|
||||
ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize);
|
||||
|
||||
|
||||
jffs2_add_tn_to_tree(tn, tnp);
|
||||
|
||||
return 0;
|
||||
@ -351,7 +351,7 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re
|
||||
{
|
||||
/* We don't mark unknown nodes as REF_UNCHECKED */
|
||||
BUG_ON(ref_flags(ref) == REF_UNCHECKED);
|
||||
|
||||
|
||||
un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
|
||||
|
||||
if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) {
|
||||
@ -423,7 +423,7 @@ static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
|
||||
bufstart = buf + *rdlen;
|
||||
len = right_size - *rdlen;
|
||||
}
|
||||
|
||||
|
||||
dbg_readinode("read more %d bytes\n", len);
|
||||
|
||||
err = jffs2_flash_read(c, offs, len, &retlen, bufstart);
|
||||
@ -432,7 +432,7 @@ static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
|
||||
"error code: %d.\n", len, offs, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
if (retlen < len) {
|
||||
JFFS2_ERROR("short read at %#08x: %d instead of %d.\n",
|
||||
offs, retlen, len);
|
||||
@ -460,7 +460,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
int len, err;
|
||||
|
||||
*mctime_ver = 0;
|
||||
|
||||
|
||||
dbg_readinode("ino #%u\n", f->inocache->ino);
|
||||
|
||||
if (jffs2_is_writebuffered(c)) {
|
||||
@ -487,7 +487,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
buf = kmalloc(len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
spin_lock(&c->erase_completion_lock);
|
||||
valid_ref = jffs2_first_valid_node(f->inocache->nodes);
|
||||
if (!valid_ref && f->inocache->ino != 1)
|
||||
@ -514,7 +514,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
* size = JFFS2_MIN_NODE_HEADER.
|
||||
*/
|
||||
if (jffs2_is_writebuffered(c)) {
|
||||
/*
|
||||
/*
|
||||
* We treat 'buf' as 2 adjacent wbufs. We want to
|
||||
* adjust bufstart such as it points to the
|
||||
* beginning of the node within this wbuf.
|
||||
@ -540,17 +540,17 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err);
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
|
||||
if (retlen < len) {
|
||||
JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len);
|
||||
err = -EIO;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
|
||||
node = (union jffs2_node_union *)bufstart;
|
||||
|
||||
|
||||
switch (je16_to_cpu(node->u.nodetype)) {
|
||||
|
||||
|
||||
case JFFS2_NODETYPE_DIRENT:
|
||||
|
||||
if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {
|
||||
@ -558,21 +558,21 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
if (unlikely(err))
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
|
||||
err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver);
|
||||
if (err == 1) {
|
||||
jffs2_mark_node_obsolete(c, ref);
|
||||
break;
|
||||
} else if (unlikely(err))
|
||||
goto free_out;
|
||||
|
||||
|
||||
if (je32_to_cpu(node->d.version) > *highest_version)
|
||||
*highest_version = je32_to_cpu(node->d.version);
|
||||
|
||||
break;
|
||||
|
||||
case JFFS2_NODETYPE_INODE:
|
||||
|
||||
|
||||
if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {
|
||||
err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart);
|
||||
if (unlikely(err))
|
||||
@ -588,7 +588,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
|
||||
if (je32_to_cpu(node->i.version) > *highest_version)
|
||||
*highest_version = je32_to_cpu(node->i.version);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -597,7 +597,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
if (unlikely(err))
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
|
||||
err = read_unknown(c, ref, &node->u);
|
||||
if (err == 1) {
|
||||
jffs2_mark_node_obsolete(c, ref);
|
||||
@ -625,7 +625,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
|
||||
return err;
|
||||
}
|
||||
|
||||
static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
|
||||
static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
|
||||
struct jffs2_inode_info *f,
|
||||
struct jffs2_raw_inode *latest_node)
|
||||
{
|
||||
@ -677,7 +677,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
|
||||
ret = 0; /* Prevent freeing the metadata update node */
|
||||
} else
|
||||
jffs2_mark_node_obsolete(c, fn->raw);
|
||||
|
||||
|
||||
BUG_ON(rb->rb_left);
|
||||
if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
|
||||
/* We were then left-hand child of our parent. We need
|
||||
@ -763,7 +763,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case S_IFREG:
|
||||
/* If it was a regular file, truncate it to the latest node's isize */
|
||||
jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
|
||||
@ -788,10 +788,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
|
||||
jffs2_do_clear_inode(c, f);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
|
||||
je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
|
||||
|
||||
|
||||
if (ret || retlen != je32_to_cpu(latest_node->csize)) {
|
||||
if (retlen != je32_to_cpu(latest_node->csize))
|
||||
ret = -EIO;
|
||||
@ -805,7 +805,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
|
||||
f->target[je32_to_cpu(latest_node->csize)] = '\0';
|
||||
dbg_readinode("symlink's target '%s' cached\n", f->target);
|
||||
}
|
||||
|
||||
|
||||
/* fall through... */
|
||||
|
||||
case S_IFBLK:
|
||||
@ -848,7 +848,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
|
||||
}
|
||||
|
||||
/* Scan the list of all nodes present for this ino, build map of versions, etc. */
|
||||
int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
uint32_t ino, struct jffs2_raw_inode *latest_node)
|
||||
{
|
||||
dbg_readinode("read inode #%u\n", ino);
|
||||
@ -864,7 +864,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
case INO_STATE_CHECKEDABSENT:
|
||||
f->inocache->state = INO_STATE_READING;
|
||||
break;
|
||||
|
||||
|
||||
case INO_STATE_CHECKING:
|
||||
case INO_STATE_GC:
|
||||
/* If it's in either of these states, we need
|
||||
@ -957,7 +957,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
|
||||
kfree(f->target);
|
||||
f->target = NULL;
|
||||
}
|
||||
|
||||
|
||||
fds = f->dents;
|
||||
while(fds) {
|
||||
fd = fds;
|
||||
|
@ -38,11 +38,11 @@ static uint32_t pseudo_random;
|
||||
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s);
|
||||
|
||||
/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
|
||||
/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
|
||||
* Returning an error will abort the mount - bad checksums etc. should just mark the space
|
||||
* as dirty.
|
||||
*/
|
||||
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s);
|
||||
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s);
|
||||
@ -131,8 +131,8 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
|
||||
/* Now decide which list to put it on */
|
||||
switch(ret) {
|
||||
case BLK_STATE_ALLFF:
|
||||
/*
|
||||
* Empty block. Since we can't be sure it
|
||||
/*
|
||||
* Empty block. Since we can't be sure it
|
||||
* was entirely erased, we just queue it for erase
|
||||
* again. It will be marked as such when the erase
|
||||
* is complete. Meanwhile we still count it as empty
|
||||
@ -234,7 +234,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
|
||||
}
|
||||
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
|
||||
if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) {
|
||||
/* If we're going to start writing into a block which already
|
||||
/* 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. */
|
||||
|
||||
@ -250,7 +250,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
|
||||
}
|
||||
#endif
|
||||
if (c->nr_erasing_blocks) {
|
||||
if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
|
||||
if ( !c->used_size && ((c->nr_free_blocks+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");
|
||||
printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);
|
||||
ret = -EIO;
|
||||
@ -263,7 +263,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
|
||||
if (buf_size)
|
||||
kfree(flashbuf);
|
||||
#ifndef __ECOS
|
||||
else
|
||||
else
|
||||
c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
|
||||
#endif
|
||||
return ret;
|
||||
@ -391,7 +391,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
|
||||
ofs = 0;
|
||||
|
||||
@ -431,7 +431,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
|
||||
|
||||
dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);
|
||||
|
||||
scan_more:
|
||||
scan_more:
|
||||
while(ofs < jeb->offset + c->sector_size) {
|
||||
|
||||
jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
|
||||
@ -496,7 +496,7 @@ scan_more:
|
||||
|
||||
/* If we're only checking the beginning of a block with a cleanmarker,
|
||||
bail now */
|
||||
if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
|
||||
if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
|
||||
c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
|
||||
D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
|
||||
return BLK_STATE_CLEANMARKER;
|
||||
@ -505,7 +505,7 @@ scan_more:
|
||||
/* See how much more there is to read in this eraseblock... */
|
||||
buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
|
||||
if (!buf_len) {
|
||||
/* No more to read. Break out of main loop without marking
|
||||
/* No more to read. Break out of main loop without marking
|
||||
this range of empty space as dirty (because it's not) */
|
||||
D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",
|
||||
empty_start));
|
||||
@ -540,8 +540,8 @@ scan_more:
|
||||
}
|
||||
if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {
|
||||
/* OK. We're out of possibilities. Whinge and move on */
|
||||
noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
|
||||
JFFS2_MAGIC_BITMASK, ofs,
|
||||
noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
|
||||
JFFS2_MAGIC_BITMASK, ofs,
|
||||
je16_to_cpu(node->magic));
|
||||
DIRTY_SPACE(4);
|
||||
ofs += 4;
|
||||
@ -556,7 +556,7 @@ scan_more:
|
||||
if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
|
||||
noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
|
||||
ofs, je16_to_cpu(node->magic),
|
||||
je16_to_cpu(node->nodetype),
|
||||
je16_to_cpu(node->nodetype),
|
||||
je32_to_cpu(node->totlen),
|
||||
je32_to_cpu(node->hdr_crc),
|
||||
hdr_crc);
|
||||
@ -565,7 +565,7 @@ scan_more:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ofs + je32_to_cpu(node->totlen) >
|
||||
if (ofs + je32_to_cpu(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",
|
||||
@ -600,7 +600,7 @@ scan_more:
|
||||
if (err) return err;
|
||||
ofs += PAD(je32_to_cpu(node->totlen));
|
||||
break;
|
||||
|
||||
|
||||
case JFFS2_NODETYPE_DIRENT:
|
||||
if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
|
||||
buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
|
||||
@ -620,7 +620,7 @@ scan_more:
|
||||
case JFFS2_NODETYPE_CLEANMARKER:
|
||||
D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
|
||||
if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
|
||||
printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
|
||||
printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
|
||||
ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
|
||||
DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
|
||||
ofs += PAD(sizeof(struct jffs2_unknown_node));
|
||||
@ -639,7 +639,7 @@ scan_more:
|
||||
marker_ref->flash_offset = ofs | REF_NORMAL;
|
||||
marker_ref->__totlen = c->cleanmarker_size;
|
||||
jeb->first_node = jeb->last_node = marker_ref;
|
||||
|
||||
|
||||
USED_SPACE(PAD(c->cleanmarker_size));
|
||||
ofs += PAD(c->cleanmarker_size);
|
||||
}
|
||||
@ -690,7 +690,7 @@ scan_more:
|
||||
}
|
||||
}
|
||||
|
||||
D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
|
||||
D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
|
||||
jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
|
||||
|
||||
/* mark_node_obsolete can add to wasted !! */
|
||||
@ -730,7 +730,7 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin
|
||||
return ic;
|
||||
}
|
||||
|
||||
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s)
|
||||
{
|
||||
struct jffs2_raw_node_ref *raw;
|
||||
@ -740,11 +740,11 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
|
||||
D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
|
||||
|
||||
/* We do very little here now. Just check the ino# to which we should attribute
|
||||
this node; we can do all the CRC checking etc. later. There's a tradeoff here --
|
||||
this node; we can do all the CRC checking etc. later. There's a tradeoff here --
|
||||
we used to scan the flash once only, reading everything we want from it into
|
||||
memory, then building all our in-core data structures and freeing the extra
|
||||
information. Now we allow the first part of the mount to complete a lot quicker,
|
||||
but we have to go _back_ to the flash in order to finish the CRC checking, etc.
|
||||
but we have to go _back_ to the flash in order to finish the CRC checking, etc.
|
||||
Which means that the _full_ amount of time to get to proper write mode with GC
|
||||
operational may actually be _longer_ than before. Sucks to be me. */
|
||||
|
||||
@ -790,7 +790,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
|
||||
jeb->last_node->next_phys = raw;
|
||||
jeb->last_node = raw;
|
||||
|
||||
D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
|
||||
D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
|
||||
je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
|
||||
je32_to_cpu(ri->offset),
|
||||
je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)));
|
||||
@ -806,7 +806,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
|
||||
struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s)
|
||||
{
|
||||
struct jffs2_raw_node_ref *raw;
|
||||
@ -840,7 +840,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
|
||||
crc = crc32(0, fd->name, rd->nsize);
|
||||
if (crc != je32_to_cpu(rd->name_crc)) {
|
||||
printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
|
||||
ofs, je32_to_cpu(rd->name_crc), crc);
|
||||
ofs, je32_to_cpu(rd->name_crc), crc);
|
||||
D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino)));
|
||||
jffs2_free_full_dirent(fd);
|
||||
/* FIXME: Why do we believe totlen? */
|
||||
@ -860,7 +860,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
|
||||
jffs2_free_raw_node_ref(raw);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
raw->__totlen = PAD(je32_to_cpu(rd->totlen));
|
||||
raw->flash_offset = ofs | REF_PRISTINE;
|
||||
raw->next_phys = NULL;
|
||||
|
@ -82,7 +82,7 @@ static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item)
|
||||
je32_to_cpu(item->d.ino));
|
||||
break;
|
||||
default:
|
||||
JFFS2_WARNING("UNKNOWN node type %u\n",
|
||||
JFFS2_WARNING("UNKNOWN node type %u\n",
|
||||
je16_to_cpu(item->u.nodetype));
|
||||
return 1;
|
||||
}
|
||||
@ -174,7 +174,7 @@ void jffs2_sum_disable_collecting(struct jffs2_summary *s)
|
||||
s->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
|
||||
}
|
||||
|
||||
int jffs2_sum_is_disabled(struct jffs2_summary *s)
|
||||
int jffs2_sum_is_disabled(struct jffs2_summary *s)
|
||||
{
|
||||
return (s->sum_size == JFFS2_SUMMARY_NOSUM_SIZE);
|
||||
}
|
||||
@ -609,7 +609,7 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
|
||||
sdrnt_ptr->nsize = c->summary->sum_list_head->d.nsize;
|
||||
sdrnt_ptr->type = c->summary->sum_list_head->d.type;
|
||||
|
||||
memcpy(sdrnt_ptr->name, c->summary->sum_list_head->d.name,
|
||||
memcpy(sdrnt_ptr->name, c->summary->sum_list_head->d.name,
|
||||
c->summary->sum_list_head->d.nsize);
|
||||
|
||||
wpage += JFFS2_SUMMARY_DIRENT_SIZE(c->summary->sum_list_head->d.nsize);
|
||||
@ -687,7 +687,7 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
|
||||
datasize = c->summary->sum_size + sizeof(struct jffs2_sum_marker);
|
||||
infosize = sizeof(struct jffs2_raw_summary) + datasize;
|
||||
padsize = jeb->free_size - infosize;
|
||||
infosize += padsize;
|
||||
infosize += padsize;
|
||||
datasize += padsize;
|
||||
|
||||
/* Is there enough space for summary? */
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: super.c,v 1.109 2005/09/07 08:34:55 havasi Exp $
|
||||
* $Id: super.c,v 1.110 2005/11/07 11:14:42 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -62,7 +62,7 @@ static int jffs2_sync_fs(struct super_block *sb, int wait)
|
||||
|
||||
down(&c->alloc_sem);
|
||||
jffs2_flush_wbuf_pad(c);
|
||||
up(&c->alloc_sem);
|
||||
up(&c->alloc_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ static int jffs2_sb_set(struct super_block *sb, void *data)
|
||||
}
|
||||
|
||||
static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name,
|
||||
int flags, const char *dev_name,
|
||||
void *data, struct mtd_info *mtd)
|
||||
{
|
||||
struct super_block *sb;
|
||||
@ -172,7 +172,7 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
|
||||
}
|
||||
|
||||
static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name,
|
||||
int flags, const char *dev_name,
|
||||
void *data, int mtdnr)
|
||||
{
|
||||
struct mtd_info *mtd;
|
||||
@ -201,7 +201,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
|
||||
|
||||
/* The preferred way of mounting in future; especially when
|
||||
CONFIG_BLK_DEV is implemented - we specify the underlying
|
||||
MTD device by number or by name, so that we don't require
|
||||
MTD device by number or by name, so that we don't require
|
||||
block device support to be present in the kernel. */
|
||||
|
||||
/* FIXME: How to do the root fs this way? */
|
||||
@ -225,7 +225,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
|
||||
} else if (isdigit(dev_name[3])) {
|
||||
/* Mount by MTD device number name */
|
||||
char *endptr;
|
||||
|
||||
|
||||
mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
|
||||
if (!*endptr) {
|
||||
/* It was a valid number */
|
||||
@ -235,7 +235,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
|
||||
}
|
||||
}
|
||||
|
||||
/* Try the old way - the hack where we allowed users to mount
|
||||
/* Try the old way - the hack where we allowed users to mount
|
||||
/dev/mtdblock$(n) but didn't actually _use_ the blkdev */
|
||||
|
||||
err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
|
||||
@ -376,5 +376,5 @@ module_exit(exit_jffs2_fs);
|
||||
|
||||
MODULE_DESCRIPTION("The Journalling Flash File System, v2");
|
||||
MODULE_AUTHOR("Red Hat, Inc.");
|
||||
MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
|
||||
MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
|
||||
// the sake of this tag. It's Free Software.
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: symlink.c,v 1.18 2005/11/06 11:03:27 gleixner Exp $
|
||||
* $Id: symlink.c,v 1.19 2005/11/07 11:14:42 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
|
||||
|
||||
struct inode_operations jffs2_symlink_inode_operations =
|
||||
{
|
||||
{
|
||||
.readlink = generic_readlink,
|
||||
.follow_link = jffs2_follow_link,
|
||||
.setattr = jffs2_setattr
|
||||
@ -44,7 +44,7 @@ static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||
* stopped using our f->target string which we provide by means of
|
||||
* nd_set_link() call.
|
||||
*/
|
||||
|
||||
|
||||
if (!p) {
|
||||
printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
|
||||
p = ERR_PTR(-EIO);
|
||||
@ -52,7 +52,7 @@ static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||
D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target));
|
||||
|
||||
nd_set_link(nd, p);
|
||||
|
||||
|
||||
/*
|
||||
* We will unlock the f->sem mutex but VFS will use the f->target string. This is safe
|
||||
* since the only way that may cause f->target to be changed is iput() operation.
|
||||
|
128
fs/jffs2/wbuf.c
128
fs/jffs2/wbuf.c
@ -188,7 +188,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
|
||||
/* Find the first node to be recovered, by skipping over every
|
||||
node which ends before the wbuf starts, or which is obsolete. */
|
||||
first_raw = &jeb->first_node;
|
||||
while (*first_raw &&
|
||||
while (*first_raw &&
|
||||
(ref_obsolete(*first_raw) ||
|
||||
(ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {
|
||||
D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
|
||||
@ -237,7 +237,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
|
||||
ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
|
||||
else
|
||||
ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
|
||||
|
||||
|
||||
if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) {
|
||||
/* ECC recovered */
|
||||
ret = 0;
|
||||
@ -274,15 +274,15 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
|
||||
if (end-start >= c->wbuf_pagesize) {
|
||||
/* Need to do another write immediately, but it's possible
|
||||
that this is just because the wbuf itself is completely
|
||||
full, and there's nothing earlier read back from the
|
||||
flash. Hence 'buf' isn't necessarily what we're writing
|
||||
full, and there's nothing earlier read back from the
|
||||
flash. Hence 'buf' isn't necessarily what we're writing
|
||||
from. */
|
||||
unsigned char *rewrite_buf = buf?:c->wbuf;
|
||||
uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
|
||||
|
||||
D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
|
||||
towrite, ofs));
|
||||
|
||||
|
||||
#ifdef BREAKMEHEADER
|
||||
static int breakme;
|
||||
if (breakme++ == 20) {
|
||||
@ -434,7 +434,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
|
||||
this happens, if we have a change to a new block,
|
||||
or if fsync forces us to flush the writebuffer.
|
||||
if we have a switch to next page, we will not have
|
||||
enough remaining space for this.
|
||||
enough remaining space for this.
|
||||
*/
|
||||
if (pad ) {
|
||||
c->wbuf_len = PAD(c->wbuf_len);
|
||||
@ -442,7 +442,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
|
||||
/* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR
|
||||
with 8 byte page size */
|
||||
memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);
|
||||
|
||||
|
||||
if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
|
||||
struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
|
||||
padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
|
||||
@ -453,7 +453,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
|
||||
}
|
||||
/* else jffs2_flash_writev has actually filled in the rest of the
|
||||
buffer for us, and will deal with the node refs etc. later. */
|
||||
|
||||
|
||||
#ifdef BREAKME
|
||||
static int breakme;
|
||||
if (breakme++ == 20) {
|
||||
@ -462,9 +462,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
|
||||
c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
|
||||
&retlen, brokenbuf, NULL, c->oobinfo);
|
||||
ret = -EIO;
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
|
||||
|
||||
if (jffs2_cleanmarker_oob(c))
|
||||
ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
|
||||
else
|
||||
@ -485,7 +485,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
|
||||
}
|
||||
|
||||
spin_lock(&c->erase_completion_lock);
|
||||
|
||||
|
||||
/* Adjust free size of the block if we padded. */
|
||||
if (pad) {
|
||||
struct jffs2_eraseblock *jeb;
|
||||
@ -495,7 +495,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
|
||||
D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n",
|
||||
(jeb==c->nextblock)?"next":"", jeb->offset));
|
||||
|
||||
/* wbuf_pagesize - wbuf_len is the amount of space that's to be
|
||||
/* wbuf_pagesize - wbuf_len is the amount of space that's to be
|
||||
padded. If there is less free space in the block than that,
|
||||
something screwed up */
|
||||
if (jeb->free_size < (c->wbuf_pagesize - c->wbuf_len)) {
|
||||
@ -523,9 +523,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Trigger garbage collection to flush the write-buffer.
|
||||
/* Trigger garbage collection to flush the write-buffer.
|
||||
If ino arg is zero, do it if _any_ real (i.e. not GC) writes are
|
||||
outstanding. If ino arg non-zero, do it only if a write for the
|
||||
outstanding. If ino arg non-zero, do it only if a write for the
|
||||
given inode is outstanding. */
|
||||
int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
|
||||
{
|
||||
@ -620,13 +620,13 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
|
||||
/* If not NAND flash, don't bother */
|
||||
if (!jffs2_is_writebuffered(c))
|
||||
return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
|
||||
|
||||
|
||||
down_write(&c->wbuf_sem);
|
||||
|
||||
/* If wbuf_ofs is not initialized, set it to target address */
|
||||
if (c->wbuf_ofs == 0xFFFFFFFF) {
|
||||
c->wbuf_ofs = PAGE_DIV(to);
|
||||
c->wbuf_len = PAGE_MOD(to);
|
||||
c->wbuf_len = PAGE_MOD(to);
|
||||
memset(c->wbuf,0xff,c->wbuf_pagesize);
|
||||
}
|
||||
|
||||
@ -640,10 +640,10 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
|
||||
memset(c->wbuf,0xff,c->wbuf_pagesize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity checks on target address.
|
||||
It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
|
||||
and it's permitted to write at the beginning of a new
|
||||
|
||||
/* Sanity checks on target address.
|
||||
It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
|
||||
and it's permitted to write at the beginning of a new
|
||||
erase block. Anything else, and you die.
|
||||
New block starts at xxx000c (0-b = block header)
|
||||
*/
|
||||
@ -661,8 +661,8 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
|
||||
}
|
||||
/* set pointer to new block */
|
||||
c->wbuf_ofs = PAGE_DIV(to);
|
||||
c->wbuf_len = PAGE_MOD(to);
|
||||
}
|
||||
c->wbuf_len = PAGE_MOD(to);
|
||||
}
|
||||
|
||||
if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
|
||||
/* We're not writing immediately after the writebuffer. Bad. */
|
||||
@ -682,21 +682,21 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
|
||||
invec = 0;
|
||||
outvec = 0;
|
||||
|
||||
/* Fill writebuffer first, if already in use */
|
||||
/* Fill writebuffer first, if already in use */
|
||||
if (c->wbuf_len) {
|
||||
uint32_t invec_ofs = 0;
|
||||
|
||||
/* adjust alignment offset */
|
||||
/* adjust alignment offset */
|
||||
if (c->wbuf_len != PAGE_MOD(to)) {
|
||||
c->wbuf_len = PAGE_MOD(to);
|
||||
/* take care of alignment to next page */
|
||||
if (!c->wbuf_len)
|
||||
c->wbuf_len = c->wbuf_pagesize;
|
||||
}
|
||||
|
||||
|
||||
while(c->wbuf_len < c->wbuf_pagesize) {
|
||||
uint32_t thislen;
|
||||
|
||||
|
||||
if (invec == count)
|
||||
goto alldone;
|
||||
|
||||
@ -704,17 +704,17 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
|
||||
|
||||
if (thislen >= invecs[invec].iov_len)
|
||||
thislen = invecs[invec].iov_len;
|
||||
|
||||
|
||||
invec_ofs = thislen;
|
||||
|
||||
memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
|
||||
c->wbuf_len += thislen;
|
||||
donelen += thislen;
|
||||
/* Get next invec, if actual did not fill the buffer */
|
||||
if (c->wbuf_len < c->wbuf_pagesize)
|
||||
if (c->wbuf_len < c->wbuf_pagesize)
|
||||
invec++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* write buffer is full, flush buffer */
|
||||
ret = __jffs2_flush_wbuf(c, NOPAD);
|
||||
if (ret) {
|
||||
@ -773,10 +773,10 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
|
||||
|
||||
/* We did cross a page boundary, so we write some now */
|
||||
if (jffs2_cleanmarker_oob(c))
|
||||
ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
|
||||
ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
|
||||
else
|
||||
ret = jffs2_flash_direct_writev(c, outvecs, splitvec+1, outvec_to, &wbuf_retlen);
|
||||
|
||||
|
||||
if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
|
||||
/* At this point we have no problem,
|
||||
c->wbuf is empty. However refile nextblock to avoid
|
||||
@ -793,7 +793,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
donelen += wbuf_retlen;
|
||||
c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
|
||||
|
||||
@ -837,7 +837,7 @@ alldone:
|
||||
jffs2_wbuf_dirties_inode(c, ino);
|
||||
|
||||
ret = 0;
|
||||
|
||||
|
||||
exit:
|
||||
up_write(&c->wbuf_sem);
|
||||
return ret;
|
||||
@ -880,18 +880,18 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
|
||||
if ( (ret == -EBADMSG) && (*retlen == len) ) {
|
||||
printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
|
||||
len, ofs);
|
||||
/*
|
||||
* We have the raw data without ECC correction in the buffer, maybe
|
||||
/*
|
||||
* We have the raw data without ECC correction in the buffer, maybe
|
||||
* we are lucky and all data or parts are correct. We check the node.
|
||||
* If data are corrupted node check will sort it out.
|
||||
* We keep this block, it will fail on write or erase and the we
|
||||
* mark it bad. Or should we do that now? But we should give him a chance.
|
||||
* Maybe we had a system crash or power loss before the ecc write or
|
||||
* Maybe we had a system crash or power loss before the ecc write or
|
||||
* a erase was completed.
|
||||
* So we return success. :)
|
||||
*/
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if no writebuffer available or write buffer empty, return */
|
||||
if (!c->wbuf_pagesize || !c->wbuf_len)
|
||||
@ -906,16 +906,16 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
|
||||
if (owbf > c->wbuf_len) /* is read beyond write buffer ? */
|
||||
goto exit;
|
||||
lwbf = c->wbuf_len - owbf; /* number of bytes to copy */
|
||||
if (lwbf > len)
|
||||
if (lwbf > len)
|
||||
lwbf = len;
|
||||
} else {
|
||||
} else {
|
||||
orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */
|
||||
if (orbf > len) /* is write beyond write buffer ? */
|
||||
goto exit;
|
||||
lwbf = len - orbf; /* number of bytes to copy */
|
||||
if (lwbf > c->wbuf_len)
|
||||
if (lwbf > c->wbuf_len)
|
||||
lwbf = c->wbuf_len;
|
||||
}
|
||||
}
|
||||
if (lwbf > 0)
|
||||
memcpy(buf+orbf,c->wbuf+owbf,lwbf);
|
||||
|
||||
@ -943,7 +943,7 @@ int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
|
||||
printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
/*
|
||||
/*
|
||||
* if mode = 0, we scan for a total empty oob area, else we have
|
||||
* to take care of the cleanmarker in the first page of the block
|
||||
*/
|
||||
@ -952,41 +952,41 @@ int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
|
||||
D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if (retlen < len) {
|
||||
D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read "
|
||||
"(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset));
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* Special check for first page */
|
||||
for(i = 0; i < oob_size ; i++) {
|
||||
/* Yeah, we know about the cleanmarker. */
|
||||
if (mode && i >= c->fsdata_pos &&
|
||||
if (mode && i >= c->fsdata_pos &&
|
||||
i < c->fsdata_pos + c->fsdata_len)
|
||||
continue;
|
||||
|
||||
if (buf[i] != 0xFF) {
|
||||
D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n",
|
||||
buf[i], i, jeb->offset));
|
||||
ret = 1;
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* we know, we are aligned :) */
|
||||
/* we know, we are aligned :) */
|
||||
for (page = oob_size; page < len; page += sizeof(long)) {
|
||||
unsigned long dat = *(unsigned long *)(&buf[page]);
|
||||
if(dat != -1) {
|
||||
ret = 1;
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(buf);
|
||||
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1068,7 +1068,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
|
||||
n.totlen = cpu_to_je32(8);
|
||||
|
||||
ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n);
|
||||
|
||||
|
||||
if (ret) {
|
||||
D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
|
||||
return ret;
|
||||
@ -1080,7 +1080,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* On NAND we try to mark this block bad. If the block was erased more
|
||||
* than MAX_ERASE_FAILURES we mark it finaly bad.
|
||||
* Don't care about failures. This block remains on the erase-pending
|
||||
@ -1101,7 +1101,7 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
|
||||
|
||||
D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Marking bad block at %08x\n", bad_offset));
|
||||
ret = c->mtd->block_markbad(c->mtd, bad_offset);
|
||||
|
||||
|
||||
if (ret) {
|
||||
D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
|
||||
return ret;
|
||||
@ -1125,7 +1125,7 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
|
||||
/* Do this only, if we have an oob buffer */
|
||||
if (!c->mtd->oobsize)
|
||||
return 0;
|
||||
|
||||
|
||||
/* Cleanmarker is out-of-band, so inline size zero */
|
||||
c->cleanmarker_size = 0;
|
||||
|
||||
@ -1151,7 +1151,7 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
|
||||
c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
|
||||
c->badblock_pos = 15;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
|
||||
return -EINVAL;
|
||||
@ -1168,7 +1168,7 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
|
||||
init_rwsem(&c->wbuf_sem);
|
||||
c->wbuf_pagesize = c->mtd->oobblock;
|
||||
c->wbuf_ofs = 0xFFFFFFFF;
|
||||
|
||||
|
||||
c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
|
||||
if (!c->wbuf)
|
||||
return -ENOMEM;
|
||||
@ -1194,13 +1194,13 @@ void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
|
||||
|
||||
int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
|
||||
c->cleanmarker_size = 0; /* No cleanmarkers needed */
|
||||
|
||||
|
||||
/* Initialize write buffer */
|
||||
init_rwsem(&c->wbuf_sem);
|
||||
|
||||
|
||||
|
||||
|
||||
c->wbuf_pagesize = c->mtd->erasesize;
|
||||
|
||||
|
||||
/* Find a suitable c->sector_size
|
||||
* - Not too much sectors
|
||||
* - Sectors have to be at least 4 K + some bytes
|
||||
@ -1210,11 +1210,11 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
|
||||
*/
|
||||
|
||||
c->sector_size = 8 * c->mtd->erasesize;
|
||||
|
||||
|
||||
while (c->sector_size < 8192) {
|
||||
c->sector_size *= 2;
|
||||
}
|
||||
|
||||
|
||||
/* It may be necessary to adjust the flash size */
|
||||
c->flash_size = c->mtd->size;
|
||||
|
||||
@ -1222,7 +1222,7 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
|
||||
c->flash_size = (c->flash_size / c->sector_size) * c->sector_size;
|
||||
printk(KERN_WARNING "JFFS2 flash size adjusted to %dKiB\n", c->flash_size);
|
||||
};
|
||||
|
||||
|
||||
c->wbuf_ofs = 0xFFFFFFFF;
|
||||
c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
|
||||
if (!c->wbuf)
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
* $Id: write.c,v 1.96 2005/09/07 08:34:55 havasi Exp $
|
||||
* $Id: write.c,v 1.97 2005/11/07 11:14:42 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -54,7 +54,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
|
||||
/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
|
||||
write it to the flash, link it into the existing inode/fragment list */
|
||||
|
||||
struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode)
|
||||
@ -86,7 +86,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
raw = jffs2_alloc_raw_node_ref();
|
||||
if (!raw)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
||||
fn = jffs2_alloc_full_dnode();
|
||||
if (!fn) {
|
||||
jffs2_free_raw_node_ref(raw);
|
||||
@ -110,7 +110,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
|
||||
BUG_ON(!retried);
|
||||
D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, "
|
||||
"highest version %d -> updating dnode\n",
|
||||
"highest version %d -> updating dnode\n",
|
||||
je32_to_cpu(ri->version), f->highest_version));
|
||||
ri->version = cpu_to_je32(++f->highest_version);
|
||||
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
|
||||
@ -120,7 +120,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
(alloc_mode==ALLOC_GC)?0:f->inocache->ino);
|
||||
|
||||
if (ret || (retlen != sizeof(*ri) + datalen)) {
|
||||
printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
|
||||
printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
|
||||
sizeof(*ri)+datalen, flash_ofs, ret, retlen);
|
||||
|
||||
/* Mark the space as dirtied */
|
||||
@ -128,10 +128,10 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
/* Doesn't belong to any inode */
|
||||
raw->next_in_ino = NULL;
|
||||
|
||||
/* Don't change raw->size to match retlen. We may have
|
||||
/* Don't change raw->size to match retlen. We may have
|
||||
written the node header already, and only the data will
|
||||
seem corrupted, in which case the scan would skip over
|
||||
any node we write before the original intended end of
|
||||
any node we write before the original intended end of
|
||||
this node */
|
||||
raw->flash_offset |= REF_OBSOLETE;
|
||||
jffs2_add_physical_node_ref(c, raw);
|
||||
@ -148,7 +148,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
retried = 1;
|
||||
|
||||
D1(printk(KERN_DEBUG "Retrying failed write.\n"));
|
||||
|
||||
|
||||
jffs2_dbg_acct_sanity_check(c,jeb);
|
||||
jffs2_dbg_acct_paranoia_check(c, jeb);
|
||||
|
||||
@ -159,7 +159,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
/* Locking pain */
|
||||
up(&f->sem);
|
||||
jffs2_complete_reservation(c);
|
||||
|
||||
|
||||
ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs,
|
||||
&dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE);
|
||||
down(&f->sem);
|
||||
@ -181,9 +181,9 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
return ERR_PTR(ret?ret:-EIO);
|
||||
}
|
||||
/* Mark the space used */
|
||||
/* If node covers at least a whole page, or if it starts at the
|
||||
beginning of a page and runs to the end of the file, or if
|
||||
it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
|
||||
/* If node covers at least a whole page, or if it starts at the
|
||||
beginning of a page and runs to the end of the file, or if
|
||||
it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
|
||||
*/
|
||||
if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
|
||||
( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
|
||||
@ -201,7 +201,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
|
||||
D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
|
||||
flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
|
||||
flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
|
||||
je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
|
||||
je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
|
||||
|
||||
@ -221,7 +221,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
|
||||
int retried = 0;
|
||||
int ret;
|
||||
|
||||
D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
|
||||
D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
|
||||
je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
|
||||
je32_to_cpu(rd->name_crc)));
|
||||
|
||||
@ -235,7 +235,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
|
||||
vecs[0].iov_len = sizeof(*rd);
|
||||
vecs[1].iov_base = (unsigned char *)name;
|
||||
vecs[1].iov_len = namelen;
|
||||
|
||||
|
||||
jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
|
||||
|
||||
raw = jffs2_alloc_raw_node_ref();
|
||||
@ -276,7 +276,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
|
||||
ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
|
||||
(alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
|
||||
if (ret || (retlen != sizeof(*rd) + namelen)) {
|
||||
printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
|
||||
printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
|
||||
sizeof(*rd)+namelen, flash_ofs, ret, retlen);
|
||||
/* Mark the space as dirtied */
|
||||
if (retlen) {
|
||||
@ -307,7 +307,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
|
||||
/* Locking pain */
|
||||
up(&f->sem);
|
||||
jffs2_complete_reservation(c);
|
||||
|
||||
|
||||
ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs,
|
||||
&dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
|
||||
down(&f->sem);
|
||||
@ -346,7 +346,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
|
||||
we don't have to go digging in struct inode or its equivalent. It should set:
|
||||
mode, uid, gid, (starting)isize, atime, ctime, mtime */
|
||||
int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
struct jffs2_raw_inode *ri, unsigned char *buf,
|
||||
struct jffs2_raw_inode *ri, unsigned char *buf,
|
||||
uint32_t offset, uint32_t writelen, uint32_t *retlen)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -354,7 +354,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
|
||||
|
||||
D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",
|
||||
f->inocache->ino, offset, writelen));
|
||||
|
||||
|
||||
while(writelen) {
|
||||
struct jffs2_full_dnode *fn;
|
||||
unsigned char *comprbuf = NULL;
|
||||
@ -451,8 +451,8 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
|
||||
uint32_t alloclen, phys_ofs;
|
||||
int ret;
|
||||
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
/* Try to reserve enough space for both node and dirent.
|
||||
* Just the node will do for now, though
|
||||
*/
|
||||
ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL,
|
||||
JFFS2_SUMMARY_INODE_SIZE);
|
||||
@ -477,7 +477,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
|
||||
jffs2_complete_reservation(c);
|
||||
return PTR_ERR(fn);
|
||||
}
|
||||
/* No data here. Only a metadata node, which will be
|
||||
/* No data here. Only a metadata node, which will be
|
||||
obsoleted by the first data write
|
||||
*/
|
||||
f->metadata = fn;
|
||||
@ -486,7 +486,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
|
||||
jffs2_complete_reservation(c);
|
||||
ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
|
||||
ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
|
||||
|
||||
|
||||
if (ret) {
|
||||
/* Eep. */
|
||||
D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
|
||||
@ -519,9 +519,9 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
|
||||
fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
jffs2_free_raw_dirent(rd);
|
||||
|
||||
|
||||
if (IS_ERR(fd)) {
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
/* dirent failed to write. Delete the inode normally
|
||||
as if it were the final unlink() */
|
||||
jffs2_complete_reservation(c);
|
||||
up(&dir_f->sem);
|
||||
@ -548,7 +548,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
|
||||
uint32_t alloclen, phys_ofs;
|
||||
int ret;
|
||||
|
||||
if (1 /* alternative branch needs testing */ ||
|
||||
if (1 /* alternative branch needs testing */ ||
|
||||
!jffs2_can_mark_obsolete(c)) {
|
||||
/* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */
|
||||
|
||||
@ -570,7 +570,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
|
||||
rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
|
||||
rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
|
||||
rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
|
||||
|
||||
|
||||
rd->pino = cpu_to_je32(dir_f->inocache->ino);
|
||||
rd->version = cpu_to_je32(++dir_f->highest_version);
|
||||
rd->ino = cpu_to_je32(0);
|
||||
@ -581,7 +581,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
|
||||
rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
|
||||
|
||||
fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);
|
||||
|
||||
|
||||
jffs2_free_raw_dirent(rd);
|
||||
|
||||
if (IS_ERR(fd)) {
|
||||
@ -600,7 +600,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
|
||||
down(&dir_f->sem);
|
||||
|
||||
while ((*prev) && (*prev)->nhash <= nhash) {
|
||||
if ((*prev)->nhash == nhash &&
|
||||
if ((*prev)->nhash == nhash &&
|
||||
!memcmp((*prev)->name, name, namelen) &&
|
||||
!(*prev)->name[namelen]) {
|
||||
struct jffs2_full_dirent *this = *prev;
|
||||
@ -621,7 +621,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
|
||||
/* 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) {
|
||||
if (dead_f && dead_f->inocache) {
|
||||
|
||||
down(&dead_f->sem);
|
||||
|
||||
@ -629,9 +629,9 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
|
||||
while (dead_f->dents) {
|
||||
/* There can be only deleted ones */
|
||||
fd = dead_f->dents;
|
||||
|
||||
|
||||
dead_f->dents = fd->next;
|
||||
|
||||
|
||||
if (fd->ino) {
|
||||
printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
|
||||
dead_f->inocache->ino, fd->name, fd->ino);
|
||||
@ -672,7 +672,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
|
||||
jffs2_free_raw_dirent(rd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
down(&dir_f->sem);
|
||||
|
||||
/* Build a deletion node */
|
||||
@ -693,7 +693,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
|
||||
rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
|
||||
|
||||
fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
|
||||
|
||||
|
||||
jffs2_free_raw_dirent(rd);
|
||||
|
||||
if (IS_ERR(fd)) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in the
|
||||
* For licensing information, see the file 'LICENCE' in the
|
||||
* jffs2 directory.
|
||||
*
|
||||
* $Id: jffs2.h,v 1.38 2005/09/26 11:37:23 havasi Exp $
|
||||
@ -70,10 +70,10 @@
|
||||
//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
|
||||
|
||||
|
||||
#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
|
||||
mount time, don't wait for it to
|
||||
#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
|
||||
mount time, don't wait for it to
|
||||
happen later */
|
||||
#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
|
||||
#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
|
||||
compression type */
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ struct jffs2_raw_dirent
|
||||
} __attribute__((packed));
|
||||
|
||||
/* The JFFS2 raw inode structure: Used for storage on physical media. */
|
||||
/* The uid, gid, atime, mtime and ctime members could be longer, but
|
||||
/* The uid, gid, atime, mtime and ctime members could be longer, but
|
||||
are left like this for space efficiency. If and when people decide
|
||||
they really need them extended, it's simple enough to add support for
|
||||
a new type of raw node.
|
||||
@ -165,7 +165,7 @@ struct jffs2_raw_summary
|
||||
jint32_t sum[0]; /* inode summary info */
|
||||
} __attribute__((packed));
|
||||
|
||||
union jffs2_node_union
|
||||
union jffs2_node_union
|
||||
{
|
||||
struct jffs2_raw_inode i;
|
||||
struct jffs2_raw_dirent d;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: jffs2_fs_i.h,v 1.18 2005/07/17 11:13:48 dedekind Exp $ */
|
||||
/* $Id: jffs2_fs_i.h,v 1.19 2005/11/07 11:14:52 gleixner Exp $ */
|
||||
|
||||
#ifndef _JFFS2_FS_I
|
||||
#define _JFFS2_FS_I
|
||||
@ -25,7 +25,7 @@ struct jffs2_inode_info {
|
||||
/* There may be one datanode which isn't referenced by any of the
|
||||
above fragments, if it contains a metadata update but no actual
|
||||
data - or if this is a directory inode */
|
||||
/* This also holds the _only_ dnode for symlinks/device nodes,
|
||||
/* This also holds the _only_ dnode for symlinks/device nodes,
|
||||
etc. */
|
||||
struct jffs2_full_dnode *metadata;
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
struct jffs2_inodirty;
|
||||
|
||||
/* A struct for the overall file system control. Pointers to
|
||||
jffs2_sb_info structs are named `c' in the source code.
|
||||
jffs2_sb_info structs are named `c' in the source code.
|
||||
Nee jffs_control
|
||||
*/
|
||||
struct jffs2_sb_info {
|
||||
@ -35,7 +35,7 @@ struct jffs2_sb_info {
|
||||
struct completion gc_thread_start; /* GC thread start completion */
|
||||
struct completion gc_thread_exit; /* GC thread exit completion port */
|
||||
|
||||
struct semaphore alloc_sem; /* Used to protect all the following
|
||||
struct semaphore alloc_sem; /* Used to protect all the following
|
||||
fields, and also to protect against
|
||||
out-of-order writing of nodes. And GC. */
|
||||
uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
|
||||
@ -64,7 +64,7 @@ struct jffs2_sb_info {
|
||||
uint32_t nospc_dirty_size;
|
||||
|
||||
uint32_t nr_blocks;
|
||||
struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
|
||||
struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
|
||||
* from the offset (blocks[ofs / sector_size]) */
|
||||
struct jffs2_eraseblock *nextblock; /* The block we're currently filling */
|
||||
|
||||
@ -82,21 +82,21 @@ struct jffs2_sb_info {
|
||||
struct list_head bad_list; /* Bad blocks. */
|
||||
struct list_head bad_used_list; /* Bad blocks with valid data in. */
|
||||
|
||||
spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
|
||||
spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
|
||||
against erase completion handler */
|
||||
wait_queue_head_t erase_wait; /* For waiting for erases to complete */
|
||||
|
||||
wait_queue_head_t inocache_wq;
|
||||
struct jffs2_inode_cache **inocache_list;
|
||||
spinlock_t inocache_lock;
|
||||
|
||||
|
||||
/* Sem to allow jffs2_garbage_collect_deletion_dirent to
|
||||
drop the erase_completion_lock while it's holding a pointer
|
||||
drop the erase_completion_lock while it's holding a pointer
|
||||
to an obsoleted node. I don't like this. Alternatives welcomed. */
|
||||
struct semaphore erase_free_sem;
|
||||
|
||||
uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
|
||||
|
||||
|
||||
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
|
||||
/* Write-behind buffer for NAND flash */
|
||||
unsigned char *wbuf;
|
||||
|
Loading…
Reference in New Issue
Block a user