Skip to content

Commit 56ee7db

Browse files
dhavalehsiangkao
authored andcommitted
erofs: fix refcount on the metabuf used for inode lookup
In erofs_find_target_block() when erofs_dirnamecmp() returns 0, we do not assign the target metabuf. This causes the caller erofs_namei()'s erofs_put_metabuf() at the end to be not effective leaving the refcount on the page. As the page from metabuf (buf->page) is never put, such page cannot be migrated or reclaimed. Fix it now by putting the metabuf from previous loop and assigning the current metabuf to target before returning so caller erofs_namei() can do the final put as it was intended. Fixes: 500edd0 ("erofs: use meta buffers for inode lookup") Cc: <stable@vger.kernel.org> # 5.18+ Signed-off-by: Sandeep Dhavale <dhavale@google.com> Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Chao Yu <chao@kernel.org> Link: https://lore.kernel.org/r/20240221210348.3667795-1-dhavale@google.com Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
1 parent 841c351 commit 56ee7db

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

fs/erofs/namei.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -130,24 +130,24 @@ static void *erofs_find_target_block(struct erofs_buf *target,
130130
/* string comparison without already matched prefix */
131131
diff = erofs_dirnamecmp(name, &dname, &matched);
132132

133-
if (!diff) {
134-
*_ndirents = 0;
135-
goto out;
136-
} else if (diff > 0) {
137-
head = mid + 1;
138-
startprfx = matched;
139-
140-
if (!IS_ERR(candidate))
141-
erofs_put_metabuf(target);
142-
*target = buf;
143-
candidate = de;
144-
*_ndirents = ndirents;
145-
} else {
133+
if (diff < 0) {
146134
erofs_put_metabuf(&buf);
147-
148135
back = mid - 1;
149136
endprfx = matched;
137+
continue;
138+
}
139+
140+
if (!IS_ERR(candidate))
141+
erofs_put_metabuf(target);
142+
*target = buf;
143+
if (!diff) {
144+
*_ndirents = 0;
145+
return de;
150146
}
147+
head = mid + 1;
148+
startprfx = matched;
149+
candidate = de;
150+
*_ndirents = ndirents;
151151
continue;
152152
}
153153
out: /* free if the candidate is valid */

0 commit comments

Comments
 (0)