From patchwork Mon Nov 11 20:18:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13871232 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3905D3ABF4 for ; Mon, 11 Nov 2024 20:19:47 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E86696B00A5; Mon, 11 Nov 2024 15:19:36 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id E0EEB6B00A6; Mon, 11 Nov 2024 15:19:36 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C87296B00A7; Mon, 11 Nov 2024 15:19:36 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id A5CA66B00A5 for ; Mon, 11 Nov 2024 15:19:36 -0500 (EST) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 62FD41C73BF for ; Mon, 11 Nov 2024 20:19:36 +0000 (UTC) X-FDA: 82774928292.26.E5D2903 Received: from mail-oi1-f173.google.com (mail-oi1-f173.google.com [209.85.167.173]) by imf20.hostedemail.com (Postfix) with ESMTP id B4C871C000E for ; Mon, 11 Nov 2024 20:18:43 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=toxicpanda-com.20230601.gappssmtp.com header.s=20230601 header.b=rYzyObNl; spf=none (imf20.hostedemail.com: domain of josef@toxicpanda.com has no SPF policy when checking 209.85.167.173) smtp.mailfrom=josef@toxicpanda.com; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731356232; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=+nXKwcxfUzOePvYnZ4Bb/p4hYsf8sSP8uIyFDoaTPjc=; b=ijJi842hVXwJX3FbRjGnMhbtiEJJkbCScIKxVF3KUqigfeK4ldrpsSA8zj4lX/SpwXsNWz Js3svbHbBiTxmbzwtDtZ4b9VxMlAdZ8VUOyXmE5bGJEgyYUnvgXdFGkRic5WrrHWOvyo4c qaJABSoBG2KnNxR4Gsq/Yfg49Htvgqg= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731356232; a=rsa-sha256; cv=none; b=GBtwR/sEVPxJAbs6OGN2HbHMb4CkGmqXC5Thhp5bQ4tV4HwuGxSFohwTgMrPs7qe507Ls9 HA/AvMXWw4TxADIK1KDJZOCjCpduOyFhIwowTfl8dBXE44EijV1xUIwAtDMp3692nvuFbA z84ug2Hqpo6j2n6V+CwcOIK7mByRsZA= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=toxicpanda-com.20230601.gappssmtp.com header.s=20230601 header.b=rYzyObNl; spf=none (imf20.hostedemail.com: domain of josef@toxicpanda.com has no SPF policy when checking 209.85.167.173) smtp.mailfrom=josef@toxicpanda.com; dmarc=none Received: by mail-oi1-f173.google.com with SMTP id 5614622812f47-3e60966297fso2283323b6e.1 for ; Mon, 11 Nov 2024 12:19:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1731356374; x=1731961174; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=+nXKwcxfUzOePvYnZ4Bb/p4hYsf8sSP8uIyFDoaTPjc=; b=rYzyObNlum9/8TbbD4hsXQNISz5O/04Qfrkrd381+P7WYnUU2GRbXEm1X50hUAZqgk 2B1eZennVMKkI2sH+UcNN8koorofswf4Xdb/jZOIwcy1xL2EuvdP1s8aZN1+9KomC4Tt 4TtsJXvtrahle372fH3gb8rakA4qAnEsiS+Dxm64xQqSzhNzXx+siMB5Yn+aWUbsxTch s3wQuif7sgD9s9Avlnfdoa2hKegSsATYNf+EC64BVD/QnyhcpqPiVWt/G+Bg9CBUvOL5 n+y+yw8DUaZkhS0ziWbZtrRMoi6OTEAzrX6TnG1twidZrF+tP2nt+1SLy2XBczmuFpHp zBXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731356374; x=1731961174; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+nXKwcxfUzOePvYnZ4Bb/p4hYsf8sSP8uIyFDoaTPjc=; b=X6v2KJUQD5u32971JL5BWUbIcQKKhEOsk0F1eYefSvOcTxIwQGhD0RNlrSbLwvkxbv K7WuheamVWdXbPqyaFvhJP5raZpsGlbBMxz8zwmd4kdlAjaU8k0cdhFBH38ENsWbp9B3 o8wKJw1T88al5NtXCy6TzpD0+nGlHv4l4Q7DkAaRV00P8TfKQKDb9NL5Hjpk2/DlQW/r qigkdawNWnBkIUfgYfLICWYIylVhPxH/+RCMhveEovEOAosaUiQy7ijyV+cFghaMXm4L poyFJrYNb5BLUDk8TqAG+IW00/zdZHE/T6yN+DsfDd8owbK+H+JV9mDdc/wSBTzRmjly 5P9Q== X-Forwarded-Encrypted: i=1; AJvYcCWRQWelu/w37qgNZ1IrM06/ATJnkMbaguuiGEm6uxk86Nj3PhQeggllB7TCsKPc5rfgWcg3fxUjZg==@kvack.org X-Gm-Message-State: AOJu0YwY16JtKt5ohU5Nd/LMJAdAUhNkTFbYxsHdjh9y/1QhPWn61m7G chvqLZdYocb5HA5gGM5xH0xUurUZ5UNvVf3UjL27CGmutDTGk0OjrpdJtG/rMR0= X-Google-Smtp-Source: AGHT+IHAntmNSKHnJiD7mii22aSouugOuv2LnJCY83E+/C/49mfb6yy9irDZkbJmhglaB0kAus4AaA== X-Received: by 2002:a05:6808:3a15:b0:3e6:943:63c9 with SMTP id 5614622812f47-3e79470a33cmr12285250b6e.33.1731356373743; Mon, 11 Nov 2024 12:19:33 -0800 (PST) Received: from localhost (syn-076-182-020-124.res.spectrum.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3962089fesm63519156d6.61.2024.11.11.12.19.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Nov 2024 12:19:33 -0800 (PST) From: Josef Bacik To: kernel-team@fb.com, linux-fsdevel@vger.kernel.org, jack@suse.cz, amir73il@gmail.com, brauner@kernel.org, torvalds@linux-foundation.org, linux-xfs@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-mm@kvack.org, linux-ext4@vger.kernel.org Subject: [PATCH v6 14/17] fsnotify: generate pre-content permission event on page fault Date: Mon, 11 Nov 2024 15:18:03 -0500 Message-ID: <4046b63f054f5896c9c4c715180664eca1366ac1.1731355931.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: B4C871C000E X-Stat-Signature: bjz89gyhjj48aix37fxnddezftraekfk X-HE-Tag: 1731356323-300334 X-HE-Meta: U2FsdGVkX1/tErC+frwBj2HouwGdOGFcoS+RuTJYweZa4zRDEQR/VgQMhteDgcpjHLuTIyBdSFNdfoMBWmgzPSGM3yX1E5z4i+OxY+bnW2sy3UGPnu8I+MXuVIDuGPu4ze91dvCTAign+g4FoN6ZWuqX0CwU5mAOa6gi8RgYJxmiqs8L4KICB7wYu3TgiVH+AUcWU3GaF7KqRRiwgtg2UXQMhU0ol/+IOcMHUxIrgBA5uAIS6se4Ku3MJOqPopPfYoFwiIKIX6r5yoSaZSAQl3qIGlZq+RkpZ/m4sfH1BWcoMTHnpe+pFgTUlxPi0dVOMB/U5I5K/g3FtJqRhYZ34T3YOQw61wpaXVASPNhPfP0AQo/IbEmjwVc/ljZS6QMCIh5DQuKuIuBVw+wEn0fWgNQdO5/By2t1hTXaCtIP9kxBigHGjO1J65OmUNtROU9IF3HRixAzmBjCfWI02uvudZVYX5U+90VwzTsNnGllFamm+tmlLo106RRDFMKPsH5uPniqB+o5CHRwAqIZOo19S+OrP3ddO+a7FzHpFQpb/SG54cOC5h52+eBjQ0JnmDghwcTaOXNTUEJjW8XXDkMOu9f5qOdqTg1I+K7PbEPsXqwliKJm4NS5eJ4GM8Z3qLzbCwjzFBylyhdHsKAwxFx0q0hcglpMkc5g+Kjwd1+dUDWzOjZCEdbWJwPlvuiM5A5zf/5I33d89tKR0LlfaXAq6jE8aJ8ImnNfabdCEtRaRY0fWtLEVKQ/nY+pFZbej+OQF7xZYKGP4C9+TIs4XX//8U6A5ZlqEmdiDL2NgqhAkv8tdHVVSmbWt6UD1tu6bsWoX+WUb5zJ3qAfwK6ffmUAmv9Km/OKlhbpZQazdCkYtqqjzqG6hoZy+sOj0srpFrI9KCPcZ7xf7PuoM/iMhA1ujjgHnHYXywM24O056tejsxOjG7cGp9UPJ833bORO+y5XL9n6DJ13SE+YuPqHAr/ Kslz4+9I qi05ZZUni1FVnR9ZOgRwCMxEO0ICINLXK6GhRVaXdLuuYawvHMA7SVTSZBsrw7czoUMIQaHtBVz/AsKZvZi6hxIKdt7FrN21dS6vrbe6Eque1/U3jk0KSuq41zwMR6zDQk2BbhevwAx+pkUsmGKyv1/80zxLRF0ZXWrfwJElUfiG2qfXsno+f/NA7w2YWFTK3aPXhbmgVfK/0VKNUWaMFpR6u22nWbH8BKioW2Mi0mSfWo78cxyAeqW6hpaCjAgmQRge507ECnXEz0KhU2eoEq8nnvoECIXiOMPcewvBzH6BGLBVmxUk+UA5/Tmek/wI4ETQXjazBs6pAZuP2BB+SEbrsalnpDCt5OSWwpV7K5dpVWhUHtzwixj/D8hpCdx4SUoPNtuuU0p5HB/ZdLpLIlbyj+g== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: FS_PRE_ACCESS or FS_PRE_MODIFY will be generated on page fault depending on the faulting method. This pre-content event is meant to be used by hierarchical storage managers that want to fill in the file content on first read access. Export a simple helper that file systems that have their own ->fault() will use, and have a more complicated helper to be do fancy things with in filemap_fault. Signed-off-by: Josef Bacik --- include/linux/mm.h | 1 + mm/filemap.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 61fff5d34ed5..bce9e2f5dfa4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3405,6 +3405,7 @@ extern vm_fault_t filemap_fault(struct vm_fault *vmf); extern vm_fault_t filemap_map_pages(struct vm_fault *vmf, pgoff_t start_pgoff, pgoff_t end_pgoff); extern vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf); +extern vm_fault_t filemap_fsnotify_fault(struct vm_fault *vmf); extern unsigned long stack_guard_gap; /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */ diff --git a/mm/filemap.c b/mm/filemap.c index fc36a00fa014..aa3c92d605b4 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include "internal.h" @@ -3287,6 +3288,52 @@ static vm_fault_t filemap_fault_recheck_pte_none(struct vm_fault *vmf) return ret; } +/** + * filemap_fsnotify_fault - maybe emit a pre-content event. + * @vmf: struct vm_fault containing details of the fault. + * @folio: the folio we're faulting in. + * + * If we have a pre-content watch on this file we will emit an event for this + * range. If we return anything the fault caller should return immediately, we + * will return VM_FAULT_RETRY if we had to emit an event, which will trigger the + * fault again and then the fault handler will run the second time through. + * + * This is meant to be called with the folio that we will be filling in to make + * sure the event is emitted for the correct range. + * + * Return: a bitwise-OR of %VM_FAULT_ codes, 0 if nothing happened. + */ +vm_fault_t filemap_fsnotify_fault(struct vm_fault *vmf) +{ + struct file *fpin = NULL; + int mask = (vmf->flags & FAULT_FLAG_WRITE) ? MAY_WRITE : MAY_ACCESS; + loff_t pos = vmf->pgoff >> PAGE_SHIFT; + size_t count = PAGE_SIZE; + vm_fault_t ret; + + /* + * We already did this and now we're retrying with everything locked, + * don't emit the event and continue. + */ + if (vmf->flags & FAULT_FLAG_TRIED) + return 0; + + /* No watches, we're done. */ + if (!fsnotify_file_has_pre_content_watches(vmf->vma->vm_file)) + return 0; + + fpin = maybe_unlock_mmap_for_io(vmf, fpin); + if (!fpin) + return VM_FAULT_SIGBUS; + + ret = fsnotify_file_area_perm(fpin, mask, &pos, count); + fput(fpin); + if (ret) + return VM_FAULT_SIGBUS; + return VM_FAULT_RETRY; +} +EXPORT_SYMBOL_GPL(filemap_fsnotify_fault); + /** * filemap_fault - read in file data for page fault handling * @vmf: struct vm_fault containing details of the fault @@ -3390,6 +3437,37 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) * or because readahead was otherwise unable to retrieve it. */ if (unlikely(!folio_test_uptodate(folio))) { + /* + * If this is a precontent file we have can now emit an event to + * try and populate the folio. + */ + if (!(vmf->flags & FAULT_FLAG_TRIED) && + fsnotify_file_has_pre_content_watches(file)) { + loff_t pos = folio_pos(folio); + size_t count = folio_size(folio); + + /* We're NOWAIT, we have to retry. */ + if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT) { + folio_unlock(folio); + goto out_retry; + } + + if (mapping_locked) + filemap_invalidate_unlock_shared(mapping); + mapping_locked = false; + + folio_unlock(folio); + fpin = maybe_unlock_mmap_for_io(vmf, fpin); + if (!fpin) + goto out_retry; + + error = fsnotify_file_area_perm(fpin, MAY_ACCESS, &pos, + count); + if (error) + ret = VM_FAULT_SIGBUS; + goto out_retry; + } + /* * If the invalidate lock is not held, the folio was in cache * and uptodate and now it is not. Strange but possible since we