diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2011-05-09 16:42:37 +0100 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2011-05-09 16:42:37 +0100 |
commit | 855d23ce2665c56437bd88fa6a0d45b6713bd194 (patch) | |
tree | 0678f8d0e93dfafd783bf9782f457bc7235b2128 /fs/gfs2/dir.c | |
parent | 2baee03fb916563d7cc597e5460e4cb938815c52 (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.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index f7a31374ff8..410265151ad 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); |