Re: [PATCH v4 1/6] fs: add write-stream management ioctls

Kanchan Joshi <[email protected]> Fri, 31 Jul 2026 13:45:48 +0530
Newsgroups org.kernel.vger.linux-xfs,org.kernel.vger.linux-block,org.kernel.vger.linux-fsdevel
Message-ID <[email protected]>
On 7/30/2026 10:52 PM, Darrick J. Wong wrote:
> On Thu, Jul 30, 2026 at 08:22:51PM +0530, Kanchan Joshi wrote:
>> On 7/21/2026 8:33 AM, Darrick J. Wong wrote:
>>> On Fri, Jul 17, 2026 at 06:25:33PM +0530, Kanchan Joshi wrote:
>>>> From: Anuj Gupta<[email protected]>
>>>>
>>>> Wire up the userspace interface for write stream management via four
>>>> ioctls:
>>>>
>>>>     FS_IOC_WRITE_STREAM_GET_MAX  query the max streams supported
>>>>     FS_IOC_WRITE_STREAM_OPEN     open a stream id, returns a stream fd
>>>>     FS_IOC_WRITE_STREAM_SET      attach the stream fd to an open file
>>>>     FS_IOC_WRITE_STREAM_GET      query the stream id value set on a file
>>>>
>>>> Application should query the available streams by using
>>>> FS_IOC_WRITE_STREAM_GET_MAX. If returned value is N, valid stream id for
>>>> the file are 1 to N.
>>>>
>>>> Application calls FS_IOC_WRITE_STREAM_OPEN to get fd for a stream-id.
>>>> By default, kernel picks an available stream-id and returns the fd for
>>>> it. The flag FS_WRITE_STREAM_OPEN_EXACT can be used to request a
>>>> specific stream_id. This is useful if application cares about keeping a
>>>> stable stream-id-to-spatial-isolation-bucket mapping across restarts.
>>> Hmm.  If FS_IOC_WRITE_STREAM_OPEN returns an fd that represents an open
>>> stream id, then why does STREAM_SET below take a pointer to a signed
>>> s32?
>> Not a pointer, that s32 is to pass the stream fd.
> Oh, but that third argument to ioctl()/is/ supposed to be a pointer to
> some data.  From ioctl(2):
> 
> "The third argument is an untyped pointer to memory.  It's traditionally
> char  *argp (from the days before void * was valid C), and will be so
> named for this discussion."
> 
> You can also see this reflected in the discussion of the R/W/WR variants
> of _IO:
> https://docs.kernel.org/driver-api/ioctl.html
> 
> "[data_type] may be a pointer to data to be passed into the kernel
> (_IOW), out of the kernel (_IOR), or both (_IOWR)"
> 
> Granted your kernel code can treat that argp as an integer and not a
> __user pointer if it wants to, but that goes against most ioctl
> implementations.  Further, subsystems that marshal ioctl information for
> passing through to another layer (e.g. fuse) assume that the third
> argument is a pointer and that it can copy sizeof(data_type) bytes at
> that address in and out of the kernel as part of marshalling.

Next version will refactor all ioctls to use pointer to struct.

>>> And why does STREAM_GET take a pointer to a u32?
>> This also is a scalar value and not a pointer. The returned stream-id is
>> a u32.
>>
>>> IOWs it'd be much easier to distinguish these things if the ioctls took
>>> pointers to structs instead of u32/s32 pointers directly.
>> Maybe IOCTL naming is the source of confusion, because we introduced
>> stream-fds alongside stream-ids. More on this below.
>>> Also it's a little weird that STREAM_SET associates an open file with a
>>> stream fd, but STREAM_GET returns the stream*id* (not the fd)
>>> associated with an open file.
>> The confusion stems from keeping symmetric names for different
>> operations. Let me explain the intent and propose revised names below.
>>
>> Christoph's idea was to use FD for a write-stream so that it remains
>> exclusive to the application and unrelated applications don't collide.
>>
>> So, in this version, write-stream ids are implemented as independent
>> resource:
>> - To set a file's write-stream ID to X, the app must first obtain the fd
>> for stream X.
>> - That stream/fd will be unavailable if some other application has
>> already opened it.
>> - If applications gets the stream fd, it can use that to set stream id
>> for multiple files.
>> - It can close the stream-fd and that does not change anything for the
>> file resource (i.e, its inode continue to carry the stream-id value that
>> was set).
>>
>> Christoph - does this match?
>>
>> Here are the revised names (suggestions?):
>>
>> 1. FS_IOC_QUERY_MAX_WRITE_STREAM_IDS		_IOR('f', 135, __u32)
>>
>> Returns (in __u32) number of supported stream-ids.
>>
>> 2. FS_IOC_OPEN_WRITE_STREAM_ID			_IOWR('f', 136, struct
>> fs_write_stream_open)
>>
>> Open the specific write-stream id (or any available one via a flag) and
>> return its FD. This gives right to use that stream-id.
>>
>> And the following manage setting/clearing/querying write-stream on the file:
>>
>> 3. FS_IOC_SET_FILE_WRITE_STREAM_BY_FD		_IOW('f', 137, __s32)
>>
>> Sets a file's write-stream value (in inode) to whatever the stream fd
>> (passed as __s32) carries. So one never sets scalar values into a file
>> directly.
>>
>> 4. FS_IOC_QUERY_FILE_WRITE_STREAM_ID		_IOR('f', 138, __u32)
>>
>> Queries the write-stream value (__u32) currently assigned to the file
>> (its inode).
>>
>> 5. FS_IOC_CLEAR_FILE_WRITE_STREAM_ID		_IO('f', 139)
>>
>> To clear (zeroing) the write-stream value on the file's inode.
>>
>>
>>> Can you extract the stream id from the fd that FS_IOC_WRITE_STREAM_OPEN
>>> returns?
>> Can be done by implementing the ioctl handler for that stream fd, but
>> did not feel the need of it. Do you see the utility? If yes, name can
>> potentially be FS_IOC_QUERY_WRITE_STREAM_ID_FROM_FD.
> Why not reuse FS_IOC_QUERY_FILE_WRITE_STREAM_ID?

That's for the file (with data), it requires regular file-fd. It's not 
working on the stream-fd. You asked for knowing the stream-id associated 
to stream-fd.