From patchwork Fri Mar 4 16:10:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 8505191 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A81B39F8A8 for ; Fri, 4 Mar 2016 16:12:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8894B20122 for ; Fri, 4 Mar 2016 16:11:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 77CDA20114 for ; Fri, 4 Mar 2016 16:11:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759277AbcCDQLy (ORCPT ); Fri, 4 Mar 2016 11:11:54 -0500 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:63098 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759711AbcCDQLf (ORCPT ); Fri, 4 Mar 2016 11:11:35 -0500 Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.15.0.59/8.15.0.59) with SMTP id u24G9RX7031370; Fri, 4 Mar 2016 08:11:29 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=facebook; bh=7zT7/MoUTSyc2JcRHcaAhVuqH/npFgoZJdF5yb2VNP4=; b=KUgNHFemUDDC7+oURnC3P128GdqNh1tGHvGPMYxkDKBcBJcY10paVv2SIRS/ExMmNQUc aF1WVL48FVHKJAAu9Tp+NmeK2pFBM0EdY1qdFqTpn/rkhSU+8PjiAjNu4x0GJ3TAR05d fNSLaUy67zHZJ7QwyBfUi5PRycJdYPjIHB4= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 21f6yj1f44-6 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Fri, 04 Mar 2016 08:11:29 -0800 Received: from localhost.localdomain (192.168.54.13) by mail.thefacebook.com (192.168.16.15) with Microsoft SMTP Server (TLS) id 14.3.248.2; Fri, 4 Mar 2016 08:11:01 -0800 From: Jens Axboe To: , CC: , , , Jens Axboe Subject: [PATCH 04/11] Add system call for setting inode/file write stream ID Date: Fri, 4 Mar 2016 09:10:46 -0700 Message-ID: <1457107853-8689-5-git-send-email-axboe@fb.com> X-Mailer: git-send-email 2.4.1.168.g1ea28e1 In-Reply-To: <1457107853-8689-1-git-send-email-axboe@fb.com> References: <1457107853-8689-1-git-send-email-axboe@fb.com> MIME-Version: 1.0 X-Originating-IP: [192.168.54.13] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-03-04_07:, , signatures=0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Single system call: ssize_t streamid(int fd, int cmd, unsigned int flags, int streamid); where 'fd' is a file descriptor to the file that we want to set the write stream ID on. 'cmd' is one of the following: STREAMID_OPEN Open/allocate a new stream ID STREAMID_CLOSE Close/free a previously allocated stream ID STREAMID_GET Return the currently assigned stream ID 'flags' is a mask of one or more of the following: STREAMID_F_INODE Set stream ID on the inode STREAMID_F_FILE Set stream ID on the file 'streamid' is either 0, which means that streamid() will return the first available stream ID, or it's set to some integer value between 1 and STREAMID_MAX (both inclusive) to ask for a specific stream ID value. streamid() returns the allocated stream ID on succes, or -1 and sets errno appropriately. Possible error values: -EINVAL cmd/flags isn't valid -ESPIPE 'fd' refers to a pipe -EBADF 'fd' isn't valid -EBUSY 'streamid' is already allocated/assigned Signed-off-by: Jens Axboe --- fs/read_write.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/streamid.h | 13 ++++++++++ include/uapi/linux/Kbuild | 1 + 3 files changed, 77 insertions(+) create mode 100644 include/linux/streamid.h diff --git a/fs/read_write.c b/fs/read_write.c index dadf24e5c95b..6dcae3eb7b0f 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "internal.h" #include @@ -1668,3 +1669,65 @@ out: return ret; } EXPORT_SYMBOL(vfs_dedupe_file_range); + +SYSCALL_DEFINE4(streamid, int, fd, int, cmd, + unsigned int, flags, int, streamid) +{ + struct inode *inode; + ssize_t ret = 0; + struct fd f; + + if (cmd != STREAMID_OPEN && cmd != STREAMID_CLOSE && + cmd != STREAMID_GET) + return -EINVAL; + if (flags & ~(STREAMID_F_INODE | STREAMID_F_FILE)) + return -EINVAL; + + f = fdget(fd); + if (!f.file) + return -EBADF; + + inode = file_inode(f.file); + if (S_ISFIFO(inode->i_mode)) { + ret = -ESPIPE; + goto done; + } + + if (cmd == STREAMID_OPEN) { + if (flags & STREAMID_F_FILE) { + if (f.file->f_streamid) { + ret = -EBUSY; + goto done; + } + f.file->f_streamid = ret; + } + if (flags & STREAMID_F_INODE) { + spin_lock(&inode->i_lock); + if (inode_streamid(inode)) + ret = -EBUSY; + else + inode->i_streamid = ret; + spin_unlock(&inode->i_lock); + } + } else if (cmd == STREAMID_CLOSE) { + if (f.file->f_streamid == streamid) + f.file->f_streamid = 0; + if (inode_streamid(inode) == streamid) { + spin_lock(&inode->i_lock); + inode->i_streamid = 0; + spin_unlock(&inode->i_lock); + } + } else if (cmd == STREAMID_GET) { + ret = 0; + if (flags & STREAMID_F_FILE) + ret = f.file->f_streamid; + if (!ret && (flags & STREAMID_F_INODE)) + ret = inode_streamid(inode); + if (!(flags & (STREAMID_F_FILE | STREAMID_F_INODE))) + ret = file_streamid(f.file); + } + +done: + fdput(f); + return ret; +} diff --git a/include/linux/streamid.h b/include/linux/streamid.h new file mode 100644 index 000000000000..ea1f8e7eb8a5 --- /dev/null +++ b/include/linux/streamid.h @@ -0,0 +1,13 @@ +#ifndef STREAMID_H +#define STREAMID_H + +enum { + STREAMID_OPEN = 1, /* open new stream */ + STREAMID_CLOSE = 2, /* close stream */ + STREAMID_GET = 3, /* get file/inode stream ID */ + + STREAMID_F_INODE = 1, /* set streamid on the inode */ + STREAMID_F_FILE = 2, /* set streamid on the file */ +}; + +#endif diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index ebd10e624598..7d1540da0bb1 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -385,6 +385,7 @@ header-y += soundcard.h header-y += sound.h header-y += stat.h header-y += stddef.h +header-y += streamid.h header-y += string.h header-y += suspend_ioctls.h header-y += swab.h