aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/dir.c')
-rw-r--r--fs/jffs2/dir.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 757306fa3ff4..6421be874ce3 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: dir.c,v 1.84 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: dir.c,v 1.85 2005/03/01 10:34:03 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -296,11 +296,11 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
296 struct jffs2_full_dirent *fd; 296 struct jffs2_full_dirent *fd;
297 int namelen; 297 int namelen;
298 uint32_t alloclen, phys_ofs; 298 uint32_t alloclen, phys_ofs;
299 int ret; 299 int ret, targetlen = strlen(target);
300 300
301 /* FIXME: If you care. We'd need to use frags for the target 301 /* FIXME: If you care. We'd need to use frags for the target
302 if it grows much more than this */ 302 if it grows much more than this */
303 if (strlen(target) > 254) 303 if (targetlen > 254)
304 return -EINVAL; 304 return -EINVAL;
305 305
306 ri = jffs2_alloc_raw_inode(); 306 ri = jffs2_alloc_raw_inode();
@@ -314,7 +314,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
314 * Just the node will do for now, though 314 * Just the node will do for now, though
315 */ 315 */
316 namelen = dentry->d_name.len; 316 namelen = dentry->d_name.len;
317 ret = jffs2_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL); 317 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
318 318
319 if (ret) { 319 if (ret) {
320 jffs2_free_raw_inode(ri); 320 jffs2_free_raw_inode(ri);
@@ -333,16 +333,16 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
333 333
334 f = JFFS2_INODE_INFO(inode); 334 f = JFFS2_INODE_INFO(inode);
335 335
336 inode->i_size = strlen(target); 336 inode->i_size = targetlen;
337 ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size); 337 ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
338 ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size); 338 ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
339 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); 339 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
340 340
341 ri->compr = JFFS2_COMPR_NONE; 341 ri->compr = JFFS2_COMPR_NONE;
342 ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target))); 342 ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
343 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 343 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
344 344
345 fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL); 345 fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL);
346 346
347 jffs2_free_raw_inode(ri); 347 jffs2_free_raw_inode(ri);
348 348
@@ -353,6 +353,20 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
353 jffs2_clear_inode(inode); 353 jffs2_clear_inode(inode);
354 return PTR_ERR(fn); 354 return PTR_ERR(fn);
355 } 355 }
356
357 /* We use f->dents field to store the target path. */
358 f->dents = kmalloc(targetlen + 1, GFP_KERNEL);
359 if (!f->dents) {
360 printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
361 up(&f->sem);
362 jffs2_complete_reservation(c);
363 jffs2_clear_inode(inode);
364 return -ENOMEM;
365 }
366
367 memcpy(f->dents, target, targetlen + 1);
368 D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents));
369
356 /* No data here. Only a metadata node, which will be 370 /* No data here. Only a metadata node, which will be
357 obsoleted by the first data write 371 obsoleted by the first data write
358 */ 372 */