summaryrefslogtreecommitdiff
path: root/fs/gfs2/dir.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-05-09 16:42:37 +0100
committerSteven Whitehouse <swhiteho@redhat.com>2011-05-09 16:42:37 +0100
commit855d23ce2665c56437bd88fa6a0d45b6713bd194 (patch)
tree0678f8d0e93dfafd783bf9782f457bc7235b2128 /fs/gfs2/dir.c
parent2baee03fb916563d7cc597e5460e4cb938815c52 (diff)
GFS2: Make gfs2_dir_del update link count when required
When we remove an entry from a directory, we can save ourselves some trouble if we know the type of the entry in question, since if it is itself a directory, we can update the link count of the parent at the same time as removing the directory entry. In addition this patch also merges the rmdir and unlink code which was almost identical anyway. This eliminates the calls to remove the . and .. directory entries on each rmdir (not needed since the directory will be deallocated, anyway) which was the only thing preventing passing the dentry to gfs2_dir_del(). The passing of the dentry rather than just the name allows us to figure out the type of the entry which is being removed, and thus adjust the link count when required. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r--fs/gfs2/dir.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index f7a31374ff82..410265151ad1 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1669,8 +1669,9 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
* Returns: 0 on success, error code on failure
*/
-int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
+int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry)
{
+ const struct qstr *name = &dentry->d_name;
struct gfs2_dirent *dent, *prev = NULL;
struct buffer_head *bh;
int error;
@@ -1711,6 +1712,8 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
gfs2_trans_add_bh(dip->i_gl, bh, 1);
dip->i_entries--;
dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
+ if (S_ISDIR(dentry->d_inode->i_mode))
+ drop_nlink(&dip->i_inode);
gfs2_dinode_out(dip, bh->b_data);
brelse(bh);
mark_inode_dirty(&dip->i_inode);