aboutsummaryrefslogtreecommitdiff
path: root/fs/ocfs2/extent_map.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-29 17:44:21 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-29 17:44:21 -0700
commit501b7c77de3e90519e95fd99e923bf9a29cd120d (patch)
treef7dc56286e7309186f335d32f03434e82f31a41d /fs/ocfs2/extent_map.c
parent74e651f0aa100f3e5d3432a8dd8869c089e8d72f (diff)
parent184d7d20d352c7374f70ebca7468dc8cd5cc618a (diff)
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: ocfs2: remove redundant NULL checks in ocfs2_direct_IO_get_blocks() ocfs2: clean up some osb fields ocfs2: fix init of uuid_net_key ocfs2: silence a debug print ocfs2: silence ENOENT during lookup of broken links ocfs2: Cleanup message prints ocfs2: silence -EEXIST from ocfs2_extent_map_insert/lookup [PATCH] fs/ocfs2/dlm/dlmrecovery.c: make dlm_lockres_master_requery() static ocfs2: warn the user on a dead timeout mismatch ocfs2: OCFS2_FS must depend on SYSFS ocfs2: Compile-time disabling of ocfs2 debugging output. configfs: Clear up a few extra spaces where there should be TABs. configfs: Release memory in configfs_example.
Diffstat (limited to 'fs/ocfs2/extent_map.c')
-rw-r--r--fs/ocfs2/extent_map.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index 1a5c69071df..fcd4475d1f8 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -298,7 +298,7 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
ret = ocfs2_extent_map_insert(inode, rec,
le16_to_cpu(el->l_tree_depth));
- if (ret) {
+ if (ret && (ret != -EEXIST)) {
mlog_errno(ret);
goto out_free;
}
@@ -427,6 +427,11 @@ static int ocfs2_extent_map_insert_entry(struct ocfs2_extent_map *em,
/*
* Simple rule: on any return code other than -EAGAIN, anything left
* in the insert_context will be freed.
+ *
+ * Simple rule #2: A return code of -EEXIST from this function or
+ * its calls to ocfs2_extent_map_insert_entry() signifies that another
+ * thread beat us to the insert. It is not an actual error, but it
+ * tells the caller we have no more work to do.
*/
static int ocfs2_extent_map_try_insert(struct inode *inode,
struct ocfs2_extent_rec *rec,
@@ -448,22 +453,32 @@ static int ocfs2_extent_map_try_insert(struct inode *inode,
goto out_unlock;
}
+ /* Since insert_entry failed, the map MUST have old_ent */
old_ent = ocfs2_extent_map_lookup(em, le32_to_cpu(rec->e_cpos),
- le32_to_cpu(rec->e_clusters), NULL,
- NULL);
+ le32_to_cpu(rec->e_clusters),
+ NULL, NULL);
BUG_ON(!old_ent);
- ret = -EEXIST;
- if (old_ent->e_tree_depth < tree_depth)
+ if (old_ent->e_tree_depth < tree_depth) {
+ /* Another thread beat us to the lower tree_depth */
+ ret = -EEXIST;
goto out_unlock;
+ }
if (old_ent->e_tree_depth == tree_depth) {
+ /*
+ * Another thread beat us to this tree_depth.
+ * Let's make sure we agree with that thread (the
+ * extent_rec should be identical).
+ */
if (!memcmp(rec, &old_ent->e_rec,
sizeof(struct ocfs2_extent_rec)))
ret = 0;
+ else
+ /* FIXME: Should this be ESRCH/EBADR??? */
+ ret = -EEXIST;
- /* FIXME: Should this be ESRCH/EBADR??? */
goto out_unlock;
}
@@ -599,7 +614,7 @@ static int ocfs2_extent_map_insert(struct inode *inode,
tree_depth, &ctxt);
} while (ret == -EAGAIN);
- if (ret < 0)
+ if ((ret < 0) && (ret != -EEXIST))
mlog_errno(ret);
if (ctxt.left_ent)