diff options
author | Artem B. Bityuckiy <dedekind@infradead.org> | 2005-03-01 05:50:52 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-05-23 06:48:15 -0400 |
commit | 32f1a95d505b99b1f01b6aeea36ec3f97245b357 (patch) | |
tree | 5da0e8b01362cf6b0cc79f11e5e9b3fd4ad169d6 /fs/jffs2/dir.c | |
parent | 20a6c211903dce92a0db7f19c221cfa3f2cb4c32 (diff) |
[JFFS2] Add symlink caching support.
Signed-off-by: Artem B. Bityuckiy <dedekind@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2/dir.c')
-rw-r--r-- | fs/jffs2/dir.c | 28 |
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 | */ |