aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jffs2/dir.c12
-rw-r--r--fs/jffs2/os-linux.h3
-rw-r--r--fs/jffs2/readinode.c45
-rw-r--r--fs/jffs2/symlink.c26
-rw-r--r--include/linux/jffs2_fs_i.h5
5 files changed, 44 insertions, 47 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 3ca0d25eef1d..5738df223775 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.86 2005/07/06 12:13:09 dwmw2 Exp $ 10 * $Id: dir.c,v 1.87 2005/07/17 11:13:46 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -344,9 +344,9 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
344 return PTR_ERR(fn); 344 return PTR_ERR(fn);
345 } 345 }
346 346
347 /* We use f->dents field to store the target path. */ 347 /* We use f->target field to store the target path. */
348 f->dents = kmalloc(targetlen + 1, GFP_KERNEL); 348 f->target = kmalloc(targetlen + 1, GFP_KERNEL);
349 if (!f->dents) { 349 if (!f->target) {
350 printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); 350 printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
351 up(&f->sem); 351 up(&f->sem);
352 jffs2_complete_reservation(c); 352 jffs2_complete_reservation(c);
@@ -354,8 +354,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
354 return -ENOMEM; 354 return -ENOMEM;
355 } 355 }
356 356
357 memcpy(f->dents, target, targetlen + 1); 357 memcpy(f->target, target, targetlen + 1);
358 D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents)); 358 D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target));
359 359
360 /* No data here. Only a metadata node, which will be 360 /* No data here. Only a metadata node, which will be
361 obsoleted by the first data write 361 obsoleted by the first data write
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index d900c8929b09..0fc952eaf8c8 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -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: os-linux.h,v 1.58 2005/07/12 02:34:35 tpoynor Exp $ 10 * $Id: os-linux.h,v 1.59 2005/07/17 11:13:46 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -57,6 +57,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
57 f->fragtree = RB_ROOT; 57 f->fragtree = RB_ROOT;
58 f->metadata = NULL; 58 f->metadata = NULL;
59 f->dents = NULL; 59 f->dents = NULL;
60 f->target = NULL;
60 f->flags = 0; 61 f->flags = 0;
61 f->usercompr = 0; 62 f->usercompr = 0;
62} 63}
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index cf39bcf3e3cf..49da1a6cfc81 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.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: readinode.c,v 1.126 2005/07/17 06:56:21 dedekind Exp $ 10 * $Id: readinode.c,v 1.127 2005/07/17 11:13:46 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -547,11 +547,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
547 547
548 if (f->inocache->state != INO_STATE_CHECKING) { 548 if (f->inocache->state != INO_STATE_CHECKING) {
549 /* Symlink's inode data is the target path. Read it and 549 /* Symlink's inode data is the target path. Read it and
550 * keep in RAM to facilitate quick follow symlink operation. 550 * keep in RAM to facilitate quick follow symlink
551 * We use f->dents field to store the target path, which 551 * operation. */
552 * is somewhat ugly. */ 552 f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
553 f->dents = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL); 553 if (!f->target) {
554 if (!f->dents) {
555 printk(KERN_WARNING "Can't allocate %d bytes of memory " 554 printk(KERN_WARNING "Can't allocate %d bytes of memory "
556 "for the symlink target path cache\n", 555 "for the symlink target path cache\n",
557 je32_to_cpu(latest_node->csize)); 556 je32_to_cpu(latest_node->csize));
@@ -561,21 +560,21 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
561 } 560 }
562 561
563 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node), 562 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
564 je32_to_cpu(latest_node->csize), &retlen, (char *)f->dents); 563 je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
565 564
566 if (ret || retlen != je32_to_cpu(latest_node->csize)) { 565 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
567 if (retlen != je32_to_cpu(latest_node->csize)) 566 if (retlen != je32_to_cpu(latest_node->csize))
568 ret = -EIO; 567 ret = -EIO;
569 kfree(f->dents); 568 kfree(f->target);
570 f->dents = NULL; 569 f->target = NULL;
571 up(&f->sem); 570 up(&f->sem);
572 jffs2_do_clear_inode(c, f); 571 jffs2_do_clear_inode(c, f);
573 return -ret; 572 return -ret;
574 } 573 }
575 574
576 ((char *)f->dents)[je32_to_cpu(latest_node->csize)] = '\0'; 575 f->target[je32_to_cpu(latest_node->csize)] = '\0';
577 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n", 576 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
578 (char *)f->dents)); 577 f->target));
579 } 578 }
580 579
581 /* fall through... */ 580 /* fall through... */
@@ -638,20 +637,16 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
638 637
639 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 638 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
640 639
641 /* For symlink inodes we us f->dents to store the target path name */ 640 if (f->target) {
642 if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) { 641 kfree(f->target);
643 if (f->dents) { 642 f->target = NULL;
644 kfree(f->dents); 643 }
645 f->dents = NULL; 644
646 } 645 fds = f->dents;
647 } else { 646 while(fds) {
648 fds = f->dents; 647 fd = fds;
649 648 fds = fd->next;
650 while(fds) { 649 jffs2_free_full_dirent(fd);
651 fd = fds;
652 fds = fd->next;
653 jffs2_free_full_dirent(fd);
654 }
655 } 650 }
656 651
657 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { 652 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 82ef484f5e12..6fd5ee4f90b7 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.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: symlink.c,v 1.16 2005/03/01 10:50:48 dedekind Exp $ 10 * $Id: symlink.c,v 1.18 2005/11/06 11:03:27 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -30,35 +30,33 @@ struct inode_operations jffs2_symlink_inode_operations =
30static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) 30static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
31{ 31{
32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); 32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
33 char *p = (char *)f->dents; 33 char *p = (char *)f->target;
34 34
35 /* 35 /*
36 * We don't acquire the f->sem mutex here since the only data we 36 * We don't acquire the f->sem mutex here since the only data we
37 * use is f->dents which in case of the symlink inode points to the 37 * use is f->target.
38 * symlink's target path.
39 * 38 *
40 * 1. If we are here the inode has already built and f->dents has 39 * 1. If we are here the inode has already built and f->target has
41 * to point to the target path. 40 * to point to the target path.
42 * 2. Nobody uses f->dents (if the inode is symlink's inode). The 41 * 2. Nobody uses f->target (if the inode is symlink's inode). The
43 * exception is inode freeing function which frees f->dents. But 42 * exception is inode freeing function which frees f->target. But
44 * it can't be called while we are here and before VFS has 43 * it can't be called while we are here and before VFS has
45 * stopped using our f->dents string which we provide by means of 44 * stopped using our f->target string which we provide by means of
46 * nd_set_link() call. 45 * nd_set_link() call.
47 */ 46 */
48 47
49 if (!p) { 48 if (!p) {
50 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); 49 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
51 p = ERR_PTR(-EIO); 50 p = ERR_PTR(-EIO);
52 } else {
53 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
54 } 51 }
52 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target));
55 53
56 nd_set_link(nd, p); 54 nd_set_link(nd, p);
57 55
58 /* 56 /*
59 * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe 57 * We will unlock the f->sem mutex but VFS will use the f->target string. This is safe
60 * since the only way that may cause f->dents to be changed is iput() operation. 58 * since the only way that may cause f->target to be changed is iput() operation.
61 * But VFS will not use f->dents after iput() has been called. 59 * But VFS will not use f->target after iput() has been called.
62 */ 60 */
63 return NULL; 61 return NULL;
64} 62}
diff --git a/include/linux/jffs2_fs_i.h b/include/linux/jffs2_fs_i.h
index 6dbb1cce6646..a5db884ec607 100644
--- a/include/linux/jffs2_fs_i.h
+++ b/include/linux/jffs2_fs_i.h
@@ -1,4 +1,4 @@
1/* $Id: jffs2_fs_i.h,v 1.17 2004/11/11 23:51:27 dwmw2 Exp $ */ 1/* $Id: jffs2_fs_i.h,v 1.18 2005/07/17 11:13:48 dedekind Exp $ */
2 2
3#ifndef _JFFS2_FS_I 3#ifndef _JFFS2_FS_I
4#define _JFFS2_FS_I 4#define _JFFS2_FS_I
@@ -32,6 +32,9 @@ struct jffs2_inode_info {
32 /* Directory entries */ 32 /* Directory entries */
33 struct jffs2_full_dirent *dents; 33 struct jffs2_full_dirent *dents;
34 34
35 /* The target path if this is the inode of a symlink */
36 unsigned char *target;
37
35 /* Some stuff we just have to keep in-core at all times, for each inode. */ 38 /* Some stuff we just have to keep in-core at all times, for each inode. */
36 struct jffs2_inode_cache *inocache; 39 struct jffs2_inode_cache *inocache;
37 40