summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2019-05-14 16:31:08 -0400
committerRichard Weinberger <richard@nod.at>2019-07-08 13:13:41 -0400
commitbacfa94b08027b9f66ede7044972e3b066766b3e (patch)
treec137b940ba432e0a4c9b70012b0343b86371825b
parent6fbc7275c7a9ba97877050335f290341a1fd8dbf (diff)
ubifs: Correctly use tnc_next() in search_dh_cookie()
Commit c877154d307f fixed an uninitialized variable and optimized the function to not call tnc_next() in the first iteration of the loop. While this seemed perfectly legit and wise, it turned out to be illegal. If the lookup function does not find an exact match it will rewind the cursor by 1. The rewinded cursor will not match the name hash we are looking for and this results in a spurious -ENOENT. So we need to move to the next entry in case of an non-exact match, but not if the match was exact. While we are here, update the documentation to avoid further confusion. Cc: Hyunchul Lee <hyc.lee@gmail.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Fixes: c877154d307f ("ubifs: Fix uninitialized variable in search_dh_cookie()") Fixes: 781f675e2d7e ("ubifs: Fix unlink code wrt. double hash lookups") Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r--fs/ubifs/tnc.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index f5a823cb0e43..e8e7b0e9532e 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -1158,8 +1158,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
1158 * o exact match, i.e. the found zero-level znode contains key @key, then %1 1158 * o exact match, i.e. the found zero-level znode contains key @key, then %1
1159 * is returned and slot number of the matched branch is stored in @n; 1159 * is returned and slot number of the matched branch is stored in @n;
1160 * o not exact match, which means that zero-level znode does not contain 1160 * o not exact match, which means that zero-level znode does not contain
1161 * @key, then %0 is returned and slot number of the closest branch is stored 1161 * @key, then %0 is returned and slot number of the closest branch or %-1
1162 * in @n; 1162 * is stored in @n; In this case calling tnc_next() is mandatory.
1163 * o @key is so small that it is even less than the lowest key of the 1163 * o @key is so small that it is even less than the lowest key of the
1164 * leftmost zero-level node, then %0 is returned and %0 is stored in @n. 1164 * leftmost zero-level node, then %0 is returned and %0 is stored in @n.
1165 * 1165 *
@@ -1882,13 +1882,19 @@ int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
1882 1882
1883static int search_dh_cookie(struct ubifs_info *c, const union ubifs_key *key, 1883static int search_dh_cookie(struct ubifs_info *c, const union ubifs_key *key,
1884 struct ubifs_dent_node *dent, uint32_t cookie, 1884 struct ubifs_dent_node *dent, uint32_t cookie,
1885 struct ubifs_znode **zn, int *n) 1885 struct ubifs_znode **zn, int *n, int exact)
1886{ 1886{
1887 int err; 1887 int err;
1888 struct ubifs_znode *znode = *zn; 1888 struct ubifs_znode *znode = *zn;
1889 struct ubifs_zbranch *zbr; 1889 struct ubifs_zbranch *zbr;
1890 union ubifs_key *dkey; 1890 union ubifs_key *dkey;
1891 1891
1892 if (!exact) {
1893 err = tnc_next(c, &znode, n);
1894 if (err)
1895 return err;
1896 }
1897
1892 for (;;) { 1898 for (;;) {
1893 zbr = &znode->zbranch[*n]; 1899 zbr = &znode->zbranch[*n];
1894 dkey = &zbr->key; 1900 dkey = &zbr->key;
@@ -1930,7 +1936,7 @@ static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
1930 if (unlikely(err < 0)) 1936 if (unlikely(err < 0))
1931 goto out_unlock; 1937 goto out_unlock;
1932 1938
1933 err = search_dh_cookie(c, key, dent, cookie, &znode, &n); 1939 err = search_dh_cookie(c, key, dent, cookie, &znode, &n, err);
1934 1940
1935out_unlock: 1941out_unlock:
1936 mutex_unlock(&c->tnc_mutex); 1942 mutex_unlock(&c->tnc_mutex);
@@ -2723,7 +2729,7 @@ int ubifs_tnc_remove_dh(struct ubifs_info *c, const union ubifs_key *key,
2723 if (unlikely(err < 0)) 2729 if (unlikely(err < 0))
2724 goto out_free; 2730 goto out_free;
2725 2731
2726 err = search_dh_cookie(c, key, dent, cookie, &znode, &n); 2732 err = search_dh_cookie(c, key, dent, cookie, &znode, &n, err);
2727 if (err) 2733 if (err)
2728 goto out_free; 2734 goto out_free;
2729 } 2735 }