write.c (e631ddba588783edd521c5a89f7b2902772fb691) | write.c (182ec4eee397543101a6db8906ed88727d3f7e53) |
---|---|
1/* 2 * JFFS2 -- Journalling Flash File System, Version 2. 3 * 4 * Copyright (C) 2001-2003 Red Hat, Inc. 5 * 6 * Created by David Woodhouse <dwmw2@infradead.org> 7 * 8 * For licensing information, see the file 'LICENCE' in this directory. 9 * | 1/* 2 * JFFS2 -- Journalling Flash File System, Version 2. 3 * 4 * Copyright (C) 2001-2003 Red Hat, Inc. 5 * 6 * Created by David Woodhouse <dwmw2@infradead.org> 7 * 8 * For licensing information, see the file 'LICENCE' in this directory. 9 * |
10 * $Id: write.c,v 1.96 2005/09/07 08:34:55 havasi Exp $ | 10 * $Id: write.c,v 1.97 2005/11/07 11:14:42 gleixner Exp $ |
11 * 12 */ 13 14#include <linux/kernel.h> 15#include <linux/fs.h> 16#include <linux/crc32.h> 17#include <linux/slab.h> 18#include <linux/pagemap.h> --- 30 unchanged lines hidden (view full) --- 49 ri->mode = cpu_to_jemode(mode); 50 51 f->highest_version = 1; 52 ri->version = cpu_to_je32(f->highest_version); 53 54 return 0; 55} 56 | 11 * 12 */ 13 14#include <linux/kernel.h> 15#include <linux/fs.h> 16#include <linux/crc32.h> 17#include <linux/slab.h> 18#include <linux/pagemap.h> --- 30 unchanged lines hidden (view full) --- 49 ri->mode = cpu_to_jemode(mode); 50 51 f->highest_version = 1; 52 ri->version = cpu_to_je32(f->highest_version); 53 54 return 0; 55} 56 |
57/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, | 57/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, |
58 write it to the flash, link it into the existing inode/fragment list */ 59 60struct 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) 61 62{ 63 struct jffs2_raw_node_ref *raw; 64 struct jffs2_full_dnode *fn; 65 size_t retlen; --- 15 unchanged lines hidden (view full) --- 81 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); 82 83 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 84 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); 85 } 86 raw = jffs2_alloc_raw_node_ref(); 87 if (!raw) 88 return ERR_PTR(-ENOMEM); | 58 write it to the flash, link it into the existing inode/fragment list */ 59 60struct 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) 61 62{ 63 struct jffs2_raw_node_ref *raw; 64 struct jffs2_full_dnode *fn; 65 size_t retlen; --- 15 unchanged lines hidden (view full) --- 81 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); 82 83 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 84 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); 85 } 86 raw = jffs2_alloc_raw_node_ref(); 87 if (!raw) 88 return ERR_PTR(-ENOMEM); |
89 | 89 |
90 fn = jffs2_alloc_full_dnode(); 91 if (!fn) { 92 jffs2_free_raw_node_ref(raw); 93 return ERR_PTR(-ENOMEM); 94 } 95 96 fn->ofs = je32_to_cpu(ri->offset); 97 fn->size = je32_to_cpu(ri->dsize); --- 7 unchanged lines hidden (view full) --- 105 106 raw->flash_offset = flash_ofs; 107 raw->__totlen = PAD(sizeof(*ri)+datalen); 108 raw->next_phys = NULL; 109 110 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { 111 BUG_ON(!retried); 112 D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, " | 90 fn = jffs2_alloc_full_dnode(); 91 if (!fn) { 92 jffs2_free_raw_node_ref(raw); 93 return ERR_PTR(-ENOMEM); 94 } 95 96 fn->ofs = je32_to_cpu(ri->offset); 97 fn->size = je32_to_cpu(ri->dsize); --- 7 unchanged lines hidden (view full) --- 105 106 raw->flash_offset = flash_ofs; 107 raw->__totlen = PAD(sizeof(*ri)+datalen); 108 raw->next_phys = NULL; 109 110 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { 111 BUG_ON(!retried); 112 D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, " |
113 "highest version %d -> updating dnode\n", | 113 "highest version %d -> updating dnode\n", |
114 je32_to_cpu(ri->version), f->highest_version)); 115 ri->version = cpu_to_je32(++f->highest_version); 116 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 117 } 118 119 ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen, 120 (alloc_mode==ALLOC_GC)?0:f->inocache->ino); 121 122 if (ret || (retlen != sizeof(*ri) + datalen)) { | 114 je32_to_cpu(ri->version), f->highest_version)); 115 ri->version = cpu_to_je32(++f->highest_version); 116 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 117 } 118 119 ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen, 120 (alloc_mode==ALLOC_GC)?0:f->inocache->ino); 121 122 if (ret || (retlen != sizeof(*ri) + datalen)) { |
123 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", | 123 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", |
124 sizeof(*ri)+datalen, flash_ofs, ret, retlen); 125 126 /* Mark the space as dirtied */ 127 if (retlen) { 128 /* Doesn't belong to any inode */ 129 raw->next_in_ino = NULL; 130 | 124 sizeof(*ri)+datalen, flash_ofs, ret, retlen); 125 126 /* Mark the space as dirtied */ 127 if (retlen) { 128 /* Doesn't belong to any inode */ 129 raw->next_in_ino = NULL; 130 |
131 /* Don't change raw->size to match retlen. We may have | 131 /* Don't change raw->size to match retlen. We may have |
132 written the node header already, and only the data will 133 seem corrupted, in which case the scan would skip over | 132 written the node header already, and only the data will 133 seem corrupted, in which case the scan would skip over |
134 any node we write before the original intended end of | 134 any node we write before the original intended end of |
135 this node */ 136 raw->flash_offset |= REF_OBSOLETE; 137 jffs2_add_physical_node_ref(c, raw); 138 jffs2_mark_node_obsolete(c, raw); 139 } else { 140 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 141 jffs2_free_raw_node_ref(raw); 142 } 143 if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) { 144 /* Try to reallocate space and retry */ 145 uint32_t dummy; 146 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 147 148 retried = 1; 149 150 D1(printk(KERN_DEBUG "Retrying failed write.\n")); | 135 this node */ 136 raw->flash_offset |= REF_OBSOLETE; 137 jffs2_add_physical_node_ref(c, raw); 138 jffs2_mark_node_obsolete(c, raw); 139 } else { 140 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 141 jffs2_free_raw_node_ref(raw); 142 } 143 if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) { 144 /* Try to reallocate space and retry */ 145 uint32_t dummy; 146 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 147 148 retried = 1; 149 150 D1(printk(KERN_DEBUG "Retrying failed write.\n")); |
151 | 151 |
152 jffs2_dbg_acct_sanity_check(c,jeb); 153 jffs2_dbg_acct_paranoia_check(c, jeb); 154 155 if (alloc_mode == ALLOC_GC) { 156 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, 157 &dummy, JFFS2_SUMMARY_INODE_SIZE); 158 } else { 159 /* Locking pain */ 160 up(&f->sem); 161 jffs2_complete_reservation(c); | 152 jffs2_dbg_acct_sanity_check(c,jeb); 153 jffs2_dbg_acct_paranoia_check(c, jeb); 154 155 if (alloc_mode == ALLOC_GC) { 156 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, 157 &dummy, JFFS2_SUMMARY_INODE_SIZE); 158 } else { 159 /* Locking pain */ 160 up(&f->sem); 161 jffs2_complete_reservation(c); |
162 | 162 |
163 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, 164 &dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE); 165 down(&f->sem); 166 } 167 168 if (!ret) { 169 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 170 --- 5 unchanged lines hidden (view full) --- 176 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 177 jffs2_free_raw_node_ref(raw); 178 } 179 /* Release the full_dnode which is now useless, and return */ 180 jffs2_free_full_dnode(fn); 181 return ERR_PTR(ret?ret:-EIO); 182 } 183 /* Mark the space used */ | 163 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, 164 &dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE); 165 down(&f->sem); 166 } 167 168 if (!ret) { 169 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 170 --- 5 unchanged lines hidden (view full) --- 176 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 177 jffs2_free_raw_node_ref(raw); 178 } 179 /* Release the full_dnode which is now useless, and return */ 180 jffs2_free_full_dnode(fn); 181 return ERR_PTR(ret?ret:-EIO); 182 } 183 /* Mark the space used */ |
184 /* If node covers at least a whole page, or if it starts at the 185 beginning of a page and runs to the end of the file, or if 186 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. | 184 /* If node covers at least a whole page, or if it starts at the 185 beginning of a page and runs to the end of the file, or if 186 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. |
187 */ 188 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || 189 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && 190 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { 191 raw->flash_offset |= REF_PRISTINE; 192 } else { 193 raw->flash_offset |= REF_NORMAL; 194 } 195 jffs2_add_physical_node_ref(c, raw); 196 197 /* Link into per-inode list */ 198 spin_lock(&c->erase_completion_lock); 199 raw->next_in_ino = f->inocache->nodes; 200 f->inocache->nodes = raw; 201 spin_unlock(&c->erase_completion_lock); 202 203 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", | 187 */ 188 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || 189 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && 190 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { 191 raw->flash_offset |= REF_PRISTINE; 192 } else { 193 raw->flash_offset |= REF_NORMAL; 194 } 195 jffs2_add_physical_node_ref(c, raw); 196 197 /* Link into per-inode list */ 198 spin_lock(&c->erase_completion_lock); 199 raw->next_in_ino = f->inocache->nodes; 200 f->inocache->nodes = raw; 201 spin_unlock(&c->erase_completion_lock); 202 203 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", |
204 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), | 204 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), |
205 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), 206 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); 207 208 if (retried) { 209 jffs2_dbg_acct_sanity_check(c,NULL); 210 } 211 212 return fn; 213} 214 215struct 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) 216{ 217 struct jffs2_raw_node_ref *raw; 218 struct jffs2_full_dirent *fd; 219 size_t retlen; 220 struct kvec vecs[2]; 221 int retried = 0; 222 int ret; 223 | 205 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), 206 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); 207 208 if (retried) { 209 jffs2_dbg_acct_sanity_check(c,NULL); 210 } 211 212 return fn; 213} 214 215struct 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) 216{ 217 struct jffs2_raw_node_ref *raw; 218 struct jffs2_full_dirent *fd; 219 size_t retlen; 220 struct kvec vecs[2]; 221 int retried = 0; 222 int ret; 223 |
224 D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", | 224 D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", |
225 je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), 226 je32_to_cpu(rd->name_crc))); 227 228 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { 229 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); 230 BUG(); 231 } 232 ); 233 234 vecs[0].iov_base = rd; 235 vecs[0].iov_len = sizeof(*rd); 236 vecs[1].iov_base = (unsigned char *)name; 237 vecs[1].iov_len = namelen; | 225 je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), 226 je32_to_cpu(rd->name_crc))); 227 228 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { 229 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); 230 BUG(); 231 } 232 ); 233 234 vecs[0].iov_base = rd; 235 vecs[0].iov_len = sizeof(*rd); 236 vecs[1].iov_base = (unsigned char *)name; 237 vecs[1].iov_len = namelen; |
238 | 238 |
239 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); 240 241 raw = jffs2_alloc_raw_node_ref(); 242 243 if (!raw) 244 return ERR_PTR(-ENOMEM); 245 246 fd = jffs2_alloc_full_dirent(namelen+1); --- 24 unchanged lines hidden (view full) --- 271 rd->version = cpu_to_je32(++f->highest_version); 272 fd->version = je32_to_cpu(rd->version); 273 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 274 } 275 276 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, 277 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); 278 if (ret || (retlen != sizeof(*rd) + namelen)) { | 239 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); 240 241 raw = jffs2_alloc_raw_node_ref(); 242 243 if (!raw) 244 return ERR_PTR(-ENOMEM); 245 246 fd = jffs2_alloc_full_dirent(namelen+1); --- 24 unchanged lines hidden (view full) --- 271 rd->version = cpu_to_je32(++f->highest_version); 272 fd->version = je32_to_cpu(rd->version); 273 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 274 } 275 276 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, 277 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); 278 if (ret || (retlen != sizeof(*rd) + namelen)) { |
279 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", | 279 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", |
280 sizeof(*rd)+namelen, flash_ofs, ret, retlen); 281 /* Mark the space as dirtied */ 282 if (retlen) { 283 raw->next_in_ino = NULL; 284 raw->flash_offset |= REF_OBSOLETE; 285 jffs2_add_physical_node_ref(c, raw); 286 jffs2_mark_node_obsolete(c, raw); 287 } else { --- 14 unchanged lines hidden (view full) --- 302 303 if (alloc_mode == ALLOC_GC) { 304 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, 305 &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 306 } else { 307 /* Locking pain */ 308 up(&f->sem); 309 jffs2_complete_reservation(c); | 280 sizeof(*rd)+namelen, flash_ofs, ret, retlen); 281 /* Mark the space as dirtied */ 282 if (retlen) { 283 raw->next_in_ino = NULL; 284 raw->flash_offset |= REF_OBSOLETE; 285 jffs2_add_physical_node_ref(c, raw); 286 jffs2_mark_node_obsolete(c, raw); 287 } else { --- 14 unchanged lines hidden (view full) --- 302 303 if (alloc_mode == ALLOC_GC) { 304 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, 305 &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 306 } else { 307 /* Locking pain */ 308 up(&f->sem); 309 jffs2_complete_reservation(c); |
310 | 310 |
311 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, 312 &dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 313 down(&f->sem); 314 } 315 316 if (!ret) { 317 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 318 jffs2_dbg_acct_sanity_check(c,jeb); --- 22 unchanged lines hidden (view full) --- 341 342 return fd; 343} 344 345/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that 346 we don't have to go digging in struct inode or its equivalent. It should set: 347 mode, uid, gid, (starting)isize, atime, ctime, mtime */ 348int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | 311 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, 312 &dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 313 down(&f->sem); 314 } 315 316 if (!ret) { 317 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 318 jffs2_dbg_acct_sanity_check(c,jeb); --- 22 unchanged lines hidden (view full) --- 341 342 return fd; 343} 344 345/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that 346 we don't have to go digging in struct inode or its equivalent. It should set: 347 mode, uid, gid, (starting)isize, atime, ctime, mtime */ 348int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, |
349 struct jffs2_raw_inode *ri, unsigned char *buf, | 349 struct jffs2_raw_inode *ri, unsigned char *buf, |
350 uint32_t offset, uint32_t writelen, uint32_t *retlen) 351{ 352 int ret = 0; 353 uint32_t writtenlen = 0; 354 355 D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", 356 f->inocache->ino, offset, writelen)); | 350 uint32_t offset, uint32_t writelen, uint32_t *retlen) 351{ 352 int ret = 0; 353 uint32_t writtenlen = 0; 354 355 D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", 356 f->inocache->ino, offset, writelen)); |
357 | 357 |
358 while(writelen) { 359 struct jffs2_full_dnode *fn; 360 unsigned char *comprbuf = NULL; 361 uint16_t comprtype = JFFS2_COMPR_NONE; 362 uint32_t phys_ofs, alloclen; 363 uint32_t datalen, cdatalen; 364 int retried = 0; 365 --- 80 unchanged lines hidden (view full) --- 446int 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) 447{ 448 struct jffs2_raw_dirent *rd; 449 struct jffs2_full_dnode *fn; 450 struct jffs2_full_dirent *fd; 451 uint32_t alloclen, phys_ofs; 452 int ret; 453 | 358 while(writelen) { 359 struct jffs2_full_dnode *fn; 360 unsigned char *comprbuf = NULL; 361 uint16_t comprtype = JFFS2_COMPR_NONE; 362 uint32_t phys_ofs, alloclen; 363 uint32_t datalen, cdatalen; 364 int retried = 0; 365 --- 80 unchanged lines hidden (view full) --- 446int 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) 447{ 448 struct jffs2_raw_dirent *rd; 449 struct jffs2_full_dnode *fn; 450 struct jffs2_full_dirent *fd; 451 uint32_t alloclen, phys_ofs; 452 int ret; 453 |
454 /* Try to reserve enough space for both node and dirent. 455 * Just the node will do for now, though | 454 /* Try to reserve enough space for both node and dirent. 455 * Just the node will do for now, though |
456 */ 457 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, 458 JFFS2_SUMMARY_INODE_SIZE); 459 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); 460 if (ret) { 461 up(&f->sem); 462 return ret; 463 } --- 8 unchanged lines hidden (view full) --- 472 473 if (IS_ERR(fn)) { 474 D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n")); 475 /* Eeek. Wave bye bye */ 476 up(&f->sem); 477 jffs2_complete_reservation(c); 478 return PTR_ERR(fn); 479 } | 456 */ 457 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, 458 JFFS2_SUMMARY_INODE_SIZE); 459 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); 460 if (ret) { 461 up(&f->sem); 462 return ret; 463 } --- 8 unchanged lines hidden (view full) --- 472 473 if (IS_ERR(fn)) { 474 D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n")); 475 /* Eeek. Wave bye bye */ 476 up(&f->sem); 477 jffs2_complete_reservation(c); 478 return PTR_ERR(fn); 479 } |
480 /* No data here. Only a metadata node, which will be | 480 /* No data here. Only a metadata node, which will be |
481 obsoleted by the first data write 482 */ 483 f->metadata = fn; 484 485 up(&f->sem); 486 jffs2_complete_reservation(c); 487 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 488 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 481 obsoleted by the first data write 482 */ 483 f->metadata = fn; 484 485 up(&f->sem); 486 jffs2_complete_reservation(c); 487 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 488 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); |
489 | 489 |
490 if (ret) { 491 /* Eep. */ 492 D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); 493 return ret; 494 } 495 496 rd = jffs2_alloc_raw_dirent(); 497 if (!rd) { --- 16 unchanged lines hidden (view full) --- 514 rd->nsize = namelen; 515 rd->type = DT_REG; 516 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 517 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 518 519 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 520 521 jffs2_free_raw_dirent(rd); | 490 if (ret) { 491 /* Eep. */ 492 D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); 493 return ret; 494 } 495 496 rd = jffs2_alloc_raw_dirent(); 497 if (!rd) { --- 16 unchanged lines hidden (view full) --- 514 rd->nsize = namelen; 515 rd->type = DT_REG; 516 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 517 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 518 519 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 520 521 jffs2_free_raw_dirent(rd); |
522 | 522 |
523 if (IS_ERR(fd)) { | 523 if (IS_ERR(fd)) { |
524 /* dirent failed to write. Delete the inode normally | 524 /* dirent failed to write. Delete the inode normally |
525 as if it were the final unlink() */ 526 jffs2_complete_reservation(c); 527 up(&dir_f->sem); 528 return PTR_ERR(fd); 529 } 530 531 /* Link the fd into the inode's list, obsoleting an old 532 one if necessary. */ --- 10 unchanged lines hidden (view full) --- 543 const char *name, int namelen, struct jffs2_inode_info *dead_f, 544 uint32_t time) 545{ 546 struct jffs2_raw_dirent *rd; 547 struct jffs2_full_dirent *fd; 548 uint32_t alloclen, phys_ofs; 549 int ret; 550 | 525 as if it were the final unlink() */ 526 jffs2_complete_reservation(c); 527 up(&dir_f->sem); 528 return PTR_ERR(fd); 529 } 530 531 /* Link the fd into the inode's list, obsoleting an old 532 one if necessary. */ --- 10 unchanged lines hidden (view full) --- 543 const char *name, int namelen, struct jffs2_inode_info *dead_f, 544 uint32_t time) 545{ 546 struct jffs2_raw_dirent *rd; 547 struct jffs2_full_dirent *fd; 548 uint32_t alloclen, phys_ofs; 549 int ret; 550 |
551 if (1 /* alternative branch needs testing */ || | 551 if (1 /* alternative branch needs testing */ || |
552 !jffs2_can_mark_obsolete(c)) { 553 /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ 554 555 rd = jffs2_alloc_raw_dirent(); 556 if (!rd) 557 return -ENOMEM; 558 559 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, --- 5 unchanged lines hidden (view full) --- 565 566 down(&dir_f->sem); 567 568 /* Build a deletion node */ 569 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 570 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); 571 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); 572 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); | 552 !jffs2_can_mark_obsolete(c)) { 553 /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ 554 555 rd = jffs2_alloc_raw_dirent(); 556 if (!rd) 557 return -ENOMEM; 558 559 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, --- 5 unchanged lines hidden (view full) --- 565 566 down(&dir_f->sem); 567 568 /* Build a deletion node */ 569 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 570 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); 571 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); 572 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); |
573 | 573 |
574 rd->pino = cpu_to_je32(dir_f->inocache->ino); 575 rd->version = cpu_to_je32(++dir_f->highest_version); 576 rd->ino = cpu_to_je32(0); 577 rd->mctime = cpu_to_je32(time); 578 rd->nsize = namelen; 579 rd->type = DT_UNKNOWN; 580 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 581 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 582 583 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); | 574 rd->pino = cpu_to_je32(dir_f->inocache->ino); 575 rd->version = cpu_to_je32(++dir_f->highest_version); 576 rd->ino = cpu_to_je32(0); 577 rd->mctime = cpu_to_je32(time); 578 rd->nsize = namelen; 579 rd->type = DT_UNKNOWN; 580 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 581 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 582 583 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); |
584 | 584 |
585 jffs2_free_raw_dirent(rd); 586 587 if (IS_ERR(fd)) { 588 jffs2_complete_reservation(c); 589 up(&dir_f->sem); 590 return PTR_ERR(fd); 591 } 592 593 /* File it. This will mark the old one obsolete. */ 594 jffs2_add_fd_to_list(c, fd, &dir_f->dents); 595 up(&dir_f->sem); 596 } else { 597 struct jffs2_full_dirent **prev = &dir_f->dents; 598 uint32_t nhash = full_name_hash(name, namelen); 599 600 down(&dir_f->sem); 601 602 while ((*prev) && (*prev)->nhash <= nhash) { | 585 jffs2_free_raw_dirent(rd); 586 587 if (IS_ERR(fd)) { 588 jffs2_complete_reservation(c); 589 up(&dir_f->sem); 590 return PTR_ERR(fd); 591 } 592 593 /* File it. This will mark the old one obsolete. */ 594 jffs2_add_fd_to_list(c, fd, &dir_f->dents); 595 up(&dir_f->sem); 596 } else { 597 struct jffs2_full_dirent **prev = &dir_f->dents; 598 uint32_t nhash = full_name_hash(name, namelen); 599 600 down(&dir_f->sem); 601 602 while ((*prev) && (*prev)->nhash <= nhash) { |
603 if ((*prev)->nhash == nhash && | 603 if ((*prev)->nhash == nhash && |
604 !memcmp((*prev)->name, name, namelen) && 605 !(*prev)->name[namelen]) { 606 struct jffs2_full_dirent *this = *prev; 607 608 D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n", 609 this->ino, ref_offset(this->raw))); 610 611 *prev = this->next; --- 4 unchanged lines hidden (view full) --- 616 prev = &((*prev)->next); 617 } 618 up(&dir_f->sem); 619 } 620 621 /* dead_f is NULL if this was a rename not a real unlink */ 622 /* Also catch the !f->inocache case, where there was a dirent 623 pointing to an inode which didn't exist. */ | 604 !memcmp((*prev)->name, name, namelen) && 605 !(*prev)->name[namelen]) { 606 struct jffs2_full_dirent *this = *prev; 607 608 D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n", 609 this->ino, ref_offset(this->raw))); 610 611 *prev = this->next; --- 4 unchanged lines hidden (view full) --- 616 prev = &((*prev)->next); 617 } 618 up(&dir_f->sem); 619 } 620 621 /* dead_f is NULL if this was a rename not a real unlink */ 622 /* Also catch the !f->inocache case, where there was a dirent 623 pointing to an inode which didn't exist. */ |
624 if (dead_f && dead_f->inocache) { | 624 if (dead_f && dead_f->inocache) { |
625 626 down(&dead_f->sem); 627 628 if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) { 629 while (dead_f->dents) { 630 /* There can be only deleted ones */ 631 fd = dead_f->dents; | 625 626 down(&dead_f->sem); 627 628 if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) { 629 while (dead_f->dents) { 630 /* There can be only deleted ones */ 631 fd = dead_f->dents; |
632 | 632 |
633 dead_f->dents = fd->next; | 633 dead_f->dents = fd->next; |
634 | 634 |
635 if (fd->ino) { 636 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", 637 dead_f->inocache->ino, fd->name, fd->ino); 638 } else { 639 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", 640 fd->name, dead_f->inocache->ino)); 641 } 642 jffs2_mark_node_obsolete(c, fd->raw); --- 24 unchanged lines hidden (view full) --- 667 return -ENOMEM; 668 669 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 670 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 671 if (ret) { 672 jffs2_free_raw_dirent(rd); 673 return ret; 674 } | 635 if (fd->ino) { 636 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", 637 dead_f->inocache->ino, fd->name, fd->ino); 638 } else { 639 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", 640 fd->name, dead_f->inocache->ino)); 641 } 642 jffs2_mark_node_obsolete(c, fd->raw); --- 24 unchanged lines hidden (view full) --- 667 return -ENOMEM; 668 669 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 670 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 671 if (ret) { 672 jffs2_free_raw_dirent(rd); 673 return ret; 674 } |
675 | 675 |
676 down(&dir_f->sem); 677 678 /* Build a deletion node */ 679 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 680 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); 681 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); 682 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); 683 --- 4 unchanged lines hidden (view full) --- 688 rd->nsize = namelen; 689 690 rd->type = type; 691 692 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 693 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 694 695 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); | 676 down(&dir_f->sem); 677 678 /* Build a deletion node */ 679 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 680 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); 681 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); 682 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); 683 --- 4 unchanged lines hidden (view full) --- 688 rd->nsize = namelen; 689 690 rd->type = type; 691 692 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 693 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 694 695 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); |
696 | 696 |
697 jffs2_free_raw_dirent(rd); 698 699 if (IS_ERR(fd)) { 700 jffs2_complete_reservation(c); 701 up(&dir_f->sem); 702 return PTR_ERR(fd); 703 } 704 705 /* File it. This will mark the old one obsolete. */ 706 jffs2_add_fd_to_list(c, fd, &dir_f->dents); 707 708 jffs2_complete_reservation(c); 709 up(&dir_f->sem); 710 711 return 0; 712} | 697 jffs2_free_raw_dirent(rd); 698 699 if (IS_ERR(fd)) { 700 jffs2_complete_reservation(c); 701 up(&dir_f->sem); 702 return PTR_ERR(fd); 703 } 704 705 /* File it. This will mark the old one obsolete. */ 706 jffs2_add_fd_to_list(c, fd, &dir_f->dents); 707 708 jffs2_complete_reservation(c); 709 up(&dir_f->sem); 710 711 return 0; 712} |