diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/jffs2/dir.c | 40 | ||||
-rw-r--r-- | fs/jffs2/erase.c | 4 | ||||
-rw-r--r-- | fs/jffs2/file.c | 8 | ||||
-rw-r--r-- | fs/jffs2/fs.c | 20 | ||||
-rw-r--r-- | fs/jffs2/gc.c | 51 | ||||
-rw-r--r-- | fs/jffs2/nodelist.c | 13 | ||||
-rw-r--r-- | fs/jffs2/nodelist.h | 75 | ||||
-rw-r--r-- | fs/jffs2/nodemgmt.c | 35 | ||||
-rw-r--r-- | fs/jffs2/os-linux.h | 14 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 24 | ||||
-rw-r--r-- | fs/jffs2/summary.c | 30 | ||||
-rw-r--r-- | fs/jffs2/wbuf.c | 52 | ||||
-rw-r--r-- | fs/jffs2/write.c | 85 | ||||
-rw-r--r-- | fs/jffs2/xattr.c | 60 | ||||
-rw-r--r-- | fs/jffs2/xattr.h | 14 |
15 files changed, 234 insertions, 291 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index ff1b7950dd4..edd8371fc6a 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -308,7 +308,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char struct jffs2_full_dnode *fn; struct jffs2_full_dirent *fd; int namelen; - uint32_t alloclen, phys_ofs; + uint32_t alloclen; int ret, targetlen = strlen(target); /* FIXME: If you care. We'd need to use frags for the target @@ -327,8 +327,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char * Just the node will do for now, though */ namelen = dentry->d_name.len; - ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, - ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) { jffs2_free_raw_inode(ri); @@ -356,7 +356,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char 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); + fn = jffs2_write_dnode(c, f, ri, target, targetlen, ALLOC_NORMAL); jffs2_free_raw_inode(ri); @@ -400,8 +400,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char return ret; } - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, - ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); if (ret) { /* Eep. */ jffs2_clear_inode(inode); @@ -433,7 +433,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 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); + fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); if (IS_ERR(fd)) { /* dirent failed to write. Delete the inode normally @@ -471,7 +471,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) struct jffs2_full_dnode *fn; struct jffs2_full_dirent *fd; int namelen; - uint32_t alloclen, phys_ofs; + uint32_t alloclen; int ret; mode |= S_IFDIR; @@ -486,8 +486,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) * 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, - JFFS2_SUMMARY_INODE_SIZE); + ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, + JFFS2_SUMMARY_INODE_SIZE); if (ret) { jffs2_free_raw_inode(ri); @@ -512,7 +512,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) ri->data_crc = cpu_to_je32(0); ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); - fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); + fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL); jffs2_free_raw_inode(ri); @@ -542,8 +542,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) return ret; } - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, - ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); if (ret) { /* Eep. */ jffs2_clear_inode(inode); @@ -575,7 +575,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 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); + fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); if (IS_ERR(fd)) { /* dirent failed to write. Delete the inode normally @@ -631,7 +631,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de int namelen; union jffs2_device_node dev; int devlen = 0; - uint32_t alloclen, phys_ofs; + uint32_t alloclen; int ret; if (!new_valid_dev(rdev)) @@ -650,7 +650,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de * Just the node will do for now, though */ namelen = dentry->d_name.len; - ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, + ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) { @@ -678,7 +678,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de 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); + fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, ALLOC_NORMAL); jffs2_free_raw_inode(ri); @@ -708,8 +708,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de return ret; } - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, - ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); if (ret) { /* Eep. */ jffs2_clear_inode(inode); @@ -744,7 +744,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 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); + fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); if (IS_ERR(fd)) { /* dirent failed to write. Delete the inode normally diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index f677d6950fd..4616fed7573 100644 --- a/fs/jffs2/erase.c +++ b/fs/jffs2/erase.c @@ -230,6 +230,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, at the end of the linked list. Stash it and continue from the beginning of the list */ ic = (struct jffs2_inode_cache *)(*prev); + BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE); prev = &ic->nodes; continue; } @@ -410,10 +411,9 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb /* Everything else got zeroed before the erase */ jeb->free_size = c->sector_size; - marker_ref->next_in_ino = NULL; marker_ref->flash_offset = jeb->offset | REF_NORMAL; - jffs2_link_node_ref(c, jeb, marker_ref, c->cleanmarker_size); + jffs2_link_node_ref(c, jeb, marker_ref, c->cleanmarker_size, NULL); } spin_lock(&c->erase_completion_lock); diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index e18c9437d58..bb8844f40e4 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -134,13 +134,13 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg, struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_raw_inode ri; struct jffs2_full_dnode *fn; - uint32_t phys_ofs, alloc_len; + uint32_t 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)); - ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, - ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, + ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) return ret; @@ -166,7 +166,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg, 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); + fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_NORMAL); if (IS_ERR(fn)) { ret = PTR_ERR(fn); diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index a0f84673ce5..7b6c24b14f8 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -37,7 +37,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) unsigned char *mdata = NULL; int mdatalen = 0; unsigned int ivalid; - uint32_t phys_ofs, alloclen; + uint32_t alloclen; int ret; D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); ret = inode_change_ok(inode, iattr); @@ -79,8 +79,8 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) return -ENOMEM; } - ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, - ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) { jffs2_free_raw_inode(ri); if (S_ISLNK(inode->i_mode & S_IFMT)) @@ -131,7 +131,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) else ri->data_crc = cpu_to_je32(0); - new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL); + new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, ALLOC_NORMAL); if (S_ISLNK(inode->i_mode)) kfree(mdata); @@ -664,13 +664,6 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) { return ret; } - /* add setups for other bizarre flashes here... */ - if (jffs2_nor_ecc(c)) { - ret = jffs2_nor_ecc_flash_setup(c); - if (ret) - return ret; - } - /* and Dataflash */ if (jffs2_dataflash(c)) { ret = jffs2_dataflash_setup(c); @@ -694,11 +687,6 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) { jffs2_nand_flash_cleanup(c); } - /* add cleanups for other bizarre flashes here... */ - if (jffs2_nor_ecc(c)) { - jffs2_nor_ecc_flash_cleanup(c); - } - /* and DataFlash */ if (jffs2_dataflash(c)) { jffs2_dataflash_cleanup(c); diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 4773ba24304..f9e982a65ac 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c @@ -545,7 +545,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, if (ic && alloclen > sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN) alloclen = sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN; - ret = jffs2_reserve_space_gc(c, alloclen, &phys_ofs, &alloclen, rawlen); + ret = jffs2_reserve_space_gc(c, alloclen, &alloclen, rawlen); /* 'rawlen' is not the exact summary size; it is only an upper estimation */ if (ret) @@ -626,19 +626,16 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, /* OK, all the CRCs are good; this node can just be copied as-is. */ retry: - nraw->flash_offset = phys_ofs; + nraw->flash_offset = phys_ofs = write_ofs(c); ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node); if (ret || (retlen != rawlen)) { printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", - rawlen, phys_ofs, ret, retlen); + rawlen, nraw->flash_offset, ret, retlen); if (retlen) { - /* Doesn't belong to any inode */ - nraw->next_in_ino = NULL; - nraw->flash_offset |= REF_OBSOLETE; - jffs2_add_physical_node_ref(c, nraw, rawlen); + jffs2_add_physical_node_ref(c, nraw, rawlen, NULL); jffs2_mark_node_obsolete(c, nraw); } else { printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); @@ -656,7 +653,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); - ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy, rawlen); + ret = jffs2_reserve_space_gc(c, rawlen, &dummy, rawlen); /* this is not the exact summary size of it, it is only an upper estimation */ @@ -678,18 +675,8 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, goto out_node; } nraw->flash_offset |= REF_PRISTINE; - jffs2_add_physical_node_ref(c, nraw, rawlen); + jffs2_add_physical_node_ref(c, nraw, rawlen, ic); - if (ic) { - /* Link into per-inode list. This is safe because of the ic - state being INO_STATE_GC. Note that if we're doing this - for an inode which is in-core, the 'nraw' pointer is then - going to be fetched from ic->nodes by our caller. */ - spin_lock(&c->erase_completion_lock); - nraw->next_in_ino = ic->nodes; - ic->nodes = nraw; - spin_unlock(&c->erase_completion_lock); - } jffs2_mark_node_obsolete(c, raw); D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw))); @@ -709,7 +696,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ struct jffs2_node_frag *last_frag; union jffs2_device_node dev; char *mdata = NULL, mdatalen = 0; - uint32_t alloclen, phys_ofs, ilen; + uint32_t alloclen, ilen; int ret; if (S_ISBLK(JFFS2_F_I_MODE(f)) || @@ -735,7 +722,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ } - ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen, + ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &alloclen, JFFS2_SUMMARY_INODE_SIZE); if (ret) { printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n", @@ -773,7 +760,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); - new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, phys_ofs, ALLOC_GC); + new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, ALLOC_GC); if (IS_ERR(new_fn)) { printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); @@ -794,7 +781,7 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er { struct jffs2_full_dirent *new_fd; struct jffs2_raw_dirent rd; - uint32_t alloclen, phys_ofs; + uint32_t alloclen; int ret; rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -816,14 +803,14 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er 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, + ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &alloclen, JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize)); if (ret) { printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n", sizeof(rd)+rd.nsize, ret); return ret; } - new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, phys_ofs, ALLOC_GC); + new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, ALLOC_GC); if (IS_ERR(new_fd)) { printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd)); @@ -951,7 +938,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras struct jffs2_raw_inode ri; struct jffs2_node_frag *frag; struct jffs2_full_dnode *new_fn; - uint32_t alloclen, phys_ofs, ilen; + uint32_t alloclen, ilen; int ret; D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", @@ -1030,14 +1017,14 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras ri.data_crc = cpu_to_je32(0); ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); - ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen, - JFFS2_SUMMARY_INODE_SIZE); + ret = jffs2_reserve_space_gc(c, sizeof(ri), &alloclen, + JFFS2_SUMMARY_INODE_SIZE); if (ret) { printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n", sizeof(ri), ret); return ret; } - new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_GC); + new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_GC); if (IS_ERR(new_fn)) { printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn)); @@ -1099,7 +1086,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era { struct jffs2_full_dnode *new_fn; struct jffs2_raw_inode ri; - uint32_t alloclen, phys_ofs, offset, orig_end, orig_start; + uint32_t alloclen, offset, orig_end, orig_start; int ret = 0; unsigned char *comprbuf = NULL, *writebuf; unsigned long pg; @@ -1256,7 +1243,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era uint32_t cdatalen; uint16_t comprtype = JFFS2_COMPR_NONE; - ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, + ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &alloclen, JFFS2_SUMMARY_INODE_SIZE); if (ret) { @@ -1293,7 +1280,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era 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); + new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, ALLOC_GC); jffs2_free_comprbuf(comprbuf, writebuf); diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index 7d563f938b1..d25d4919ca9 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c @@ -1048,7 +1048,8 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c) } void jffs2_link_node_ref(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_node_ref *ref, uint32_t len) + struct jffs2_raw_node_ref *ref, uint32_t len, + struct jffs2_inode_cache *ic) { if (!jeb->first_node) jeb->first_node = ref; @@ -1065,6 +1066,13 @@ void jffs2_link_node_ref(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, } jeb->last_node = ref; + if (ic) { + ref->next_in_ino = ic->nodes; + ic->nodes = ref; + } else { + ref->next_in_ino = NULL; + } + switch(ref_flags(ref)) { case REF_UNCHECKED: c->unchecked_size += len; @@ -1120,12 +1128,11 @@ int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size; ref->flash_offset |= REF_OBSOLETE; - ref->next_in_ino = 0; #ifdef TEST_TOTLEN ref->__totlen = size; #endif - jffs2_link_node_ref(c, jeb, ref, size); + jffs2_link_node_ref(c, jeb, ref, size, NULL); } return 0; diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index 80d1fda2212..76f1b9419ee 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h @@ -77,9 +77,9 @@ struct jffs2_raw_node_ref { struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref - for this inode. If this is the last, it points to the inode_cache - for this inode instead. The inode_cache will have NULL in the first - word so you know when you've got there :) */ + for this object. If this _is_ the last, it points to the inode_cache, + xattr_ref or xattr_datum instead. The common part of those structures + has NULL in the first word. See jffs2_raw_ref_to_ic() below */ struct jffs2_raw_node_ref *next_phys; uint32_t flash_offset; #define TEST_TOTLEN @@ -88,6 +88,18 @@ struct jffs2_raw_node_ref #endif }; +static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_node_ref *raw) +{ + while(raw->next_in_ino) { + raw = raw->next_in_ino; + } + + /* NB. This can be a jffs2_xattr_datum or jffs2_xattr_ref and + not actually a jffs2_inode_cache. Check ->class */ + return ((struct jffs2_inode_cache *)raw); +} + + /* 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: */ @@ -113,20 +125,27 @@ struct jffs2_raw_node_ref a pointer to the first physical node which is part of this inode, too. */ struct jffs2_inode_cache { + /* First part of structure is shared with other objects which + can terminate the raw node refs' next_in_ino list -- which + currently struct jffs2_xattr_datum and struct jffs2_xattr_ref. */ + struct jffs2_full_dirent *scan_dents; /* Used during scan to hold temporary lists of dirents, and later must be set to NULL to mark the end of the raw_node_ref->next_in_ino chain. */ - u8 class; /* It's used for identification */ - u8 flags; - uint16_t state; - struct jffs2_inode_cache *next; struct jffs2_raw_node_ref *nodes; + uint8_t class; /* It's used for identification */ + + /* end of shared structure */ + + uint8_t flags; + uint16_t state; uint32_t ino; - int nlink; + struct jffs2_inode_cache *next; #ifdef CONFIG_JFFS2_FS_XATTR struct jffs2_xattr_ref *xref; #endif + int nlink; }; /* Inode states for 'state' above. We need the 'GC' state to prevent @@ -148,6 +167,8 @@ struct jffs2_inode_cache { #define INOCACHE_HASHSIZE 128 +#define write_ofs(c) ((c)->nextblock->offset + (c)->sector_size - (c)->nextblock->free_size) + /* Larger representation of a raw node, kept in-core only when the struct inode for this particular ino is instantiated. @@ -250,15 +271,6 @@ static inline int jffs2_encode_dev(union jffs2_device_node *jdev, dev_t rdev) } } -static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_node_ref *raw) -{ - while(raw->next_in_ino) { - raw = raw->next_in_ino; - } - - return ((struct jffs2_inode_cache *)raw); -} - static inline struct jffs2_node_frag *frag_first(struct rb_root *root) { struct rb_node *node = root->rb_node; @@ -307,32 +319,43 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); void jffs2_link_node_ref(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_node_ref *ref, uint32_t len); + struct jffs2_raw_node_ref *ref, uint32_t len, + struct jffs2_inode_cache *ic); extern uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, struct jffs2_raw_node_ref *ref); /* nodemgmt.c */ int jffs2_thread_should_wake(struct jffs2_sb_info *c); -int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, +int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *len, int prio, uint32_t sumsize); -int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, +int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *len, uint32_t sumsize); -int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, uint32_t len); +int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, + struct jffs2_raw_node_ref *new, + uint32_t len, + struct jffs2_inode_cache *ic); void jffs2_complete_reservation(struct jffs2_sb_info *c); void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw); /* write.c */ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri); -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); +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, 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, 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, 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); -int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time); +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); +int jffs2_do_link(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, + uint8_t type, const char *name, int namelen, uint32_t time); /* readinode.c */ diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 9a0f312cfcd..8feb8749bc7 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c @@ -23,13 +23,12 @@ * jffs2_reserve_space - request physical space to write nodes to flash * @c: superblock info * @minsize: Minimum acceptable size of allocation - * @ofs: Returned value of node offset * @len: Returned value of allocation length * @prio: Allocation type - ALLOC_{NORMAL,DELETION} * * Requests a block of physical space on the flash. Returns zero for success - * and puts 'ofs' and 'len' into the appriopriate place, or returns -ENOSPC - * or other error if appropriate. + * and puts 'len' into the appropriate place, or returns -ENOSPC or other + * error if appropriate. Doesn't return len since that's * * If it returns zero, jffs2_reserve_space() also downs the per-filesystem * allocation semaphore, to prevent more than one allocation from being @@ -40,9 +39,9 @@ */ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, - uint32_t *ofs, uint32_t *len, uint32_t sumsize); + uint32_t *len, uint32_t sumsize); -int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, +int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *len, int prio, uint32_t sumsize) { int ret = -EAGAIN; @@ -132,7 +131,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs spin_lock(&c->erase_completion_lock); } - ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize); + ret = jffs2_do_reserve_space(c, minsize, len, sumsize); if (ret) { D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret)); } @@ -143,8 +142,8 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs return ret; } -int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, - uint32_t *len, uint32_t sumsize) +int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, + uint32_t *len, uint32_t sumsize) { int ret = -EAGAIN; minsize = PAD(minsize); @@ -153,7 +152,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t * spin_lock(&c->erase_completion_lock); while(ret == -EAGAIN) { - ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize); + ret = jffs2_do_reserve_space(c, minsize, len, sumsize); if (ret) { D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); } @@ -259,10 +258,11 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c) } /* Called with alloc sem _and_ erase_completion_lock */ -static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize) +static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, + uint32_t *len, uint32_t sumsize) { struct jffs2_eraseblock *jeb = c->nextblock; - uint32_t reserved_size; /* for summary information at the end of the jeb */ + uint32_t reserved_size; /* for summary information at the end of the jeb */ int ret; restart: @@ -349,7 +349,6 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin } /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has enough space */ - *ofs = jeb->offset + (c->sector_size - jeb->free_size); *len = jeb->free_size - reserved_size; if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size && @@ -365,7 +364,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin spin_lock(&c->erase_completion_lock); } - D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs)); + D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", + *len, jeb->offset + (c->sector_size - jeb->free_size))); return 0; } @@ -381,7 +381,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin * 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, uint32_t len) +int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, + uint32_t len, struct jffs2_inode_cache *ic) { struct jffs2_eraseblock *jeb; @@ -403,7 +404,7 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r #endif spin_lock(&c->erase_completion_lock); - jffs2_link_node_ref(c, jeb, new, len); + jffs2_link_node_ref(c, jeb, new, len, ic); if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) { /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ @@ -660,6 +661,10 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref spin_lock(&c->erase_completion_lock); ic = jffs2_raw_ref_to_ic(ref); + /* It seems we should never call jffs2_mark_node_obsolete() for + XATTR nodes.... yet. Make sure we notice if/when we change + that :) */ + BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE); for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino)) ; diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index d2ad2a2081d..743c9e52152 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -92,11 +92,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) #define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e) #define jffs2_wbuf_timeout NULL #define jffs2_wbuf_process NULL -#define jffs2_nor_ecc(c) (0) #define jffs2_dataflash(c) (0) -#define jffs2_nor_wbuf_flash(c) (0) -#define jffs2_nor_ecc_flash_setup(c) (0) -#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) #define jffs2_dataflash_setup(c) (0) #define jffs2_dataflash_cleanup(c) do {} while (0) #define jffs2_nor_wbuf_flash_setup(c) (0) @@ -109,9 +105,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) #ifdef CONFIG_JFFS2_SUMMARY #define jffs2_can_mark_obsolete(c) (0) #else -#define jffs2_can_mark_obsolete(c) \ - ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & (MTD_ECC|MTD_PROGRAM_REGIONS))) || \ - c->mtd->type == MTD_RAM) +#define jffs2_can_mark_obsolete(c) (c->mtd->flags & (MTD_BIT_WRITEABLE)) #endif #define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) @@ -135,15 +129,11 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); int jffs2_nand_flash_setup(struct jffs2_sb_info *c); void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c); -#define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC)) -int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c); -void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c); - #define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH) int jffs2_dataflash_setup(struct jffs2_sb_info *c); void jffs2_dataflash_cleanup(struct jffs2_sb_info *c); -#define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_PROGRAM_REGIONS)) +#define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && ! (c->mtd->flags & MTD_BIT_WRITEABLE)) int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c); void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c); diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index cffafec01e4..6fce703c054 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -361,9 +361,9 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc xd->node = raw; raw->flash_offset = ofs | REF_PRISTINE; - raw->next_in_ino = (void *)xd; - jffs2_link_node_ref(c, jeb, raw, totlen); + jffs2_link_node_ref(c, jeb, raw, totlen, NULL); + /* FIXME */ raw->next_in_ino = (void *)xd; if (jffs2_sum_active()) jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); @@ -425,9 +425,9 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock c->xref_temp = ref; raw->flash_offset = ofs | REF_PRISTINE; - raw->next_in_ino = (void *)ref; - jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rr->totlen))); + jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rr->totlen)), NULL); + /* FIXME */ raw->next_in_ino = (void *)ref; if (jffs2_sum_active()) jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); @@ -844,10 +844,9 @@ scan_more: printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n"); return -ENOMEM; } - marker_ref->next_in_ino = NULL; marker_ref->flash_offset = ofs | REF_NORMAL; - jffs2_link_node_ref(c, jeb, marker_ref, c->cleanmarker_size); + jffs2_link_node_ref(c, jeb, marker_ref, c->cleanmarker_size, NULL); ofs += PAD(c->cleanmarker_size); } @@ -892,8 +891,7 @@ scan_more: if (!ref) return -ENOMEM; ref->flash_offset = ofs | REF_PRISTINE; - ref->next_in_ino = 0; - jffs2_link_node_ref(c, jeb, ref, PAD(je32_to_cpu(node->totlen))); + jffs2_link_node_ref(c, jeb, ref, PAD(je32_to_cpu(node->totlen)), NULL); /* We can't summarise nodes we don't grok */ jffs2_sum_disable_collecting(s); @@ -1004,10 +1002,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc raw->flash_offset = ofs | REF_UNCHECKED; - raw->next_in_ino = ic->nodes; - ic->nodes = raw; - - jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(ri->totlen))); + jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(ri->totlen)), ic); 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), @@ -1082,10 +1077,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo } raw->flash_offset = ofs | REF_PRISTINE; - raw->next_in_ino = ic->nodes; - ic->nodes = raw; - - jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rd->totlen))); + jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rd->totlen)), ic); fd->raw = raw; fd->next = NULL; diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 1451732e1fa..351ba9f8185 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c @@ -430,10 +430,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras raw->flash_offset |= REF_UNCHECKED; - raw->next_in_ino = ic->nodes; - ic->nodes = raw; - - jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spi->totlen))); + jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spi->totlen)), ic); *pseudo_random += je32_to_cpu(spi->version); @@ -473,10 +470,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras } raw->flash_offset |= REF_PRISTINE; - raw->next_in_ino = ic->nodes; - ic->nodes = raw; - - jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spd->totlen))); + jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spd->totlen)), ic); fd->raw = raw; fd->next = NULL; @@ -525,9 +519,9 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras xd->node = raw; raw->flash_offset |= REF_UNCHECKED; - raw->next_in_ino = (void *)xd; - jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spx->totlen))); + jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spx->totlen)), NULL); + /* FIXME */ raw->next_in_ino = (void *)xd; *pseudo_random += je32_to_cpu(spx->xid); sp += JFFS2_SUMMARY_XATTR_SIZE; @@ -561,9 +555,9 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras c->xref_temp = ref; raw->flash_offset |= REF_UNCHECKED; - raw->next_in_ino = (void *)ref; - jffs2_link_node_ref(c, jeb, raw, PAD(sizeof(struct jffs2_raw_xref))); + jffs2_link_node_ref(c, jeb, raw, PAD(sizeof(struct jffs2_raw_xref)), NULL); + /* FIXME */ raw->next_in_ino = (void *)ref; *pseudo_random += raw->flash_offset; sp += JFFS2_SUMMARY_XREF_SIZE; @@ -664,9 +658,8 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb } marker_ref->flash_offset = jeb->offset | REF_NORMAL; - marker_ref->next_in_ino = NULL; - jffs2_link_node_ref(c, jeb, marker_ref, je32_to_cpu(summary->cln_mkr)); + jffs2_link_node_ref(c, jeb, marker_ref, je32_to_cpu(summary->cln_mkr), NULL); } } @@ -686,10 +679,9 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb return -ENOMEM; } - cache_ref->next_in_ino = NULL; cache_ref->flash_offset |= REF_NORMAL; - jffs2_link_node_ref(c, jeb, cache_ref, sumsize); + jffs2_link_node_ref(c, jeb, cache_ref, sumsize, NULL); if (unlikely(jeb->free_size)) { JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n", @@ -849,9 +841,8 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size; ref->flash_offset |= REF_OBSOLETE; - ref->next_in_ino = 0; - jffs2_link_node_ref(c, jeb, ref, c->sector_size - jeb->free_size); + jffs2_link_node_ref(c, jeb, ref, c->sector_size - jeb->free_size, NULL); } c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE; @@ -909,11 +900,10 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) return -ENOMEM; } - summary_ref->next_in_ino = NULL; summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL; spin_lock(&c->erase_completion_lock); - jffs2_link_node_ref(c, jeb, summary_ref, infosize); + jffs2_link_node_ref(c, jeb, summary_ref, infosize, NULL); return 0; } diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 0442a5753d3..916c87d3393 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -265,12 +265,14 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) /* ... and get an allocation of space from a shiny new block instead */ - ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len, JFFS2_SUMMARY_NOSUM_SIZE); + ret = jffs2_reserve_space_gc(c, end-start, &len, JFFS2_SUMMARY_NOSUM_SIZE); if (ret) { printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n"); kfree(buf); return; } + ofs = write_ofs(c); + if (end-start >= c->wbuf_pagesize) { /* Need to do another write immediately, but it's possible that this is just because the wbuf itself is completely @@ -312,9 +314,8 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) return; raw2->flash_offset = ofs | REF_OBSOLETE; - raw2->next_in_ino = NULL; - jffs2_add_physical_node_ref(c, raw2, ref_totlen(c, jeb, *first_raw)); + jffs2_add_physical_node_ref(c, raw2, ref_totlen(c, jeb, *first_raw), NULL); } return; } @@ -507,11 +508,10 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) return -ENOMEM; ref->flash_offset = c->wbuf_ofs + c->wbuf_len; ref->flash_offset |= REF_OBSOLETE; - ref->next_in_ino = NULL; spin_lock(&c->erase_completion_lock); - jffs2_link_node_ref(c, jeb, ref, waste); + jffs2_link_node_ref(c, jeb, ref, waste, NULL); /* FIXME: that made it count as dirty. Convert to wasted */ jeb->dirty_size -= waste; c->dirty_size -= waste; @@ -650,19 +650,6 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, } /* - * Fixup the wbuf if we are moving to a new eraseblock. The - * checks below fail for ECC'd NOR because cleanmarker == 16, - * so a block starts at xxx0010. - */ - if (jffs2_nor_ecc(c)) { - if (((c->wbuf_ofs % c->sector_size) == 0) && !c->wbuf_len) { - c->wbuf_ofs = PAGE_DIV(to); - c->wbuf_len = PAGE_MOD(to); - 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 erase block. Anything else, @@ -1107,7 +1094,7 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c) /* Initialise write buffer */ init_rwsem(&c->wbuf_sem); - c->wbuf_pagesize = c->mtd->oobblock; + c->wbuf_pagesize = c->mtd->writesize; c->wbuf_ofs = 0xFFFFFFFF; c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); @@ -1178,33 +1165,14 @@ void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) { kfree(c->wbuf); } -int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) { - /* Cleanmarker is actually larger on the flashes */ - c->cleanmarker_size = 16; - - /* Initialize write buffer */ - init_rwsem(&c->wbuf_sem); - c->wbuf_pagesize = c->mtd->eccsize; - c->wbuf_ofs = 0xFFFFFFFF; - - c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); - if (!c->wbuf) - return -ENOMEM; - - return 0; -} - -void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) { - kfree(c->wbuf); -} - int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) { - /* Cleanmarker currently occupies a whole programming region */ - c->cleanmarker_size = MTD_PROGREGION_SIZE(c->mtd); + /* Cleanmarker currently occupies whole programming regions, + * either one or 2 for 8Byte STMicro flashes. */ + c->cleanmarker_size = max(16u, c->mtd->writesize); /* Initialize write buffer */ init_rwsem(&c->wbuf_sem); - c->wbuf_pagesize = MTD_PROGREGION_SIZE(c->mtd); + c->wbuf_pagesize = c->mtd->writesize; c->wbuf_ofs = 0xFFFFFFFF; c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index 4462541d11f..0e12b7561b7 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c @@ -56,12 +56,15 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint /* 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) +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, int alloc_mode) { struct jffs2_raw_node_ref *raw; struct jffs2_full_dnode *fn; size_t retlen; + uint32_t flash_ofs; struct kvec vecs[2]; int ret; int retried = 0; @@ -77,8 +80,6 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 vecs[1].iov_base = (unsigned char *)data; vecs[1].iov_len = datalen; - jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); - if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); } @@ -102,7 +103,9 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 retry: fn->raw = raw; - raw->flash_offset = flash_ofs; + raw->flash_offset = flash_ofs = write_ofs(c); + + jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { BUG_ON(!retried); @@ -122,16 +125,13 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 /* Mark the space as dirtied */ if (retlen) { - /* Doesn't belong to any inode */ - raw->next_in_ino = NULL; - /* 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 this node */ raw->flash_offset |= REF_OBSOLETE; - jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen)); + jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen), NULL); jffs2_mark_node_obsolete(c, raw); } else { printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); @@ -150,19 +150,20 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 jffs2_dbg_acct_paranoia_check(c, jeb); if (alloc_mode == ALLOC_GC) { - ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, - &dummy, JFFS2_SUMMARY_INODE_SIZE); + ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &dummy, + JFFS2_SUMMARY_INODE_SIZE); } else { /* 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); + ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &dummy, + alloc_mode, JFFS2_SUMMARY_INODE_SIZE); down(&f->sem); } if (!ret) { + flash_ofs = write_ofs(c); D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); jffs2_dbg_acct_sanity_check(c,jeb); @@ -189,13 +190,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 } else { raw->flash_offset |= REF_NORMAL; } - jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen)); - - /* Link into per-inode list */ - spin_lock(&c->erase_completion_lock); - raw->next_in_ino = f->inocache->nodes; - f->inocache->nodes = raw; - spin_unlock(&c->erase_completion_lock); + jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen), f->inocache); 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), @@ -209,12 +204,15 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 return fn; } -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) +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, int alloc_mode) { struct jffs2_raw_node_ref *raw; struct jffs2_full_dirent *fd; size_t retlen; struct kvec vecs[2]; + uint32_t flash_ofs = write_ofs(c); int retried = 0; int ret; @@ -275,9 +273,8 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff sizeof(*rd)+namelen, flash_ofs, ret, retlen); /* Mark the space as dirtied */ if (retlen) { - raw->next_in_ino = NULL; raw->flash_offset |= REF_OBSOLETE; - jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen)); + jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen), NULL); jffs2_mark_node_obsolete(c, raw); } else { printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); @@ -296,19 +293,20 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff jffs2_dbg_acct_paranoia_check(c, jeb); if (alloc_mode == ALLOC_GC) { - ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, - &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); + ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &dummy, + JFFS2_SUMMARY_DIRENT_SIZE(namelen)); } else { /* 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)); + ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &dummy, + alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); down(&f->sem); } if (!ret) { + flash_ofs = write_ofs(c); D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); @@ -323,12 +321,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff } /* Mark the space used */ raw->flash_offset |= REF_PRISTINE; - jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen)); - - spin_lock(&c->erase_completion_lock); - raw->next_in_ino = f->inocache->nodes; - f->inocache->nodes = raw; - spin_unlock(&c->erase_completion_lock); + jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen), f->inocache); if (retried) { jffs2_dbg_acct_sanity_check(c,NULL); @@ -354,14 +347,14 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn; unsigned char *comprbuf = NULL; uint16_t comprtype = JFFS2_COMPR_NONE; - uint32_t phys_ofs, alloclen; + uint32_t alloclen; uint32_t datalen, cdatalen; int retried = 0; retry: D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); - ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, + ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) { D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); @@ -389,7 +382,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); - fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY); + fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY); jffs2_free_comprbuf(comprbuf, buf); @@ -443,13 +436,13 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str struct jffs2_raw_dirent *rd; struct jffs2_full_dnode *fn; struct jffs2_full_dirent *fd; - uint32_t alloclen, phys_ofs; + uint32_t alloclen; int ret; /* 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, + ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); if (ret) { @@ -460,7 +453,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str 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); + fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL); D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n", jemode_to_cpu(ri->mode))); @@ -479,7 +472,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str up(&f->sem); jffs2_complete_reservation(c); - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); if (ret) { @@ -511,7 +504,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); - fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); + fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL); jffs2_free_raw_dirent(rd); @@ -540,7 +533,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, { struct jffs2_raw_dirent *rd; struct jffs2_full_dirent *fd; - uint32_t alloclen, phys_ofs; + uint32_t alloclen; int ret; if (1 /* alternative branch needs testing */ || @@ -551,7 +544,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, if (!rd) return -ENOMEM; - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); if (ret) { jffs2_free_raw_dirent(rd); @@ -575,7 +568,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); - fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); + fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_DELETION); jffs2_free_raw_dirent(rd); @@ -654,14 +647,14 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint { struct jffs2_raw_dirent *rd; struct jffs2_full_dirent *fd; - uint32_t alloclen, phys_ofs; + uint32_t alloclen; int ret; rd = jffs2_alloc_raw_dirent(); if (!rd) return -ENOMEM; - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); if (ret) { jffs2_free_raw_dirent(rd); @@ -687,7 +680,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); - fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); + fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL); jffs2_free_raw_dirent(rd); diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index e16f8460ff0..008f91b1c17 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -49,9 +49,9 @@ * is used to be as a wrapper of do_verify_xattr_datum() and do_load_xattr_datum(). * If xd need to call do_verify_xattr_datum() at first, it's called before calling * do_load_xattr_datum(). The meanings of return value is same as do_verify_xattr_datum(). - * save_xattr_datum(c, xd, phys_ofs) + * save_xattr_datum(c, xd) * is used to write xdatum to medium. xd->version will be incremented. - * create_xattr_datum(c, xprefix, xname, xvalue, xsize, phys_ofs) + * create_xattr_datum(c, xprefix, xname, xvalue, xsize) * is used to create new xdatum and write to medium. * -------------------------------------------------- */ @@ -301,7 +301,7 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x return rc; } -static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd, uint32_t phys_ofs) +static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { /* must be called under down_write(xattr_sem) */ struct jffs2_raw_xattr rx; @@ -309,6 +309,7 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x struct kvec vecs[2]; uint32_t length; int rc, totlen; + uint32_t phys_ofs = write_ofs(c); BUG_ON(!xd->xname); @@ -322,7 +323,6 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x if (!raw) return -ENOMEM; raw->flash_offset = phys_ofs; - raw->next_in_ino = (void *)xd; /* Setup raw-xattr */ rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -345,8 +345,7 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x rc = rc ? rc : -EIO; if (length) { raw->flash_offset |= REF_OBSOLETE; - raw->next_in_ino = NULL; - jffs2_add_physical_node_ref(c, raw, PAD(totlen)); + jffs2_add_physical_node_ref(c, raw, PAD(totlen), NULL); jffs2_mark_node_obsolete(c, raw); } else { jffs2_free_raw_node_ref(raw); @@ -356,7 +355,9 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x /* success */ raw->flash_offset |= REF_PRISTINE; - jffs2_add_physical_node_ref(c, raw, PAD(totlen)); + jffs2_add_physical_node_ref(c, raw, PAD(totlen), NULL); + /* FIXME */ raw->next_in_ino = (void *)xd; + if (xd->node) delete_xattr_datum_node(c, xd); xd->node = raw; @@ -369,8 +370,7 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, int xprefix, const char *xname, - const char *xvalue, int xsize, - uint32_t phys_ofs) + const char *xvalue, int xsize) { /* must be called under down_write(xattr_sem) */ struct jffs2_xattr_datum *xd; @@ -419,7 +419,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, xd->value_len = xsize; xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len); - rc = save_xattr_datum(c, xd, phys_ofs); + rc = save_xattr_datum(c, xd); if (rc) { kfree(xd->xname); jffs2_free_xattr_datum(xd); @@ -446,9 +446,9 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, * delete_xattr_ref(c, ref) * is used to delete jffs2_xattr_ref object. If the reference counter of xdatum * is refered by this xref become 0, delete_xattr_datum() is called later. - * save_xattr_ref(c, ref, phys_ofs) + * save_xattr_ref(c, ref) * is used to write xref to medium. - * create_xattr_ref(c, ic, xd, phys_ofs) + * create_xattr_ref(c, ic, xd) * is used to create a new xref and write to medium. * jffs2_xattr_delete_inode(c, ic) * is called to remove xrefs related to obsolete inode when inode is unlinked. @@ -554,19 +554,19 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re jffs2_free_xattr_ref(ref); } -static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, uint32_t phys_ofs) +static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) { /* must be called under down_write(xattr_sem) */ struct jffs2_raw_node_ref *raw; struct jffs2_raw_xref rr; uint32_t length; + uint32_t phys_ofs = write_ofs(c); int ret; raw = jffs2_alloc_raw_node_ref(); if (!raw) return -ENOMEM; raw->flash_offset = phys_ofs; - raw->next_in_ino = (void *)ref; rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF); @@ -584,8 +584,7 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, ret = ret ? ret : -EIO; if (length) { raw->flash_offset |= REF_OBSOLETE; - raw->next_in_ino = NULL; - jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr))); + jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)), NULL); jffs2_mark_node_obsolete(c, raw); } else { jffs2_free_raw_node_ref(raw); @@ -594,7 +593,8 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, } raw->flash_offset |= REF_PRISTINE; - jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr))); + jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)), NULL); + /* FIXME */ raw->next_in_ino = (void *)ref; if (ref->node) delete_xattr_ref_node(c, ref); ref->node = raw; @@ -605,7 +605,7 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, } static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, - struct jffs2_xattr_datum *xd, uint32_t phys_ofs) + struct jffs2_xattr_datum *xd) { /* must be called under down_write(xattr_sem) */ struct jffs2_xattr_ref *ref; @@ -617,7 +617,7 @@ static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct ref->ic = ic; ref->xd = xd; - ret = save_xattr_ref(c, ref, phys_ofs); + ret = save_xattr_ref(c, ref); if (ret) { jffs2_free_xattr_ref(ref); return ERR_PTR(ret); @@ -1063,7 +1063,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, struct jffs2_inode_cache *ic = f->inocache; struct jffs2_xattr_datum *xd; struct jffs2_xattr_ref *ref, *newref, **pref; - uint32_t phys_ofs, length, request; + uint32_t length, request; int rc; rc = check_xattr_ref_inode(c, ic); @@ -1071,7 +1071,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, return rc; request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size); - rc = jffs2_reserve_space(c, request, &phys_ofs, &length, + rc = jffs2_reserve_space(c, request, &length, ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE); if (rc) { JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); @@ -1118,7 +1118,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, goto out; } found: - xd = create_xattr_datum(c, xprefix, xname, buffer, size, phys_ofs); + xd = create_xattr_datum(c, xprefix, xname, buffer, size); if (IS_ERR(xd)) { rc = PTR_ERR(xd); goto out; @@ -1128,7 +1128,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, /* create xattr_ref */ request = PAD(sizeof(struct jffs2_raw_xref)); - rc = jffs2_reserve_space(c, request, &phys_ofs, &length, + rc = jffs2_reserve_space(c, request, &length, ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE); if (rc) { JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); @@ -1142,7 +1142,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, down_write(&c->xattr_sem); if (ref) *pref = ref->next; - newref = create_xattr_ref(c, ic, xd, phys_ofs); + newref = create_xattr_ref(c, ic, xd); if (IS_ERR(newref)) { if (ref) { ref->next = ic->xref; @@ -1171,7 +1171,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, * -------------------------------------------------- */ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) { - uint32_t phys_ofs, totlen, length, old_ofs; + uint32_t totlen, length, old_ofs; int rc = -EINVAL; down_write(&c->xattr_sem); @@ -1191,13 +1191,13 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt } else if (unlikely(rc < 0)) goto out; } - rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE); + rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); if (rc || length < totlen) { JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen); rc = rc ? rc : -EBADFD; goto out; } - rc = save_xattr_datum(c, xd, phys_ofs); + rc = save_xattr_datum(c, xd); if (!rc) dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n", xd->xid, xd->version, old_ofs, ref_offset(xd->node)); @@ -1209,7 +1209,7 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) { - uint32_t phys_ofs, totlen, length, old_ofs; + uint32_t totlen, length, old_ofs; int rc = -EINVAL; down_write(&c->xattr_sem); @@ -1220,14 +1220,14 @@ int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ if (totlen != sizeof(struct jffs2_raw_xref)) goto out; - rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE); + rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE); if (rc || length < totlen) { JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n", __FUNCTION__, rc, totlen); rc = rc ? rc : -EBADFD; goto out; } - rc = save_xattr_ref(c, ref, phys_ofs); + rc = save_xattr_ref(c, ref); if (!rc) dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n", ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node)); diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index e2aa2394ab6..2c199856c58 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h @@ -20,11 +20,11 @@ struct jffs2_xattr_datum { void *always_null; - u8 class; - u8 flags; - u16 xprefix; /* see JFFS2_XATTR_PREFIX_* */ - struct jffs2_raw_node_ref *node; + uint8_t class; + uint8_t flags; + uint16_t xprefix; /* see JFFS2_XATTR_PREFIX_* */ + struct list_head xindex; /* chained from c->xattrindex[n] */ uint32_t refcnt; /* # of xattr_ref refers this */ uint32_t xid; @@ -42,11 +42,11 @@ struct jffs2_inode_cache; struct jffs2_xattr_ref { void *always_null; - u8 class; - u8 flags; /* Currently unused */ + struct jffs2_raw_node_ref *node; + uint8_t class; + uint8_t flags; /* Currently unused */ u16 unused; - struct jffs2_raw_node_ref *node; union { struct jffs2_inode_cache *ic; /* reference to jffs2_inode_cache */ uint32_t ino; /* only used in scanning/building */ |