[Ocfs2-devel] [PATCH 2/2] Disable index if indexed directory find fails
Goldwyn Rodrigues
rgoldwyn at gmail.com
Wed Jun 15 08:58:25 PDT 2011
Disable directory indexing during a dirent search operation. In order to
disable, the inode's buffer_head has to be passed through.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn at suse.de>
---
fs/ocfs2/dir.c | 30 ++++++++++++++++++++----------
fs/ocfs2/dir.h | 10 +++++-----
fs/ocfs2/export.c | 2 +-
fs/ocfs2/ioctl.c | 3 ++-
fs/ocfs2/move_extents.c | 2 +-
fs/ocfs2/namei.c | 33 +++++++++++++++++----------------
fs/ocfs2/sysfile.c | 2 +-
7 files changed, 47 insertions(+), 35 deletions(-)
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 3a6f6e4..b6cf5d2 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -1113,13 +1113,22 @@ static void ocfs2_dx_disable(struct inode
*dir, struct buffer_head *di_bh)
* in the indexed directory case, multiple buffers are involved.
*/
int ocfs2_find_entry(const char *name, int namelen,
- struct inode *dir, struct ocfs2_dir_lookup_result *lookup)
+ struct inode *dir, struct buffer_head *di_bh,
+ struct ocfs2_dir_lookup_result *lookup)
{
struct buffer_head *bh;
struct ocfs2_dir_entry *res_dir = NULL;
+ int ret = 0;
+
+ if (ocfs2_dir_indexed(dir)) {
+ ret = ocfs2_find_entry_dx(name, namelen, dir, lookup);
+ if (ret == -EINVAL) {
+ ocfs2_dx_disable(dir, di_bh);
+ ret = 0;
+ } else
+ return ret;
+ }
- if (ocfs2_dir_indexed(dir))
- return ocfs2_find_entry_dx(name, namelen, dir, lookup);
/*
* The unindexed dir code only uses part of the lookup
@@ -2083,7 +2092,7 @@ bail_nolock:
int ocfs2_find_files_on_disk(const char *name,
int namelen,
u64 *blkno,
- struct inode *inode,
+ struct inode *inode, struct buffer_head *di_bh,
struct ocfs2_dir_lookup_result *lookup)
{
int status = -ENOENT;
@@ -2091,7 +2100,7 @@ int ocfs2_find_files_on_disk(const char *name,
trace_ocfs2_find_files_on_disk(namelen, name, blkno,
(unsigned long long)OCFS2_I(inode)->ip_blkno);
- status = ocfs2_find_entry(name, namelen, inode, lookup);
+ status = ocfs2_find_entry(name, namelen, inode, di_bh, lookup);
if (status)
goto leave;
@@ -2107,13 +2116,14 @@ leave:
* Convenience function for callers which just want the block number
* mapped to a name and don't require the full dirent info, etc.
*/
-int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name,
- int namelen, u64 *blkno)
+int ocfs2_lookup_ino_from_name(struct inode *dir, struct buffer_head *di_bh,
+ const char *name, int namelen, u64 *blkno)
{
int ret;
struct ocfs2_dir_lookup_result lookup = { NULL, };
- ret = ocfs2_find_files_on_disk(name, namelen, blkno, dir, &lookup);
+ ret = ocfs2_find_files_on_disk(name, namelen, blkno, dir, di_bh,
+ &lookup);
ocfs2_free_dir_lookup_result(&lookup);
return ret;
@@ -2126,7 +2136,7 @@ int ocfs2_lookup_ino_from_name(struct inode
*dir, const char *name,
*
* Callers should have i_mutex + a cluster lock on dir
*/
-int ocfs2_check_dir_for_entry(struct inode *dir,
+int ocfs2_check_dir_for_entry(struct inode *dir, struct buffer_head *bh,
const char *name,
int namelen)
{
@@ -2137,7 +2147,7 @@ int ocfs2_check_dir_for_entry(struct inode *dir,
(unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name);
ret = -EEXIST;
- if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0)
+ if (ocfs2_find_entry(name, namelen, dir, bh, &lookup) == 0)
goto bail;
ret = 0;
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
index e683f3d..2c271d9 100644
--- a/fs/ocfs2/dir.h
+++ b/fs/ocfs2/dir.h
@@ -55,7 +55,7 @@ struct ocfs2_dir_lookup_result {
void ocfs2_free_dir_lookup_result(struct ocfs2_dir_lookup_result *res);
int ocfs2_find_entry(const char *name, int namelen,
- struct inode *dir,
+ struct inode *dir, struct buffer_head *di_bh,
struct ocfs2_dir_lookup_result *lookup);
int ocfs2_delete_entry(handle_t *handle,
struct inode *dir,
@@ -80,7 +80,7 @@ int ocfs2_update_entry(struct inode *dir, handle_t *handle,
struct ocfs2_dir_lookup_result *res,
struct inode *new_entry_inode);
-int ocfs2_check_dir_for_entry(struct inode *dir,
+int ocfs2_check_dir_for_entry(struct inode *dir, struct buffer_head *di_bh,
const char *name,
int namelen);
int ocfs2_empty_dir(struct inode *inode);
@@ -88,10 +88,10 @@ int ocfs2_empty_dir(struct inode *inode);
int ocfs2_find_files_on_disk(const char *name,
int namelen,
u64 *blkno,
- struct inode *inode,
+ struct inode *inode, struct buffer_head *di_bh,
struct ocfs2_dir_lookup_result *res);
-int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name,
- int namelen, u64 *blkno);
+int ocfs2_lookup_ino_from_name(struct inode *dir, struct buffer_head *di_bh,
+ const char *name, int namelen, u64 *blkno);
int ocfs2_readdir(struct file *filp, void *dirent, filldir_t filldir);
int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv,
filldir_t filldir);
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 745db42..a130bcc 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -160,7 +160,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
goto bail;
}
- status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
+ status = ocfs2_lookup_ino_from_name(dir, NULL, "..", 2, &blkno);
if (status < 0) {
parent = ERR_PTR(-ENOENT);
goto bail_unlock;
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index bc91072..a6078d1 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -403,6 +403,7 @@ int ocfs2_info_handle_freeinode(struct inode *inode,
sizeof(namebuf),
type, i);
status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
+ NULL,
namebuf,
strlen(namebuf),
&blkno);
@@ -691,7 +692,7 @@ int ocfs2_info_handle_freefrag(struct inode *inode,
} else {
ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type,
OCFS2_INVALID_SLOT);
- status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
+ status = ocfs2_lookup_ino_from_name(osb->sys_root_inode, NULL,
namebuf,
strlen(namebuf),
&blkno);
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
index cd94270..37bb243 100644
--- a/fs/ocfs2/move_extents.c
+++ b/fs/ocfs2/move_extents.c
@@ -380,7 +380,7 @@ static int ocfs2_find_victim_alloc_group(struct
inode *inode,
struct ocfs2_group_desc *bg;
ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type, slot);
- ret = ocfs2_lookup_ino_from_name(osb->sys_root_inode, namebuf,
+ ret = ocfs2_lookup_ino_from_name(osb->sys_root_inode, NULL, namebuf,
strlen(namebuf), &blkno);
if (ret) {
ret = -ENOENT;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index e5d738c..396ca7c 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -123,7 +123,7 @@ static struct dentry *ocfs2_lookup(struct inode
*dir, struct dentry *dentry,
goto bail;
}
- status = ocfs2_lookup_ino_from_name(dir, dentry->d_name.name,
+ status = ocfs2_lookup_ino_from_name(dir, NULL, dentry->d_name.name,
dentry->d_name.len, &blkno);
if (status < 0)
goto bail_add;
@@ -261,8 +261,8 @@ static int ocfs2_mknod(struct inode *dir,
goto leave;
}
- status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
- dentry->d_name.len);
+ status = ocfs2_check_dir_for_entry(dir, parent_fe_bh,
+ dentry->d_name.name, dentry->d_name.len);
if (status)
goto leave;
@@ -668,8 +668,8 @@ static int ocfs2_link(struct dentry *old_dentry,
goto out;
}
- err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
- dentry->d_name.len);
+ err = ocfs2_check_dir_for_entry(dir, parent_fe_bh,
+ dentry->d_name.name, dentry->d_name.len);
if (err)
goto out;
@@ -827,7 +827,7 @@ static int ocfs2_unlink(struct inode *dir,
status = ocfs2_find_files_on_disk(dentry->d_name.name,
dentry->d_name.len, &blkno, dir,
- &lookup);
+ parent_node_bh, &lookup);
if (status < 0) {
if (status != -ENOENT)
mlog_errno(status);
@@ -1148,7 +1148,7 @@ static int ocfs2_rename(struct inode *old_dir,
update_dot_dot = 1;
status = ocfs2_find_files_on_disk("..", 2, &old_inode_parent,
- old_inode,
+ old_inode, old_inode_bh,
&old_inode_dot_dot_res);
if (status) {
status = -EIO;
@@ -1167,7 +1167,8 @@ static int ocfs2_rename(struct inode *old_dir,
}
}
- status = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name,
+ status = ocfs2_lookup_ino_from_name(old_dir, NULL,
+ old_dentry->d_name.name,
old_dentry->d_name.len,
&old_de_ino);
if (status) {
@@ -1190,7 +1191,7 @@ static int ocfs2_rename(struct inode *old_dir,
* to delete it */
status = ocfs2_find_files_on_disk(new_dentry->d_name.name,
new_dentry->d_name.len,
- &newfe_blkno, new_dir,
+ &newfe_blkno, new_dir, new_dir_bh,
&target_lookup_res);
/* The only error we allow here is -ENOENT because the new
* file not existing is perfectly valid. */
@@ -1272,7 +1273,7 @@ static int ocfs2_rename(struct inode *old_dir,
} else {
BUG_ON(new_dentry->d_parent->d_inode != new_dir);
- status = ocfs2_check_dir_for_entry(new_dir,
+ status = ocfs2_check_dir_for_entry(new_dir, new_dir_bh,
new_dentry->d_name.name,
new_dentry->d_name.len);
if (status)
@@ -1367,7 +1368,7 @@ static int ocfs2_rename(struct inode *old_dir,
* we're dealing with.
*/
status = ocfs2_find_entry(old_dentry->d_name.name,
- old_dentry->d_name.len, old_dir,
+ old_dentry->d_name.len, old_dir, old_dir_bh,
&old_entry_lookup);
if (status)
goto bail;
@@ -1634,8 +1635,8 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}
- status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
- dentry->d_name.len);
+ status = ocfs2_check_dir_for_entry(dir, parent_fe_bh,
+ dentry->d_name.name, dentry->d_name.len);
if (status)
goto bail;
@@ -2090,7 +2091,7 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
/* find it's spot in the orphan directory */
status = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN, orphan_dir_inode,
- &lookup);
+ orphan_dir_bh, &lookup);
if (status) {
mlog_errno(status);
goto leave;
@@ -2373,8 +2374,8 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
goto leave;
}
- status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
- dentry->d_name.len);
+ status = ocfs2_check_dir_for_entry(dir, parent_di_bh,
+ dentry->d_name.name, dentry->d_name.len);
if (status)
goto leave;
diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c
index 3d635f4..37cf15f 100644
--- a/fs/ocfs2/sysfile.c
+++ b/fs/ocfs2/sysfile.c
@@ -146,7 +146,7 @@ static struct inode *
_ocfs2_get_system_file_inode(struct ocfs2_super *osb,
sizeof(namebuf),
type, slot);
- status = ocfs2_lookup_ino_from_name(osb->sys_root_inode, namebuf,
+ status = ocfs2_lookup_ino_from_name(osb->sys_root_inode, NULL, namebuf,
strlen(namebuf), &blkno);
if (status < 0) {
goto bail;
--
1.7.5.3
--
Goldwyn
More information about the Ocfs2-devel
mailing list