diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2014-01-06 13:49:43 +0100 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2014-01-06 13:49:43 +0100 |
commit | 2b47dad866d04f14c328f888ba5406057b8c7d33 (patch) | |
tree | 9eb66c086c2e49080234e0a9a1014624354ebea3 /fs/gfs2/dir.c | |
parent | GFS2: Consolidate transaction blocks calculation for dir add (diff) | |
download | linux-2b47dad866d04f14c328f888ba5406057b8c7d33.tar.xz linux-2b47dad866d04f14c328f888ba5406057b8c7d33.zip |
GFS2: Remember directory insert point
When we look to see if there is enough space to add a dir
entry without allocation, we have then been repeating the
same search later when we do the actual insertion. This
patch caches the details of the location in the gfs2_diradd
structure, so that we do not have to repeat the search.
This will provide a performance improvement which will be
greater as the size of the directory increases.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 0b6be202a82c..d5988aafaa74 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1659,26 +1659,34 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) /** * gfs2_dir_add - Add new filename into directory - * @dip: The GFS2 inode - * @filename: The new name - * @inode: The inode number of the entry - * @type: The type of the entry + * @inode: The directory inode + * @name: The new name + * @nip: The GFS2 inode to be linked in to the directory + * @da: The directory addition info + * + * If the call to gfs2_diradd_alloc_required resulted in there being + * no need to allocate any new directory blocks, then it will contain + * a pointer to the directory entry and the bh in which it resides. We + * can use that without having to repeat the search. If there was no + * free space, then we must now create more space. * * Returns: 0 on success, error code on failure */ int gfs2_dir_add(struct inode *inode, const struct qstr *name, - const struct gfs2_inode *nip) + const struct gfs2_inode *nip, struct gfs2_diradd *da) { struct gfs2_inode *ip = GFS2_I(inode); - struct buffer_head *bh; - struct gfs2_dirent *dent; + struct buffer_head *bh = da->bh; + struct gfs2_dirent *dent = da->dent; struct gfs2_leaf *leaf; int error; while(1) { - dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, - &bh); + if (da->bh == NULL) { + dent = gfs2_dirent_search(inode, name, + gfs2_dirent_find_space, &bh); + } if (dent) { if (IS_ERR(dent)) return PTR_ERR(dent); @@ -1689,6 +1697,8 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, leaf = (struct gfs2_leaf *)bh->b_data; be16_add_cpu(&leaf->lf_entries, 1); } + da->dent = NULL; + da->bh = NULL; brelse(bh); ip->i_entries++; ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; @@ -2030,6 +2040,8 @@ int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name, struct buffer_head *bh; da->nr_blocks = 0; + da->bh = NULL; + da->dent = NULL; dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh); if (!dent) { @@ -2038,7 +2050,8 @@ int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name, } if (IS_ERR(dent)) return PTR_ERR(dent); - brelse(bh); + da->bh = bh; + da->dent = dent; return 0; } |