Skip to content

Commit e165e2a

Browse files
prati0100akpm00
authored andcommitted
mm: shmem: allow freezing inode mapping
To prepare a shmem inode for live update, its index -> folio mappings must be serialized. Once the mappings are serialized, they cannot change since it would cause the serialized data to become inconsistent. This can be done by pinning the folios to avoid migration, and by making sure no folios can be added to or removed from the inode. While mechanisms to pin folios already exist, the only way to stop folios being added or removed are the grow and shrink file seals. But file seals come with their own semantics, one of which is that they can't be removed. This doesn't work with liveupdate since it can be cancelled or error out, which would need the seals to be removed and the file's normal functionality to be restored. Introduce SHMEM_F_MAPPING_FROZEN to indicate this instead. It is internal to shmem and is not directly exposed to userspace. It functions similar to F_SEAL_GROW | F_SEAL_SHRINK, but additionally disallows hole punching, and can be removed. Link: https://lkml.kernel.org/r/20251125165850.3389713-12-pasha.tatashin@soleen.com Signed-off-by: Pratyush Yadav <ptyadav@amazon.de> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Tested-by: David Matlack <dmatlack@google.com> Cc: Aleksander Lobakin <aleksander.lobakin@intel.com> Cc: Alexander Graf <graf@amazon.com> Cc: Alice Ryhl <aliceryhl@google.com> Cc: Andriy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: anish kumar <yesanishhere@gmail.com> Cc: Anna Schumaker <anna.schumaker@oracle.com> Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Borislav Betkov <bp@alien8.de> Cc: Chanwoo Choi <cw00.choi@samsung.com> Cc: Chen Ridong <chenridong@huawei.com> Cc: Chris Li <chrisl@kernel.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Daniel Wagner <wagi@kernel.org> Cc: Danilo Krummrich <dakr@kernel.org> Cc: Dan Williams <dan.j.williams@intel.com> Cc: David Hildenbrand <david@redhat.com> Cc: David Jeffery <djeffery@redhat.com> Cc: David Rientjes <rientjes@google.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Guixin Liu <kanie@linux.alibaba.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Hugh Dickins <hughd@google.com> Cc: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Ira Weiny <ira.weiny@intel.com> Cc: Jann Horn <jannh@google.com> Cc: Jason Gunthorpe <jgg@nvidia.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Joanthan Cameron <Jonathan.Cameron@huawei.com> Cc: Joel Granados <joel.granados@kernel.org> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Lennart Poettering <lennart@poettering.net> Cc: Leon Romanovsky <leon@kernel.org> Cc: Leon Romanovsky <leonro@nvidia.com> Cc: Lukas Wunner <lukas@wunner.de> Cc: Marc Rutland <mark.rutland@arm.com> Cc: Masahiro Yamada <masahiroy@kernel.org> Cc: Matthew Maurer <mmaurer@google.com> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Myugnjoo Ham <myungjoo.ham@samsung.com> Cc: Parav Pandit <parav@nvidia.com> Cc: Pratyush Yadav <pratyush@kernel.org> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: Saeed Mahameed <saeedm@nvidia.com> Cc: Samiullah Khawaja <skhawaja@google.com> Cc: Song Liu <song@kernel.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Stuart Hayes <stuart.w.hayes@gmail.com> Cc: Tejun Heo <tj@kernel.org> Cc: Thomas Gleinxer <tglx@linutronix.de> Cc: Thomas Weißschuh <linux@weissschuh.net> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: William Tu <witu@nvidia.com> Cc: Yoann Congal <yoann.congal@smile.fr> Cc: Zhu Yanjun <yanjun.zhu@linux.dev> Cc: Zijun Hu <quic_zijuhu@quicinc.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 6ff1610 commit e165e2a

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

include/linux/shmem_fs.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ struct swap_iocb;
2424
#define SHMEM_F_NORESERVE BIT(0)
2525
/* Disallow swapping. */
2626
#define SHMEM_F_LOCKED BIT(1)
27+
/*
28+
* Disallow growing, shrinking, or hole punching in the inode. Combined with
29+
* folio pinning, makes sure the inode's mapping stays fixed.
30+
*
31+
* In some ways similar to F_SEAL_GROW | F_SEAL_SHRINK, but can be removed and
32+
* isn't directly visible to userspace.
33+
*/
34+
#define SHMEM_F_MAPPING_FROZEN BIT(2)
2735

2836
struct shmem_inode_info {
2937
spinlock_t lock;
@@ -186,6 +194,15 @@ static inline bool shmem_file(struct file *file)
186194
return shmem_mapping(file->f_mapping);
187195
}
188196

197+
/* Must be called with inode lock taken exclusive. */
198+
static inline void shmem_freeze(struct inode *inode, bool freeze)
199+
{
200+
if (freeze)
201+
SHMEM_I(inode)->flags |= SHMEM_F_MAPPING_FROZEN;
202+
else
203+
SHMEM_I(inode)->flags &= ~SHMEM_F_MAPPING_FROZEN;
204+
}
205+
189206
/*
190207
* If fallocate(FALLOC_FL_KEEP_SIZE) has been used, there may be pages
191208
* beyond i_size's notion of EOF, which fallocate has committed to reserving:

mm/shmem.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,8 @@ static int shmem_setattr(struct mnt_idmap *idmap,
12971297
return -EPERM;
12981298

12991299
if (newsize != oldsize) {
1300+
if (info->flags & SHMEM_F_MAPPING_FROZEN)
1301+
return -EPERM;
13001302
error = shmem_reacct_size(SHMEM_I(inode)->flags,
13011303
oldsize, newsize);
13021304
if (error)
@@ -3289,6 +3291,10 @@ shmem_write_begin(const struct kiocb *iocb, struct address_space *mapping,
32893291
return -EPERM;
32903292
}
32913293

3294+
if (unlikely((info->flags & SHMEM_F_MAPPING_FROZEN) &&
3295+
pos + len > inode->i_size))
3296+
return -EPERM;
3297+
32923298
ret = shmem_get_folio(inode, index, pos + len, &folio, SGP_WRITE);
32933299
if (ret)
32943300
return ret;
@@ -3662,6 +3668,11 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
36623668

36633669
inode_lock(inode);
36643670

3671+
if (info->flags & SHMEM_F_MAPPING_FROZEN) {
3672+
error = -EPERM;
3673+
goto out;
3674+
}
3675+
36653676
if (mode & FALLOC_FL_PUNCH_HOLE) {
36663677
struct address_space *mapping = file->f_mapping;
36673678
loff_t unmap_start = round_up(offset, PAGE_SIZE);

0 commit comments

Comments
 (0)