aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-05-09 08:30:08 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-05-09 11:43:53 -0400
commit3d6ecb7d16fd4248fce58387a982a0756ad3fcc2 (patch)
treeb988b57c8a46fcfabe3738ccdb8982d67cd24c97 /fs/gfs2
parent855d23ce2665c56437bd88fa6a0d45b6713bd194 (diff)
GFS2: When adding a new dir entry, inc link count if it is a subdir
This adds an increment of the link count when we add a new directory entry, if that entry is itself a directory. This means that we no longer need separate code to perform this operation. Now that both adding and removing directory entries automatically update the parent directory's link count if required, that makes the code shorter and simpler than before. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/dir.c6
-rw-r--r--fs/gfs2/dir.h2
-rw-r--r--fs/gfs2/inode.c48
-rw-r--r--fs/gfs2/inode.h1
-rw-r--r--fs/gfs2/ops_inode.c11
5 files changed, 8 insertions, 60 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 410265151ad1..091ee4779538 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1597,7 +1597,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
1597 */ 1597 */
1598 1598
1599int gfs2_dir_add(struct inode *inode, const struct qstr *name, 1599int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1600 const struct gfs2_inode *nip, unsigned type) 1600 const struct gfs2_inode *nip)
1601{ 1601{
1602 struct gfs2_inode *ip = GFS2_I(inode); 1602 struct gfs2_inode *ip = GFS2_I(inode);
1603 struct buffer_head *bh; 1603 struct buffer_head *bh;
@@ -1613,7 +1613,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1613 return PTR_ERR(dent); 1613 return PTR_ERR(dent);
1614 dent = gfs2_init_dirent(inode, dent, name, bh); 1614 dent = gfs2_init_dirent(inode, dent, name, bh);
1615 gfs2_inum_out(nip, dent); 1615 gfs2_inum_out(nip, dent);
1616 dent->de_type = cpu_to_be16(type); 1616 dent->de_type = cpu_to_be16(IF2DT(nip->i_inode.i_mode));
1617 if (ip->i_diskflags & GFS2_DIF_EXHASH) { 1617 if (ip->i_diskflags & GFS2_DIF_EXHASH) {
1618 leaf = (struct gfs2_leaf *)bh->b_data; 1618 leaf = (struct gfs2_leaf *)bh->b_data;
1619 be16_add_cpu(&leaf->lf_entries, 1); 1619 be16_add_cpu(&leaf->lf_entries, 1);
@@ -1625,6 +1625,8 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1625 gfs2_trans_add_bh(ip->i_gl, bh, 1); 1625 gfs2_trans_add_bh(ip->i_gl, bh, 1);
1626 ip->i_entries++; 1626 ip->i_entries++;
1627 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; 1627 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1628 if (S_ISDIR(nip->i_inode.i_mode))
1629 inc_nlink(&ip->i_inode);
1628 gfs2_dinode_out(ip, bh->b_data); 1630 gfs2_dinode_out(ip, bh->b_data);
1629 brelse(bh); 1631 brelse(bh);
1630 error = 0; 1632 error = 0;
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h
index 66831f1d23ea..e686af11becd 100644
--- a/fs/gfs2/dir.h
+++ b/fs/gfs2/dir.h
@@ -22,7 +22,7 @@ extern struct inode *gfs2_dir_search(struct inode *dir,
22extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename, 22extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
23 const struct gfs2_inode *ip); 23 const struct gfs2_inode *ip);
24extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename, 24extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
25 const struct gfs2_inode *ip, unsigned int type); 25 const struct gfs2_inode *ip);
26extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry); 26extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry);
27extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, 27extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
28 filldir_t filldir); 28 filldir_t filldir);
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 5a02606b68c0..a8c14c9985e2 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -362,52 +362,6 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
362 return error; 362 return error;
363} 363}
364 364
365/**
366 * gfs2_change_nlink - Change nlink count on inode
367 * @ip: The GFS2 inode
368 * @diff: The change in the nlink count required
369 *
370 * Returns: errno
371 */
372int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
373{
374 struct buffer_head *dibh;
375 u32 nlink;
376 int error;
377
378 BUG_ON(diff != 1 && diff != -1);
379 nlink = ip->i_inode.i_nlink + diff;
380
381 /* If we are reducing the nlink count, but the new value ends up being
382 bigger than the old one, we must have underflowed. */
383 if (diff < 0 && nlink > ip->i_inode.i_nlink) {
384 if (gfs2_consist_inode(ip))
385 gfs2_dinode_print(ip);
386 return -EIO;
387 }
388
389 error = gfs2_meta_inode_buffer(ip, &dibh);
390 if (error)
391 return error;
392
393 if (diff > 0)
394 inc_nlink(&ip->i_inode);
395 else
396 drop_nlink(&ip->i_inode);
397
398 ip->i_inode.i_ctime = CURRENT_TIME;
399
400 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
401 gfs2_dinode_out(ip, dibh->b_data);
402 brelse(dibh);
403 mark_inode_dirty(&ip->i_inode);
404
405 if (ip->i_inode.i_nlink == 0)
406 gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */
407
408 return error;
409}
410
411struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) 365struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
412{ 366{
413 struct qstr qstr; 367 struct qstr qstr;
@@ -723,7 +677,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
723 goto fail_quota_locks; 677 goto fail_quota_locks;
724 } 678 }
725 679
726 error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); 680 error = gfs2_dir_add(&dip->i_inode, name, ip);
727 if (error) 681 if (error)
728 goto fail_end_trans; 682 goto fail_end_trans;
729 683
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 8d1344a4e673..f9b8289deec5 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -106,7 +106,6 @@ extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr, int nonbl
106 106
107extern int gfs2_inode_refresh(struct gfs2_inode *ip); 107extern int gfs2_inode_refresh(struct gfs2_inode *ip);
108 108
109extern int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
110extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, 109extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
111 int is_root); 110 int is_root);
112extern struct inode *gfs2_createi(struct gfs2_holder *ghs, 111extern struct inode *gfs2_createi(struct gfs2_holder *ghs,
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 765da06c8f55..6b8c2bdb5a0c 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -235,7 +235,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
235 if (error) 235 if (error)
236 goto out_end_trans; 236 goto out_end_trans;
237 237
238 error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode)); 238 error = gfs2_dir_add(dir, &dentry->d_name, ip);
239 if (error) 239 if (error)
240 goto out_brelse; 240 goto out_brelse;
241 241
@@ -554,9 +554,6 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
554 brelse(dibh); 554 brelse(dibh);
555 } 555 }
556 556
557 error = gfs2_change_nlink(dip, +1);
558 gfs2_assert_withdraw(sdp, !error); /* dip already pinned */
559
560 gfs2_trans_end(sdp); 557 gfs2_trans_end(sdp);
561 if (dip->i_alloc->al_rgd) 558 if (dip->i_alloc->al_rgd)
562 gfs2_inplace_release(dip); 559 gfs2_inplace_release(dip);
@@ -857,10 +854,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
857 } 854 }
858 855
859 if (dir_rename) { 856 if (dir_rename) {
860 error = gfs2_change_nlink(ndip, +1);
861 if (error)
862 goto out_end_trans;
863
864 error = gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR); 857 error = gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR);
865 if (error) 858 if (error)
866 goto out_end_trans; 859 goto out_end_trans;
@@ -879,7 +872,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
879 if (error) 872 if (error)
880 goto out_end_trans; 873 goto out_end_trans;
881 874
882 error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode)); 875 error = gfs2_dir_add(ndir, &ndentry->d_name, ip);
883 if (error) 876 if (error)
884 goto out_end_trans; 877 goto out_end_trans;
885 878