From patchwork Tue Jun 25 11:00:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mateusz Guzik X-Patchwork-Id: 13710867 Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E141145B32; Tue, 25 Jun 2024 11:00:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719313257; cv=none; b=G2myj4I9DHQ2cUqoEP33t27zaukRtBsWmQe5ISMDzWQYOn1yzPnTQpPZs7QkJPcAaEFAVJdKdfw47qze1/D+3O/3b/y22EGZ4kFu1aB/sv5Rnctwm4RnEjT03q2hmXjzDjeQUoqZ1KoQPseZR3NGoHRaZqph6DftK0FTIQDkkNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719313257; c=relaxed/simple; bh=0vIHAQ7YvjnLKfwQTv8MsCHk2eaPF3/En/Mr81Z6QRc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hoOILcBu6BAvvp8XxWy3NYBXtNTzAKV/q/fD4aBP1DTWPwFcMW1SBrfOqRuIxodyQqgTNM8zQVh/Xv3KgIde3n/n6SmsiJL3mZgOSaiVwijJTKzyxyXYfA2Z0xFTZfpCEGpoM+Pu8vK/pjan4GkZfK51z934e2sBxTEGiU/SV44= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=cI5dbOXS; arc=none smtp.client-ip=209.85.208.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cI5dbOXS" Received: by mail-lj1-f172.google.com with SMTP id 38308e7fff4ca-2ebe0a81dc8so69581841fa.2; Tue, 25 Jun 2024 04:00:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719313254; x=1719918054; 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=zTaK8ifaWbHOYZsMnepqrh6GgtvKb4cednFDr4sSDjo=; b=cI5dbOXSFFw6vdSG08JzCC+WoMQ/rbijGZpbOmbeyuYKMt11zakhnybFew91tmUMD4 S18f+GFEKf1s7TgET6/RWD/evXpe3Hmy5A8xs/IacQaSYrVJ2aVejMMdMc0JQMguw5rf iJHSENK3Hmxs8Xjv4b0Sf1hVxIJFfpBHHYv2ta0etc6/plSqIPx+h+afOZBuI96jSiCz XJ6hsyT/1+9JtZo6nffEBiPtHycbu7p5gWEbynkV2zJZeLUeoWlxaDWvKUY0XTLvsUz4 Z1hBUlqo37dU2MGvsY2FLEVwqhR5g3N5Bvce9LDoYqlXUZ/v05n2/nhTCvGJGzrQ+xWj I7PA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719313254; x=1719918054; 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=zTaK8ifaWbHOYZsMnepqrh6GgtvKb4cednFDr4sSDjo=; b=N29hPRJN4andGlAmQR+mSNF+x2eNYYwu9bTFQ1brTLADi/QXFhIo/dozPHOevcOkh9 rnDA+cDNYR3B1s45vOf3yXAPtlqtr6NxZtS3S1pifa3gK3/4ntlmIQUL3bUN0ONY42K7 7NIuQYy8KrMRp5nBJYRUSx3JYjvv+4C1Ux2DCOq3eytrpBH4CgFIV3PDpSLGWx1rQ9pV D/1PAA/nNUNNJuJ95tD0rHH8EJKSggoGnkZUVHdy9Wan6qPwvSTVVWN5AsQgnh7Oi1KT BgSOS0ldXlEOUp5RAFF9V0TXDsQjva9+egaE/+DUpem5Tf/q2cVuOQlejHLcOLtTphJB Vtkw== X-Forwarded-Encrypted: i=1; AJvYcCUBoG/egcjMVqjufSLy0EdZLDkiXoMEFhtmSfeDjl5GmBr9z8p7o9N+fUtQ/6a1boFY0Vt2oM43G8RN9SlfBXzHO9qqAm2225ZWtnw9K0gibHRSJORsTNfc3wocaBCyZSnlj/rq9PFiVr6nqHyqzamQetoTMostYfgSwMgTAnmf0TvNlT2G X-Gm-Message-State: AOJu0YxL5Qyj0xkK9VYDNnHRSpf+0QlOKNtK+bivgFtRjE6E0H9hnzuo mkyb144a/E+pLdUf+2cHW0w90dFr1jVLFLTsoqmhnzt0fYoyunXR X-Google-Smtp-Source: AGHT+IHpV9HXs0P4QbXTCeQhNYlDDBqrB2zbBl6B1KNa8va0iJtWcu6ToloiWeqSJ7giQ1iNQeXX6g== X-Received: by 2002:a05:6512:3703:b0:52c:e4bf:d55d with SMTP id 2adb3069b0e04-52ce4bfd59fmr4509583e87.8.1719313254090; Tue, 25 Jun 2024 04:00:54 -0700 (PDT) Received: from f.. (cst-prg-81-171.cust.vodafone.cz. [46.135.81.171]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a724162f037sm337272566b.194.2024.06.25.04.00.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Jun 2024 04:00:53 -0700 (PDT) From: Mateusz Guzik To: brauner@kernel.org Cc: viro@zeniv.linux.org.uk, jack@suse.cz, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, io-uring@vger.kernel.org, axboe@kernel.dk, torvalds@linux-foundation.org, xry111@xry111.site, loongarch@lists.linux.dev, Mateusz Guzik Subject: [PATCH 1/2] vfs: add CLASS fd_raw Date: Tue, 25 Jun 2024 13:00:27 +0200 Message-ID: <20240625110029.606032-2-mjguzik@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240625110029.606032-1-mjguzik@gmail.com> References: <20240625110029.606032-1-mjguzik@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Signed-off-by: Mateusz Guzik --- include/linux/file.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/file.h b/include/linux/file.h index 169692cb1906..45d0f4800abd 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -84,6 +84,7 @@ static inline void fdput_pos(struct fd f) } DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd) +DEFINE_CLASS(fd_raw, struct fd, fdput(_T), fdget_raw(fd), int fd) extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); extern int replace_fd(unsigned fd, struct file *file, unsigned flags); From patchwork Tue Jun 25 11:00:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mateusz Guzik X-Patchwork-Id: 13710868 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B6BC14AD24; Tue, 25 Jun 2024 11:00:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719313260; cv=none; b=Pj24ZXca6OGnWXsaWIVOz/smFmNciyI6zEhuGqwn6IvECRl6GaH7dWreHEqTxGXUfUSuxDUCBr3Pt2koLRKStAHesTNBsXTkK4X5trtzICsHFOETPTIctVzzX1LzRRuzuBvEOgNcrTeudx+b6pgS68nS2Rr+L6C2nk0aF5hLzqA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719313260; c=relaxed/simple; bh=Qx9nn4N/0uGydqFiWspNCnMlo9JldIIWKGZCDF/mhZQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MfURCKajDuZ0wGYD17BGD6PKzdl4GgOD7rX5n+Diujlh64CpfQ2lFFRt8DJlCtWw6hjb1BH4nVUJKzz8pcJlWsnuO9eNdS51s+yUKXOrMcMt9eyyNMX83Y1CZL9UTUuFJvvQ7+LMizIMMsVwGP4WEskJVCMJvjd/G/2sLdS9kIo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JM1eg0Dw; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JM1eg0Dw" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-a724e067017so278147066b.0; Tue, 25 Jun 2024 04:00:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719313257; x=1719918057; 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=PDtwFciM4nTzlZf6ylZvaFvsdHMJWGfNAlLJgEeCQsA=; b=JM1eg0DwXecIN+t5QcPbnp5mU24AkoXVE9NFa3YetzmYuqdBOcpk/CSnnPs3Vb1eTc Dc1LO9jgu37Nhx6yRypxY63RNg6qtZkpqMy342BNAPjw2zHcjxKSWidO14wev7w30YG9 BkQrzeqCocf/ENEUoBJk5Se1LAl710OfdXpMhEFdyH8R5R10GgHgbP4Jenm81Ue4/Y+d kFnFJjOPsbKkgNAEoa3ZiFJGr5QprAjqR9iNKGZdLa4YYoVcSb4oTlm3qd3FRV85YAFr v4c2Jh/PvrXP4yUhFIDVZWnGbH3sFGE8rP2h07Xa7/zqehljPJ8e5LK1oldQ3+M6ONJv gA/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719313257; x=1719918057; 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=PDtwFciM4nTzlZf6ylZvaFvsdHMJWGfNAlLJgEeCQsA=; b=JEqVThQ3ZKJN6rYF2eWILYR0ustO1JRTwnYo6m++1m8s90JO8fr+ttuSjj4bX9Wid3 ElIrh/Srp/TpMwGBmhBcx9kIAN1J1IejczwURIywgmI5saiARgDZGYsToB1OreyRDMvG /h/DFvO56lF4pIAmJuSnaBT6bxpei9Pa60C0OTrJgPO4JXr+cGUEYLLY50hJB1Nwr1cZ nTE0PTgLBGAgaeOng6/4HPGy94s1KQzIgJ5J2fZs79waJqZ0dU0xaYgg2gRsV9mIgyBX p9tH7YxWxuP0yJ7RtuyOMu0JJr38erWm6OmIsBhL4vt4g8lTncj+k3oTaGkGoqYJf4qe YkwQ== X-Forwarded-Encrypted: i=1; AJvYcCUUod9h1n/35ogJx0tLLdwylmNkeIh7rY7np2/UUHxdHAD99up1bBkyczLz0BZ3YzZ+QCjQIXHKEUBYgqoFmU3UxI3GkXCj5VLJZw61PnwQiNmDWFtSc6pmRJudenU5K/wapwYCfQ70nPE6L4rvWQsdMpp1+azCsP4ro6mF+j8TbBM2SIz/ X-Gm-Message-State: AOJu0YwOa92F8Wl6zZHZFXjuZFFGZHnvI4sAkiNPxbIZmq19T0nj5IFX SMFxUHXZfWyzhVnRIXFsl3g/O6lcu15igNDvVyPAtCsyU7OxlmHg X-Google-Smtp-Source: AGHT+IFRTq88DKEIGsB/us3b8O3gHDEVsHBBdW8y2F64wmd0hTEryoAiUGyf/l8EJQYEkL/YHFmbDA== X-Received: by 2002:a17:907:774b:b0:a6e:57ff:7700 with SMTP id a640c23a62f3a-a7245b8522bmr412104166b.42.1719313256623; Tue, 25 Jun 2024 04:00:56 -0700 (PDT) Received: from f.. (cst-prg-81-171.cust.vodafone.cz. [46.135.81.171]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a724162f037sm337272566b.194.2024.06.25.04.00.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Jun 2024 04:00:56 -0700 (PDT) From: Mateusz Guzik To: brauner@kernel.org Cc: viro@zeniv.linux.org.uk, jack@suse.cz, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, io-uring@vger.kernel.org, axboe@kernel.dk, torvalds@linux-foundation.org, xry111@xry111.site, loongarch@lists.linux.dev, Mateusz Guzik Subject: [PATCH 2/2] vfs: support statx(..., NULL, AT_EMPTY_PATH, ...) Date: Tue, 25 Jun 2024 13:00:28 +0200 Message-ID: <20240625110029.606032-3-mjguzik@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240625110029.606032-1-mjguzik@gmail.com> References: <20240625110029.606032-1-mjguzik@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The newly used helper also checks for 0-sized buffers. This avoids path lookup code, lockref management, memory allocation and in case of NULL path userspace memory access (which can be quite expensive with SMAP on x86_64). statx with AT_EMPTY_PATH paired with "" or NULL argument as appropriate issued on Sapphire Rapids (ops/s): stock: 4231237 0-check: 5944063 (+40%) NULL path: 6601619 (+11%/+56%) Signed-off-by: Mateusz Guzik --- fs/internal.h | 2 ++ fs/stat.c | 90 ++++++++++++++++++++++++++++++++++-------------- io_uring/statx.c | 23 +++++++------ 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index 1caa6a8f666f..0a018ebcaf49 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -244,6 +244,8 @@ extern const struct dentry_operations ns_dentry_operations; int getname_statx_lookup_flags(int flags); int do_statx(int dfd, struct filename *filename, unsigned int flags, unsigned int mask, struct statx __user *buffer); +int do_statx_fd(int fd, unsigned int flags, unsigned int mask, + struct statx __user *buffer); /* * fs/splice.c: diff --git a/fs/stat.c b/fs/stat.c index 106684034fdb..1214826f3a36 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -214,6 +214,43 @@ int getname_statx_lookup_flags(int flags) return lookup_flags; } +static int vfs_statx_path(struct path *path, int flags, struct kstat *stat, + u32 request_mask) +{ + int error = vfs_getattr(path, stat, request_mask, flags); + + if (request_mask & STATX_MNT_ID_UNIQUE) { + stat->mnt_id = real_mount(path->mnt)->mnt_id_unique; + stat->result_mask |= STATX_MNT_ID_UNIQUE; + } else { + stat->mnt_id = real_mount(path->mnt)->mnt_id; + stat->result_mask |= STATX_MNT_ID; + } + + if (path->mnt->mnt_root == path->dentry) + stat->attributes |= STATX_ATTR_MOUNT_ROOT; + stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT; + + /* Handle STATX_DIOALIGN for block devices. */ + if (request_mask & STATX_DIOALIGN) { + struct inode *inode = d_backing_inode(path->dentry); + + if (S_ISBLK(inode->i_mode)) + bdev_statx_dioalign(inode, stat); + } + + return error; +} + +static int vfs_statx_fd(int fd, int flags, struct kstat *stat, + u32 request_mask) +{ + CLASS(fd_raw, f)(fd); + if (!f.file) + return -EBADF; + return vfs_statx_path(&f.file->f_path, flags, stat, request_mask); +} + /** * vfs_statx - Get basic and extra attributes by filename * @dfd: A file descriptor representing the base dir for a relative filename @@ -243,36 +280,13 @@ static int vfs_statx(int dfd, struct filename *filename, int flags, retry: error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); if (error) - goto out; - - error = vfs_getattr(&path, stat, request_mask, flags); - - if (request_mask & STATX_MNT_ID_UNIQUE) { - stat->mnt_id = real_mount(path.mnt)->mnt_id_unique; - stat->result_mask |= STATX_MNT_ID_UNIQUE; - } else { - stat->mnt_id = real_mount(path.mnt)->mnt_id; - stat->result_mask |= STATX_MNT_ID; - } - - if (path.mnt->mnt_root == path.dentry) - stat->attributes |= STATX_ATTR_MOUNT_ROOT; - stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT; - - /* Handle STATX_DIOALIGN for block devices. */ - if (request_mask & STATX_DIOALIGN) { - struct inode *inode = d_backing_inode(path.dentry); - - if (S_ISBLK(inode->i_mode)) - bdev_statx_dioalign(inode, stat); - } - + return error; + error = vfs_statx_path(&path, flags, stat, request_mask); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } -out: return error; } @@ -677,6 +691,29 @@ int do_statx(int dfd, struct filename *filename, unsigned int flags, return cp_statx(&stat, buffer); } +int do_statx_fd(int fd, unsigned int flags, unsigned int mask, + struct statx __user *buffer) +{ + struct kstat stat; + int error; + + if (mask & STATX__RESERVED) + return -EINVAL; + if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE) + return -EINVAL; + + /* STATX_CHANGE_COOKIE is kernel-only for now. Ignore requests + * from userland. + */ + mask &= ~STATX_CHANGE_COOKIE; + + error = vfs_statx_fd(fd, flags, &stat, mask); + if (error) + return error; + + return cp_statx(&stat, buffer); +} + /** * sys_statx - System call to get enhanced stats * @dfd: Base directory to pathwalk from *or* fd to stat. @@ -696,6 +733,9 @@ SYSCALL_DEFINE5(statx, int ret; struct filename *name; + if (flags == AT_EMPTY_PATH && vfs_empty_path(dfd, filename)) + return do_statx_fd(dfd, flags, mask, buffer); + name = getname_flags(filename, getname_statx_lookup_flags(flags), NULL); ret = do_statx(dfd, name, flags, mask, buffer); putname(name); diff --git a/io_uring/statx.c b/io_uring/statx.c index abb874209caa..fe967ecb1762 100644 --- a/io_uring/statx.c +++ b/io_uring/statx.c @@ -23,6 +23,7 @@ struct io_statx { int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); + struct filename *filename; const char __user *path; if (sqe->buf_index || sqe->splice_fd_in) @@ -36,15 +37,14 @@ int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2)); sx->flags = READ_ONCE(sqe->statx_flags); - sx->filename = getname_flags(path, - getname_statx_lookup_flags(sx->flags), - NULL); - - if (IS_ERR(sx->filename)) { - int ret = PTR_ERR(sx->filename); - - sx->filename = NULL; - return ret; + sx->filename = NULL; + if (!(sx->flags == AT_EMPTY_PATH && vfs_empty_path(sx->dfd, path))) { + filename = getname_flags(path, + getname_statx_lookup_flags(sx->flags), + NULL); + if (IS_ERR(filename)) + return PTR_ERR(filename); + sx->filename = filename; } req->flags |= REQ_F_NEED_CLEANUP; @@ -59,7 +59,10 @@ int io_statx(struct io_kiocb *req, unsigned int issue_flags) WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); - ret = do_statx(sx->dfd, sx->filename, sx->flags, sx->mask, sx->buffer); + if (sx->filename == NULL) + ret = do_statx_fd(sx->dfd, sx->flags, sx->mask, sx->buffer); + else + ret = do_statx(sx->dfd, sx->filename, sx->flags, sx->mask, sx->buffer); io_req_set_res(req, ret, 0); return IOU_OK; }