diff options
Diffstat (limited to 'fs/jffs2/dir.c')
-rw-r--r-- | fs/jffs2/dir.c | 121 |
1 files changed, 69 insertions, 52 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 3ca0d25eef1d..a7bf9cb2567f 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.90 2005/11/07 11:14:39 gleixner Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -64,7 +64,7 @@ struct inode_operations jffs2_dir_inode_operations = | |||
64 | 64 | ||
65 | 65 | ||
66 | /* We keep the dirent list sorted in increasing order of name hash, | 66 | /* We keep the dirent list sorted in increasing order of name hash, |
67 | and we use the same hash function as the dentries. Makes this | 67 | and we use the same hash function as the dentries. Makes this |
68 | nice and simple | 68 | nice and simple |
69 | */ | 69 | */ |
70 | static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | 70 | static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, |
@@ -85,7 +85,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | |||
85 | 85 | ||
86 | /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */ | 86 | /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */ |
87 | for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) { | 87 | for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) { |
88 | if (fd_list->nhash == target->d_name.hash && | 88 | if (fd_list->nhash == target->d_name.hash && |
89 | (!fd || fd_list->version > fd->version) && | 89 | (!fd || fd_list->version > fd->version) && |
90 | strlen(fd_list->name) == target->d_name.len && | 90 | strlen(fd_list->name) == target->d_name.len && |
91 | !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) { | 91 | !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) { |
@@ -147,7 +147,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
147 | curofs++; | 147 | curofs++; |
148 | /* First loop: curofs = 2; offset = 2 */ | 148 | /* First loop: curofs = 2; offset = 2 */ |
149 | if (curofs < offset) { | 149 | if (curofs < offset) { |
150 | D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", | 150 | D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", |
151 | fd->name, fd->ino, fd->type, curofs, offset)); | 151 | fd->name, fd->ino, fd->type, curofs, offset)); |
152 | continue; | 152 | continue; |
153 | } | 153 | } |
@@ -182,7 +182,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
182 | ri = jffs2_alloc_raw_inode(); | 182 | ri = jffs2_alloc_raw_inode(); |
183 | if (!ri) | 183 | if (!ri) |
184 | return -ENOMEM; | 184 | return -ENOMEM; |
185 | 185 | ||
186 | c = JFFS2_SB_INFO(dir_i->i_sb); | 186 | c = JFFS2_SB_INFO(dir_i->i_sb); |
187 | 187 | ||
188 | D1(printk(KERN_DEBUG "jffs2_create()\n")); | 188 | D1(printk(KERN_DEBUG "jffs2_create()\n")); |
@@ -203,7 +203,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
203 | f = JFFS2_INODE_INFO(inode); | 203 | f = JFFS2_INODE_INFO(inode); |
204 | dir_f = JFFS2_INODE_INFO(dir_i); | 204 | dir_f = JFFS2_INODE_INFO(dir_i); |
205 | 205 | ||
206 | ret = jffs2_do_create(c, dir_f, f, ri, | 206 | ret = jffs2_do_create(c, dir_f, f, ri, |
207 | dentry->d_name.name, dentry->d_name.len); | 207 | dentry->d_name.name, dentry->d_name.len); |
208 | 208 | ||
209 | if (ret) { | 209 | if (ret) { |
@@ -232,11 +232,14 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry) | |||
232 | struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); | 232 | struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); |
233 | struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode); | 233 | struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode); |
234 | int ret; | 234 | int ret; |
235 | uint32_t now = get_seconds(); | ||
235 | 236 | ||
236 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, | 237 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, |
237 | dentry->d_name.len, dead_f); | 238 | dentry->d_name.len, dead_f, now); |
238 | if (dead_f->inocache) | 239 | if (dead_f->inocache) |
239 | dentry->d_inode->i_nlink = dead_f->inocache->nlink; | 240 | dentry->d_inode->i_nlink = dead_f->inocache->nlink; |
241 | if (!ret) | ||
242 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | ||
240 | return ret; | 243 | return ret; |
241 | } | 244 | } |
242 | /***********************************************************************/ | 245 | /***********************************************************************/ |
@@ -249,6 +252,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de | |||
249 | struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); | 252 | struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); |
250 | int ret; | 253 | int ret; |
251 | uint8_t type; | 254 | uint8_t type; |
255 | uint32_t now; | ||
252 | 256 | ||
253 | /* Don't let people make hard links to bad inodes. */ | 257 | /* Don't let people make hard links to bad inodes. */ |
254 | if (!f->inocache) | 258 | if (!f->inocache) |
@@ -261,13 +265,15 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de | |||
261 | type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; | 265 | type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; |
262 | if (!type) type = DT_REG; | 266 | if (!type) type = DT_REG; |
263 | 267 | ||
264 | ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len); | 268 | now = get_seconds(); |
269 | ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now); | ||
265 | 270 | ||
266 | if (!ret) { | 271 | if (!ret) { |
267 | down(&f->sem); | 272 | down(&f->sem); |
268 | old_dentry->d_inode->i_nlink = ++f->inocache->nlink; | 273 | old_dentry->d_inode->i_nlink = ++f->inocache->nlink; |
269 | up(&f->sem); | 274 | up(&f->sem); |
270 | d_instantiate(dentry, old_dentry->d_inode); | 275 | d_instantiate(dentry, old_dentry->d_inode); |
276 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | ||
271 | atomic_inc(&old_dentry->d_inode->i_count); | 277 | atomic_inc(&old_dentry->d_inode->i_count); |
272 | } | 278 | } |
273 | return ret; | 279 | return ret; |
@@ -297,14 +303,15 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
297 | 303 | ||
298 | if (!ri) | 304 | if (!ri) |
299 | return -ENOMEM; | 305 | return -ENOMEM; |
300 | 306 | ||
301 | c = JFFS2_SB_INFO(dir_i->i_sb); | 307 | c = JFFS2_SB_INFO(dir_i->i_sb); |
302 | 308 | ||
303 | /* Try to reserve enough space for both node and dirent. | 309 | /* Try to reserve enough space for both node and dirent. |
304 | * Just the node will do for now, though | 310 | * Just the node will do for now, though |
305 | */ | 311 | */ |
306 | namelen = dentry->d_name.len; | 312 | namelen = dentry->d_name.len; |
307 | ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL); | 313 | ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, |
314 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | ||
308 | 315 | ||
309 | if (ret) { | 316 | if (ret) { |
310 | jffs2_free_raw_inode(ri); | 317 | jffs2_free_raw_inode(ri); |
@@ -331,7 +338,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
331 | ri->compr = JFFS2_COMPR_NONE; | 338 | ri->compr = JFFS2_COMPR_NONE; |
332 | ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); | 339 | ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); |
333 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 340 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
334 | 341 | ||
335 | fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL); | 342 | fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL); |
336 | 343 | ||
337 | jffs2_free_raw_inode(ri); | 344 | jffs2_free_raw_inode(ri); |
@@ -344,9 +351,9 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
344 | return PTR_ERR(fn); | 351 | return PTR_ERR(fn); |
345 | } | 352 | } |
346 | 353 | ||
347 | /* We use f->dents field to store the target path. */ | 354 | /* We use f->target field to store the target path. */ |
348 | f->dents = kmalloc(targetlen + 1, GFP_KERNEL); | 355 | f->target = kmalloc(targetlen + 1, GFP_KERNEL); |
349 | if (!f->dents) { | 356 | if (!f->target) { |
350 | printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); | 357 | printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); |
351 | up(&f->sem); | 358 | up(&f->sem); |
352 | jffs2_complete_reservation(c); | 359 | jffs2_complete_reservation(c); |
@@ -354,17 +361,18 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
354 | return -ENOMEM; | 361 | return -ENOMEM; |
355 | } | 362 | } |
356 | 363 | ||
357 | memcpy(f->dents, target, targetlen + 1); | 364 | memcpy(f->target, target, targetlen + 1); |
358 | D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents)); | 365 | D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target)); |
359 | 366 | ||
360 | /* No data here. Only a metadata node, which will be | 367 | /* No data here. Only a metadata node, which will be |
361 | obsoleted by the first data write | 368 | obsoleted by the first data write |
362 | */ | 369 | */ |
363 | f->metadata = fn; | 370 | f->metadata = fn; |
364 | up(&f->sem); | 371 | up(&f->sem); |
365 | 372 | ||
366 | jffs2_complete_reservation(c); | 373 | jffs2_complete_reservation(c); |
367 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); | 374 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, |
375 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
368 | if (ret) { | 376 | if (ret) { |
369 | /* Eep. */ | 377 | /* Eep. */ |
370 | jffs2_clear_inode(inode); | 378 | jffs2_clear_inode(inode); |
@@ -399,7 +407,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
399 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); | 407 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); |
400 | 408 | ||
401 | if (IS_ERR(fd)) { | 409 | if (IS_ERR(fd)) { |
402 | /* dirent failed to write. Delete the inode normally | 410 | /* dirent failed to write. Delete the inode normally |
403 | as if it were the final unlink() */ | 411 | as if it were the final unlink() */ |
404 | jffs2_complete_reservation(c); | 412 | jffs2_complete_reservation(c); |
405 | jffs2_free_raw_dirent(rd); | 413 | jffs2_free_raw_dirent(rd); |
@@ -442,14 +450,15 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
442 | ri = jffs2_alloc_raw_inode(); | 450 | ri = jffs2_alloc_raw_inode(); |
443 | if (!ri) | 451 | if (!ri) |
444 | return -ENOMEM; | 452 | return -ENOMEM; |
445 | 453 | ||
446 | c = JFFS2_SB_INFO(dir_i->i_sb); | 454 | c = JFFS2_SB_INFO(dir_i->i_sb); |
447 | 455 | ||
448 | /* Try to reserve enough space for both node and dirent. | 456 | /* Try to reserve enough space for both node and dirent. |
449 | * Just the node will do for now, though | 457 | * Just the node will do for now, though |
450 | */ | 458 | */ |
451 | namelen = dentry->d_name.len; | 459 | namelen = dentry->d_name.len; |
452 | ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); | 460 | ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, |
461 | JFFS2_SUMMARY_INODE_SIZE); | ||
453 | 462 | ||
454 | if (ret) { | 463 | if (ret) { |
455 | jffs2_free_raw_inode(ri); | 464 | jffs2_free_raw_inode(ri); |
@@ -473,7 +482,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
473 | 482 | ||
474 | ri->data_crc = cpu_to_je32(0); | 483 | ri->data_crc = cpu_to_je32(0); |
475 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 484 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
476 | 485 | ||
477 | fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); | 486 | fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); |
478 | 487 | ||
479 | jffs2_free_raw_inode(ri); | 488 | jffs2_free_raw_inode(ri); |
@@ -485,20 +494,21 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
485 | jffs2_clear_inode(inode); | 494 | jffs2_clear_inode(inode); |
486 | return PTR_ERR(fn); | 495 | return PTR_ERR(fn); |
487 | } | 496 | } |
488 | /* No data here. Only a metadata node, which will be | 497 | /* No data here. Only a metadata node, which will be |
489 | obsoleted by the first data write | 498 | obsoleted by the first data write |
490 | */ | 499 | */ |
491 | f->metadata = fn; | 500 | f->metadata = fn; |
492 | up(&f->sem); | 501 | up(&f->sem); |
493 | 502 | ||
494 | jffs2_complete_reservation(c); | 503 | jffs2_complete_reservation(c); |
495 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); | 504 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, |
505 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
496 | if (ret) { | 506 | if (ret) { |
497 | /* Eep. */ | 507 | /* Eep. */ |
498 | jffs2_clear_inode(inode); | 508 | jffs2_clear_inode(inode); |
499 | return ret; | 509 | return ret; |
500 | } | 510 | } |
501 | 511 | ||
502 | rd = jffs2_alloc_raw_dirent(); | 512 | rd = jffs2_alloc_raw_dirent(); |
503 | if (!rd) { | 513 | if (!rd) { |
504 | /* Argh. Now we treat it like a normal delete */ | 514 | /* Argh. Now we treat it like a normal delete */ |
@@ -525,9 +535,9 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
525 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); | 535 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); |
526 | 536 | ||
527 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); | 537 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); |
528 | 538 | ||
529 | if (IS_ERR(fd)) { | 539 | if (IS_ERR(fd)) { |
530 | /* dirent failed to write. Delete the inode normally | 540 | /* dirent failed to write. Delete the inode normally |
531 | as if it were the final unlink() */ | 541 | as if it were the final unlink() */ |
532 | jffs2_complete_reservation(c); | 542 | jffs2_complete_reservation(c); |
533 | jffs2_free_raw_dirent(rd); | 543 | jffs2_free_raw_dirent(rd); |
@@ -589,19 +599,20 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
589 | ri = jffs2_alloc_raw_inode(); | 599 | ri = jffs2_alloc_raw_inode(); |
590 | if (!ri) | 600 | if (!ri) |
591 | return -ENOMEM; | 601 | return -ENOMEM; |
592 | 602 | ||
593 | c = JFFS2_SB_INFO(dir_i->i_sb); | 603 | c = JFFS2_SB_INFO(dir_i->i_sb); |
594 | 604 | ||
595 | if (S_ISBLK(mode) || S_ISCHR(mode)) { | 605 | if (S_ISBLK(mode) || S_ISCHR(mode)) { |
596 | dev = cpu_to_je16(old_encode_dev(rdev)); | 606 | dev = cpu_to_je16(old_encode_dev(rdev)); |
597 | devlen = sizeof(dev); | 607 | devlen = sizeof(dev); |
598 | } | 608 | } |
599 | 609 | ||
600 | /* Try to reserve enough space for both node and dirent. | 610 | /* Try to reserve enough space for both node and dirent. |
601 | * Just the node will do for now, though | 611 | * Just the node will do for now, though |
602 | */ | 612 | */ |
603 | namelen = dentry->d_name.len; | 613 | namelen = dentry->d_name.len; |
604 | ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL); | 614 | ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, |
615 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | ||
605 | 616 | ||
606 | if (ret) { | 617 | if (ret) { |
607 | jffs2_free_raw_inode(ri); | 618 | jffs2_free_raw_inode(ri); |
@@ -627,7 +638,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
627 | ri->compr = JFFS2_COMPR_NONE; | 638 | ri->compr = JFFS2_COMPR_NONE; |
628 | ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); | 639 | ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); |
629 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 640 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
630 | 641 | ||
631 | fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL); | 642 | fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL); |
632 | 643 | ||
633 | jffs2_free_raw_inode(ri); | 644 | jffs2_free_raw_inode(ri); |
@@ -639,14 +650,15 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
639 | jffs2_clear_inode(inode); | 650 | jffs2_clear_inode(inode); |
640 | return PTR_ERR(fn); | 651 | return PTR_ERR(fn); |
641 | } | 652 | } |
642 | /* No data here. Only a metadata node, which will be | 653 | /* No data here. Only a metadata node, which will be |
643 | obsoleted by the first data write | 654 | obsoleted by the first data write |
644 | */ | 655 | */ |
645 | f->metadata = fn; | 656 | f->metadata = fn; |
646 | up(&f->sem); | 657 | up(&f->sem); |
647 | 658 | ||
648 | jffs2_complete_reservation(c); | 659 | jffs2_complete_reservation(c); |
649 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); | 660 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, |
661 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
650 | if (ret) { | 662 | if (ret) { |
651 | /* Eep. */ | 663 | /* Eep. */ |
652 | jffs2_clear_inode(inode); | 664 | jffs2_clear_inode(inode); |
@@ -682,9 +694,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
682 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); | 694 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); |
683 | 695 | ||
684 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); | 696 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); |
685 | 697 | ||
686 | if (IS_ERR(fd)) { | 698 | if (IS_ERR(fd)) { |
687 | /* dirent failed to write. Delete the inode normally | 699 | /* dirent failed to write. Delete the inode normally |
688 | as if it were the final unlink() */ | 700 | as if it were the final unlink() */ |
689 | jffs2_complete_reservation(c); | 701 | jffs2_complete_reservation(c); |
690 | jffs2_free_raw_dirent(rd); | 702 | jffs2_free_raw_dirent(rd); |
@@ -716,8 +728,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
716 | struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); | 728 | struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); |
717 | struct jffs2_inode_info *victim_f = NULL; | 729 | struct jffs2_inode_info *victim_f = NULL; |
718 | uint8_t type; | 730 | uint8_t type; |
731 | uint32_t now; | ||
719 | 732 | ||
720 | /* The VFS will check for us and prevent trying to rename a | 733 | /* The VFS will check for us and prevent trying to rename a |
721 | * file over a directory and vice versa, but if it's a directory, | 734 | * file over a directory and vice versa, but if it's a directory, |
722 | * the VFS can't check whether the victim is empty. The filesystem | 735 | * the VFS can't check whether the victim is empty. The filesystem |
723 | * needs to do that for itself. | 736 | * needs to do that for itself. |
@@ -739,19 +752,20 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
739 | } | 752 | } |
740 | 753 | ||
741 | /* XXX: We probably ought to alloc enough space for | 754 | /* XXX: We probably ought to alloc enough space for |
742 | both nodes at the same time. Writing the new link, | 755 | both nodes at the same time. Writing the new link, |
743 | then getting -ENOSPC, is quite bad :) | 756 | then getting -ENOSPC, is quite bad :) |
744 | */ | 757 | */ |
745 | 758 | ||
746 | /* Make a hard link */ | 759 | /* Make a hard link */ |
747 | 760 | ||
748 | /* XXX: This is ugly */ | 761 | /* XXX: This is ugly */ |
749 | type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; | 762 | type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; |
750 | if (!type) type = DT_REG; | 763 | if (!type) type = DT_REG; |
751 | 764 | ||
752 | ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), | 765 | now = get_seconds(); |
766 | ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), | ||
753 | old_dentry->d_inode->i_ino, type, | 767 | old_dentry->d_inode->i_ino, type, |
754 | new_dentry->d_name.name, new_dentry->d_name.len); | 768 | new_dentry->d_name.name, new_dentry->d_name.len, now); |
755 | 769 | ||
756 | if (ret) | 770 | if (ret) |
757 | return ret; | 771 | return ret; |
@@ -768,14 +782,14 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
768 | } | 782 | } |
769 | } | 783 | } |
770 | 784 | ||
771 | /* If it was a directory we moved, and there was no victim, | 785 | /* If it was a directory we moved, and there was no victim, |
772 | increase i_nlink on its new parent */ | 786 | increase i_nlink on its new parent */ |
773 | if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f) | 787 | if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f) |
774 | new_dir_i->i_nlink++; | 788 | new_dir_i->i_nlink++; |
775 | 789 | ||
776 | /* Unlink the original */ | 790 | /* Unlink the original */ |
777 | ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), | 791 | ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), |
778 | old_dentry->d_name.name, old_dentry->d_name.len, NULL); | 792 | old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); |
779 | 793 | ||
780 | /* We don't touch inode->i_nlink */ | 794 | /* We don't touch inode->i_nlink */ |
781 | 795 | ||
@@ -792,12 +806,15 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
792 | /* Might as well let the VFS know */ | 806 | /* Might as well let the VFS know */ |
793 | d_instantiate(new_dentry, old_dentry->d_inode); | 807 | d_instantiate(new_dentry, old_dentry->d_inode); |
794 | atomic_inc(&old_dentry->d_inode->i_count); | 808 | atomic_inc(&old_dentry->d_inode->i_count); |
809 | new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now); | ||
795 | return ret; | 810 | return ret; |
796 | } | 811 | } |
797 | 812 | ||
798 | if (S_ISDIR(old_dentry->d_inode->i_mode)) | 813 | if (S_ISDIR(old_dentry->d_inode->i_mode)) |
799 | old_dir_i->i_nlink--; | 814 | old_dir_i->i_nlink--; |
800 | 815 | ||
816 | new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); | ||
817 | |||
801 | return 0; | 818 | return 0; |
802 | } | 819 | } |
803 | 820 | ||