Thirteen hotfixes, Eight are cc:stable and the remainder are for post-5.18
issues or are too minor to warrant backporting -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCYuCV7gAKCRDdBJ7gKXxA jrK2AQDeoayQKXJFTcEltKAUTooXM/BoRf+O3ti/xrSWpwta8wEAjaBIJ8e7UlCj g+p6u/pd38f226ldzI5w3bIBSPCbnwU= =3rO0 -----END PGP SIGNATURE----- Merge tag 'mm-hotfixes-stable-2022-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull misc fixes from Andrew Morton: "Thirteen hotfixes. Eight are cc:stable and the remainder are for post-5.18 issues or are too minor to warrant backporting" * tag 'mm-hotfixes-stable-2022-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mailmap: update Gao Xiang's email addresses userfaultfd: provide properly masked address for huge-pages Revert "ocfs2: mount shared volume without ha stack" hugetlb: fix memoryleak in hugetlb_mcopy_atomic_pte fs: sendfile handles O_NONBLOCK of out_fd ntfs: fix use-after-free in ntfs_ucsncmp() secretmem: fix unhandled fault in truncate mm/hugetlb: separate path for hwpoison entry in copy_hugetlb_page_range() mm: fix missing wake-up event for FSDAX pages mm: fix page leak with multiple threads mapping the same page mailmap: update Seth Forshee's email address tmpfs: fix the issue that the mount and remount results are inconsistent. mm: kfence: apply kmemleak_ignore_phys on early allocated pool
This commit is contained in:
Коммит
39c3c396f8
3
.mailmap
3
.mailmap
|
@ -135,6 +135,8 @@ Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com>
|
|||
Frank Zago <fzago@systemfabricworks.com>
|
||||
Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com>
|
||||
Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com>
|
||||
Gao Xiang <xiang@kernel.org> <hsiangkao@linux.alibaba.com>
|
||||
Gao Xiang <xiang@kernel.org> <hsiangkao@redhat.com>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@linux.vnet.ibm.com>
|
||||
|
@ -371,6 +373,7 @@ Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk>
|
|||
Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>
|
||||
Sebastian Reichel <sre@kernel.org> <sre@debian.org>
|
||||
Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
|
||||
Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com>
|
||||
Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
|
||||
Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com>
|
||||
Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com>
|
||||
|
|
|
@ -592,8 +592,12 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
|
|||
a = (ATTR_RECORD*)((u8*)ctx->attr +
|
||||
le32_to_cpu(ctx->attr->length));
|
||||
for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
|
||||
if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
|
||||
le32_to_cpu(ctx->mrec->bytes_allocated))
|
||||
u8 *mrec_end = (u8 *)ctx->mrec +
|
||||
le32_to_cpu(ctx->mrec->bytes_allocated);
|
||||
u8 *name_end = (u8 *)a + le16_to_cpu(a->name_offset) +
|
||||
a->name_length * sizeof(ntfschar);
|
||||
if ((u8*)a < (u8*)ctx->mrec || (u8*)a > mrec_end ||
|
||||
name_end > mrec_end)
|
||||
break;
|
||||
ctx->attr = a;
|
||||
if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||
|
||||
|
|
|
@ -277,7 +277,6 @@ enum ocfs2_mount_options
|
|||
OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
|
||||
OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
|
||||
OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
|
||||
OCFS2_MOUNT_NOCLUSTER = 1 << 18, /* No cluster aware filesystem mount */
|
||||
};
|
||||
|
||||
#define OCFS2_OSB_SOFT_RO 0x0001
|
||||
|
@ -673,8 +672,7 @@ static inline int ocfs2_cluster_o2cb_global_heartbeat(struct ocfs2_super *osb)
|
|||
|
||||
static inline int ocfs2_mount_local(struct ocfs2_super *osb)
|
||||
{
|
||||
return ((osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT)
|
||||
|| (osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER));
|
||||
return (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT);
|
||||
}
|
||||
|
||||
static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super *osb)
|
||||
|
|
|
@ -252,16 +252,14 @@ static int __ocfs2_find_empty_slot(struct ocfs2_slot_info *si,
|
|||
int i, ret = -ENOSPC;
|
||||
|
||||
if ((preferred >= 0) && (preferred < si->si_num_slots)) {
|
||||
if (!si->si_slots[preferred].sl_valid ||
|
||||
!si->si_slots[preferred].sl_node_num) {
|
||||
if (!si->si_slots[preferred].sl_valid) {
|
||||
ret = preferred;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < si->si_num_slots; i++) {
|
||||
if (!si->si_slots[i].sl_valid ||
|
||||
!si->si_slots[i].sl_node_num) {
|
||||
if (!si->si_slots[i].sl_valid) {
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
|
@ -456,30 +454,24 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
|
|||
spin_lock(&osb->osb_lock);
|
||||
ocfs2_update_slot_info(si);
|
||||
|
||||
if (ocfs2_mount_local(osb))
|
||||
/* use slot 0 directly in local mode */
|
||||
slot = 0;
|
||||
else {
|
||||
/* search for ourselves first and take the slot if it already
|
||||
* exists. Perhaps we need to mark this in a variable for our
|
||||
* own journal recovery? Possibly not, though we certainly
|
||||
* need to warn to the user */
|
||||
slot = __ocfs2_node_num_to_slot(si, osb->node_num);
|
||||
/* search for ourselves first and take the slot if it already
|
||||
* exists. Perhaps we need to mark this in a variable for our
|
||||
* own journal recovery? Possibly not, though we certainly
|
||||
* need to warn to the user */
|
||||
slot = __ocfs2_node_num_to_slot(si, osb->node_num);
|
||||
if (slot < 0) {
|
||||
/* if no slot yet, then just take 1st available
|
||||
* one. */
|
||||
slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
|
||||
if (slot < 0) {
|
||||
/* if no slot yet, then just take 1st available
|
||||
* one. */
|
||||
slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
|
||||
if (slot < 0) {
|
||||
spin_unlock(&osb->osb_lock);
|
||||
mlog(ML_ERROR, "no free slots available!\n");
|
||||
status = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
} else
|
||||
printk(KERN_INFO "ocfs2: Slot %d on device (%s) was "
|
||||
"already allocated to this node!\n",
|
||||
slot, osb->dev_str);
|
||||
}
|
||||
spin_unlock(&osb->osb_lock);
|
||||
mlog(ML_ERROR, "no free slots available!\n");
|
||||
status = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
} else
|
||||
printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already "
|
||||
"allocated to this node!\n", slot, osb->dev_str);
|
||||
|
||||
ocfs2_set_slot(si, slot, osb->node_num);
|
||||
osb->slot_num = slot;
|
||||
|
|
|
@ -172,7 +172,6 @@ enum {
|
|||
Opt_dir_resv_level,
|
||||
Opt_journal_async_commit,
|
||||
Opt_err_cont,
|
||||
Opt_nocluster,
|
||||
Opt_err,
|
||||
};
|
||||
|
||||
|
@ -206,7 +205,6 @@ static const match_table_t tokens = {
|
|||
{Opt_dir_resv_level, "dir_resv_level=%u"},
|
||||
{Opt_journal_async_commit, "journal_async_commit"},
|
||||
{Opt_err_cont, "errors=continue"},
|
||||
{Opt_nocluster, "nocluster"},
|
||||
{Opt_err, NULL}
|
||||
};
|
||||
|
||||
|
@ -618,13 +616,6 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
|
|||
goto out;
|
||||
}
|
||||
|
||||
tmp = OCFS2_MOUNT_NOCLUSTER;
|
||||
if ((osb->s_mount_opt & tmp) != (parsed_options.mount_opt & tmp)) {
|
||||
ret = -EINVAL;
|
||||
mlog(ML_ERROR, "Cannot change nocluster option on remount\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL |
|
||||
OCFS2_MOUNT_HB_NONE;
|
||||
if ((osb->s_mount_opt & tmp) != (parsed_options.mount_opt & tmp)) {
|
||||
|
@ -865,7 +856,6 @@ static int ocfs2_verify_userspace_stack(struct ocfs2_super *osb,
|
|||
}
|
||||
|
||||
if (ocfs2_userspace_stack(osb) &&
|
||||
!(osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER) &&
|
||||
strncmp(osb->osb_cluster_stack, mopt->cluster_stack,
|
||||
OCFS2_STACK_LABEL_LEN)) {
|
||||
mlog(ML_ERROR,
|
||||
|
@ -1137,11 +1127,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
|||
osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
|
||||
"ordered");
|
||||
|
||||
if ((osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER) &&
|
||||
!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT))
|
||||
printk(KERN_NOTICE "ocfs2: The shared device (%s) is mounted "
|
||||
"without cluster aware mode.\n", osb->dev_str);
|
||||
|
||||
atomic_set(&osb->vol_state, VOLUME_MOUNTED);
|
||||
wake_up(&osb->osb_mount_event);
|
||||
|
||||
|
@ -1452,9 +1437,6 @@ static int ocfs2_parse_options(struct super_block *sb,
|
|||
case Opt_journal_async_commit:
|
||||
mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
|
||||
break;
|
||||
case Opt_nocluster:
|
||||
mopt->mount_opt |= OCFS2_MOUNT_NOCLUSTER;
|
||||
break;
|
||||
default:
|
||||
mlog(ML_ERROR,
|
||||
"Unrecognized mount option \"%s\" "
|
||||
|
@ -1566,9 +1548,6 @@ static int ocfs2_show_options(struct seq_file *s, struct dentry *root)
|
|||
if (opts & OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT)
|
||||
seq_printf(s, ",journal_async_commit");
|
||||
|
||||
if (opts & OCFS2_MOUNT_NOCLUSTER)
|
||||
seq_printf(s, ",nocluster");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1263,6 +1263,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
|||
count, fl);
|
||||
file_end_write(out.file);
|
||||
} else {
|
||||
if (out.file->f_flags & O_NONBLOCK)
|
||||
fl |= SPLICE_F_NONBLOCK;
|
||||
|
||||
retval = splice_file_to_pipe(in.file, opipe, &pos, count, fl);
|
||||
}
|
||||
|
||||
|
|
|
@ -192,17 +192,19 @@ static inline void msg_init(struct uffd_msg *msg)
|
|||
}
|
||||
|
||||
static inline struct uffd_msg userfault_msg(unsigned long address,
|
||||
unsigned long real_address,
|
||||
unsigned int flags,
|
||||
unsigned long reason,
|
||||
unsigned int features)
|
||||
{
|
||||
struct uffd_msg msg;
|
||||
|
||||
msg_init(&msg);
|
||||
msg.event = UFFD_EVENT_PAGEFAULT;
|
||||
|
||||
if (!(features & UFFD_FEATURE_EXACT_ADDRESS))
|
||||
address &= PAGE_MASK;
|
||||
msg.arg.pagefault.address = address;
|
||||
msg.arg.pagefault.address = (features & UFFD_FEATURE_EXACT_ADDRESS) ?
|
||||
real_address : address;
|
||||
|
||||
/*
|
||||
* These flags indicate why the userfault occurred:
|
||||
* - UFFD_PAGEFAULT_FLAG_WP indicates a write protect fault.
|
||||
|
@ -488,8 +490,8 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
|
|||
|
||||
init_waitqueue_func_entry(&uwq.wq, userfaultfd_wake_function);
|
||||
uwq.wq.private = current;
|
||||
uwq.msg = userfault_msg(vmf->real_address, vmf->flags, reason,
|
||||
ctx->features);
|
||||
uwq.msg = userfault_msg(vmf->address, vmf->real_address, vmf->flags,
|
||||
reason, ctx->features);
|
||||
uwq.ctx = ctx;
|
||||
uwq.waken = false;
|
||||
|
||||
|
|
|
@ -1130,23 +1130,27 @@ static inline bool is_zone_movable_page(const struct page *page)
|
|||
#if defined(CONFIG_ZONE_DEVICE) && defined(CONFIG_FS_DAX)
|
||||
DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
|
||||
|
||||
bool __put_devmap_managed_page(struct page *page);
|
||||
static inline bool put_devmap_managed_page(struct page *page)
|
||||
bool __put_devmap_managed_page_refs(struct page *page, int refs);
|
||||
static inline bool put_devmap_managed_page_refs(struct page *page, int refs)
|
||||
{
|
||||
if (!static_branch_unlikely(&devmap_managed_key))
|
||||
return false;
|
||||
if (!is_zone_device_page(page))
|
||||
return false;
|
||||
return __put_devmap_managed_page(page);
|
||||
return __put_devmap_managed_page_refs(page, refs);
|
||||
}
|
||||
|
||||
#else /* CONFIG_ZONE_DEVICE && CONFIG_FS_DAX */
|
||||
static inline bool put_devmap_managed_page(struct page *page)
|
||||
static inline bool put_devmap_managed_page_refs(struct page *page, int refs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_ZONE_DEVICE && CONFIG_FS_DAX */
|
||||
|
||||
static inline bool put_devmap_managed_page(struct page *page)
|
||||
{
|
||||
return put_devmap_managed_page_refs(page, 1);
|
||||
}
|
||||
|
||||
/* 127: arbitrary random number, small enough to assemble well */
|
||||
#define folio_ref_zero_or_close_to_overflow(folio) \
|
||||
((unsigned int) folio_ref_count(folio) + 127u <= 127u)
|
||||
|
|
6
mm/gup.c
6
mm/gup.c
|
@ -87,7 +87,8 @@ retry:
|
|||
* belongs to this folio.
|
||||
*/
|
||||
if (unlikely(page_folio(page) != folio)) {
|
||||
folio_put_refs(folio, refs);
|
||||
if (!put_devmap_managed_page_refs(&folio->page, refs))
|
||||
folio_put_refs(folio, refs);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
|
@ -176,7 +177,8 @@ static void gup_put_folio(struct folio *folio, int refs, unsigned int flags)
|
|||
refs *= GUP_PIN_COUNTING_BIAS;
|
||||
}
|
||||
|
||||
folio_put_refs(folio, refs);
|
||||
if (!put_devmap_managed_page_refs(&folio->page, refs))
|
||||
folio_put_refs(folio, refs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
10
mm/hugetlb.c
10
mm/hugetlb.c
|
@ -4788,8 +4788,13 @@ again:
|
|||
* sharing with another vma.
|
||||
*/
|
||||
;
|
||||
} else if (unlikely(is_hugetlb_entry_migration(entry) ||
|
||||
is_hugetlb_entry_hwpoisoned(entry))) {
|
||||
} else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) {
|
||||
bool uffd_wp = huge_pte_uffd_wp(entry);
|
||||
|
||||
if (!userfaultfd_wp(dst_vma) && uffd_wp)
|
||||
entry = huge_pte_clear_uffd_wp(entry);
|
||||
set_huge_pte_at(dst, addr, dst_pte, entry);
|
||||
} else if (unlikely(is_hugetlb_entry_migration(entry))) {
|
||||
swp_entry_t swp_entry = pte_to_swp_entry(entry);
|
||||
bool uffd_wp = huge_pte_uffd_wp(entry);
|
||||
|
||||
|
@ -5947,6 +5952,7 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
|
|||
|
||||
page = alloc_huge_page(dst_vma, dst_addr, 0);
|
||||
if (IS_ERR(page)) {
|
||||
put_page(*pagep);
|
||||
ret = -ENOMEM;
|
||||
*pagep = NULL;
|
||||
goto out;
|
||||
|
|
|
@ -603,14 +603,6 @@ static unsigned long kfence_init_pool(void)
|
|||
addr += 2 * PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The pool is live and will never be deallocated from this point on.
|
||||
* Remove the pool object from the kmemleak object tree, as it would
|
||||
* otherwise overlap with allocations returned by kfence_alloc(), which
|
||||
* are registered with kmemleak through the slab post-alloc hook.
|
||||
*/
|
||||
kmemleak_free(__kfence_pool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -623,8 +615,16 @@ static bool __init kfence_init_pool_early(void)
|
|||
|
||||
addr = kfence_init_pool();
|
||||
|
||||
if (!addr)
|
||||
if (!addr) {
|
||||
/*
|
||||
* The pool is live and will never be deallocated from this point on.
|
||||
* Ignore the pool object from the kmemleak phys object tree, as it would
|
||||
* otherwise overlap with allocations returned by kfence_alloc(), which
|
||||
* are registered with kmemleak through the slab post-alloc hook.
|
||||
*/
|
||||
kmemleak_ignore_phys(__pa(__kfence_pool));
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only release unprotected pages, and do not try to go back and change
|
||||
|
|
|
@ -4369,9 +4369,12 @@ vm_fault_t finish_fault(struct vm_fault *vmf)
|
|||
return VM_FAULT_OOM;
|
||||
}
|
||||
|
||||
/* See comment in handle_pte_fault() */
|
||||
/*
|
||||
* See comment in handle_pte_fault() for how this scenario happens, we
|
||||
* need to return NOPAGE so that we drop this page.
|
||||
*/
|
||||
if (pmd_devmap_trans_unstable(vmf->pmd))
|
||||
return 0;
|
||||
return VM_FAULT_NOPAGE;
|
||||
|
||||
vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
|
||||
vmf->address, &vmf->ptl);
|
||||
|
|
|
@ -499,7 +499,7 @@ void free_zone_device_page(struct page *page)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_FS_DAX
|
||||
bool __put_devmap_managed_page(struct page *page)
|
||||
bool __put_devmap_managed_page_refs(struct page *page, int refs)
|
||||
{
|
||||
if (page->pgmap->type != MEMORY_DEVICE_FS_DAX)
|
||||
return false;
|
||||
|
@ -509,9 +509,9 @@ bool __put_devmap_managed_page(struct page *page)
|
|||
* refcount is 1, then the page is free and the refcount is
|
||||
* stable because nobody holds a reference on the page.
|
||||
*/
|
||||
if (page_ref_dec_return(page) == 1)
|
||||
if (page_ref_sub_return(page, refs) == 1)
|
||||
wake_up_var(&page->_refcount);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(__put_devmap_managed_page);
|
||||
EXPORT_SYMBOL(__put_devmap_managed_page_refs);
|
||||
#endif /* CONFIG_FS_DAX */
|
||||
|
|
|
@ -55,22 +55,28 @@ static vm_fault_t secretmem_fault(struct vm_fault *vmf)
|
|||
gfp_t gfp = vmf->gfp_mask;
|
||||
unsigned long addr;
|
||||
struct page *page;
|
||||
vm_fault_t ret;
|
||||
int err;
|
||||
|
||||
if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode))
|
||||
return vmf_error(-EINVAL);
|
||||
|
||||
filemap_invalidate_lock_shared(mapping);
|
||||
|
||||
retry:
|
||||
page = find_lock_page(mapping, offset);
|
||||
if (!page) {
|
||||
page = alloc_page(gfp | __GFP_ZERO);
|
||||
if (!page)
|
||||
return VM_FAULT_OOM;
|
||||
if (!page) {
|
||||
ret = VM_FAULT_OOM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = set_direct_map_invalid_noflush(page);
|
||||
if (err) {
|
||||
put_page(page);
|
||||
return vmf_error(err);
|
||||
ret = vmf_error(err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
__SetPageUptodate(page);
|
||||
|
@ -86,7 +92,8 @@ retry:
|
|||
if (err == -EEXIST)
|
||||
goto retry;
|
||||
|
||||
return vmf_error(err);
|
||||
ret = vmf_error(err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
addr = (unsigned long)page_address(page);
|
||||
|
@ -94,7 +101,11 @@ retry:
|
|||
}
|
||||
|
||||
vmf->page = page;
|
||||
return VM_FAULT_LOCKED;
|
||||
ret = VM_FAULT_LOCKED;
|
||||
|
||||
out:
|
||||
filemap_invalidate_unlock_shared(mapping);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct secretmem_vm_ops = {
|
||||
|
@ -162,12 +173,20 @@ static int secretmem_setattr(struct user_namespace *mnt_userns,
|
|||
struct dentry *dentry, struct iattr *iattr)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
unsigned int ia_valid = iattr->ia_valid;
|
||||
int ret;
|
||||
|
||||
filemap_invalidate_lock(mapping);
|
||||
|
||||
if ((ia_valid & ATTR_SIZE) && inode->i_size)
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
else
|
||||
ret = simple_setattr(mnt_userns, dentry, iattr);
|
||||
|
||||
return simple_setattr(mnt_userns, dentry, iattr);
|
||||
filemap_invalidate_unlock(mapping);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct inode_operations secretmem_iops = {
|
||||
|
|
|
@ -3392,7 +3392,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
|
|||
break;
|
||||
case Opt_nr_blocks:
|
||||
ctx->blocks = memparse(param->string, &rest);
|
||||
if (*rest)
|
||||
if (*rest || ctx->blocks > S64_MAX)
|
||||
goto bad_value;
|
||||
ctx->seen |= SHMEM_SEEN_BLOCKS;
|
||||
break;
|
||||
|
@ -3514,10 +3514,7 @@ static int shmem_reconfigure(struct fs_context *fc)
|
|||
|
||||
raw_spin_lock(&sbinfo->stat_lock);
|
||||
inodes = sbinfo->max_inodes - sbinfo->free_inodes;
|
||||
if (ctx->blocks > S64_MAX) {
|
||||
err = "Number of blocks too large";
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) {
|
||||
if (!sbinfo->max_blocks) {
|
||||
err = "Cannot retroactively limit size";
|
||||
|
|
Загрузка…
Ссылка в новой задаче