[RFC PATCH 5/5] fs: add set and query write stream

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

 



Add two new fcntls:
F_GET_WRITE_STREAM - to query the write-stream on inode
F_SET_WRITE_STREAM - to set the write-stream on inode

Application should query the available streams by calling
F_GET_MAX_WRITE_STREAMS first.
If returned value is N, applications can choose any value from 1 to N
while setting the stream.
Setting the value 0 is not flagged as an error as that implies no
stream.
But setting a larger value than available streams is rejected.

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

diff --git a/fs/fcntl.c b/fs/fcntl.c
index 36ca833e9a0b..ce89393f8dbf 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -422,6 +422,33 @@ static long fcntl_get_max_write_streams(struct file *file)
 	return vfs_user_write_streams(inode);
 }
 
+static long fcntl_get_write_stream(struct file *file)
+{
+	struct inode *inode = file_inode(file);
+
+	if (S_ISBLK(inode->i_mode))
+		inode = file->f_mapping->host;
+
+	return inode->i_write_stream;
+}
+
+static long fcntl_set_write_stream(struct file *file, unsigned long arg)
+{
+	struct inode *inode = file_inode(file);
+
+	if (!inode_owner_or_capable(file_mnt_idmap(file), inode))
+		return -EPERM;
+
+	if (S_ISBLK(inode->i_mode))
+		inode = file->f_mapping->host;
+
+	if (arg > vfs_user_write_streams(inode))
+		return -EINVAL;
+
+	WRITE_ONCE(inode->i_write_stream, arg);
+	return 0;
+}
+
 /* Is the file descriptor a dup of the file? */
 static long f_dupfd_query(int fd, struct file *filp)
 {
@@ -583,6 +610,12 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
 	case F_GET_MAX_WRITE_STREAMS:
 		err = fcntl_get_max_write_streams(filp);
 		break;
+	case F_GET_WRITE_STREAM:
+		err = fcntl_get_write_stream(filp);
+		break;
+	case F_SET_WRITE_STREAM:
+		err = fcntl_set_write_stream(filp, arg);
+		break;
 	default:
 		break;
 	}
diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h
index 87ec808d0f03..dd3c498515ce 100644
--- a/include/uapi/linux/fcntl.h
+++ b/include/uapi/linux/fcntl.h
@@ -65,6 +65,8 @@
  *  Query available write streams
  */
 #define F_GET_MAX_WRITE_STREAMS (F_LINUX_SPECIFIC_BASE + 15)
+#define F_GET_WRITE_STREAM	(F_LINUX_SPECIFIC_BASE + 16)
+#define F_SET_WRITE_STREAM	(F_LINUX_SPECIFIC_BASE + 17)
 
 /*
  * Valid hint values for F_{GET,SET}_RW_HINT. 0 is "not set", or can be
-- 
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