[RFC PATCH 2/5] fs: add the interface to query user write streams

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add new fcntl F_GET_MAX_WRITE_STREAMS.
This returns the numbers of streams that are available for userspace.

And for that, use ->user_write_streams() callback when the involved
filesystem provides it.
In absence of such callback, use 'max_write_streams' queue limit of the
underlying block device.

Signed-off-by: Kanchan Joshi <joshi.k@xxxxxxxxxxx>
---
 fs/fcntl.c                 | 31 +++++++++++++++++++++++++++++++
 include/uapi/linux/fcntl.h |  5 +++++
 2 files changed, 36 insertions(+)

diff --git a/fs/fcntl.c b/fs/fcntl.c
index 5598e4d57422..36ca833e9a0b 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -27,6 +27,7 @@
 #include <linux/compat.h>
 #include <linux/mount.h>
 #include <linux/rw_hint.h>
+#include <linux/blkdev.h>
 
 #include <linux/poll.h>
 #include <asm/siginfo.h>
@@ -394,6 +395,33 @@ static long fcntl_set_rw_hint(struct file *file, unsigned int cmd,
 	return 0;
 }
 
+static u8 vfs_user_write_streams(struct inode *inode)
+{
+	struct super_block *sb;
+
+	if (S_ISBLK(inode->i_mode))
+		return bdev_max_write_streams(I_BDEV(inode));
+
+	sb = inode->i_sb;
+	/* If available, use per-mount/fs policy */
+	if (sb->s_op && sb->s_op->user_write_streams)
+		return sb->s_op->user_write_streams(sb);
+	/* otherwise, fallback to queue limit */
+	if (sb->s_bdev)
+		return bdev_max_write_streams(sb->s_bdev);
+	return 0;
+}
+
+static long fcntl_get_max_write_streams(struct file *file)
+{
+	struct inode *inode = file_inode(file);
+
+	if (S_ISBLK(inode->i_mode))
+		inode = file->f_mapping->host;
+
+	return vfs_user_write_streams(inode);
+}
+
 /* Is the file descriptor a dup of the file? */
 static long f_dupfd_query(int fd, struct file *filp)
 {
@@ -552,6 +580,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
 	case F_SET_RW_HINT:
 		err = fcntl_set_rw_hint(filp, cmd, arg);
 		break;
+	case F_GET_MAX_WRITE_STREAMS:
+		err = fcntl_get_max_write_streams(filp);
+		break;
 	default:
 		break;
 	}
diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h
index f291ab4f94eb..87ec808d0f03 100644
--- a/include/uapi/linux/fcntl.h
+++ b/include/uapi/linux/fcntl.h
@@ -61,6 +61,11 @@
 #define F_GET_FILE_RW_HINT	(F_LINUX_SPECIFIC_BASE + 13)
 #define F_SET_FILE_RW_HINT	(F_LINUX_SPECIFIC_BASE + 14)
 
+/*
+ *  Query available write streams
+ */
+#define F_GET_MAX_WRITE_STREAMS (F_LINUX_SPECIFIC_BASE + 15)
+
 /*
  * Valid hint values for F_{GET,SET}_RW_HINT. 0 is "not set", or can be
  * used to clear any hints previously set.
-- 
2.25.1





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux