Skip to content

Commit 39c3c39

Browse files
committed
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
2 parents 5de64d4 + 1f7ea54 commit 39c3c39

File tree

15 files changed

+105
-93
lines changed

15 files changed

+105
-93
lines changed

.mailmap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com>
135135
Frank Zago <fzago@systemfabricworks.com>
136136
Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com>
137137
Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com>
138+
Gao Xiang <xiang@kernel.org> <hsiangkao@linux.alibaba.com>
139+
Gao Xiang <xiang@kernel.org> <hsiangkao@redhat.com>
138140
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
139141
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
140142
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>
371373
Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>
372374
Sebastian Reichel <sre@kernel.org> <sre@debian.org>
373375
Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
376+
Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com>
374377
Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
375378
Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com>
376379
Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com>

fs/ntfs/attrib.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,12 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
592592
a = (ATTR_RECORD*)((u8*)ctx->attr +
593593
le32_to_cpu(ctx->attr->length));
594594
for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
595-
if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
596-
le32_to_cpu(ctx->mrec->bytes_allocated))
595+
u8 *mrec_end = (u8 *)ctx->mrec +
596+
le32_to_cpu(ctx->mrec->bytes_allocated);
597+
u8 *name_end = (u8 *)a + le16_to_cpu(a->name_offset) +
598+
a->name_length * sizeof(ntfschar);
599+
if ((u8*)a < (u8*)ctx->mrec || (u8*)a > mrec_end ||
600+
name_end > mrec_end)
597601
break;
598602
ctx->attr = a;
599603
if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||

fs/ocfs2/ocfs2.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@ enum ocfs2_mount_options
277277
OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
278278
OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
279279
OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
280-
OCFS2_MOUNT_NOCLUSTER = 1 << 18, /* No cluster aware filesystem mount */
281280
};
282281

283282
#define OCFS2_OSB_SOFT_RO 0x0001
@@ -673,8 +672,7 @@ static inline int ocfs2_cluster_o2cb_global_heartbeat(struct ocfs2_super *osb)
673672

674673
static inline int ocfs2_mount_local(struct ocfs2_super *osb)
675674
{
676-
return ((osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT)
677-
|| (osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER));
675+
return (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT);
678676
}
679677

680678
static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super *osb)

fs/ocfs2/slot_map.c

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,14 @@ static int __ocfs2_find_empty_slot(struct ocfs2_slot_info *si,
252252
int i, ret = -ENOSPC;
253253

254254
if ((preferred >= 0) && (preferred < si->si_num_slots)) {
255-
if (!si->si_slots[preferred].sl_valid ||
256-
!si->si_slots[preferred].sl_node_num) {
255+
if (!si->si_slots[preferred].sl_valid) {
257256
ret = preferred;
258257
goto out;
259258
}
260259
}
261260

262261
for(i = 0; i < si->si_num_slots; i++) {
263-
if (!si->si_slots[i].sl_valid ||
264-
!si->si_slots[i].sl_node_num) {
262+
if (!si->si_slots[i].sl_valid) {
265263
ret = i;
266264
break;
267265
}
@@ -456,30 +454,24 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
456454
spin_lock(&osb->osb_lock);
457455
ocfs2_update_slot_info(si);
458456

459-
if (ocfs2_mount_local(osb))
460-
/* use slot 0 directly in local mode */
461-
slot = 0;
462-
else {
463-
/* search for ourselves first and take the slot if it already
464-
* exists. Perhaps we need to mark this in a variable for our
465-
* own journal recovery? Possibly not, though we certainly
466-
* need to warn to the user */
467-
slot = __ocfs2_node_num_to_slot(si, osb->node_num);
457+
/* search for ourselves first and take the slot if it already
458+
* exists. Perhaps we need to mark this in a variable for our
459+
* own journal recovery? Possibly not, though we certainly
460+
* need to warn to the user */
461+
slot = __ocfs2_node_num_to_slot(si, osb->node_num);
462+
if (slot < 0) {
463+
/* if no slot yet, then just take 1st available
464+
* one. */
465+
slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
468466
if (slot < 0) {
469-
/* if no slot yet, then just take 1st available
470-
* one. */
471-
slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
472-
if (slot < 0) {
473-
spin_unlock(&osb->osb_lock);
474-
mlog(ML_ERROR, "no free slots available!\n");
475-
status = -EINVAL;
476-
goto bail;
477-
}
478-
} else
479-
printk(KERN_INFO "ocfs2: Slot %d on device (%s) was "
480-
"already allocated to this node!\n",
481-
slot, osb->dev_str);
482-
}
467+
spin_unlock(&osb->osb_lock);
468+
mlog(ML_ERROR, "no free slots available!\n");
469+
status = -EINVAL;
470+
goto bail;
471+
}
472+
} else
473+
printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already "
474+
"allocated to this node!\n", slot, osb->dev_str);
483475

484476
ocfs2_set_slot(si, slot, osb->node_num);
485477
osb->slot_num = slot;

fs/ocfs2/super.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ enum {
172172
Opt_dir_resv_level,
173173
Opt_journal_async_commit,
174174
Opt_err_cont,
175-
Opt_nocluster,
176175
Opt_err,
177176
};
178177

@@ -206,7 +205,6 @@ static const match_table_t tokens = {
206205
{Opt_dir_resv_level, "dir_resv_level=%u"},
207206
{Opt_journal_async_commit, "journal_async_commit"},
208207
{Opt_err_cont, "errors=continue"},
209-
{Opt_nocluster, "nocluster"},
210208
{Opt_err, NULL}
211209
};
212210

@@ -618,13 +616,6 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
618616
goto out;
619617
}
620618

621-
tmp = OCFS2_MOUNT_NOCLUSTER;
622-
if ((osb->s_mount_opt & tmp) != (parsed_options.mount_opt & tmp)) {
623-
ret = -EINVAL;
624-
mlog(ML_ERROR, "Cannot change nocluster option on remount\n");
625-
goto out;
626-
}
627-
628619
tmp = OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL |
629620
OCFS2_MOUNT_HB_NONE;
630621
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,
865856
}
866857

867858
if (ocfs2_userspace_stack(osb) &&
868-
!(osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER) &&
869859
strncmp(osb->osb_cluster_stack, mopt->cluster_stack,
870860
OCFS2_STACK_LABEL_LEN)) {
871861
mlog(ML_ERROR,
@@ -1137,11 +1127,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
11371127
osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
11381128
"ordered");
11391129

1140-
if ((osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER) &&
1141-
!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT))
1142-
printk(KERN_NOTICE "ocfs2: The shared device (%s) is mounted "
1143-
"without cluster aware mode.\n", osb->dev_str);
1144-
11451130
atomic_set(&osb->vol_state, VOLUME_MOUNTED);
11461131
wake_up(&osb->osb_mount_event);
11471132

@@ -1452,9 +1437,6 @@ static int ocfs2_parse_options(struct super_block *sb,
14521437
case Opt_journal_async_commit:
14531438
mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
14541439
break;
1455-
case Opt_nocluster:
1456-
mopt->mount_opt |= OCFS2_MOUNT_NOCLUSTER;
1457-
break;
14581440
default:
14591441
mlog(ML_ERROR,
14601442
"Unrecognized mount option \"%s\" "
@@ -1566,9 +1548,6 @@ static int ocfs2_show_options(struct seq_file *s, struct dentry *root)
15661548
if (opts & OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT)
15671549
seq_printf(s, ",journal_async_commit");
15681550

1569-
if (opts & OCFS2_MOUNT_NOCLUSTER)
1570-
seq_printf(s, ",nocluster");
1571-
15721551
return 0;
15731552
}
15741553

fs/read_write.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
12631263
count, fl);
12641264
file_end_write(out.file);
12651265
} else {
1266+
if (out.file->f_flags & O_NONBLOCK)
1267+
fl |= SPLICE_F_NONBLOCK;
1268+
12661269
retval = splice_file_to_pipe(in.file, opipe, &pos, count, fl);
12671270
}
12681271

fs/userfaultfd.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,19 @@ static inline void msg_init(struct uffd_msg *msg)
192192
}
193193

194194
static inline struct uffd_msg userfault_msg(unsigned long address,
195+
unsigned long real_address,
195196
unsigned int flags,
196197
unsigned long reason,
197198
unsigned int features)
198199
{
199200
struct uffd_msg msg;
201+
200202
msg_init(&msg);
201203
msg.event = UFFD_EVENT_PAGEFAULT;
202204

203-
if (!(features & UFFD_FEATURE_EXACT_ADDRESS))
204-
address &= PAGE_MASK;
205-
msg.arg.pagefault.address = address;
205+
msg.arg.pagefault.address = (features & UFFD_FEATURE_EXACT_ADDRESS) ?
206+
real_address : address;
207+
206208
/*
207209
* These flags indicate why the userfault occurred:
208210
* - 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)
488490

489491
init_waitqueue_func_entry(&uwq.wq, userfaultfd_wake_function);
490492
uwq.wq.private = current;
491-
uwq.msg = userfault_msg(vmf->real_address, vmf->flags, reason,
492-
ctx->features);
493+
uwq.msg = userfault_msg(vmf->address, vmf->real_address, vmf->flags,
494+
reason, ctx->features);
493495
uwq.ctx = ctx;
494496
uwq.waken = false;
495497

include/linux/mm.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,23 +1130,27 @@ static inline bool is_zone_movable_page(const struct page *page)
11301130
#if defined(CONFIG_ZONE_DEVICE) && defined(CONFIG_FS_DAX)
11311131
DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
11321132

1133-
bool __put_devmap_managed_page(struct page *page);
1134-
static inline bool put_devmap_managed_page(struct page *page)
1133+
bool __put_devmap_managed_page_refs(struct page *page, int refs);
1134+
static inline bool put_devmap_managed_page_refs(struct page *page, int refs)
11351135
{
11361136
if (!static_branch_unlikely(&devmap_managed_key))
11371137
return false;
11381138
if (!is_zone_device_page(page))
11391139
return false;
1140-
return __put_devmap_managed_page(page);
1140+
return __put_devmap_managed_page_refs(page, refs);
11411141
}
1142-
11431142
#else /* CONFIG_ZONE_DEVICE && CONFIG_FS_DAX */
1144-
static inline bool put_devmap_managed_page(struct page *page)
1143+
static inline bool put_devmap_managed_page_refs(struct page *page, int refs)
11451144
{
11461145
return false;
11471146
}
11481147
#endif /* CONFIG_ZONE_DEVICE && CONFIG_FS_DAX */
11491148

1149+
static inline bool put_devmap_managed_page(struct page *page)
1150+
{
1151+
return put_devmap_managed_page_refs(page, 1);
1152+
}
1153+
11501154
/* 127: arbitrary random number, small enough to assemble well */
11511155
#define folio_ref_zero_or_close_to_overflow(folio) \
11521156
((unsigned int) folio_ref_count(folio) + 127u <= 127u)

mm/gup.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ static inline struct folio *try_get_folio(struct page *page, int refs)
8787
* belongs to this folio.
8888
*/
8989
if (unlikely(page_folio(page) != folio)) {
90-
folio_put_refs(folio, refs);
90+
if (!put_devmap_managed_page_refs(&folio->page, refs))
91+
folio_put_refs(folio, refs);
9192
goto retry;
9293
}
9394

@@ -176,7 +177,8 @@ static void gup_put_folio(struct folio *folio, int refs, unsigned int flags)
176177
refs *= GUP_PIN_COUNTING_BIAS;
177178
}
178179

179-
folio_put_refs(folio, refs);
180+
if (!put_devmap_managed_page_refs(&folio->page, refs))
181+
folio_put_refs(folio, refs);
180182
}
181183

182184
/**

mm/hugetlb.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4788,8 +4788,13 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
47884788
* sharing with another vma.
47894789
*/
47904790
;
4791-
} else if (unlikely(is_hugetlb_entry_migration(entry) ||
4792-
is_hugetlb_entry_hwpoisoned(entry))) {
4791+
} else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) {
4792+
bool uffd_wp = huge_pte_uffd_wp(entry);
4793+
4794+
if (!userfaultfd_wp(dst_vma) && uffd_wp)
4795+
entry = huge_pte_clear_uffd_wp(entry);
4796+
set_huge_pte_at(dst, addr, dst_pte, entry);
4797+
} else if (unlikely(is_hugetlb_entry_migration(entry))) {
47934798
swp_entry_t swp_entry = pte_to_swp_entry(entry);
47944799
bool uffd_wp = huge_pte_uffd_wp(entry);
47954800

@@ -5947,6 +5952,7 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
59475952

59485953
page = alloc_huge_page(dst_vma, dst_addr, 0);
59495954
if (IS_ERR(page)) {
5955+
put_page(*pagep);
59505956
ret = -ENOMEM;
59515957
*pagep = NULL;
59525958
goto out;

0 commit comments

Comments
 (0)