diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2013-06-11 08:45:29 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2013-06-11 08:45:29 -0400 |
commit | 5a00f3cc978be45b9d2597851bedaa40630bc597 (patch) | |
tree | 716a1b29594e352c4c793b699331d4d57578cce9 /fs/gfs2/dir.c | |
parent | a9aefd707c65aa5a7945b3f16bd39f314aa8414d (diff) |
GFS2: Only do one directory search on create
Creation of a new inode requires a directory search in order to ensure
that we are not trying to create an inode with the same name as an
existing one. This was hidden away inside the create_ok() function.
In the case that there was an existing inode, and a lookup can be
substituted for a create (which is the case with regular files
when the O_EXCL flag is not in use) then we were doing a second
lookup in order to return the inode.
This patch merges these two lookups into one. This can be done by
passing a flag to gfs2_dir_search() to tell it to just return -EEXIST
in the cases where we don't actually want to look up the inode.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index b631c9043460..f0c70529948f 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -1555,9 +1555,9 @@ out: | |||
1555 | 1555 | ||
1556 | /** | 1556 | /** |
1557 | * gfs2_dir_search - Search a directory | 1557 | * gfs2_dir_search - Search a directory |
1558 | * @dip: The GFS2 inode | 1558 | * @dip: The GFS2 dir inode |
1559 | * @filename: | 1559 | * @name: The name we are looking up |
1560 | * @inode: | 1560 | * @fail_on_exist: Fail if the name exists rather than looking it up |
1561 | * | 1561 | * |
1562 | * This routine searches a directory for a file or another directory. | 1562 | * This routine searches a directory for a file or another directory. |
1563 | * Assumes a glock is held on dip. | 1563 | * Assumes a glock is held on dip. |
@@ -1565,22 +1565,25 @@ out: | |||
1565 | * Returns: errno | 1565 | * Returns: errno |
1566 | */ | 1566 | */ |
1567 | 1567 | ||
1568 | struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) | 1568 | struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name, |
1569 | bool fail_on_exist) | ||
1569 | { | 1570 | { |
1570 | struct buffer_head *bh; | 1571 | struct buffer_head *bh; |
1571 | struct gfs2_dirent *dent; | 1572 | struct gfs2_dirent *dent; |
1572 | struct inode *inode; | 1573 | u64 addr, formal_ino; |
1574 | u16 dtype; | ||
1573 | 1575 | ||
1574 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); | 1576 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); |
1575 | if (dent) { | 1577 | if (dent) { |
1576 | if (IS_ERR(dent)) | 1578 | if (IS_ERR(dent)) |
1577 | return ERR_CAST(dent); | 1579 | return ERR_CAST(dent); |
1578 | inode = gfs2_inode_lookup(dir->i_sb, | 1580 | dtype = be16_to_cpu(dent->de_type); |
1579 | be16_to_cpu(dent->de_type), | 1581 | addr = be64_to_cpu(dent->de_inum.no_addr); |
1580 | be64_to_cpu(dent->de_inum.no_addr), | 1582 | formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino); |
1581 | be64_to_cpu(dent->de_inum.no_formal_ino), 0); | ||
1582 | brelse(bh); | 1583 | brelse(bh); |
1583 | return inode; | 1584 | if (fail_on_exist) |
1585 | return ERR_PTR(-EEXIST); | ||
1586 | return gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0); | ||
1584 | } | 1587 | } |
1585 | return ERR_PTR(-ENOENT); | 1588 | return ERR_PTR(-ENOENT); |
1586 | } | 1589 | } |