diff options
Diffstat (limited to 'fs/jffs2/dir.c')
-rw-r--r-- | fs/jffs2/dir.c | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 757306fa3ff4..3ca0d25eef1d 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.86 2005/07/06 12:13:09 dwmw2 Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -22,16 +22,6 @@ | |||
22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
23 | #include "nodelist.h" | 23 | #include "nodelist.h" |
24 | 24 | ||
25 | /* Urgh. Please tell me there's a nicer way of doing these. */ | ||
26 | #include <linux/version.h> | ||
27 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48) | ||
28 | typedef int mknod_arg_t; | ||
29 | #define NAMEI_COMPAT(x) ((void *)x) | ||
30 | #else | ||
31 | typedef dev_t mknod_arg_t; | ||
32 | #define NAMEI_COMPAT(x) (x) | ||
33 | #endif | ||
34 | |||
35 | static int jffs2_readdir (struct file *, void *, filldir_t); | 25 | static int jffs2_readdir (struct file *, void *, filldir_t); |
36 | 26 | ||
37 | static int jffs2_create (struct inode *,struct dentry *,int, | 27 | static int jffs2_create (struct inode *,struct dentry *,int, |
@@ -43,7 +33,7 @@ static int jffs2_unlink (struct inode *,struct dentry *); | |||
43 | static int jffs2_symlink (struct inode *,struct dentry *,const char *); | 33 | static int jffs2_symlink (struct inode *,struct dentry *,const char *); |
44 | static int jffs2_mkdir (struct inode *,struct dentry *,int); | 34 | static int jffs2_mkdir (struct inode *,struct dentry *,int); |
45 | static int jffs2_rmdir (struct inode *,struct dentry *); | 35 | static int jffs2_rmdir (struct inode *,struct dentry *); |
46 | static int jffs2_mknod (struct inode *,struct dentry *,int,mknod_arg_t); | 36 | static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t); |
47 | static int jffs2_rename (struct inode *, struct dentry *, | 37 | static int jffs2_rename (struct inode *, struct dentry *, |
48 | struct inode *, struct dentry *); | 38 | struct inode *, struct dentry *); |
49 | 39 | ||
@@ -58,8 +48,8 @@ struct file_operations jffs2_dir_operations = | |||
58 | 48 | ||
59 | struct inode_operations jffs2_dir_inode_operations = | 49 | struct inode_operations jffs2_dir_inode_operations = |
60 | { | 50 | { |
61 | .create = NAMEI_COMPAT(jffs2_create), | 51 | .create = jffs2_create, |
62 | .lookup = NAMEI_COMPAT(jffs2_lookup), | 52 | .lookup = jffs2_lookup, |
63 | .link = jffs2_link, | 53 | .link = jffs2_link, |
64 | .unlink = jffs2_unlink, | 54 | .unlink = jffs2_unlink, |
65 | .symlink = jffs2_symlink, | 55 | .symlink = jffs2_symlink, |
@@ -296,11 +286,11 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
296 | struct jffs2_full_dirent *fd; | 286 | struct jffs2_full_dirent *fd; |
297 | int namelen; | 287 | int namelen; |
298 | uint32_t alloclen, phys_ofs; | 288 | uint32_t alloclen, phys_ofs; |
299 | int ret; | 289 | int ret, targetlen = strlen(target); |
300 | 290 | ||
301 | /* FIXME: If you care. We'd need to use frags for the target | 291 | /* FIXME: If you care. We'd need to use frags for the target |
302 | if it grows much more than this */ | 292 | if it grows much more than this */ |
303 | if (strlen(target) > 254) | 293 | if (targetlen > 254) |
304 | return -EINVAL; | 294 | return -EINVAL; |
305 | 295 | ||
306 | ri = jffs2_alloc_raw_inode(); | 296 | ri = jffs2_alloc_raw_inode(); |
@@ -314,7 +304,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
314 | * Just the node will do for now, though | 304 | * Just the node will do for now, though |
315 | */ | 305 | */ |
316 | namelen = dentry->d_name.len; | 306 | namelen = dentry->d_name.len; |
317 | ret = jffs2_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL); | 307 | ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL); |
318 | 308 | ||
319 | if (ret) { | 309 | if (ret) { |
320 | jffs2_free_raw_inode(ri); | 310 | jffs2_free_raw_inode(ri); |
@@ -333,16 +323,16 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
333 | 323 | ||
334 | f = JFFS2_INODE_INFO(inode); | 324 | f = JFFS2_INODE_INFO(inode); |
335 | 325 | ||
336 | inode->i_size = strlen(target); | 326 | inode->i_size = targetlen; |
337 | ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size); | 327 | ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size); |
338 | ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size); | 328 | 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)); | 329 | ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); |
340 | 330 | ||
341 | ri->compr = JFFS2_COMPR_NONE; | 331 | ri->compr = JFFS2_COMPR_NONE; |
342 | ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target))); | 332 | ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); |
343 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 333 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
344 | 334 | ||
345 | fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL); | 335 | fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL); |
346 | 336 | ||
347 | jffs2_free_raw_inode(ri); | 337 | jffs2_free_raw_inode(ri); |
348 | 338 | ||
@@ -353,6 +343,20 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
353 | jffs2_clear_inode(inode); | 343 | jffs2_clear_inode(inode); |
354 | return PTR_ERR(fn); | 344 | return PTR_ERR(fn); |
355 | } | 345 | } |
346 | |||
347 | /* We use f->dents field to store the target path. */ | ||
348 | f->dents = kmalloc(targetlen + 1, GFP_KERNEL); | ||
349 | if (!f->dents) { | ||
350 | printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); | ||
351 | up(&f->sem); | ||
352 | jffs2_complete_reservation(c); | ||
353 | jffs2_clear_inode(inode); | ||
354 | return -ENOMEM; | ||
355 | } | ||
356 | |||
357 | memcpy(f->dents, target, targetlen + 1); | ||
358 | D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents)); | ||
359 | |||
356 | /* No data here. Only a metadata node, which will be | 360 | /* No data here. Only a metadata node, which will be |
357 | obsoleted by the first data write | 361 | obsoleted by the first data write |
358 | */ | 362 | */ |
@@ -564,7 +568,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | |||
564 | return ret; | 568 | return ret; |
565 | } | 569 | } |
566 | 570 | ||
567 | static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mknod_arg_t rdev) | 571 | static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, dev_t rdev) |
568 | { | 572 | { |
569 | struct jffs2_inode_info *f, *dir_f; | 573 | struct jffs2_inode_info *f, *dir_f; |
570 | struct jffs2_sb_info *c; | 574 | struct jffs2_sb_info *c; |