6.16 enables block I/O path for FDP, but file I/O needs further work. This was covered in LSFMM [1]; among other things, we discussed application and kernel-driven placement policies. The series shows one of the ways to enable application-driven placement, without resorting to per-FS plumbing. But filesystem can control the number of streams that applications get to use. This can be useful for fs-specific policies or for metadata (placement) about which applications have no knowledge. Application interface involves three new fcntls: - F_GET_MAX_WRITE_STREAMS: To query the number of streams that are available. - F_SET_WRITE_STREAM: To set a particular stream on a file. - F_GET_WRITE_STREAM: To know what stream is set on the file. An example program using these is attached below [2]. [1] https://lwn.net/Articles/1018642/ [2] #define _GNU_SOURCE #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <errno.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <linux/fcntl.h> #define BUF_SIZE (4096) int write_fd(int fd, int st) { char buf[BUF_SIZE]; int ret, set, get; if (fd < 0) { printf("[!]invalid fd\n"); return fd; } ret = fcntl(fd, F_GET_MAX_WRITE_STREAMS); if (ret < 0) { printf("F_GET_MAX_WRITE_STREAMS: failed (%s)\n", strerror(errno)); return ret; } if (st > ret) { printf("error in setting stream, available upto %d\n", ret); return -1; } ret = fcntl(fd, F_SET_WRITE_STREAM, st); if (ret < 0) { printf("F_SET_WRITE_STREAM: failed (%s)\n", strerror(errno)); return ret; } set = st; ret = fcntl(fd, F_GET_WRITE_STREAM); if (ret < 0) { printf("F_GET_WRITE_STREAM: failed (%s)\n", strerror(errno)); return ret; } get = ret; if (get != set) printf("unexpected, set %d but get %d\n", set, get); ret = write(fd, buf, BUF_SIZE); if (ret < BUF_SIZE) { printf("failed, wrote %d bytes (expected %d)\n", ret, BUF_SIZE); return ret; } return 0; } int main(int argc, char *argv[]) { int ret, regfd; /* two file writes, one buffered another direct */ regfd = open("/mnt/f_buffered", O_CREAT | O_RDWR, 0644); ret = write_fd(regfd, 7); close(regfd); regfd = open("/mnt/f_direct", O_CREAT | O_RDWR| O_DIRECT, 0644); ret = write_fd(regfd, 6); close(regfd); return ret; } Kanchan Joshi (5): fs: add a new user_write_streams() callback fs: add the interface to query user write streams fs: add a write stream field to the inode fs: propagate write stream fs: add set and query write stream fs/btrfs/extent_io.c | 1 + fs/buffer.c | 14 ++++++--- fs/direct-io.c | 1 + fs/ext4/page-io.c | 1 + fs/fcntl.c | 64 ++++++++++++++++++++++++++++++++++++++ fs/inode.c | 1 + fs/iomap/direct-io.c | 1 + fs/iomap/ioend.c | 1 + fs/mpage.c | 1 + include/linux/fs.h | 8 ++++- include/uapi/linux/fcntl.h | 7 +++++ 11 files changed, 94 insertions(+), 6 deletions(-) base-commit: 66639db858112bf6b0f76677f7517643d586e575 -- 2.25.1