diff options
Diffstat (limited to 'fs/jffs2/dir.c')
-rw-r--r-- | fs/jffs2/dir.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 2bba3d3435be..c0c141f6fde1 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -226,7 +226,8 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
226 | d_instantiate(dentry, inode); | 226 | d_instantiate(dentry, inode); |
227 | 227 | ||
228 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", | 228 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", |
229 | inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); | 229 | inode->i_ino, inode->i_mode, inode->i_nlink, |
230 | f->inocache->pino_nlink, inode->i_mapping->nrpages)); | ||
230 | return 0; | 231 | return 0; |
231 | 232 | ||
232 | fail: | 233 | fail: |
@@ -250,7 +251,7 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry) | |||
250 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, | 251 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, |
251 | dentry->d_name.len, dead_f, now); | 252 | dentry->d_name.len, dead_f, now); |
252 | if (dead_f->inocache) | 253 | if (dead_f->inocache) |
253 | dentry->d_inode->i_nlink = dead_f->inocache->nlink; | 254 | dentry->d_inode->i_nlink = dead_f->inocache->pino_nlink; |
254 | if (!ret) | 255 | if (!ret) |
255 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | 256 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); |
256 | return ret; | 257 | return ret; |
@@ -283,7 +284,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de | |||
283 | 284 | ||
284 | if (!ret) { | 285 | if (!ret) { |
285 | mutex_lock(&f->sem); | 286 | mutex_lock(&f->sem); |
286 | old_dentry->d_inode->i_nlink = ++f->inocache->nlink; | 287 | old_dentry->d_inode->i_nlink = ++f->inocache->pino_nlink; |
287 | mutex_unlock(&f->sem); | 288 | mutex_unlock(&f->sem); |
288 | d_instantiate(dentry, old_dentry->d_inode); | 289 | d_instantiate(dentry, old_dentry->d_inode); |
289 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | 290 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); |
@@ -500,11 +501,14 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
500 | 501 | ||
501 | inode->i_op = &jffs2_dir_inode_operations; | 502 | inode->i_op = &jffs2_dir_inode_operations; |
502 | inode->i_fop = &jffs2_dir_operations; | 503 | inode->i_fop = &jffs2_dir_operations; |
503 | /* Directories get nlink 2 at start */ | ||
504 | inode->i_nlink = 2; | ||
505 | 504 | ||
506 | f = JFFS2_INODE_INFO(inode); | 505 | f = JFFS2_INODE_INFO(inode); |
507 | 506 | ||
507 | /* Directories get nlink 2 at start */ | ||
508 | inode->i_nlink = 2; | ||
509 | /* but ic->pino_nlink is the parent ino# */ | ||
510 | f->inocache->pino_nlink = dir_i->i_ino; | ||
511 | |||
508 | ri->data_crc = cpu_to_je32(0); | 512 | ri->data_crc = cpu_to_je32(0); |
509 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 513 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
510 | 514 | ||
@@ -601,17 +605,25 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
601 | 605 | ||
602 | static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | 606 | static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) |
603 | { | 607 | { |
608 | struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb); | ||
609 | struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); | ||
604 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); | 610 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); |
605 | struct jffs2_full_dirent *fd; | 611 | struct jffs2_full_dirent *fd; |
606 | int ret; | 612 | int ret; |
613 | uint32_t now = get_seconds(); | ||
607 | 614 | ||
608 | for (fd = f->dents ; fd; fd = fd->next) { | 615 | for (fd = f->dents ; fd; fd = fd->next) { |
609 | if (fd->ino) | 616 | if (fd->ino) |
610 | return -ENOTEMPTY; | 617 | return -ENOTEMPTY; |
611 | } | 618 | } |
612 | ret = jffs2_unlink(dir_i, dentry); | 619 | |
613 | if (!ret) | 620 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, |
621 | dentry->d_name.len, f, now); | ||
622 | if (!ret) { | ||
623 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | ||
624 | clear_nlink(dentry->d_inode); | ||
614 | drop_nlink(dir_i); | 625 | drop_nlink(dir_i); |
626 | } | ||
615 | return ret; | 627 | return ret; |
616 | } | 628 | } |
617 | 629 | ||
@@ -824,7 +836,10 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
824 | inode which didn't exist. */ | 836 | inode which didn't exist. */ |
825 | if (victim_f->inocache) { | 837 | if (victim_f->inocache) { |
826 | mutex_lock(&victim_f->sem); | 838 | mutex_lock(&victim_f->sem); |
827 | victim_f->inocache->nlink--; | 839 | if (S_ISDIR(new_dentry->d_inode->i_mode)) |
840 | victim_f->inocache->pino_nlink = 0; | ||
841 | else | ||
842 | victim_f->inocache->pino_nlink--; | ||
828 | mutex_unlock(&victim_f->sem); | 843 | mutex_unlock(&victim_f->sem); |
829 | } | 844 | } |
830 | } | 845 | } |
@@ -845,8 +860,8 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
845 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); | 860 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); |
846 | mutex_lock(&f->sem); | 861 | mutex_lock(&f->sem); |
847 | inc_nlink(old_dentry->d_inode); | 862 | inc_nlink(old_dentry->d_inode); |
848 | if (f->inocache) | 863 | if (f->inocache && !S_ISDIR(old_dentry->d_inode->i_mode)) |
849 | f->inocache->nlink++; | 864 | f->inocache->pino_nlink++; |
850 | mutex_unlock(&f->sem); | 865 | mutex_unlock(&f->sem); |
851 | 866 | ||
852 | printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); | 867 | printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); |