<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/net/ceph/osd_client.c, branch v6.1.179</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v6.1.179</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v6.1.179'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-01-17T15:39:27+00:00</updated>
<entry>
<title>libceph: make calc_target() set t-&gt;paused, not just clear it</title>
<updated>2026-01-17T15:39:27+00:00</updated>
<author>
<name>Ilya Dryomov</name>
<email>idryomov@gmail.com</email>
</author>
<published>2026-01-05T18:23:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=4d3399c52e0e61720ae898f5a0b5b75d4460ae24'/>
<id>urn:sha1:4d3399c52e0e61720ae898f5a0b5b75d4460ae24</id>
<content type='text'>
commit c0fe2994f9a9d0a2ec9e42441ea5ba74b6a16176 upstream.

Currently calc_target() clears t-&gt;paused if the request shouldn't be
paused anymore, but doesn't ever set t-&gt;paused even though it's able to
determine when the request should be paused.  Setting t-&gt;paused is left
to __submit_request() which is fine for regular requests but doesn't
work for linger requests -- since __submit_request() doesn't operate
on linger requests, there is nowhere for lreq-&gt;t.paused to be set.
One consequence of this is that watches don't get reestablished on
paused -&gt; unpaused transitions in cases where requests have been paused
long enough for the (paused) unwatch request to time out and for the
subsequent (re)watch request to enter the paused state.  On top of the
watch not getting reestablished, rbd_reregister_watch() gets stuck with
rbd_dev-&gt;watch_mutex held:

  rbd_register_watch
    __rbd_register_watch
      ceph_osdc_watch
        linger_reg_commit_wait

It's waiting for lreq-&gt;reg_commit_wait to be completed, but for that to
happen the respective request needs to end up on need_resend_linger list
and be kicked when requests are unpaused.  There is no chance for that
if the request in question is never marked paused in the first place.

The fact that rbd_dev-&gt;watch_mutex remains taken out forever then
prevents the image from getting unmapped -- "rbd unmap" would inevitably
hang in D state on an attempt to grab the mutex.

Cc: stable@vger.kernel.org
Reported-by: Raphael Zimmer &lt;raphael.zimmer@tu-ilmenau.de&gt;
Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
Reviewed-by: Viacheslav Dubeyko &lt;Slava.Dubeyko@ibm.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>libceph: fix potential hang in ceph_osdc_notify()</title>
<updated>2023-08-11T10:08:19+00:00</updated>
<author>
<name>Ilya Dryomov</name>
<email>idryomov@gmail.com</email>
</author>
<published>2023-08-01T17:14:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=be52667ba24344199990e011cb7819640266799e'/>
<id>urn:sha1:be52667ba24344199990e011cb7819640266799e</id>
<content type='text'>
commit e6e2843230799230fc5deb8279728a7218b0d63c upstream.

If the cluster becomes unavailable, ceph_osdc_notify() may hang even
with osd_request_timeout option set because linger_notify_finish_wait()
waits for MWatchNotify NOTIFY_COMPLETE message with no associated OSD
request in flight -- it's completely asynchronous.

Introduce an additional timeout, derived from the specified notify
timeout.  While at it, switch both waits to killable which is more
correct.

Cc: stable@vger.kernel.org
Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
Reviewed-by: Dongsheng Yang &lt;dongsheng.yang@easystack.cn&gt;
Reviewed-by: Xiubo Li &lt;xiubli@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>treewide: use prandom_u32_max() when possible, part 1</title>
<updated>2022-10-11T23:42:55+00:00</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-10-05T14:43:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=81895a65ec63ee1daec3255dc1a06675d2fbe915'/>
<id>urn:sha1:81895a65ec63ee1daec3255dc1a06675d2fbe915</id>
<content type='text'>
Rather than incurring a division or requesting too many random bytes for
the given range, use the prandom_u32_max() function, which only takes
the minimum required bytes from the RNG and avoids divisions. This was
done mechanically with this coccinelle script:

@basic@
expression E;
type T;
identifier get_random_u32 =~ "get_random_int|prandom_u32|get_random_u32";
typedef u64;
@@
(
- ((T)get_random_u32() % (E))
+ prandom_u32_max(E)
|
- ((T)get_random_u32() &amp; ((E) - 1))
+ prandom_u32_max(E * XXX_MAKE_SURE_E_IS_POW2)
|
- ((u64)(E) * get_random_u32() &gt;&gt; 32)
+ prandom_u32_max(E)
|
- ((T)get_random_u32() &amp; ~PAGE_MASK)
+ prandom_u32_max(PAGE_SIZE)
)

@multi_line@
identifier get_random_u32 =~ "get_random_int|prandom_u32|get_random_u32";
identifier RAND;
expression E;
@@

-       RAND = get_random_u32();
        ... when != RAND
-       RAND %= (E);
+       RAND = prandom_u32_max(E);

// Find a potential literal
@literal_mask@
expression LITERAL;
type T;
identifier get_random_u32 =~ "get_random_int|prandom_u32|get_random_u32";
position p;
@@

        ((T)get_random_u32()@p &amp; (LITERAL))

// Add one to the literal.
@script:python add_one@
literal &lt;&lt; literal_mask.LITERAL;
RESULT;
@@

value = None
if literal.startswith('0x'):
        value = int(literal, 16)
elif literal[0] in '123456789':
        value = int(literal, 10)
if value is None:
        print("I don't know how to handle %s" % (literal))
        cocci.include_match(False)
elif value == 2**32 - 1 or value == 2**31 - 1 or value == 2**24 - 1 or value == 2**16 - 1 or value == 2**8 - 1:
        print("Skipping 0x%x for cleanup elsewhere" % (value))
        cocci.include_match(False)
elif value &amp; (value + 1) != 0:
        print("Skipping 0x%x because it's not a power of two minus one" % (value))
        cocci.include_match(False)
elif literal.startswith('0x'):
        coccinelle.RESULT = cocci.make_expr("0x%x" % (value + 1))
else:
        coccinelle.RESULT = cocci.make_expr("%d" % (value + 1))

// Replace the literal mask with the calculated result.
@plus_one@
expression literal_mask.LITERAL;
position literal_mask.p;
expression add_one.RESULT;
identifier FUNC;
@@

-       (FUNC()@p &amp; (LITERAL))
+       prandom_u32_max(RESULT)

@collapse_ret@
type T;
identifier VAR;
expression E;
@@

 {
-       T VAR;
-       VAR = (E);
-       return VAR;
+       return E;
 }

@drop_var@
type T;
identifier VAR;
@@

 {
-       T VAR;
        ... when != VAR
 }

Reviewed-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Reviewed-by: Kees Cook &lt;keescook@chromium.org&gt;
Reviewed-by: Yury Norov &lt;yury.norov@gmail.com&gt;
Reviewed-by: KP Singh &lt;kpsingh@kernel.org&gt;
Reviewed-by: Jan Kara &lt;jack@suse.cz&gt; # for ext4 and sbitmap
Reviewed-by: Christoph Böhmwalder &lt;christoph.boehmwalder@linbit.com&gt; # for drbd
Acked-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
Acked-by: Heiko Carstens &lt;hca@linux.ibm.com&gt; # for s390
Acked-by: Ulf Hansson &lt;ulf.hansson@linaro.org&gt; # for mmc
Acked-by: Darrick J. Wong &lt;djwong@kernel.org&gt; # for xfs
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>libceph: clean up ceph_osdc_start_request prototype</title>
<updated>2022-08-03T12:05:39+00:00</updated>
<author>
<name>Jeff Layton</name>
<email>jlayton@kernel.org</email>
</author>
<published>2022-06-30T20:21:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a8af0d682ae0c9cf62dd0ad6afdb1480951d6a10'/>
<id>urn:sha1:a8af0d682ae0c9cf62dd0ad6afdb1480951d6a10</id>
<content type='text'>
This function always returns 0, and ignores the nofail boolean. Drop the
nofail argument, make the function void return and fix up the callers.

Signed-off-by: Jeff Layton &lt;jlayton@kernel.org&gt;
Reviewed-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
</content>
</entry>
<entry>
<title>libceph: fix misleading ceph_osdc_cancel_request() comment</title>
<updated>2022-05-18T19:21:29+00:00</updated>
<author>
<name>Ilya Dryomov</name>
<email>idryomov@gmail.com</email>
</author>
<published>2022-05-16T15:17:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=d0bb883c6355bcb2cc149fb4d5c3b28ccd327a5e'/>
<id>urn:sha1:d0bb883c6355bcb2cc149fb4d5c3b28ccd327a5e</id>
<content type='text'>
cancel_request() never guaranteed that after its return the OSD
client would be completely done with the OSD request.  The callback
(if specified) can still be invoked and a ref can still be held.

Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
Reviewed-by: Xiubo Li &lt;xiubli@redhat.com&gt;
</content>
</entry>
<entry>
<title>libceph: fix potential use-after-free on linger ping and resends</title>
<updated>2022-05-18T19:21:05+00:00</updated>
<author>
<name>Ilya Dryomov</name>
<email>idryomov@gmail.com</email>
</author>
<published>2022-05-14T10:16:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=75dbb685f4e8786c33ddef8279bab0eadfb0731f'/>
<id>urn:sha1:75dbb685f4e8786c33ddef8279bab0eadfb0731f</id>
<content type='text'>
request_reinit() is not only ugly as the comment rightfully suggests,
but also unsafe.  Even though it is called with osdc-&gt;lock held for
write in all cases, resetting the OSD request refcount can still race
with handle_reply() and result in use-after-free.  Taking linger ping
as an example:

    handle_timeout thread                     handle_reply thread

                                              down_read(&amp;osdc-&gt;lock)
                                              req = lookup_request(...)
                                              ...
                                              finish_request(req)  # unregisters
                                              up_read(&amp;osdc-&gt;lock)
                                              __complete_request(req)
                                                linger_ping_cb(req)

      # req-&gt;r_kref == 2 because handle_reply still holds its ref

    down_write(&amp;osdc-&gt;lock)
    send_linger_ping(lreq)
      req = lreq-&gt;ping_req  # same req
      # cancel_linger_request is NOT
      # called - handle_reply already
      # unregistered
      request_reinit(req)
        WARN_ON(req-&gt;r_kref != 1)  # fires
        request_init(req)
          kref_init(req-&gt;r_kref)

                   # req-&gt;r_kref == 1 after kref_init

                                              ceph_osdc_put_request(req)
                                                kref_put(req-&gt;r_kref)

            # req-&gt;r_kref == 0 after kref_put, req is freed

        &lt;further req initialization/use&gt; !!!

This happens because send_linger_ping() always (re)uses the same OSD
request for watch ping requests, relying on cancel_linger_request() to
unregister it from the OSD client and rip its messages out from the
messenger.  send_linger() does the same for watch/notify registration
and watch reconnect requests.  Unfortunately cancel_request() doesn't
guarantee that after it returns the OSD client would be completely done
with the OSD request -- a ref could still be held and the callback (if
specified) could still be invoked too.

The original motivation for request_reinit() was inability to deal with
allocation failures in send_linger() and send_linger_ping().  Switching
to using osdc-&gt;req_mempool (currently only used by CephFS) respects that
and allows us to get rid of request_reinit().

Cc: stable@vger.kernel.org
Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
Reviewed-by: Xiubo Li &lt;xiubli@redhat.com&gt;
Acked-by: Jeff Layton &lt;jlayton@kernel.org&gt;
</content>
</entry>
<entry>
<title>libceph: disambiguate cluster/pool full log message</title>
<updated>2022-04-25T08:45:15+00:00</updated>
<author>
<name>Ilya Dryomov</name>
<email>idryomov@gmail.com</email>
</author>
<published>2022-03-12T10:09:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=dc9b0dc4561dedd44b2bf4b8e5ef1a8a040b2424'/>
<id>urn:sha1:dc9b0dc4561dedd44b2bf4b8e5ef1a8a040b2424</id>
<content type='text'>
Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
</content>
</entry>
<entry>
<title>libceph, ceph: move ceph_osdc_copy_from() into cephfs code</title>
<updated>2021-11-08T02:29:52+00:00</updated>
<author>
<name>Luís Henriques</name>
<email>lhenriques@suse.de</email>
</author>
<published>2021-11-04T12:31:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=aca39d9e86f3edeaac5d2c467f5fd31e0b0df606'/>
<id>urn:sha1:aca39d9e86f3edeaac5d2c467f5fd31e0b0df606</id>
<content type='text'>
This patch moves ceph_osdc_copy_from() function out of libceph code into
cephfs.  There are no other users for this function, and there is the need
(in another patch) to access internal ceph_osd_request struct members.

Signed-off-by: Luís Henriques &lt;lhenriques@suse.de&gt;
Reviewed-by: Jeff Layton &lt;jlayton@kernel.org&gt;
Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
</content>
</entry>
<entry>
<title>libceph, ceph: disambiguate ceph_connection_operations handlers</title>
<updated>2021-01-04T16:31:32+00:00</updated>
<author>
<name>Ilya Dryomov</name>
<email>idryomov@gmail.com</email>
</author>
<published>2020-12-23T15:32:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=4972cf605f8a10784bb9ec9bdf3465892fb547c8'/>
<id>urn:sha1:4972cf605f8a10784bb9ec9bdf3465892fb547c8</id>
<content type='text'>
Since a few years, kernel addresses are no longer included in oops
dumps, at least on x86.  All we get is a symbol name with offset and
size.

This is a problem for ceph_connection_operations handlers, especially
con-&gt;ops-&gt;dispatch().  All three handlers have the same name and there
is little context to disambiguate between e.g. monitor and OSD clients
because almost everything is inlined.  gdb sneakily stops at the first
matching symbol, so one has to resort to nm and addr2line.

Some of these are already prefixed with mon_, osd_ or mds_.  Let's do
the same for all others.

Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
Acked-by: Jeff Layton &lt;jlayton@kernel.org&gt;
</content>
</entry>
<entry>
<title>libceph, ceph: make use of __ceph_auth_get_authorizer() in msgr1</title>
<updated>2020-12-14T22:21:50+00:00</updated>
<author>
<name>Ilya Dryomov</name>
<email>idryomov@gmail.com</email>
</author>
<published>2020-11-19T18:13:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ce287162d9738fe03a3731904710b6700ba686aa'/>
<id>urn:sha1:ce287162d9738fe03a3731904710b6700ba686aa</id>
<content type='text'>
This shouldn't cause any functional changes.

Signed-off-by: Ilya Dryomov &lt;idryomov@gmail.com&gt;
</content>
</entry>
</feed>
