aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/dir.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2008-05-01 13:47:17 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2008-05-01 13:47:17 -0400
commit27c72b040c0be8f3704ed0b6b84c12cbba24a7e8 (patch)
tree0b84847120e817465d517d21fa4653d958222567 /fs/jffs2/dir.c
parent1b690b48786229571e590dd22fe01ecc22a8746b (diff)
[JFFS2] Track parent inode for directories (for NFS export)
To support NFS export, we need to know the parent inode of directories. Rather than growing the jffs2_inode_cache structure, share space with the nlink field -- which was always set to 1 for directories anyway. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/dir.c')
-rw-r--r--fs/jffs2/dir.c35
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
602static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) 606static 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);