Thread (92 messages) 92 messages, 6 authors, 2025-11-24

Re: [PATCH v6 12/20] mm: shmem: allow freezing inode mapping

From: Pasha Tatashin <pasha.tatashin@soleen.com>
Date: 2025-11-18 04:14:17
Also in: linux-doc, linux-fsdevel, linux-mm, lkml

quoted
+/* Must be called with inode lock taken exclusive. */
+static inline void shmem_i_mapping_freeze(struct inode *inode, bool freeze)
_mapping usually refers to operations on struct address_space.
It seems that all shmem methods that take inode are just shmem_<operation>,
so shmem_freeze() looks more appropriate.
Done, renamed to shmem_freeze()
quoted
+{
+     if (freeze)
+             SHMEM_I(inode)->flags |= SHMEM_F_MAPPING_FROZEN;
+     else
+             SHMEM_I(inode)->flags &= ~SHMEM_F_MAPPING_FROZEN;
+}
+
 /*
  * If fallocate(FALLOC_FL_KEEP_SIZE) has been used, there may be pages
  * beyond i_size's notion of EOF, which fallocate has committed to reserving:
diff --git a/mm/shmem.c b/mm/shmem.c
index 1d5036dec08a..05c3db840257 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1292,7 +1292,8 @@ static int shmem_setattr(struct mnt_idmap *idmap,
              loff_t newsize = attr->ia_size;

              /* protected by i_rwsem */
-             if ((newsize < oldsize && (info->seals & F_SEAL_SHRINK)) ||
+             if ((info->flags & SHMEM_F_MAPPING_FROZEN) ||
A corner case: if newsize == oldsize this will be a false positive
Added a fix.

Thanks,
Pasha
quoted
+                 (newsize < oldsize && (info->seals & F_SEAL_SHRINK)) ||
                  (newsize > oldsize && (info->seals & F_SEAL_GROW)))
                      return -EPERM;
@@ -3289,6 +3290,10 @@ shmem_write_begin(const struct kiocb *iocb, struct address_space *mapping,
                      return -EPERM;
      }

+     if (unlikely((info->flags & SHMEM_F_MAPPING_FROZEN) &&
+                  pos + len > inode->i_size))
+             return -EPERM;
+
      ret = shmem_get_folio(inode, index, pos + len, &folio, SGP_WRITE);
      if (ret)
              return ret;
@@ -3662,6 +3667,11 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,

      inode_lock(inode);

+     if (info->flags & SHMEM_F_MAPPING_FROZEN) {
+             error = -EPERM;
+             goto out;
+     }
+
      if (mode & FALLOC_FL_PUNCH_HOLE) {
              struct address_space *mapping = file->f_mapping;
              loff_t unmap_start = round_up(offset, PAGE_SIZE);
--
2.52.0.rc1.455.g30608eb744-goog
--
Sincerely yours,
Mike.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help