From patchwork Tue Dec 12 09:44:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13488821 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UKwHbryX" Received: from mail-lf1-x131.google.com (mail-lf1-x131.google.com [IPv6:2a00:1450:4864:20::131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6A15BE4 for ; Tue, 12 Dec 2023 01:44:48 -0800 (PST) Received: by mail-lf1-x131.google.com with SMTP id 2adb3069b0e04-50e04354de0so1421678e87.1 for ; Tue, 12 Dec 2023 01:44:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702374286; x=1702979086; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=H8Zpe6O6e50b4Mbg0l0YHYguBcBP+cYVm1GrQQWkmDA=; b=UKwHbryX8bo/T048LvZtHzpEyfldLAZPiv0XyuvnD2IaVmlQ8CsHR7klhrg/kH+Cwb Wmn4DAyXb+c9ojPAolB+nOWgeBxK65jyAR3DU7U188HZ2rwsqdgxemSeK3weSpRB1KoI lSTxDiopPLmT2poON491figMEulTSydXfP2GxucQHG62WqnCbaH/u3ZCg4kLhGNfgHJE qTfkdselCK+ePpqpRphjc2Ao2x3HEfngeHETZWtyyQrGH/gNjFn8RFUfwCkEmzgutc4G Z8ay/gI2TP/QEBwiTzB3ujskE+btaNESi6GdRZ/FSg9iuSmjTthtaE3nGd5NglRLkcxn BKjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702374286; x=1702979086; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H8Zpe6O6e50b4Mbg0l0YHYguBcBP+cYVm1GrQQWkmDA=; b=rpZisA+fWPc8bCbi6PNIFEPTizNJBHKYo3BjH/XU3pTTKeYo9U3MXLXUzcCj3xNx21 jacpPNBcoFljF3umwiVQgYd3Hk2Hi9DIL7wAuxa4OztQY6Fw1mcA/Syx6/jBPJODpX/U f048EQJEVcacdwckLXK/xfLODzc4SAp0mteRqctqa8sqg434uzoTZ7GU7+bpMUB0om5F PmtWhU3kn1Y9i8fXU6a7yBeRKCi9qvfvTcAv1sXsLO8ofpbm5Sqi420TMykusXJOln2q j/nEabNvev0/vUgVMjeDLhBH/qb34P+hFt9mC7/IZZxxS/ptMLohRZr1989YnS9c7MkE D4yw== X-Gm-Message-State: AOJu0YxAN24W8o+vwJxJsec9PGxspMAhR6xyQ14pk57eEaxS5+6tvyWC V/CRKggv4XynA+5W42udZBVQwt53HpU= X-Google-Smtp-Source: AGHT+IHSFFH82NNAi8UfscUDFXDzH1lYKop2Wl0+T8wZZhF75g3mv58nIkU6K0m3OUn/vCAx7X8zqw== X-Received: by 2002:a05:6512:3f2a:b0:50e:acd:123 with SMTP id y42-20020a0565123f2a00b0050e0acd0123mr203482lfa.46.1702374286338; Tue, 12 Dec 2023 01:44:46 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id l4-20020a05600012c400b003334041c3edsm10432244wrx.41.2023.12.12.01.44.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 01:44:45 -0800 (PST) From: Amir Goldstein To: Christian Brauner Cc: Jan Kara , Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH v3 1/5] splice: return type ssize_t from all helpers Date: Tue, 12 Dec 2023 11:44:36 +0200 Message-Id: <20231212094440.250945-2-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212094440.250945-1-amir73il@gmail.com> References: <20231212094440.250945-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Not sure why some splice helpers return long, maybe historic reasons. Change them all to return ssize_t to conform to the splice methods and to the rest of the helpers. Suggested-by: Christian Brauner Link: https://lore.kernel.org/r/20231208-horchen-helium-d3ec1535ede5@brauner/ Signed-off-by: Amir Goldstein Reviewed-by: Jan Kara Reviewed-by: David Howells --- fs/internal.h | 8 ++-- fs/overlayfs/copy_up.c | 2 +- fs/read_write.c | 2 +- fs/splice.c | 103 +++++++++++++++++++++-------------------- include/linux/splice.h | 43 +++++++++-------- io_uring/splice.c | 4 +- 6 files changed, 81 insertions(+), 81 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index de67b02226e5..bd9dedfcb675 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -241,10 +241,10 @@ int do_statx(int dfd, struct filename *filename, unsigned int flags, /* * fs/splice.c: */ -long splice_file_to_pipe(struct file *in, - struct pipe_inode_info *opipe, - loff_t *offset, - size_t len, unsigned int flags); +ssize_t splice_file_to_pipe(struct file *in, + struct pipe_inode_info *opipe, + loff_t *offset, + size_t len, unsigned int flags); /* * fs/xattr.c: diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 294b330aba9f..741d38058337 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -285,7 +285,7 @@ static int ovl_copy_up_file(struct ovl_fs *ofs, struct dentry *dentry, while (len) { size_t this_len = OVL_COPY_UP_CHUNK_SIZE; - long bytes; + ssize_t bytes; if (len < this_len) this_len = len; diff --git a/fs/read_write.c b/fs/read_write.c index 01a14570015b..7783b8522693 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1214,7 +1214,7 @@ COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd, #endif /* CONFIG_COMPAT */ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, - size_t count, loff_t max) + size_t count, loff_t max) { struct fd in, out; struct inode *in_inode, *out_inode; diff --git a/fs/splice.c b/fs/splice.c index 7cda013e5a1e..13030ce192d9 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -201,7 +201,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, unsigned int tail = pipe->tail; unsigned int head = pipe->head; unsigned int mask = pipe->ring_size - 1; - int ret = 0, page_nr = 0; + ssize_t ret = 0, page_nr = 0; if (!spd_pages) return 0; @@ -932,8 +932,8 @@ static int warn_unsupported(struct file *file, const char *op) /* * Attempt to initiate a splice from pipe to file. */ -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags) +static ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { if (unlikely(!out->f_op->splice_write)) return warn_unsupported(out, "write"); @@ -955,9 +955,9 @@ static void do_splice_eof(struct splice_desc *sd) * Callers already called rw_verify_area() on the entire range. * No need to call it for sub ranges. */ -static long do_splice_read(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags) +static ssize_t do_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) { unsigned int p_space; @@ -999,11 +999,11 @@ static long do_splice_read(struct file *in, loff_t *ppos, * If successful, it returns the amount of data spliced, 0 if it hit the EOF or * a hole and a negative error code otherwise. */ -long vfs_splice_read(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags) +ssize_t vfs_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) { - int ret; + ssize_t ret; ret = rw_verify_area(READ, in, ppos, len); if (unlikely(ret < 0)) @@ -1030,7 +1030,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, splice_direct_actor *actor) { struct pipe_inode_info *pipe; - long ret, bytes; + ssize_t ret, bytes; size_t len; int i, flags, more; @@ -1181,10 +1181,10 @@ static void direct_file_splice_eof(struct splice_desc *sd) file->f_op->splice_eof(file); } -static long do_splice_direct_actor(struct file *in, loff_t *ppos, - struct file *out, loff_t *opos, - size_t len, unsigned int flags, - splice_direct_actor *actor) +static ssize_t do_splice_direct_actor(struct file *in, loff_t *ppos, + struct file *out, loff_t *opos, + size_t len, unsigned int flags, + splice_direct_actor *actor) { struct splice_desc sd = { .len = len, @@ -1195,7 +1195,7 @@ static long do_splice_direct_actor(struct file *in, loff_t *ppos, .splice_eof = direct_file_splice_eof, .opos = opos, }; - long ret; + ssize_t ret; if (unlikely(!(out->f_mode & FMODE_WRITE))) return -EBADF; @@ -1226,8 +1226,8 @@ static long do_splice_direct_actor(struct file *in, loff_t *ppos, * * Callers already called rw_verify_area() on the entire range. */ -long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - loff_t *opos, size_t len, unsigned int flags) +ssize_t do_splice_direct(struct file *in, loff_t *ppos, struct file *out, + loff_t *opos, size_t len, unsigned int flags) { return do_splice_direct_actor(in, ppos, out, opos, len, flags, direct_splice_actor); @@ -1249,8 +1249,8 @@ EXPORT_SYMBOL(do_splice_direct); * * Callers already called rw_verify_area() on the entire range. */ -long splice_file_range(struct file *in, loff_t *ppos, struct file *out, - loff_t *opos, size_t len) +ssize_t splice_file_range(struct file *in, loff_t *ppos, struct file *out, + loff_t *opos, size_t len) { lockdep_assert(file_write_started(out)); @@ -1280,12 +1280,12 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, struct pipe_inode_info *opipe, size_t len, unsigned int flags); -long splice_file_to_pipe(struct file *in, - struct pipe_inode_info *opipe, - loff_t *offset, - size_t len, unsigned int flags) +ssize_t splice_file_to_pipe(struct file *in, + struct pipe_inode_info *opipe, + loff_t *offset, + size_t len, unsigned int flags) { - long ret; + ssize_t ret; pipe_lock(opipe); ret = wait_for_space(opipe, flags); @@ -1300,13 +1300,13 @@ long splice_file_to_pipe(struct file *in, /* * Determine where to splice to/from. */ -long do_splice(struct file *in, loff_t *off_in, struct file *out, - loff_t *off_out, size_t len, unsigned int flags) +ssize_t do_splice(struct file *in, loff_t *off_in, struct file *out, + loff_t *off_out, size_t len, unsigned int flags) { struct pipe_inode_info *ipipe; struct pipe_inode_info *opipe; loff_t offset; - long ret; + ssize_t ret; if (unlikely(!(in->f_mode & FMODE_READ) || !(out->f_mode & FMODE_WRITE))) @@ -1397,14 +1397,14 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out, return ret; } -static long __do_splice(struct file *in, loff_t __user *off_in, - struct file *out, loff_t __user *off_out, - size_t len, unsigned int flags) +static ssize_t __do_splice(struct file *in, loff_t __user *off_in, + struct file *out, loff_t __user *off_out, + size_t len, unsigned int flags) { struct pipe_inode_info *ipipe; struct pipe_inode_info *opipe; loff_t offset, *__off_in = NULL, *__off_out = NULL; - long ret; + ssize_t ret; ipipe = get_pipe_info(in, true); opipe = get_pipe_info(out, true); @@ -1443,16 +1443,16 @@ static long __do_splice(struct file *in, loff_t __user *off_in, return ret; } -static int iter_to_pipe(struct iov_iter *from, - struct pipe_inode_info *pipe, - unsigned flags) +static ssize_t iter_to_pipe(struct iov_iter *from, + struct pipe_inode_info *pipe, + unsigned int flags) { struct pipe_buffer buf = { .ops = &user_page_pipe_buf_ops, .flags = flags }; size_t total = 0; - int ret = 0; + ssize_t ret = 0; while (iov_iter_count(from)) { struct page *pages[16]; @@ -1501,8 +1501,8 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf, * For lack of a better implementation, implement vmsplice() to userspace * as a simple copy of the pipes pages to the user iov. */ -static long vmsplice_to_user(struct file *file, struct iov_iter *iter, - unsigned int flags) +static ssize_t vmsplice_to_user(struct file *file, struct iov_iter *iter, + unsigned int flags) { struct pipe_inode_info *pipe = get_pipe_info(file, true); struct splice_desc sd = { @@ -1510,7 +1510,7 @@ static long vmsplice_to_user(struct file *file, struct iov_iter *iter, .flags = flags, .u.data = iter }; - long ret = 0; + ssize_t ret = 0; if (!pipe) return -EBADF; @@ -1534,11 +1534,11 @@ static long vmsplice_to_user(struct file *file, struct iov_iter *iter, * as splice-from-memory, where the regular splice is splice-from-file (or * to file). In both cases the output is a pipe, naturally. */ -static long vmsplice_to_pipe(struct file *file, struct iov_iter *iter, - unsigned int flags) +static ssize_t vmsplice_to_pipe(struct file *file, struct iov_iter *iter, + unsigned int flags) { struct pipe_inode_info *pipe; - long ret = 0; + ssize_t ret = 0; unsigned buf_flag = 0; if (flags & SPLICE_F_GIFT) @@ -1634,7 +1634,7 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, size_t, len, unsigned int, flags) { struct fd in, out; - long error; + ssize_t error; if (unlikely(!len)) return 0; @@ -1648,7 +1648,7 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, out = fdget(fd_out); if (out.file) { error = __do_splice(in.file, off_in, out.file, off_out, - len, flags); + len, flags); fdput(out); } fdput(in); @@ -1871,15 +1871,15 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, /* * Link contents of ipipe to opipe. */ -static int link_pipe(struct pipe_inode_info *ipipe, - struct pipe_inode_info *opipe, - size_t len, unsigned int flags) +static ssize_t link_pipe(struct pipe_inode_info *ipipe, + struct pipe_inode_info *opipe, + size_t len, unsigned int flags) { struct pipe_buffer *ibuf, *obuf; unsigned int i_head, o_head; unsigned int i_tail, o_tail; unsigned int i_mask, o_mask; - int ret = 0; + ssize_t ret = 0; /* * Potential ABBA deadlock, work around it by ordering lock @@ -1962,11 +1962,12 @@ static int link_pipe(struct pipe_inode_info *ipipe, * The 'flags' used are the SPLICE_F_* variants, currently the only * applicable one is SPLICE_F_NONBLOCK. */ -long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags) +ssize_t do_tee(struct file *in, struct file *out, size_t len, + unsigned int flags) { struct pipe_inode_info *ipipe = get_pipe_info(in, true); struct pipe_inode_info *opipe = get_pipe_info(out, true); - int ret = -EINVAL; + ssize_t ret = -EINVAL; if (unlikely(!(in->f_mode & FMODE_READ) || !(out->f_mode & FMODE_WRITE))) @@ -2003,7 +2004,7 @@ long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags) SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) { struct fd in, out; - int error; + ssize_t error; if (unlikely(flags & ~SPLICE_F_ALL)) return -EINVAL; diff --git a/include/linux/splice.h b/include/linux/splice.h index 49532d5dda52..068a8e8ffd73 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -68,31 +68,30 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, typedef int (splice_direct_actor)(struct pipe_inode_info *, struct splice_desc *); -extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, - loff_t *, size_t, unsigned int, - splice_actor *); -extern ssize_t __splice_from_pipe(struct pipe_inode_info *, - struct splice_desc *, splice_actor *); -extern ssize_t splice_to_pipe(struct pipe_inode_info *, - struct splice_pipe_desc *); -extern ssize_t add_to_pipe(struct pipe_inode_info *, - struct pipe_buffer *); -long vfs_splice_read(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags); +ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + splice_actor *actor); +ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, + struct splice_desc *sd, splice_actor *actor); +ssize_t splice_to_pipe(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd); +ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf); +ssize_t vfs_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); ssize_t splice_direct_to_actor(struct file *file, struct splice_desc *sd, splice_direct_actor *actor); -long do_splice(struct file *in, loff_t *off_in, struct file *out, - loff_t *off_out, size_t len, unsigned int flags); -long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - loff_t *opos, size_t len, unsigned int flags); -long splice_file_range(struct file *in, loff_t *ppos, struct file *out, - loff_t *opos, size_t len); +ssize_t do_splice(struct file *in, loff_t *off_in, struct file *out, + loff_t *off_out, size_t len, unsigned int flags); +ssize_t do_splice_direct(struct file *in, loff_t *ppos, struct file *out, + loff_t *opos, size_t len, unsigned int flags); +ssize_t splice_file_range(struct file *in, loff_t *ppos, struct file *out, + loff_t *opos, size_t len); -extern long do_tee(struct file *in, struct file *out, size_t len, - unsigned int flags); -extern ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags); +ssize_t do_tee(struct file *in, struct file *out, size_t len, + unsigned int flags); +ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); /* * for dynamic pipe sizing diff --git a/io_uring/splice.c b/io_uring/splice.c index 7c4469e9540e..3b659cd23e9d 100644 --- a/io_uring/splice.c +++ b/io_uring/splice.c @@ -51,7 +51,7 @@ int io_tee(struct io_kiocb *req, unsigned int issue_flags) struct file *out = sp->file_out; unsigned int flags = sp->flags & ~SPLICE_F_FD_IN_FIXED; struct file *in; - long ret = 0; + ssize_t ret = 0; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); @@ -92,7 +92,7 @@ int io_splice(struct io_kiocb *req, unsigned int issue_flags) unsigned int flags = sp->flags & ~SPLICE_F_FD_IN_FIXED; loff_t *poff_in, *poff_out; struct file *in; - long ret = 0; + ssize_t ret = 0; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); From patchwork Tue Dec 12 09:44:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13488822 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RYJpYX6W" Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79A48E9 for ; Tue, 12 Dec 2023 01:44:49 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-40c48d7a7a7so15711825e9.3 for ; Tue, 12 Dec 2023 01:44:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702374288; x=1702979088; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1/K6ChuVhbhljn0qE9o6Wep7Oq1QDR+WhDyuYC63b80=; b=RYJpYX6WlU4yjcW789AN9/lgeReiOVkXrqcTgxhijptS5t3Sc5L6oXC9FmBXetoS68 o5BlqH6XMq/x/pPh08Nf2vaOZMJJY8ELQIzO23LYwsrCvXsD0Q0gzBChQKhutBDlRVI0 XRz/IiRj9MtgOISGG4xY60RDTRe9wCFQzCDj3rktWkN14IaZj3oN6p17xKsG1rtCVdF5 vhahvOBk7ppjgBF9vQCO4t2mGSI3It8Ukk4N/NyzvYUmc7qhrpxLgKXC4bx8/huwCqW5 bxSdn3yCyVGYLZn01TODKIDXx113SFsDpFOzwXnoMxyr2wyqLqqmu3pFL6yMdwZJqb7s rp5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702374288; x=1702979088; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1/K6ChuVhbhljn0qE9o6Wep7Oq1QDR+WhDyuYC63b80=; b=ghZE4LyIpFZ4+sV5XSVu8HbgFQYhLEfNNBs/XjnJuzJ+ESDIitBwCBdmZQnGXPvGeP Iw9QL5scIE67mqknfImMbMYJJYQZjIwSYMUtM5ZwryHpn0fkUYxKS27al1+sCLwi62dD uSsOP5Oap5/wTZqIod6Co8rRGJSBq/Y0iHp+UOnkBw7VapTO54C0Yowph9GUFmgNuLXi dJBKZMWDs6G5LgULL0eCzGedPLxvUKIMi4mSpHwpjsxwcWSbjhJxu+thyRlJGpI+g9hk VeqxgDIsrTJA9Z0IUthnshG4DMKlgtKOiwo7yIdmlJ70HreflBfsYjuqpcC0GXPyWBip QweQ== X-Gm-Message-State: AOJu0YxXNBJn0pFUngUBe15hJUpvwKLC+6xf4wkucMVpjYI70n9ru/vd gcrxmnwgvAM8ofGArnZOlsk= X-Google-Smtp-Source: AGHT+IFE7lj//3q8NYPR90btRPSCqeZFdQ82H+p2iBuNzqrfYUeJl5oYM0GRoOZgnsppwOBfZkiRsw== X-Received: by 2002:a5d:630f:0:b0:336:2a21:c9bd with SMTP id i15-20020a5d630f000000b003362a21c9bdmr561401wru.52.1702374287855; Tue, 12 Dec 2023 01:44:47 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id l4-20020a05600012c400b003334041c3edsm10432244wrx.41.2023.12.12.01.44.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 01:44:47 -0800 (PST) From: Amir Goldstein To: Christian Brauner Cc: Jan Kara , Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH v3 2/5] fs: use splice_copy_file_range() inline helper Date: Tue, 12 Dec 2023 11:44:37 +0200 Message-Id: <20231212094440.250945-3-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212094440.250945-1-amir73il@gmail.com> References: <20231212094440.250945-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 generic_copy_file_range() is just a wrapper around splice_file_range(), which caps the maximum copy length. The only caller of splice_file_range(), namely __ceph_copy_file_range() is already ready to cope with short copy. Move the length capping into splice_file_range() and replace the exported symbol generic_copy_file_range() with a simple inline helper. Suggested-by: Christoph Hellwig Link: https://lore.kernel.org/linux-fsdevel/20231204083849.GC32438@lst.de/ Reviewed-by: Jan Kara Signed-off-by: Amir Goldstein --- fs/ceph/file.c | 4 ++-- fs/fuse/file.c | 5 +++-- fs/nfs/nfs4file.c | 5 +++-- fs/read_write.c | 34 ---------------------------------- fs/smb/client/cifsfs.c | 5 +++-- fs/splice.c | 7 ++++--- include/linux/fs.h | 3 --- include/linux/splice.h | 7 +++++++ 8 files changed, 22 insertions(+), 48 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index f11de6e1f1c1..d380d9dad0e0 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -3090,8 +3090,8 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, len, flags); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(src_file, src_off, dst_file, - dst_off, len, flags); + ret = splice_copy_file_range(src_file, src_off, dst_file, + dst_off, len); return ret; } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a660f1f21540..148a71b8b4d0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -19,6 +19,7 @@ #include #include #include +#include static int fuse_send_open(struct fuse_mount *fm, u64 nodeid, unsigned int open_flags, int opcode, @@ -3195,8 +3196,8 @@ static ssize_t fuse_copy_file_range(struct file *src_file, loff_t src_off, len, flags); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(src_file, src_off, dst_file, - dst_off, len, flags); + ret = splice_copy_file_range(src_file, src_off, dst_file, + dst_off, len); return ret; } diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 02788c3c85e5..e238abc78a13 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "delegation.h" #include "internal.h" #include "iostat.h" @@ -195,8 +196,8 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, ret = __nfs4_copy_file_range(file_in, pos_in, file_out, pos_out, count, flags); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(file_in, pos_in, file_out, - pos_out, count, flags); + ret = splice_copy_file_range(file_in, pos_in, file_out, + pos_out, count); return ret; } diff --git a/fs/read_write.c b/fs/read_write.c index 7783b8522693..e3abf603eaaf 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1396,40 +1396,6 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, } #endif -/** - * generic_copy_file_range - copy data between two files - * @file_in: file structure to read from - * @pos_in: file offset to read from - * @file_out: file structure to write data to - * @pos_out: file offset to write data to - * @len: amount of data to copy - * @flags: copy flags - * - * This is a generic filesystem helper to copy data from one file to another. - * It has no constraints on the source or destination file owners - the files - * can belong to different superblocks and different filesystem types. Short - * copies are allowed. - * - * This should be called from the @file_out filesystem, as per the - * ->copy_file_range() method. - * - * Returns the number of bytes copied or a negative error indicating the - * failure. - */ - -ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - size_t len, unsigned int flags) -{ - /* May only be called from within ->copy_file_range() methods */ - if (WARN_ON_ONCE(flags)) - return -EINVAL; - - return splice_file_range(file_in, &pos_in, file_out, &pos_out, - min_t(size_t, len, MAX_RW_COUNT)); -} -EXPORT_SYMBOL(generic_copy_file_range); - /* * Performs necessary checks before doing a file copy * diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index ea3a7a668b45..ee461bf0ef63 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1362,8 +1363,8 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, free_xid(xid); if (rc == -EOPNOTSUPP || rc == -EXDEV) - rc = generic_copy_file_range(src_file, off, dst_file, - destoff, len, flags); + rc = splice_copy_file_range(src_file, off, dst_file, + destoff, len); return rc; } diff --git a/fs/splice.c b/fs/splice.c index 13030ce192d9..5cce69e9da12 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1243,7 +1243,7 @@ EXPORT_SYMBOL(do_splice_direct); * @len: number of bytes to splice * * Description: - * For use by generic_copy_file_range() and ->copy_file_range() methods. + * For use by ->copy_file_range() methods. * Like do_splice_direct(), but vfs_copy_file_range() already holds * start_file_write() on @out file. * @@ -1254,8 +1254,9 @@ ssize_t splice_file_range(struct file *in, loff_t *ppos, struct file *out, { lockdep_assert(file_write_started(out)); - return do_splice_direct_actor(in, ppos, out, opos, len, 0, - splice_file_range_actor); + return do_splice_direct_actor(in, ppos, out, opos, + min_t(size_t, len, MAX_RW_COUNT), + 0, splice_file_range_actor); } EXPORT_SYMBOL(splice_file_range); diff --git a/include/linux/fs.h b/include/linux/fs.h index 04422a0eccdd..900d0cd55b50 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2090,9 +2090,6 @@ extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, loff_t, size_t, unsigned int); -extern ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - size_t len, unsigned int flags); int __generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t *len, unsigned int remap_flags, diff --git a/include/linux/splice.h b/include/linux/splice.h index 068a8e8ffd73..9dec4861d09f 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -88,6 +88,13 @@ ssize_t do_splice_direct(struct file *in, loff_t *ppos, struct file *out, ssize_t splice_file_range(struct file *in, loff_t *ppos, struct file *out, loff_t *opos, size_t len); +static inline long splice_copy_file_range(struct file *in, loff_t pos_in, + struct file *out, loff_t pos_out, + size_t len) +{ + return splice_file_range(in, &pos_in, out, &pos_out, len); +} + ssize_t do_tee(struct file *in, struct file *out, size_t len, unsigned int flags); ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, From patchwork Tue Dec 12 09:44:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13488823 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GvQLVKnT" Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47F4BD2 for ; Tue, 12 Dec 2023 01:44:51 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-336346769faso183587f8f.0 for ; Tue, 12 Dec 2023 01:44:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702374290; x=1702979090; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=D1H+++gQksXiemDOFj7z8SeueCytHP3rEOoH0sYDYaI=; b=GvQLVKnTbibcx/Aoia5B6ENWVgAg5xvg9tTpNYOj98hrj6URYFnfccUkfyTTZWNu2S ZnIrNU4GaoeavY+lKlq4CKS9BIszlXhdHyiN9orDwtPc5v9MC3cfjd4xmwanphW8ZFy2 R+CU1++OX0GCeI8sE8Qlfz3P6T9CJntBdkYCoKhIu08dH9+FkWnGx2MPrItixm3TD9Go +0NAf+jFzWV/PDT7R9KCNMf09gYunyBR1xTVaDz4bJ/HRcLn+8U37vcKXxv8vnc1NKy+ QVzeNJbIQEpInjpW0rxljI1573SJ6AkoYcdazc11SKw+IZxp/2ItDBwrsoPHkRwMBow6 lv6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702374290; x=1702979090; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=D1H+++gQksXiemDOFj7z8SeueCytHP3rEOoH0sYDYaI=; b=wib+6qxmb+48AofQs5OIg2VHCMUxjXIypbtLuWl2sgEV7/C6m0TyGNvn8asz5NRpwx 1izjym2Hfq/Qa41I9weiBN5FHQn0PTHBM0PjUpYJlSoYDK9PzqyVEzjvJPBXsYDkCJ5e uoGKb41fsA7xkOocWgXJEOEH2kLC9ag3xUAUtxteYwnvQoPbCOvgtEpZLPOOAse9JS2g Vp5dZc3aIqQD5FrsdJKVajgWJoJASsnQDgJVOQj0jB1gIjGAfOBkW54TqjC1IdwaEUds VPiiO4RoZ8zWM0vZ6Gex2rih8746EFVbSvV+XH4j1DG+QTNKtSZK5m9lxVR3bhjq9SeO llBw== X-Gm-Message-State: AOJu0Yze/kJErhd68bnrrU842MF0FzcgjyPdnULU9pZ56iUX4rmgcfcY nByvy0Drkq6A9MmO7fyJVuY= X-Google-Smtp-Source: AGHT+IEMB4m9hnecMAeBG5DfSFAmdxsyCoe5zRQ7Q4UvCCbF89envqaYWQ+TaOt2Ek6FS8mYdccz8g== X-Received: by 2002:a05:600c:2154:b0:40c:246c:bd84 with SMTP id v20-20020a05600c215400b0040c246cbd84mr2949512wml.9.1702374289459; Tue, 12 Dec 2023 01:44:49 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id l4-20020a05600012c400b003334041c3edsm10432244wrx.41.2023.12.12.01.44.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 01:44:49 -0800 (PST) From: Amir Goldstein To: Christian Brauner Cc: Jan Kara , Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH v3 3/5] fsnotify: split fsnotify_perm() into two hooks Date: Tue, 12 Dec 2023 11:44:38 +0200 Message-Id: <20231212094440.250945-4-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212094440.250945-1-amir73il@gmail.com> References: <20231212094440.250945-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 We would like to make changes to the fsnotify access permission hook - add file range arguments and add the pre modify event. In preparation for these changes, split the fsnotify_perm() hook into fsnotify_open_perm() and fsnotify_file_perm(). This is needed for fanotify "pre content" events. Reviewed-by: Josef Bacik Reviewed-by: Jan Kara Signed-off-by: Amir Goldstein --- include/linux/fsnotify.h | 34 +++++++++++++++++++--------------- security/security.c | 4 ++-- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index bcb6609b54b3..926bb4461b9e 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -100,29 +100,33 @@ static inline int fsnotify_file(struct file *file, __u32 mask) return fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH); } -/* Simple call site for access decisions */ -static inline int fsnotify_perm(struct file *file, int mask) +/* + * fsnotify_file_perm - permission hook before file access + */ +static inline int fsnotify_file_perm(struct file *file, int perm_mask) { - int ret; - __u32 fsnotify_mask = 0; + __u32 fsnotify_mask = FS_ACCESS_PERM; - if (!(mask & (MAY_READ | MAY_OPEN))) + if (!(perm_mask & MAY_READ)) return 0; - if (mask & MAY_OPEN) { - fsnotify_mask = FS_OPEN_PERM; + return fsnotify_file(file, fsnotify_mask); +} - if (file->f_flags & __FMODE_EXEC) { - ret = fsnotify_file(file, FS_OPEN_EXEC_PERM); +/* + * fsnotify_open_perm - permission hook before file open + */ +static inline int fsnotify_open_perm(struct file *file) +{ + int ret; - if (ret) - return ret; - } - } else if (mask & MAY_READ) { - fsnotify_mask = FS_ACCESS_PERM; + if (file->f_flags & __FMODE_EXEC) { + ret = fsnotify_file(file, FS_OPEN_EXEC_PERM); + if (ret) + return ret; } - return fsnotify_file(file, fsnotify_mask); + return fsnotify_file(file, FS_OPEN_PERM); } /* diff --git a/security/security.c b/security/security.c index dcb3e7014f9b..d7f3703c5905 100644 --- a/security/security.c +++ b/security/security.c @@ -2586,7 +2586,7 @@ int security_file_permission(struct file *file, int mask) if (ret) return ret; - return fsnotify_perm(file, mask); + return fsnotify_file_perm(file, mask); } /** @@ -2837,7 +2837,7 @@ int security_file_open(struct file *file) if (ret) return ret; - return fsnotify_perm(file, MAY_OPEN); + return fsnotify_open_perm(file); } /** From patchwork Tue Dec 12 09:44:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13488824 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HX2FLgb6" Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 956E8D9 for ; Tue, 12 Dec 2023 01:44:52 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-333536432e0so5071684f8f.3 for ; Tue, 12 Dec 2023 01:44:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702374291; x=1702979091; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ea0v+/7dOe+rK7fNBTUS0Q19FYSn+8LMd/kdGTAt84g=; b=HX2FLgb6Ajn5axtM8/uDCIjAMOUVjRb0Ibq8C5xzmGG8jgjr1+ki362FBtsrBqW3Xl bD7adpfALwJOP0ZyC75eu2OLyDU0qn1ypVhX+QXtSFXtXN+kJ8vvykffohAyUcYAWzNm dChWlLIcOXyRGQP2Jtdj1gasguG9h6lk2b11FQ4v7wnUTGH9qAtPRD3OnmGOw8iemaOX K2VNGxlAVoTPwPgINkjJV4akA/1JVXaaP8OJw2+1IUIGttwEiJsgLM2PioSEf8/exS++ /+Yx9v64r+Fmr83agQbQwkKbJbi3rx2sk3nqtvHmN5oVfA/uy9Kn1uL1UnrX8kKsL74x P41A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702374291; x=1702979091; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ea0v+/7dOe+rK7fNBTUS0Q19FYSn+8LMd/kdGTAt84g=; b=m9CzZu59ymy3LvYx+Nk9XAnmHlj268F70owEbNBxVDQtT9s/0/eL72V+pgBSYUJEqg GCjj4bwY6VQ2mY5zKcXBTqosJDx7hm8thjdugeJ97/F0S5fQ0CPAv/lcpY5QFCh6F8os 04LgseDz/wUAkvDazFG21kEm6eSJm9hZ39Ay2n9xaMMJ2FxwC/vIOVGQDt9g42+6El/R AxKrIPQbeNhMkFCBEVcyixZtCv6cIdrp7OwkGRYazOFsunYr45jLYGa9QYxHHn8Z2+V5 qL/6NY71VkA7A4wglf8MsfhZu8M1Lom8yVL0Dfn3v6j6VfUG6rIpwLBtVqsAKfa98Sg5 ATxQ== X-Gm-Message-State: AOJu0YyI53b8ROUNclLg744PIqh/d6lQRU27U1HgPAwM7/vofBGPRq+x v5EUkqII9ksgRVdXG7Od/c0= X-Google-Smtp-Source: AGHT+IH7wgYpabkoL1aw052x4/haGasRhvMFBZ8ZNlw+Tfp6yr+iPDkZxKAye3sZ1HCrfrm8qrxrJg== X-Received: by 2002:a05:6000:ad1:b0:333:3c4d:7ff1 with SMTP id di17-20020a0560000ad100b003333c4d7ff1mr3059862wrb.78.1702374290983; Tue, 12 Dec 2023 01:44:50 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id l4-20020a05600012c400b003334041c3edsm10432244wrx.41.2023.12.12.01.44.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 01:44:50 -0800 (PST) From: Amir Goldstein To: Christian Brauner Cc: Jan Kara , Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH v3 4/5] fsnotify: assert that file_start_write() is not held in permission hooks Date: Tue, 12 Dec 2023 11:44:39 +0200 Message-Id: <20231212094440.250945-5-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212094440.250945-1-amir73il@gmail.com> References: <20231212094440.250945-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 filesystem may be modified in the context of fanotify permission events (e.g. by HSM service), so assert that sb freeze protection is not held. If the assertion fails, then the following deadlock would be possible: CPU0 CPU1 CPU2 ------------------------------------------------------------------------- file_start_write()#0 ... fsnotify_perm() fanotify_get_response() => (read event and fill file) ... ... freeze_super() ... sb_wait_write() ... vfs_write() file_start_write()#1 This example demonstrates a use case of an hierarchical storage management (HSM) service that uses fanotify permission events to fill the content of a file before access, while a 3rd process starts fsfreeze. This creates a circular dependeny: file_start_write()#0 => fanotify_get_response => file_start_write()#1 => sb_wait_write() => file_end_write()#0 Where file_end_write()#0 can never be called and none of the threads can make progress. The assertion is checked for both MAY_READ and MAY_WRITE permission hooks in preparation for a pre-modify permission event. The assertion is not checked for an open permission event, because do_open() takes mnt_want_write() in O_TRUNC case, meaning that it is not safe to write to filesystem in the content of an open permission event. Reviewed-by: Josef Bacik Reviewed-by: Jan Kara Signed-off-by: Amir Goldstein --- include/linux/fsnotify.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 926bb4461b9e..0a9d6a8a747a 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -107,6 +107,13 @@ static inline int fsnotify_file_perm(struct file *file, int perm_mask) { __u32 fsnotify_mask = FS_ACCESS_PERM; + /* + * filesystem may be modified in the context of permission events + * (e.g. by HSM filling a file on access), so sb freeze protection + * must not be held. + */ + lockdep_assert_once(file_write_not_started(file)); + if (!(perm_mask & MAY_READ)) return 0; From patchwork Tue Dec 12 09:44:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13488825 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bO4zEBVJ" Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34463DC for ; Tue, 12 Dec 2023 01:44:54 -0800 (PST) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-3362216835eso1419089f8f.3 for ; Tue, 12 Dec 2023 01:44:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702374292; x=1702979092; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IZowgpdHWDo29CSzCl+gJH076Mvg+wZkvhPUu+SH0EM=; b=bO4zEBVJ71ocXJ0U3gQ01/VOvQ46TfGSpp5DSEiWqEF4q/I0QfhTSnJD6yrc4FioD0 ZlaWapRpNCawlX5ZUnT7awXL4P8+lcCeJnKt/ZwCrOMW8Tj0EYhT+plhUs8Jav3TZVdK ogvhZo906kySthcGqa73zBQcOLYaRIvt/letWuwchd+v3qHux864xgqpUr3pswJuw3UE 9J8c32wtKIZif6VIRIgoIVVeKBCzrLKBkFiCl7O4zpJFQ/ovHwMs36Ew3lXbS0ftpFvv 8Jbz/aaQAANsG5FhpuJPyl2m+pzWOfCyaKdU00qmrX8/G2q+7qlrTJyZWBej2XCTG1e0 ZgUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702374292; x=1702979092; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IZowgpdHWDo29CSzCl+gJH076Mvg+wZkvhPUu+SH0EM=; b=Vc5O4rt8QkRjGodMeI9oSgYfcqTJys9+mKDLdygiZJ0WsTqTLA3I9nF2vVxovv3IKU VVw2TZFRGv0UMPlIHLl9Y8SSA3/0SZ1/S36ol0W2kcknKvETGklRtrmIh0trrgCYI8oY GNX9gx+8YgNA6ss6JpHTdhD+3Vh6RQ/nzJAjutcu5YQtj6g9pv5QtgyJwlddOzdeq1sR BaRSKhcb9O/28msBVhvKy+lvpS0O69KEUYQIZU4w3DF2BhHanNfxUf5zu/kEw1QHH1a5 au2abpTG5063Gi+5yVFQI6u0uyWfWgjdyoiY4gxaeAz2x/J+GGi79QMDv9AcbJBBkeJj nvJg== X-Gm-Message-State: AOJu0Yzi6ij9vsFNk67DpvrnqEikFjZmLiY/RSMPj/LtuliP1txFDTNu 3vngyPskEbfzBFjiNAN3WpA= X-Google-Smtp-Source: AGHT+IHo7rhRhKxQCxbiB92l0LtIFEckmNTYeKQcYzj45ZKshXsrAMmA4XKwyPlPFCIH8mSpEFKoPg== X-Received: by 2002:adf:e991:0:b0:333:2fd2:68e8 with SMTP id h17-20020adfe991000000b003332fd268e8mr2685438wrm.123.1702374292532; Tue, 12 Dec 2023 01:44:52 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id l4-20020a05600012c400b003334041c3edsm10432244wrx.41.2023.12.12.01.44.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 01:44:52 -0800 (PST) From: Amir Goldstein To: Christian Brauner Cc: Jan Kara , Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH v3 5/5] fsnotify: optionally pass access range in file permission hooks Date: Tue, 12 Dec 2023 11:44:40 +0200 Message-Id: <20231212094440.250945-6-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212094440.250945-1-amir73il@gmail.com> References: <20231212094440.250945-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In preparation for pre-content permission events with file access range, move fsnotify_file_perm() hook out of security_file_permission() and into the callers. Callers that have the access range information call the new hook fsnotify_file_area_perm() with the access range. Reviewed-by: Jan Kara Signed-off-by: Amir Goldstein --- fs/open.c | 4 ++++ fs/read_write.c | 10 ++++++++-- fs/readdir.c | 4 ++++ fs/remap_range.c | 8 +++++++- include/linux/fsnotify.h | 13 +++++++++++-- security/security.c | 8 +------- 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/fs/open.c b/fs/open.c index 02dc608d40d8..d877228d5939 100644 --- a/fs/open.c +++ b/fs/open.c @@ -304,6 +304,10 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (ret) return ret; + ret = fsnotify_file_area_perm(file, MAY_WRITE, &offset, len); + if (ret) + return ret; + if (S_ISFIFO(inode->i_mode)) return -ESPIPE; diff --git a/fs/read_write.c b/fs/read_write.c index e3abf603eaaf..d4c036e82b6c 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -354,6 +354,9 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count) { + int mask = read_write == READ ? MAY_READ : MAY_WRITE; + int ret; + if (unlikely((ssize_t) count < 0)) return -EINVAL; @@ -371,8 +374,11 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t } } - return security_file_permission(file, - read_write == READ ? MAY_READ : MAY_WRITE); + ret = security_file_permission(file, mask); + if (ret) + return ret; + + return fsnotify_file_area_perm(file, mask, ppos, count); } EXPORT_SYMBOL(rw_verify_area); diff --git a/fs/readdir.c b/fs/readdir.c index c8c46e294431..278bc0254732 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -96,6 +96,10 @@ int iterate_dir(struct file *file, struct dir_context *ctx) if (res) goto out; + res = fsnotify_file_perm(file, MAY_READ); + if (res) + goto out; + res = down_read_killable(&inode->i_rwsem); if (res) goto out; diff --git a/fs/remap_range.c b/fs/remap_range.c index 12131f2a6c9e..f8c1120b8311 100644 --- a/fs/remap_range.c +++ b/fs/remap_range.c @@ -102,7 +102,9 @@ static int generic_remap_checks(struct file *file_in, loff_t pos_in, static int remap_verify_area(struct file *file, loff_t pos, loff_t len, bool write) { + int mask = write ? MAY_WRITE : MAY_READ; loff_t tmp; + int ret; if (unlikely(pos < 0 || len < 0)) return -EINVAL; @@ -110,7 +112,11 @@ static int remap_verify_area(struct file *file, loff_t pos, loff_t len, if (unlikely(check_add_overflow(pos, len, &tmp))) return -EINVAL; - return security_file_permission(file, write ? MAY_WRITE : MAY_READ); + ret = security_file_permission(file, mask); + if (ret) + return ret; + + return fsnotify_file_area_perm(file, mask, &pos, len); } /* diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 0a9d6a8a747a..11e6434b8e71 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -101,9 +101,10 @@ static inline int fsnotify_file(struct file *file, __u32 mask) } /* - * fsnotify_file_perm - permission hook before file access + * fsnotify_file_area_perm - permission hook before access to file range */ -static inline int fsnotify_file_perm(struct file *file, int perm_mask) +static inline int fsnotify_file_area_perm(struct file *file, int perm_mask, + const loff_t *ppos, size_t count) { __u32 fsnotify_mask = FS_ACCESS_PERM; @@ -120,6 +121,14 @@ static inline int fsnotify_file_perm(struct file *file, int perm_mask) return fsnotify_file(file, fsnotify_mask); } +/* + * fsnotify_file_perm - permission hook before file access + */ +static inline int fsnotify_file_perm(struct file *file, int perm_mask) +{ + return fsnotify_file_area_perm(file, perm_mask, NULL, 0); +} + /* * fsnotify_open_perm - permission hook before file open */ diff --git a/security/security.c b/security/security.c index d7f3703c5905..2a7fc7881cbc 100644 --- a/security/security.c +++ b/security/security.c @@ -2580,13 +2580,7 @@ int security_kernfs_init_security(struct kernfs_node *kn_dir, */ int security_file_permission(struct file *file, int mask) { - int ret; - - ret = call_int_hook(file_permission, 0, file, mask); - if (ret) - return ret; - - return fsnotify_file_perm(file, mask); + return call_int_hook(file_permission, 0, file, mask); } /**