nbd_block_status(3)

πŸ’… nbd_block_status(3) β€” the libnbd girlies' guide ✨

okay so first things first, this whole page lives in the libnbd manual (section 3, the library-call girlies), and today's main character is nbd_block_status β€” the 32-bit-flavored block status sender. she's iconic but she has limits, and we're gonna talk about all of them. no skipping. 🫢


🌸 NAME 🌸

nbd_block_status β€” send block status command, with 32-bit callback


✨ SYNOPSIS ✨

bestie, here's the literal shape of it, do not freestyle:

#include <libnbd.h>

typedef struct {
  int (*callback) (void *user_data,
                   const char *metacontext,
                   uint64_t offset, uint32_t *entries,
                   size_t nr_entries, int *error);
  void *user_data;
  void (*free) (void *user_data);
} nbd_extent_callback;

int nbd_block_status (
      struct nbd_handle *h, uint64_t count,
      uint64_t offset, nbd_extent_callback extent_callback,
      uint32_t flags
    );

πŸ’– DESCRIPTION πŸ’–

so you're issuing the block status command to the NBD server. if the server is a supportive queen and supports it, this makes metadata context info about blocks starting at the given offset come back to you. πŸ’«

the count parameter is a hint β€” server may decide to return less status than you asked for, or the final block may spill past the range you requested. if multiple contexts are supported, the number of blocks and the cumulative length of those blocks do not have to match between contexts. lowkey feral of the protocol but that's how it is. πŸ™ˆ

⚠️ heads up: not all servers can handle a count of 4GiB or larger. nbd_get_extended_headers_negotiated(3) tells you which servers will actually parse a request bigger than 32 bits. the NBD protocol doesn't yet have a way for a client to learn if the server enforces an even smaller max block status size β€” although a future extension might add a constraint visible in nbd_get_block_size(3). and yeah, this function is inherently capped at 32-bit values, that's just her thing.

what happens at the edges, fr fr: if the server replies with a larger extent, that extent's length gets truncated to just below 32 bits, and any further extents from the server are straight-up ignored. and if the server replies with a status value larger than 32 bits (only possible when extended headers are in use), the callback gets handed an "EOVERFLOW" error. so if you want the full extent tea from a server that does 64-bit extents, you must use nbd_block_status_64(3). periodt. πŸ‘‘

depending on which metadata contexts were enabled before connecting (peep nbd_add_meta_context(3)) and which ones the server supports (peep nbd_can_meta_context(3)), this call hands you extent info by calling back to the "extent" function.

πŸ’€ and NO, the callback cannot call "nbd_*" APIs on the same handle β€” it's holding the handle lock, so you'll deadlock. do not do that to yourself.

if the callback returns -1, and no earlier error has already been detected, then the whole block status command fails with whatever non-zero value got stored into the callback's "error" parameter (defaulting to "EPROTO" if nothing's there) β€” but even then, any further contexts will still invoke the callback. she keeps going. πŸŽ€

πŸ¦‹ the extent callback, decoded πŸ¦‹

the "extent" function gets called once per type of metadata available, and it receives the user_data you passed in.

  • metacontext β€” a string, like "base:allocation".
  • entries β€” an array of pairs of integers. first entry in each pair = length of the block in bytes. second entry in each pair = a status/flags field specific to that metadata context.
  • the number of pairs handed to the function is "nr_entries/2".

the NBD protocol document, in the section about "NBD_REPLY_TYPE_BLOCK_STATUS", explains what that array actually means. for contexts libnbd knows about, <libnbd.h> has constants starting with "LIBNBD_STATE_" that help you decipher the values. 🧚

on entry to the callback, the "error" parameter holds the errno value of any previously detected error β€” but even if an earlier error was detected, the current "metacontext" and "entries" are still valid. πŸ’œ

⚠️ it is possible for the extent function to be called more times than you expect (looking at you, buggy server), so always check the "metacontext" field to make sure you're getting the data you think you're getting. it's also possible the extent function is not called at all, even for metadata contexts you requested β€” that means either the server doesn't support the context, or for some other reason it can't return the data. either way: vibe check your expectations. πŸ“

🌈 flags 🌈

the "flags" parameter may be 0 for no flags, or may contain "LIBNBD_CMD_FLAG_REQ_ONE", which means the server should return only one extent per metadata context where that extent does not exceed count bytes. caveat though: libnbd does not validate that the server actually obeyed the flag. so like. good luck, bestie. πŸ™


⭐ RETURN VALUE ⭐

if the call is successful, the function returns 0. slay.


πŸ”₯ ERRORS πŸ”₯

on error, -1 is returned. 😭

refer to "ERROR HANDLING" in libnbd(3) for how to get further details of the error.

the following parameters must not be NULL: "h". for more info see "Non-NULL parameters" in libnbd(3).


πŸ‘‘ NOTES πŸ‘‘

πŸŽ€ Strict call πŸŽ€

by default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure β€” like requesting an unknown command flag. rude but protective. πŸ’… the nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.


πŸ¦‹ HANDLE STATE πŸ¦‹

nbd_block_status can be called when the handle is in the following state:

  • Handle created, before connecting β€” ❌ error
  • Connecting β€” ❌ error
  • Connecting & handshaking (opt_mode) β€” ❌ error
  • Connected to the server β€” βœ… allowed
  • Connection shut down β€” ❌ error
  • Handle dead β€” ❌ error

so basically: be connected. that's the whole mood. 🌸


πŸ’« VERSION πŸ’«

this function first appeared in libnbd 1.0. OG behavior.

if you need to test whether this function is available at compile time, check if the following macro is defined:

#define LIBNBD_HAVE_NBD_BLOCK_STATUS 1

🌟 SEE ALSO 🌟

nbd_add_meta_context(3), nbd_aio_block_status(3), nbd_block_status_64(3), nbd_can_meta_context(3), nbd_create(3), nbd_get_block_size(3), nbd_get_extended_headers_negotiated(3), nbd_set_strict_mode(3), libnbd(3).

all the linked girlies, go read them. iykyk. 🫢


🧚 AUTHORS 🧚

Eric Blake

Richard W.M. Jones


Copyright Red Hat


πŸ“œ LICENSE πŸ“œ

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA


okay that's the whole page, mwah πŸ’‹ β€” this was libnbd-1.25.8, dated 2026-10-13, and yes the page title is nbd_block_status(3) in case you forgot already. go forth and query them extents, bestie. 🌈✨

πŸ“¦ where this page comes from