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
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
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
D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
wait_for_completion(&c->gc_thread_start);
}
-
+
return ret;
}
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;
*
* 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 $
*
*/
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");
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) {
cond_resched();
}
c->flags &= ~JFFS2_SB_FLAG_BUILDING;
-
+
dbg_fsbuild("FS build complete\n");
/* Rotate the lists by some number to ensure wear levelling */
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;
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",
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);
}
/*
- 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.
*/
}
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. */
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;
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)
{
#ifndef __ECOS
if (jffs2_blocks_use_vmalloc(c))
vfree(c->blocks);
- else
+ else
#endif
kfree(c->blocks);
*
* 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 $
*
*/
* 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;
}
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;
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) {
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");
}
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:
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;
if (!strcmp(this->name, name)) {
this->disabled = disabled;
spin_unlock(&jffs2_compressor_list_lock);
- return 0;
+ return 0;
}
}
spin_unlock(&jffs2_compressor_list_lock);
}
}
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
kfree(comprbuf);
}
-int jffs2_compressors_init(void)
+int jffs2_compressors_init(void)
{
/* Registering compressors */
#ifdef CONFIG_JFFS2_ZLIB
return 0;
}
-int jffs2_compressors_exit(void)
+int jffs2_compressors_exit(void)
{
/* Unregistering compressors */
#ifdef CONFIG_JFFS2_RUBIN
* 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 $
*
*/
#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 */
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++;
/* 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,
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) {
}
} 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,
*
*/
-
#include <linux/string.h>
#include <linux/types.h>
#include <linux/jffs2.h>
#include "compr.h"
static void init_rubin(struct rubin_state *rs, int div, int *bits)
-{
+{
int c;
rs->q = 0;
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;
static void end_rubin(struct rubin_state *rs)
-{
+{
int i;
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;
-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;
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);
}
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 */
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,
/* 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"
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;
*
* 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 $
*
*/
#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
def_strm.next_in = data_in;
def_strm.total_in = 0;
-
+
def_strm.next_out = cpage_out;
def_strm.total_out = 0;
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));
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;
-/* $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>
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 ) {
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);
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
*
* 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>
__jffs2_dbg_fragtree_paranoia_check_nolock(f);
up(&f->sem);
}
-
+
void
__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
{
__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)
__jffs2_dbg_dump_jeb_nolock(jeb);
__jffs2_dbg_dump_block_lists_nolock(c);
BUG();
-
+
}
#endif /* JFFS2_DBG_PARANOIA_CHECKS */
__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);
{
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(" ");
}
printk("%02x ", buf[i]);
-
+
i += 1;
}
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);
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)
{
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;
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;
*
* 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_
#define JFFS2_DBG_PARANOIA_CHECKS
#define JFFS2_DBG_DUMPS
-/*
+/*
* By defining/undefining the below macros one may select debugging messages
* fro specific JFFS2 subsystems.
*/
/* 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...
*/
" (%d) %s: " fmt, current->pid, \
__FUNCTION__, ##__VA_ARGS__); \
} while(0)
-
+
#define JFFS2_NOTICE(fmt, ...) \
do { \
printk(JFFS2_NOTICE_MSG_PREFIX \
__FUNCTION__, ##__VA_ARGS__); \
} while(0)
-/*
+/*
* We split our debugging messages on several parts, depending on the JFFS2
* subsystem the message belongs to.
*/
*
* 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 $
*
*/
/* 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,
/* 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)) {
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;
}
ri = jffs2_alloc_raw_inode();
if (!ri)
return -ENOMEM;
-
+
c = JFFS2_SB_INFO(dir_i->i_sb);
D1(printk(KERN_DEBUG "jffs2_create()\n"));
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) {
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;
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,
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);
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;
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);
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,
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);
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;
jffs2_clear_inode(inode);
return ret;
}
-
+
rd = jffs2_alloc_raw_dirent();
if (!rd) {
/* Argh. Now we treat it like a normal delete */
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);
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,
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);
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;
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);
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.
}
/* 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);
}
}
- /* 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 */
struct jffs2_eraseblock *jeb;
struct jffs2_sb_info *c;
};
-
+
#ifndef __ECOS
static void jffs2_erase_callback(struct erase_info *);
#endif
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;
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);
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)
jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr);
} else {
jffs2_erase_succeeded(priv->c, priv->jeb);
- }
+ }
kfree(instr);
}
#endif /* !__ECOS */
/* 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 */
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) {
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);
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);
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;
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",
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;
/* 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 =
{
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);
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));
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)) {
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);
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);
}
/* 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;
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));
}
}
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);
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
kfree(mdata);
return -ENOMEM;
}
-
+
ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen,
ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
}
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);
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);
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);
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. */
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);
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) {
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;
jffs2_do_clear_inode(c, f);
make_bad_inode(inode);
return;
- }
+ }
case S_IFSOCK:
case S_IFIFO:
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;
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);
#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);
}
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.
*/
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);
}
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);
if (ret)
return ret;
}
-
+
/* and Dataflash */
if (jffs2_dataflash(c)) {
ret = jffs2_dataflash_setup(c);
if (jffs2_nor_ecc(c)) {
jffs2_nor_ecc_flash_cleanup(c);
}
-
+
/* and DataFlash */
if (jffs2_dataflash(c)) {
jffs2_dataflash_cleanup(c);
*
* 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 $
*
*/
#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,
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;
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));
/* 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",
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);
}
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);
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);
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;
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",
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 */
if (!ret) {
/* Urgh. Return it sensibly. */
frag->node->raw = f->inocache->nodes;
- }
+ }
if (ret != -EBADFD)
goto upnout;
}
}
goto upnout;
}
-
+
/* Wasn't a dnode. Try dirent */
for (fd = f->dents; fd; fd=fd->next) {
if (fd->raw == raw)
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)
{
}
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;
}
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);
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;
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);
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) {
sizeof(ri)+ mdatalen, ret);
goto out;
}
-
+
last_frag = frag_last(&f->fragtree);
if (last_frag)
/* Fetch the inode length from the fragtree rather then
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);
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;
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) {
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;
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;
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 */
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) {
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;
}
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
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)) {
/* 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;
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;
}
{
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",
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. */
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. */
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. */
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?
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);
/* 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 */
-#define BIT_DIVIDER_MIPS 1043
+#define BIT_DIVIDER_MIPS 1043
static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */
*
* 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;
}
-
+
*
* 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 $
*
*/
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)
*
* 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 $
*
*/
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) {
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;
}
}
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);
}
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)
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;
}
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",
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);
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 */
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 */
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);
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 */
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);
}
}
/* 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. */
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)
return 0;
}
-/*
+/*
* Given an inode, probably with existing tree of fragments, add the new node
* to the fragment tree.
*/
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;
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)
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;
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. */
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);
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;
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.
*/
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));
return ret;
}
-/*
+/*
* Helper function for jffs2_add_older_frag_to_fragtree().
*
* Called when the new fragment that is being inserted
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.
*/
}
} 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) {
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);
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.
*/
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.
*/
return err;
checked = 1;
}
-
+
if (this->ofs + this->size >= fn_ofs + fn_size) {
/* We split the hole on two parts */
goto out_ok;
}
- /*
+ /*
* The beginning of the new fragment is valid since it
* overlaps the hole node.
*/
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.
*/
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),
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.
*/
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.
*/
return err;
checked = 1;
}
-
+
fn->frags += 1;
newfrag = new_fragment(fn, fn_ofs, fn_size);
if (unlikely(!newfrag))
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 {
/* 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;
while (ret && ret->ino < ino) {
ret = ret->next;
}
-
+
if (ret && ret->ino != ino)
ret = NULL;
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;
}
/* 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)
{
int i;
struct jffs2_inode_cache *this, *next;
-
+
for (i=0; i<INOCACHE_HASHSIZE; i++) {
this = c->inocache_list[i];
while (this) {
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;
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;
}
return;
dbg_fragtree("killing\n");
-
+
frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
while(frag) {
if (frag->rb.rb_left) {
}
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;
}
#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
/*
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.
*/
/* 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 */
/* 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.
*/
#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.
*/
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()
uint32_t data_crc;
uint32_t partial_crc;
uint32_t csize;
-};
+};
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
struct jffs2_raw_node_ref *ref)
{
uint32_t ref_end;
-
+
if (ref->next_phys)
ref_end = ref_offset(ref->next_phys);
else {
#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)
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);
/* 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);
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.
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;
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);
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)) {
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;
}
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));
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.
*/
* @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;
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
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);
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) {
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);
/* 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. */
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;
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 ) {
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) {
*/
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;
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);
*
* 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 $
*
*/
}
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;
}
}
/* 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);
goto out_ri;
});
-
+
if (ri->compr == JFFS2_COMPR_ZERO) {
memset(buf, 0, len);
goto out_ri;
/* 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)) {
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);
} 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",
*
* 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 $
*
*/
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;
*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);
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));
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;
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)))) {
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)
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;
{
/* 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)) {
bufstart = buf + *rdlen;
len = right_size - *rdlen;
}
-
+
dbg_readinode("read more %d bytes\n", len);
err = jffs2_flash_read(c, offs, len, &retlen, bufstart);
"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);
int len, err;
*mctime_ver = 0;
-
+
dbg_readinode("ino #%u\n", f->inocache->ino);
if (jffs2_is_writebuffered(c)) {
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)
* 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.
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)) {
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))
if (je32_to_cpu(node->i.version) > *highest_version)
*highest_version = je32_to_cpu(node->i.version);
-
+
break;
default:
if (unlikely(err))
goto free_out;
}
-
+
err = read_unknown(c, ref, &node->u);
if (err == 1) {
jffs2_mark_node_obsolete(c, ref);
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)
{
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
}
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));
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;
f->target[je32_to_cpu(latest_node->csize)] = '\0';
dbg_readinode("symlink's target '%s' cached\n", f->target);
}
-
+
/* fall through... */
case S_IFBLK:
}
/* 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);
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
kfree(f->target);
f->target = NULL;
}
-
+
fds = f->dents;
while(fds) {
fd = fds;
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);
/* 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
}
#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. */
}
#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;
if (buf_size)
kfree(flashbuf);
#ifndef __ECOS
- else
+ else
c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
#endif
return ret;
if (err)
return err;
}
-
+
/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
ofs = 0;
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);
/* 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;
/* 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));
}
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;
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);
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",
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);
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));
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);
}
}
}
- 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 !! */
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;
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. */
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)));
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;
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? */
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;
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;
}
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);
}
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);
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? */
*
* 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 $
*
*/
down(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
- up(&c->alloc_sem);
+ up(&c->alloc_sem);
return 0;
}
}
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;
}
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;
/* 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? */
} 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 */
}
}
- /* 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);
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.
*
* 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 $
*
*/
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
* 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);
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.
/* 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",
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;
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) {
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);
/* 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);
}
/* 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) {
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
}
spin_lock(&c->erase_completion_lock);
-
+
/* Adjust free size of the block if we padded. */
if (pad) {
struct jffs2_eraseblock *jeb;
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)) {
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)
{
/* 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);
}
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)
*/
}
/* 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. */
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;
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) {
/* 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
spin_unlock(&c->erase_completion_lock);
goto exit;
}
-
+
donelen += wbuf_retlen;
c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
jffs2_wbuf_dirties_inode(c, ino);
ret = 0;
-
+
exit:
up_write(&c->wbuf_sem);
return ret;
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)
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);
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
*/
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;
}
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;
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
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;
/* 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;
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;
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;
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
*/
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;
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)
*
* 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 $
*
*/
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)
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);
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));
(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 */
/* 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);
retried = 1;
D1(printk(KERN_DEBUG "Retrying failed write.\n"));
-
+
jffs2_dbg_acct_sanity_check(c,jeb);
jffs2_dbg_acct_paranoia_check(c, jeb);
/* 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);
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) &&
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)));
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)));
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();
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) {
/* 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);
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;
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;
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);
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;
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"));
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);
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 */
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);
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)) {
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;
/* 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);
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);
jffs2_free_raw_dirent(rd);
return ret;
}
-
+
down(&dir_f->sem);
/* Build a deletion node */
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)) {
*
* 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 $
//#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 */
} __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.
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;
-/* $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
/* 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;
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 {
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
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 */
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;