diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 17:44:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 17:44:21 -0700 |
commit | 501b7c77de3e90519e95fd99e923bf9a29cd120d (patch) | |
tree | f7dc56286e7309186f335d32f03434e82f31a41d /fs/ocfs2/extent_map.c | |
parent | 74e651f0aa100f3e5d3432a8dd8869c089e8d72f (diff) | |
parent | 184d7d20d352c7374f70ebca7468dc8cd5cc618a (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.c | 29 |
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) |