* Re: [PATCH v2] mm: fix the memory leak after collapsing the huge page fails
From: zhong jiang @ 2017-05-09 13:54 UTC (permalink / raw)
To: Vlastimil Babka; +Cc: akpm, kirill.shutemov, hannes, mgorman, linux-mm
In-Reply-To: <0bca4592-efa5-deba-0369-19beacfd2a63@suse.cz>
Hi, Vlastimil
I review the code again. it works well for NUMA. because
khugepaged_prealloc_page will put_page when *hpage is true.
the memory leak will still exist in !NUMA. because it ingore
the put_page. is it right? I miss something.
Thanks
zhongjiang
On 2017/5/9 20:41, Vlastimil Babka wrote:
> On 05/09/2017 02:20 PM, zhong jiang wrote:
>> On 2017/5/9 19:34, Vlastimil Babka wrote:
>>> On 05/09/2017 12:55 PM, zhongjiang wrote:
>>>> From: zhong jiang <zhongjiang@huawei.com>
>>>>
>>>> Current, when we prepare a huge page to collapse, due to some
>>>> reasons, it can fail to collapse. At the moment, we should
>>>> release the preallocate huge page.
>>>>
>>>> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
>>> Hmm, scratch that, there's no memory leak. The pointer to new_page is
>>> stored in *hpage, and put_page() is called all the way up in
>>> khugepaged_do_scan().
>> I see. I miss it. but why the new_page need to be release all the way.
> AFAIK to support preallocation and reusal of preallocated page for
> collapse attempt in different pmd. It only works for !NUMA so it's
> likely not worth all the trouble and complicated code, so I wouldn't be
> opposed to simplifying this.
>
>> I do not see the count increment when scan success. it save the memory,
>> only when page fault happen.
> I don't understand what you mean here?
>
>> Thanks
>> zhongjiang
>>>> ---
>>>> mm/khugepaged.c | 4 ++++
>>>> 1 file changed, 4 insertions(+)
>>>>
>>>> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
>>>> index 7cb9c88..586b1f1 100644
>>>> --- a/mm/khugepaged.c
>>>> +++ b/mm/khugepaged.c
>>>> @@ -1082,6 +1082,8 @@ static void collapse_huge_page(struct mm_struct *mm,
>>>> up_write(&mm->mmap_sem);
>>>> out_nolock:
>>>> trace_mm_collapse_huge_page(mm, isolated, result);
>>>> + if (page != NULL && result != SCAN_SUCCEED)
>>>> + put_page(new_page);
>>>> return;
>>>> out:
>>>> mem_cgroup_cancel_charge(new_page, memcg, true);
>>>> @@ -1555,6 +1557,8 @@ static void collapse_shmem(struct mm_struct *mm,
>>>> }
>>>> out:
>>>> VM_BUG_ON(!list_empty(&pagelist));
>>>> + if (page != NULL && result != SCAN_SUCCEED)
>>>> + put_page(new_page);
>>>> /* TODO: tracepoints */
>>>> }
>>>>
>>>>
>>> .
>>>
>>
>
> .
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC 03/10] x86/mm: Make the batched unmap TLB flush API more generic
From: Mel Gorman @ 2017-05-09 14:39 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Dave Hansen, X86 ML, linux-kernel@vger.kernel.org,
Borislav Petkov, Linus Torvalds, Andrew Morton,
linux-mm@kvack.org, Rik van Riel, Nadav Amit, Michal Hocko,
Sasha Levin
In-Reply-To: <CALCETrXO2etzB55ZYk9xy4=8bWQC1+mv877tJHg-tOUpWGk6qw@mail.gmail.com>
On Tue, May 09, 2017 at 06:02:49AM -0700, Andrew Lutomirski wrote:
> On Mon, May 8, 2017 at 8:34 AM, Dave Hansen <dave.hansen@intel.com> wrote:
> > On 05/07/2017 05:38 AM, Andy Lutomirski wrote:
> >> diff --git a/mm/rmap.c b/mm/rmap.c
> >> index f6838015810f..2e568c82f477 100644
> >> --- a/mm/rmap.c
> >> +++ b/mm/rmap.c
> >> @@ -579,25 +579,12 @@ void page_unlock_anon_vma_read(struct anon_vma *anon_vma)
> >> void try_to_unmap_flush(void)
> >> {
> >> struct tlbflush_unmap_batch *tlb_ubc = ¤t->tlb_ubc;
> >> - int cpu;
> >>
> >> if (!tlb_ubc->flush_required)
> >> return;
> >>
> >> - cpu = get_cpu();
> >> -
> >> - if (cpumask_test_cpu(cpu, &tlb_ubc->cpumask)) {
> >> - count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
> >> - local_flush_tlb();
> >> - trace_tlb_flush(TLB_LOCAL_SHOOTDOWN, TLB_FLUSH_ALL);
> >> - }
> >> -
> >> - if (cpumask_any_but(&tlb_ubc->cpumask, cpu) < nr_cpu_ids)
> >> - flush_tlb_others(&tlb_ubc->cpumask, NULL, 0, TLB_FLUSH_ALL);
> >> - cpumask_clear(&tlb_ubc->cpumask);
> >> tlb_ubc->flush_required = false;
> >> tlb_ubc->writable = false;
> >> - put_cpu();
> >> }
> >>
> >> /* Flush iff there are potentially writable TLB entries that can race with IO */
> >> @@ -613,7 +600,7 @@ static void set_tlb_ubc_flush_pending(struct mm_struct *mm, bool writable)
> >> {
> >> struct tlbflush_unmap_batch *tlb_ubc = ¤t->tlb_ubc;
> >>
> >> - cpumask_or(&tlb_ubc->cpumask, &tlb_ubc->cpumask, mm_cpumask(mm));
> >> + arch_tlbbatch_add_mm(&tlb_ubc->arch, mm);
> >> tlb_ubc->flush_required = true;
> >>
> >> /*
> >
> > Looking at this patch in isolation, how can this be safe? It removes
> > TLB flushes from the generic code. Do other patches in the series fix
> > this up?
>
> Hmm? Unless I totally screwed this up, this patch just moves the
> flushes around -- it shouldn't remove any flushes.
I think he's asking when or how arch_tlbbatch_flush gets called because
it doesn't happen in try_to_unmap_flush().
--
Mel Gorman
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH] mm, vmalloc: fix vmalloc users tracking properly
From: Michal Hocko @ 2017-05-09 14:41 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton
Cc: Tobias Klauser, linux-mm, LKML, Michal Hocko
From: Michal Hocko <mhocko@suse.com>
1f5307b1e094 ("mm, vmalloc: properly track vmalloc users") has pulled
asm/pgtable.h include dependency to linux/vmalloc.h and that turned out
to be a bad idea for some architectures. E.g. m68k fails with
In file included from arch/m68k/include/asm/pgtable_mm.h:145:0,
from arch/m68k/include/asm/pgtable.h:4,
from include/linux/vmalloc.h:9,
from arch/m68k/kernel/module.c:9:
arch/m68k/include/asm/mcf_pgtable.h: In function 'nocache_page':
>> arch/m68k/include/asm/mcf_pgtable.h:339:43: error: 'init_mm' undeclared (first use in this function)
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
as spotted by kernel build bot. nios2 fails for other reason
In file included from ./include/asm-generic/io.h:767:0,
from ./arch/nios2/include/asm/io.h:61,
from ./include/linux/io.h:25,
from ./arch/nios2/include/asm/pgtable.h:18,
from ./include/linux/mm.h:70,
from ./include/linux/pid_namespace.h:6,
from ./include/linux/ptrace.h:9,
from ./arch/nios2/include/uapi/asm/elf.h:23,
from ./arch/nios2/include/asm/elf.h:22,
from ./include/linux/elf.h:4,
from ./include/linux/module.h:15,
from init/main.c:16:
./include/linux/vmalloc.h: In function '__vmalloc_node_flags':
./include/linux/vmalloc.h:99:40: error: 'PAGE_KERNEL' undeclared (first use in this function); did you mean 'GFP_KERNEL'?
which is due to the newly added #include <asm/pgtable.h>, which on nios2
includes <linux/io.h> and thus <asm/io.h> and <asm-generic/io.h> which
again includes <linux/vmalloc.h>.
Tweaking that around just turns out a bigger headache than
necessary. This patch reverts 1f5307b1e094 and reimplements the original
fix in a different way. __vmalloc_node_flags can stay static inline
which will cover vmalloc* functions. We only have one external user
(kvmalloc_node) and we can export __vmalloc_node_flags_caller and
provide the caller directly. This is much simpler and it doesn't really
need any games with header files.
Fixes: 1f5307b1e094 ("mm, vmalloc: properly track vmalloc users")
Signed-off-by: Michal Hocko <mhocko@suse.com>
---
Hi Linus and Andrew,
it seems that this one slipped through cracks as well. Kbuild robot has
quickly noticed that my original fix doesn't compile on m68k [1] and
I've provided fix [2] at the time but it seems Andrew has missed it and
sent the wrong one which got merged. Other users have noticed as well [3].
This is a full revert along with the fix. I can split it to a revert
and the new fix if you prefer. Just let me know.
[1] http://lkml.kernel.org/r/201705030806.pzzQRBiN%fengguang.wu@intel.com
[2] http://lkml.kernel.org/r/20170503063750.GC1236@dhcp22.suse.cz
[3] http://lkml.kernel.org/r/20170509085045.7342-1-tklauser@distanz.ch
include/linux/vmalloc.h | 19 +++++++------------
mm/util.c | 3 ++-
mm/vmalloc.c | 18 +++++++++++++++++-
3 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 0328ce003992..4a0fabeb1e92 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -6,7 +6,6 @@
#include <linux/list.h>
#include <linux/llist.h>
#include <asm/page.h> /* pgprot_t */
-#include <asm/pgtable.h> /* PAGE_KERNEL */
#include <linux/rbtree.h>
struct vm_area_struct; /* vma defining user mapping in mm_types.h */
@@ -82,23 +81,19 @@ extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
pgprot_t prot, unsigned long vm_flags, int node,
const void *caller);
#ifndef CONFIG_MMU
-extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags);
+extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
+static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
+{
+ return __vmalloc_node_flags(size, node, flags);
+}
#else
-extern void *__vmalloc_node(unsigned long size, unsigned long align,
- gfp_t gfp_mask, pgprot_t prot,
- int node, const void *caller);
-
/*
* We really want to have this inlined due to caller tracking. This
* function is used by the highlevel vmalloc apis and so we want to track
* their callers and inlining will achieve that.
*/
-static inline void *__vmalloc_node_flags(unsigned long size,
- int node, gfp_t flags)
-{
- return __vmalloc_node(size, 1, flags, PAGE_KERNEL,
- node, __builtin_return_address(0));
-}
+extern void *__vmalloc_node_flags_caller(unsigned long size,
+ int node, gfp_t flags, void* caller);
#endif
extern void vfree(const void *addr);
diff --git a/mm/util.c b/mm/util.c
index 718154debc87..464df3489903 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -382,7 +382,8 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
if (ret || size <= PAGE_SIZE)
return ret;
- return __vmalloc_node_flags(size, node, flags);
+ return __vmalloc_node_flags_caller(size, node, flags,
+ __builtin_return_address(0));
}
EXPORT_SYMBOL(kvmalloc_node);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1dda6d8a200a..4a1de70e68e1 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1649,6 +1649,9 @@ void *vmap(struct page **pages, unsigned int count,
}
EXPORT_SYMBOL(vmap);
+static void *__vmalloc_node(unsigned long size, unsigned long align,
+ gfp_t gfp_mask, pgprot_t prot,
+ int node, const void *caller);
static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
pgprot_t prot, int node)
{
@@ -1791,7 +1794,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
* with mm people.
*
*/
-void *__vmalloc_node(unsigned long size, unsigned long align,
+static void *__vmalloc_node(unsigned long size, unsigned long align,
gfp_t gfp_mask, pgprot_t prot,
int node, const void *caller)
{
@@ -1806,6 +1809,19 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
}
EXPORT_SYMBOL(__vmalloc);
+static inline void *__vmalloc_node_flags(unsigned long size,
+ int node, gfp_t flags)
+{
+ return __vmalloc_node(size, 1, flags, PAGE_KERNEL,
+ node, __builtin_return_address(0));
+}
+
+
+void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void *caller)
+{
+ return __vmalloc_node(size, 1, flags, PAGE_KERNEL, node, caller);
+}
+
/**
* vmalloc - allocate virtually contiguous memory
* @size: allocation size
--
2.11.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* Re: [PATCH v2] mm: fix the memory leak after collapsing the huge page fails
From: zhong jiang @ 2017-05-09 13:56 UTC (permalink / raw)
To: Vlastimil Babka; +Cc: akpm, kirill.shutemov, hannes, mgorman, linux-mm
In-Reply-To: <5c1ad068-1998-b384-c1e2-8cbbbf15506b@suse.cz>
On 2017/5/9 21:46, Vlastimil Babka wrote:
> On 05/09/2017 03:31 PM, zhong jiang wrote:
>> On 2017/5/9 20:41, Vlastimil Babka wrote:
>>> On 05/09/2017 02:20 PM, zhong jiang wrote:
>>>> On 2017/5/9 19:34, Vlastimil Babka wrote:
>>>>> On 05/09/2017 12:55 PM, zhongjiang wrote:
>>>>>> From: zhong jiang <zhongjiang@huawei.com>
>>>>>>
>>>>>> Current, when we prepare a huge page to collapse, due to some
>>>>>> reasons, it can fail to collapse. At the moment, we should
>>>>>> release the preallocate huge page.
>>>>>>
>>>>>> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
>>>>> Hmm, scratch that, there's no memory leak. The pointer to new_page is
>>>>> stored in *hpage, and put_page() is called all the way up in
>>>>> khugepaged_do_scan().
>>>> I see. I miss it. but why the new_page need to be release all the way.
>>> AFAIK to support preallocation and reusal of preallocated page for
>>> collapse attempt in different pmd. It only works for !NUMA so it's
>>> likely not worth all the trouble and complicated code, so I wouldn't be
>>> opposed to simplifying this.
>>>
>>>> I do not see the count increment when scan success. it save the memory,
>>>> only when page fault happen.
>>> I don't understand what you mean here?
>> I mean that whether collapse huge page success or nor, preallocate page will
>> alway be release. by the above description. I seems to true.
> Ah, no. In case of success, collapse_huge_page() does *hpage = NULL; so
> the put_page() won't get to it anymore.
Thanks a lots, it's complicated logical.
Thanks
zhongjiang
>> Thanks
>> zhongjiang
>>>> Thanks
>>>> zhongjiang
>>>>>> ---
>>>>>> mm/khugepaged.c | 4 ++++
>>>>>> 1 file changed, 4 insertions(+)
>>>>>>
>>>>>> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
>>>>>> index 7cb9c88..586b1f1 100644
>>>>>> --- a/mm/khugepaged.c
>>>>>> +++ b/mm/khugepaged.c
>>>>>> @@ -1082,6 +1082,8 @@ static void collapse_huge_page(struct mm_struct *mm,
>>>>>> up_write(&mm->mmap_sem);
>>>>>> out_nolock:
>>>>>> trace_mm_collapse_huge_page(mm, isolated, result);
>>>>>> + if (page != NULL && result != SCAN_SUCCEED)
>>>>>> + put_page(new_page);
>>>>>> return;
>>>>>> out:
>>>>>> mem_cgroup_cancel_charge(new_page, memcg, true);
>>>>>> @@ -1555,6 +1557,8 @@ static void collapse_shmem(struct mm_struct *mm,
>>>>>> }
>>>>>> out:
>>>>>> VM_BUG_ON(!list_empty(&pagelist));
>>>>>> + if (page != NULL && result != SCAN_SUCCEED)
>>>>>> + put_page(new_page);
>>>>>> /* TODO: tracepoints */
>>>>>> }
>>>>>>
>>>>>>
>>>>> .
>>>>>
>>> .
>>>
>>
>
> .
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] mm, vmalloc: fix vmalloc users tracking properly
From: Tobias Klauser @ 2017-05-09 14:51 UTC (permalink / raw)
To: Michal Hocko; +Cc: Linus Torvalds, Andrew Morton, linux-mm, LKML, Michal Hocko
In-Reply-To: <20170509144108.31910-1-mhocko@kernel.org>
On 2017-05-09 at 16:41:08 +0200, Michal Hocko <mhocko@kernel.org> wrote:
> From: Michal Hocko <mhocko@suse.com>
>
> 1f5307b1e094 ("mm, vmalloc: properly track vmalloc users") has pulled
> asm/pgtable.h include dependency to linux/vmalloc.h and that turned out
> to be a bad idea for some architectures. E.g. m68k fails with
> In file included from arch/m68k/include/asm/pgtable_mm.h:145:0,
> from arch/m68k/include/asm/pgtable.h:4,
> from include/linux/vmalloc.h:9,
> from arch/m68k/kernel/module.c:9:
> arch/m68k/include/asm/mcf_pgtable.h: In function 'nocache_page':
> >> arch/m68k/include/asm/mcf_pgtable.h:339:43: error: 'init_mm' undeclared (first use in this function)
> #define pgd_offset_k(address) pgd_offset(&init_mm, address)
>
> as spotted by kernel build bot. nios2 fails for other reason
> In file included from ./include/asm-generic/io.h:767:0,
> from ./arch/nios2/include/asm/io.h:61,
> from ./include/linux/io.h:25,
> from ./arch/nios2/include/asm/pgtable.h:18,
> from ./include/linux/mm.h:70,
> from ./include/linux/pid_namespace.h:6,
> from ./include/linux/ptrace.h:9,
> from ./arch/nios2/include/uapi/asm/elf.h:23,
> from ./arch/nios2/include/asm/elf.h:22,
> from ./include/linux/elf.h:4,
> from ./include/linux/module.h:15,
> from init/main.c:16:
> ./include/linux/vmalloc.h: In function '__vmalloc_node_flags':
> ./include/linux/vmalloc.h:99:40: error: 'PAGE_KERNEL' undeclared (first use in this function); did you mean 'GFP_KERNEL'?
>
> which is due to the newly added #include <asm/pgtable.h>, which on nios2
> includes <linux/io.h> and thus <asm/io.h> and <asm-generic/io.h> which
> again includes <linux/vmalloc.h>.
>
> Tweaking that around just turns out a bigger headache than
> necessary. This patch reverts 1f5307b1e094 and reimplements the original
> fix in a different way. __vmalloc_node_flags can stay static inline
> which will cover vmalloc* functions. We only have one external user
> (kvmalloc_node) and we can export __vmalloc_node_flags_caller and
> provide the caller directly. This is much simpler and it doesn't really
> need any games with header files.
>
> Fixes: 1f5307b1e094 ("mm, vmalloc: properly track vmalloc users")
> Signed-off-by: Michal Hocko <mhocko@suse.com>
Tested-by: Tobias Klauser <tklauser@distanz.ch>
This fixes the build for ARCH=nios2, thanks.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] mm, vmalloc: fix vmalloc users tracking properly
From: kbuild test robot @ 2017-05-09 15:25 UTC (permalink / raw)
To: Michal Hocko
Cc: kbuild-all, Linus Torvalds, Andrew Morton, Tobias Klauser,
linux-mm, LKML, Michal Hocko
In-Reply-To: <20170509144108.31910-1-mhocko@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 29112 bytes --]
Hi Michal,
[auto build test ERROR on mmotm/master]
[also build test ERROR on next-20170509]
[cannot apply to v4.11]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Michal-Hocko/mm-vmalloc-fix-vmalloc-users-tracking-properly/20170509-224536
base: git://git.cmpxchg.org/linux-mmotm.git master
config: c6x-evmc6678_defconfig (attached as .config)
compiler: c6x-elf-gcc (GCC) 6.2.0
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=c6x
All error/warnings (new ones prefixed by >>):
block/bio.c:879:48: sparse: cast truncates bits from constant value (7fffffffffffffff becomes ffffffff)
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/memcontrol.h:24,
from include/linux/swap.h:8,
from block/bio.c:19:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
block/blk-core.c:1145:24: sparse: context imbalance in '__get_request' - unexpected unlock
block/blk-core.c:1284:23: sparse: context imbalance in 'blk_old_get_request' - different lock contexts for basic block
block/blk-core.c:1651:17: sparse: context imbalance in 'blk_queue_bio' - different lock contexts for basic block
block/blk-core.c:3269:17: sparse: context imbalance in 'blk_flush_plug_list' - unexpected unlock
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/highmem.h:9,
from include/linux/pagemap.h:10,
from include/linux/blkdev.h:15,
from include/linux/backing-dev.h:14,
from block/blk-core.c:16:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
block/blk-flush.c:271:9: sparse: context imbalance in 'flush_end_io' - different lock contexts for basic block
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/highmem.h:9,
from include/linux/bio.h:21,
from block/blk-flush.c:69:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
block/blk-ioc.c:110:28: sparse: context imbalance in 'ioc_release_fn' - different lock contexts for basic block
block/blk-ioc.c:191:9: sparse: context imbalance in 'put_io_context_active' - different lock contexts for basic block
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/highmem.h:9,
from include/linux/bio.h:21,
from block/blk-ioc.c:7:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
include/linux/sched.h:1526:16: sparse: incorrect type in argument 1 (different modifiers)
include/linux/sched.h:1526:16: expected struct thread_info *ti
include/linux/sched.h:1526:16: got struct thread_info [pure] *
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/highmem.h:9,
from include/linux/pagemap.h:10,
from include/linux/blkdev.h:15,
from include/linux/backing-dev.h:14,
from block/blk-mq.c:9:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
block/ioctl.c:263:16: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:263:16: got unsigned short *<noident>
block/ioctl.c:263:16: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:263:16: expected void [noderef] <asn:1>*ptr
block/ioctl.c:263:16: got unsigned short *<noident>
block/ioctl.c:268:16: sparse: incorrect type in initializer (different address spaces)
block/ioctl.c:268:16: expected void *__p
block/ioctl.c:268:16: got int [noderef] <asn:1>*<noident>
block/ioctl.c:268:16: sparse: incorrect type in argument 1 (different address spaces)
block/ioctl.c:268:16: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:268:16: got int *<noident>
block/ioctl.c:268:16: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:268:16: expected void [noderef] <asn:1>*ptr
block/ioctl.c:268:16: got int *<noident>
block/ioctl.c:273:16: sparse: incorrect type in initializer (different address spaces)
block/ioctl.c:273:16: expected void *__p
block/ioctl.c:273:16: got unsigned int [noderef] <asn:1>*<noident>
block/ioctl.c:273:16: sparse: incorrect type in argument 1 (different address spaces)
block/ioctl.c:273:16: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:273:16: got unsigned int *<noident>
block/ioctl.c:273:16: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:273:16: expected void [noderef] <asn:1>*ptr
block/ioctl.c:273:16: got unsigned int *<noident>
block/ioctl.c:278:16: sparse: incorrect type in initializer (different address spaces)
block/ioctl.c:278:16: expected void *__p
block/ioctl.c:278:16: got long [noderef] <asn:1>*<noident>
block/ioctl.c:278:16: sparse: incorrect type in argument 1 (different address spaces)
block/ioctl.c:278:16: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:278:16: got long *<noident>
block/ioctl.c:278:16: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:278:16: expected void [noderef] <asn:1>*ptr
block/ioctl.c:278:16: got long *<noident>
block/ioctl.c:283:16: sparse: incorrect type in initializer (different address spaces)
block/ioctl.c:283:16: expected void *__p
block/ioctl.c:283:16: got unsigned long [noderef] <asn:1>*<noident>
block/ioctl.c:283:16: sparse: incorrect type in argument 1 (different address spaces)
block/ioctl.c:283:16: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:283:16: got unsigned long *<noident>
block/ioctl.c:283:16: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:283:16: expected void [noderef] <asn:1>*ptr
block/ioctl.c:283:16: got unsigned long *<noident>
block/ioctl.c:288:16: sparse: incorrect type in initializer (different address spaces)
block/ioctl.c:288:16: expected void *__p
block/ioctl.c:288:16: got unsigned long long [noderef] [usertype] <asn:1>*<noident>
block/ioctl.c:288:16: sparse: incorrect type in argument 1 (different address spaces)
block/ioctl.c:288:16: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:288:16: got unsigned long long *<noident>
block/ioctl.c:288:16: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:288:16: expected void [noderef] <asn:1>*ptr
block/ioctl.c:288:16: got unsigned long long *<noident>
block/ioctl.c:445:13: sparse: incorrect type in initializer (different address spaces)
block/ioctl.c:445:13: expected void const *__p
block/ioctl.c:445:13: got int [noderef] <asn:1>*<noident>
block/ioctl.c:445:13: sparse: incorrect type in argument 1 (different address spaces)
block/ioctl.c:445:13: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:445:13: got int *<noident>
block/ioctl.c:445:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:445:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:445:13: got int *<noident>
block/ioctl.c:445:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:445:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:445:13: got int *<noident>
block/ioctl.c:445:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:445:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:445:13: got int *<noident>
block/ioctl.c:445:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:445:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:445:13: got int *<noident>
include/linux/uaccess.h:166:18: sparse: incorrect type in argument 1 (different modifiers)
include/linux/uaccess.h:166:18: expected void *<noident>
include/linux/uaccess.h:166:18: got void const *from
block/ioctl.c:487:13: sparse: incorrect type in initializer (different address spaces)
block/ioctl.c:487:13: expected void const *__p
block/ioctl.c:487:13: got int [noderef] <asn:1>*argp
block/ioctl.c:487:13: sparse: incorrect type in argument 1 (different address spaces)
block/ioctl.c:487:13: expected void const volatile [noderef] <asn:1>*<noident>
block/ioctl.c:487:13: got int *<noident>
block/ioctl.c:487:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:487:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:487:13: got int *<noident>
block/ioctl.c:487:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:487:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:487:13: got int *<noident>
block/ioctl.c:487:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:487:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:487:13: got int *<noident>
block/ioctl.c:487:13: sparse: incorrect type in argument 2 (different address spaces)
block/ioctl.c:487:13: expected void const [noderef] <asn:1>*ptr
block/ioctl.c:487:13: got int *<noident>
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/highmem.h:9,
from include/linux/pagemap.h:10,
from include/linux/blkdev.h:15,
from block/ioctl.c:2:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
block/genhd.c:1462:10: sparse: bad integer constant expression
block/genhd.c:1463:10: sparse: bad integer constant expression
block/genhd.c:1467:10: sparse: bad integer constant expression
block/genhd.c:1468:10: sparse: bad integer constant expression
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/highmem.h:9,
from include/linux/pagemap.h:10,
from include/linux/blkdev.h:15,
from block/genhd.c:10:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
block/scsi_ioctl.c:103:25: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:103:25: got int *<noident>
block/scsi_ioctl.c:103:25: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:103:25: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:103:25: got int *<noident>
block/scsi_ioctl.c:103:25: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:103:25: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:103:25: got int *<noident>
block/scsi_ioctl.c:103:25: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:103:25: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:103:25: got int *<noident>
block/scsi_ioctl.c:121:16: sparse: incorrect type in initializer (different address spaces)
block/scsi_ioctl.c:121:16: expected void *__p
block/scsi_ioctl.c:121:16: got int [noderef] <asn:1>*p
block/scsi_ioctl.c:121:16: sparse: incorrect type in argument 1 (different address spaces)
block/scsi_ioctl.c:121:16: expected void const volatile [noderef] <asn:1>*<noident>
block/scsi_ioctl.c:121:16: got int *<noident>
block/scsi_ioctl.c:121:16: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:121:16: expected void [noderef] <asn:1>*ptr
block/scsi_ioctl.c:121:16: got int *<noident>
include/linux/uaccess.h:166:18: sparse: incorrect type in argument 1 (different modifiers)
include/linux/uaccess.h:166:18: expected void *<noident>
include/linux/uaccess.h:166:18: got void const *from
block/scsi_ioctl.c:435:13: sparse: incorrect type in initializer (different address spaces)
block/scsi_ioctl.c:435:13: expected void const *__p
block/scsi_ioctl.c:435:13: got unsigned int [noderef] <asn:1>*<noident>
block/scsi_ioctl.c:435:13: sparse: incorrect type in argument 1 (different address spaces)
block/scsi_ioctl.c:435:13: expected void const volatile [noderef] <asn:1>*<noident>
block/scsi_ioctl.c:435:13: got unsigned int *<noident>
block/scsi_ioctl.c:435:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:435:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:435:13: got unsigned int *<noident>
block/scsi_ioctl.c:435:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:435:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:435:13: got unsigned int *<noident>
block/scsi_ioctl.c:435:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:435:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:435:13: got unsigned int *<noident>
block/scsi_ioctl.c:435:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:435:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:435:13: got unsigned int *<noident>
block/scsi_ioctl.c:437:13: sparse: incorrect type in initializer (different address spaces)
block/scsi_ioctl.c:437:13: expected void const *__p
block/scsi_ioctl.c:437:13: got unsigned int [noderef] <asn:1>*<noident>
block/scsi_ioctl.c:437:13: sparse: incorrect type in argument 1 (different address spaces)
block/scsi_ioctl.c:437:13: expected void const volatile [noderef] <asn:1>*<noident>
block/scsi_ioctl.c:437:13: got unsigned int *<noident>
block/scsi_ioctl.c:437:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:437:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:437:13: got unsigned int *<noident>
block/scsi_ioctl.c:437:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:437:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:437:13: got unsigned int *<noident>
block/scsi_ioctl.c:437:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:437:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:437:13: got unsigned int *<noident>
block/scsi_ioctl.c:437:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:437:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:437:13: got unsigned int *<noident>
block/scsi_ioctl.c:441:13: sparse: incorrect type in initializer (different address spaces)
block/scsi_ioctl.c:441:13: expected void const *__p
block/scsi_ioctl.c:441:13: got unsigned char [noderef] <asn:1>*<noident>
block/scsi_ioctl.c:441:13: sparse: incorrect type in argument 1 (different address spaces)
block/scsi_ioctl.c:441:13: expected void const volatile [noderef] <asn:1>*<noident>
block/scsi_ioctl.c:441:13: got unsigned char *<noident>
block/scsi_ioctl.c:441:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:441:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:441:13: got unsigned char *<noident>
block/scsi_ioctl.c:441:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:441:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:441:13: got unsigned char *<noident>
block/scsi_ioctl.c:441:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:441:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:441:13: got unsigned char *<noident>
block/scsi_ioctl.c:441:13: sparse: incorrect type in argument 2 (different address spaces)
block/scsi_ioctl.c:441:13: expected void const [noderef] <asn:1>*ptr
block/scsi_ioctl.c:441:13: got unsigned char *<noident>
include/linux/uaccess.h:166:18: sparse: incorrect type in argument 1 (different modifiers)
include/linux/uaccess.h:166:18: expected void *<noident>
include/linux/uaccess.h:166:18: got void const *from
include/linux/uaccess.h:166:18: sparse: incorrect type in argument 1 (different modifiers)
include/linux/uaccess.h:166:18: expected void *<noident>
include/linux/uaccess.h:166:18: got void const *from
include/linux/uaccess.h:166:18: sparse: incorrect type in argument 1 (different modifiers)
include/linux/uaccess.h:166:18: expected void *<noident>
include/linux/uaccess.h:166:18: got void const *from
include/linux/uaccess.h:166:18: sparse: incorrect type in argument 1 (different modifiers)
include/linux/uaccess.h:166:18: expected void *<noident>
include/linux/uaccess.h:166:18: got void const *from
In file included from include/asm-generic/io.h:767:0,
from ./arch/c6x/include/generated/asm/io.h:1,
from include/linux/io.h:25,
from include/linux/irq.h:24,
from include/asm-generic/hardirq.h:12,
from arch/c6x/include/asm/hardirq.h:18,
from include/linux/hardirq.h:8,
from include/linux/highmem.h:9,
from include/linux/pagemap.h:10,
from include/linux/blkdev.h:15,
from block/scsi_ioctl.c:23:
>> include/linux/vmalloc.h:85:21: error: conflicting types for '__vmalloc_node_flags_caller'
static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h:84:14: note: previous declaration of '__vmalloc_node_flags_caller' was here
extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmalloc.h: In function '__vmalloc_node_flags_caller':
>> include/linux/vmalloc.h:87:9: error: implicit declaration of function '__vmalloc_node_flags' [-Werror=implicit-function-declaration]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~
>> include/linux/vmalloc.h:87:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return __vmalloc_node_flags(size, node, flags);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
..
vim +/__vmalloc_node_flags_caller +85 include/linux/vmalloc.h
78 extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
79 extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
80 unsigned long start, unsigned long end, gfp_t gfp_mask,
81 pgprot_t prot, unsigned long vm_flags, int node,
82 const void *caller);
83 #ifndef CONFIG_MMU
> 84 extern void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags);
> 85 static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void* caller)
86 {
> 87 return __vmalloc_node_flags(size, node, flags);
88 }
89 #else
90 /*
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 5454 bytes --]
^ permalink raw reply
* Re: [RFC xfstests PATCH] xfstests: add a writeback error handling test
From: Jeff Layton @ 2017-05-09 15:33 UTC (permalink / raw)
To: Christoph Hellwig
Cc: fstests, linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4,
linux-cifs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, osd-dev, linux-nilfs,
linux-block, dhowells, akpm, ross.zwisler, mawilcox, jack, viro,
corbet, neilb, clm, tytso, axboe
In-Reply-To: <20170424150019.GA3288@infradead.org>
On Mon, 2017-04-24 at 08:00 -0700, Christoph Hellwig wrote:
> On Mon, Apr 24, 2017 at 09:45:51AM -0400, Jeff Layton wrote:
> > With the patch series above, ext4 now passes. xfs and btrfs end up in
> > r/o mode after the test. xfs returns -EIO at that point though, and
> > btrfs returns -EROFS. What behavior we actually want there, I'm not
> > certain. We might be able to mitigate that by putting the journals on a
> > separate device?
>
> This looks like XFS shut down because of a permanent write error from
> dm-error. Which seems like the expected behavior.
Oops, didn't see this message earlier...
Yeah, that's entirely reasonable when there is a write error to the
journal. The latest version of this uses $SCRATCH_LOGDEV to put the
journal on a different device, and with that I get the expected behavior
from xfs.
Thanks,
--
Jeff Layton <jlayton@redhat.com>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] mm, vmalloc: fix vmalloc users tracking properly
From: Michal Hocko @ 2017-05-09 15:37 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton; +Cc: Tobias Klauser, linux-mm, LKML
In-Reply-To: <20170509144108.31910-1-mhocko@kernel.org>
Sigh. I've apparently managed to screw up again. This should address the
nommu breakage reported by 0-day.
---
^ permalink raw reply
* Re: [PATCH v2] mm: fix the memory leak after collapsing the huge page fails (fwd)
From: Julia Lawall @ 2017-05-09 15:43 UTC (permalink / raw)
To: zhongjiang; +Cc: akpm, vbabka, kirill.shutemov, hannes, mgorman, linux-mm
Hello,
I don't know if there is a bug here, but it could e worth checking on. If
the loop on line 1481 is executed, page will not be NULL at the out label
on line 1560. Instead it will have a dummy value. Perhaps the value of
result keeps the if at the out label from being taken.
julia
---------- Forwarded message ----------
Date: Tue, 9 May 2017 23:27:43 +0800
From: kbuild test robot <fengguang.wu@intel.com>
To: kbuild@01.org
Cc: Julia Lawall <julia.lawall@lip6.fr>
Subject: Re: [PATCH v2] mm: fix the memory leak after collapsing the huge page
fails
Hi zhong,
[auto build test WARNING on mmotm/master]
[also build test WARNING on v4.11 next-20170509]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/zhongjiang/mm-fix-the-memory-leak-after-collapsing-the-huge-page-fails/20170509-193011
base: git://git.cmpxchg.org/linux-mmotm.git master
:::::: branch date: 4 hours ago
:::::: commit date: 4 hours ago
>> mm/khugepaged.c:1560:5-9: ERROR: invalid reference to the index variable of the iterator on line 1481
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout a5318ea654d5b764d6e06c6cfbfc21e44ce56e2b
vim +1560 mm/khugepaged.c
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1475 struct zone *zone = page_zone(new_page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1476
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1477 /*
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1478 * Replacing old pages with new one has succeed, now we need to
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1479 * copy the content and free old pages.
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1480 */
f3f0e1d2 Kirill A. Shutemov 2016-07-26 @1481 list_for_each_entry_safe(page, tmp, &pagelist, lru) {
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1482 copy_highpage(new_page + (page->index % HPAGE_PMD_NR),
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1483 page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1484 list_del(&page->lru);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1485 unlock_page(page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1486 page_ref_unfreeze(page, 1);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1487 page->mapping = NULL;
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1488 ClearPageActive(page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1489 ClearPageUnevictable(page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1490 put_page(page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1491 }
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1492
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1493 local_irq_save(flags);
11fb9989 Mel Gorman 2016-07-28 1494 __inc_node_page_state(new_page, NR_SHMEM_THPS);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1495 if (nr_none) {
11fb9989 Mel Gorman 2016-07-28 1496 __mod_node_page_state(zone->zone_pgdat, NR_FILE_PAGES, nr_none);
11fb9989 Mel Gorman 2016-07-28 1497 __mod_node_page_state(zone->zone_pgdat, NR_SHMEM, nr_none);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1498 }
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1499 local_irq_restore(flags);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1500
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1501 /*
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1502 * Remove pte page tables, so we can re-faulti
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1503 * the page as huge.
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1504 */
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1505 retract_page_tables(mapping, start);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1506
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1507 /* Everything is ready, let's unfreeze the new_page */
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1508 set_page_dirty(new_page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1509 SetPageUptodate(new_page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1510 page_ref_unfreeze(new_page, HPAGE_PMD_NR);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1511 mem_cgroup_commit_charge(new_page, memcg, false, true);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1512 lru_cache_add_anon(new_page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1513 unlock_page(new_page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1514
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1515 *hpage = NULL;
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1516 } else {
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1517 /* Something went wrong: rollback changes to the radix-tree */
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1518 shmem_uncharge(mapping->host, nr_none);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1519 spin_lock_irq(&mapping->tree_lock);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1520 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter,
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1521 start) {
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1522 if (iter.index >= end)
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1523 break;
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1524 page = list_first_entry_or_null(&pagelist,
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1525 struct page, lru);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1526 if (!page || iter.index < page->index) {
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1527 if (!nr_none)
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1528 break;
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1529 nr_none--;
59749e6c Johannes Weiner 2016-12-12 1530 /* Put holes back where they were */
59749e6c Johannes Weiner 2016-12-12 1531 radix_tree_delete(&mapping->page_tree,
59749e6c Johannes Weiner 2016-12-12 1532 iter.index);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1533 continue;
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1534 }
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1535
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1536 VM_BUG_ON_PAGE(page->index != iter.index, page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1537
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1538 /* Unfreeze the page. */
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1539 list_del(&page->lru);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1540 page_ref_unfreeze(page, 2);
6d75f366 Johannes Weiner 2016-12-12 1541 radix_tree_replace_slot(&mapping->page_tree,
6d75f366 Johannes Weiner 2016-12-12 1542 slot, page);
148deab2 Matthew Wilcox 2016-12-14 1543 slot = radix_tree_iter_resume(slot, &iter);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1544 spin_unlock_irq(&mapping->tree_lock);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1545 putback_lru_page(page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1546 unlock_page(page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1547 spin_lock_irq(&mapping->tree_lock);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1548 }
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1549 VM_BUG_ON(nr_none);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1550 spin_unlock_irq(&mapping->tree_lock);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1551
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1552 /* Unfreeze new_page, caller would take care about freeing it */
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1553 page_ref_unfreeze(new_page, 1);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1554 mem_cgroup_cancel_charge(new_page, memcg, true);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1555 unlock_page(new_page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1556 new_page->mapping = NULL;
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1557 }
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1558 out:
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1559 VM_BUG_ON(!list_empty(&pagelist));
a5318ea6 zhong jiang 2017-05-09 @1560 if (page != NULL && result != SCAN_SUCCEED)
a5318ea6 zhong jiang 2017-05-09 1561 put_page(new_page);
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1562 /* TODO: tracepoints */
f3f0e1d2 Kirill A. Shutemov 2016-07-26 1563 }
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RESENT PATCH] x86/mem: fix the offset overflow when read/write mem
From: Rik van Riel @ 2017-05-09 15:46 UTC (permalink / raw)
To: zhong jiang
Cc: David Rientjes, Bjorn Helgaas, Yoshinori Sato, Rich Felker,
Andrew Morton, arnd, hannes, kirill, mgorman, hughd, linux-mm,
linux-kernel, Xishi Qiu
In-Reply-To: <590A91DF.8030004@huawei.com>
[-- Attachment #1: Type: text/plain, Size: 1245 bytes --]
On Thu, 2017-05-04 at 10:28 +0800, zhong jiang wrote:
> On 2017/5/4 2:46, Rik van Riel wrote:
> > However, it is not as easy as simply checking the
> > end against __pa(high_memory). Some systems have
> > non-contiguous physical memory ranges, with gaps
> > of invalid addresses in-between.
>
> The invalid physical address means that it is used as
> io mapped. not in system ram region. /dev/mem is not
> access to them , is it right?
Not necessarily. Some systems simply have large
gaps in physical memory access. Their memory map
may look like this:
|MMMMMM|IO|MMMM|..................|MMMMMMMM|
Where M is memory, IO is IO space, and the
dots are simply a gap in physical address
space with no valid accesses at all.
> > At that point, is the complexity so much that it no
> > longer makes sense to try to protect against root
> > crashing the system?
> >
>
> your suggestion is to let the issue along without any protection.
> just root user know what they are doing.
Well, root already has other ways to crash the system.
Implementing validation on /dev/mem may make sense if
it can be done in a simple way, but may not be worth
it if it becomes too complex.
--
All rights reversed
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply
* [PATCH v4 00/27] fs: introduce new writeback error reporting and convert existing API as a wrapper around it
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
v4: several more cleanup patches
documentation and kerneldoc comment updates
fix bugs in gfs2 patches
make sync_file_range use same error reporting semantics
bugfixes in buffer.c
convert nfs to new scheme (maybe bogus, can be dropped)
v3: wb_err_t -> errseq_t conversion
clean up places that re-set errors after calling filemap_* functions
v2: introduce wb_err_t, use atomics
Apologies for the wide posting here, but this touches a lot of areas.
This is v3 of the patchset to improve how we're tracking and reporting
errors that occur during pagecache writeback.
There are several situations where the kernel can "lose" errors that
occur during writeback, such that fsync will return success even
though it failed to write back some data previously. The basic idea
here is to have the kernel be more deliberate about the point from
which errors are checked to ensure that that doesn't happen.
Additionally, this set changes the behavior of fsync in Linux to report
writeback errors on all fds instead of just the first one. This allows
writers to reliably tell whether their data made it to the backing
device without having to coordinate fsync calls with other writers.
This set sprawls over a large swath of kernel code. I think the first 12
patches in the series are pretty straightforward and are more or less
ready for merge.
The real changes start with patch 13. That adds support for errseq_t,
builds a new writeback error tracking API on top of that, and converts
the existing code to use it. After that, there are a few cleanup patches
to eliminate some unneeded error re-setting, etc.
Finally, there are several patches that attempt to codify the semantics
in the documentation and make it clear what filesystems should do when
there are writeback errors.
Unfortunately, testing this across so many filesystems is rather
difficult. I have a xfstest for block-based filesystems that uses
dm_error that I'll repost soon. It works well with xfs and ext4 and
those now pass after this patchset. btrfs still fails however, so it
may need some more work to get this right. I also don't have a good
general method for testing this on network filesystems (yet!).
I'd like to see better testing here and am open to suggestions. I will
note that the POSIX fsync spec says this:
"It is reasonable to assert that the key aspects of fsync() are
unreasonable to test in a test suite. That does not make the function
any less valuable, just more difficult to test. [...] It would also not
be unreasonable to omit testing for fsync(), allowing it to be treated
as a quality-of-implementation issue."
Of course, they're talking about a POSIX conformance test, but I
think the same point applies here.
At this point, I'd like to start getting some of the preliminary patches
merged (the first 12 or so). Most of those aren't terribly controversial
and seem like reasonable bugfixes and cleanups. If any subsystem
maintainers want to pick those up, then please do.
After that, I'd like to get the larger changes into linux-next with an
aim for merge in v4.13 or v4.14 (depending on how testing goes).
Feedback is of course welcome.
Jeff Layton (27):
fs: remove unneeded forward definition of mm_struct from fs.h
mm: drop "wait" parameter from write_one_page
mm: fix mapping_set_error call in me_pagecache_dirty
buffer: use mapping_set_error instead of setting the flag
btrfs: btrfs_wait_tree_block_writeback can be void return
fs: check for writeback errors after syncing out buffers in
generic_file_fsync
orangefs: don't call filemap_write_and_wait from fsync
dax: set errors in mapping when writeback fails
nilfs2: set the mapping error when calling SetPageError on writeback
9p: set mapping error when writeback fails in launder_page
fuse: set mapping error in writepage_locked when it fails
cifs: set mapping error when page writeback fails in writepage or
launder_pages
lib: add errseq_t type and infrastructure for handling it
fs: new infrastructure for writeback error handling and reporting
fs: retrofit old error reporting API onto new infrastructure
fs: adapt sync_file_range to new reporting infrastructure
mm: remove AS_EIO and AS_ENOSPC flags
mm: don't TestClearPageError in __filemap_fdatawait_range
buffer: set errors in mapping at the time that the error occurs
cifs: cleanup writeback handling errors and comments
mm: clean up error handling in write_one_page
jbd2: don't reset error in journal_finish_inode_data_buffers
gfs2: clean up some filemap_* calls
nfs: convert to new errseq_t based error tracking for writeback errors
Documentation: flesh out the section in vfs.txt on storing and
reporting writeback errors
mm: flesh out comments over mapping_set_error
mm: clean up comments in me_pagecache_dirty
Documentation/filesystems/vfs.txt | 49 +++++++++-
drivers/dax/dax.c | 1 +
fs/9p/vfs_addr.c | 5 +-
fs/block_dev.c | 1 +
fs/btrfs/disk-io.c | 6 +-
fs/btrfs/disk-io.h | 2 +-
fs/btrfs/file.c | 10 +-
fs/btrfs/tree-log.c | 9 +-
fs/buffer.c | 19 ++--
fs/cifs/cifsfs.c | 4 +-
fs/cifs/file.c | 19 ++--
fs/cifs/inode.c | 22 ++---
fs/dax.c | 4 +-
fs/exofs/dir.c | 2 +-
fs/ext2/dir.c | 2 +-
fs/ext2/file.c | 2 +-
fs/f2fs/file.c | 3 +
fs/f2fs/node.c | 6 +-
fs/file_table.c | 1 +
fs/fuse/file.c | 8 +-
fs/gfs2/glops.c | 17 +---
fs/gfs2/lops.c | 6 +-
fs/gfs2/super.c | 6 +-
fs/jbd2/commit.c | 13 +--
fs/jfs/jfs_metapage.c | 4 +-
fs/libfs.c | 3 +
fs/minix/dir.c | 2 +-
fs/nfs/file.c | 19 ++--
fs/nfs/inode.c | 5 +-
fs/nfs/write.c | 2 +-
fs/nilfs2/segment.c | 1 +
fs/open.c | 3 +
fs/orangefs/file.c | 5 +-
fs/sync.c | 13 ++-
fs/sysv/dir.c | 2 +-
fs/ufs/dir.c | 2 +-
include/linux/buffer_head.h | 1 +
include/linux/errseq.h | 19 ++++
include/linux/fs.h | 45 +++++++--
include/linux/mm.h | 2 +-
include/linux/nfs_fs.h | 3 +-
include/linux/pagemap.h | 32 +++---
lib/Makefile | 2 +-
lib/errseq.c | 199 ++++++++++++++++++++++++++++++++++++++
mm/filemap.c | 103 ++++++++++++--------
mm/memory-failure.c | 37 ++-----
mm/page-writeback.c | 23 +++--
47 files changed, 512 insertions(+), 232 deletions(-)
create mode 100644 include/linux/errseq.h
create mode 100644 lib/errseq.c
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH v4 01/27] fs: remove unneeded forward definition of mm_struct from fs.h
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
include/linux/fs.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7251f7bb45e8..38adefd8e2a0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1252,8 +1252,6 @@ extern void f_delown(struct file *filp);
extern pid_t f_getown(struct file *filp);
extern int send_sigurg(struct fown_struct *fown);
-struct mm_struct;
-
/*
* Umount options
*/
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 02/27] mm: drop "wait" parameter from write_one_page
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
The callers all set it to 1.
Also, make it clear that this function will not set any sort of AS_*
error, and that the caller must do so if necessary. No existing caller
uses this on normal files, so none of them need it.
Also, add __must_check here since, in general, the callers need to
handle an error here in some fashion.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Matthew Wilcox <mawilcox@microsoft.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fs/exofs/dir.c | 2 +-
fs/ext2/dir.c | 2 +-
fs/jfs/jfs_metapage.c | 4 ++--
fs/minix/dir.c | 2 +-
fs/sysv/dir.c | 2 +-
fs/ufs/dir.c | 2 +-
include/linux/mm.h | 2 +-
mm/page-writeback.c | 14 +++++++-------
8 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
index 42f9a0a0c4ca..e163ed980c20 100644
--- a/fs/exofs/dir.c
+++ b/fs/exofs/dir.c
@@ -72,7 +72,7 @@ static int exofs_commit_chunk(struct page *page, loff_t pos, unsigned len)
set_page_dirty(page);
if (IS_DIRSYNC(dir))
- err = write_one_page(page, 1);
+ err = write_one_page(page);
else
unlock_page(page);
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index d9650c9508e4..e2709695b177 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -100,7 +100,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
}
if (IS_DIRSYNC(dir)) {
- err = write_one_page(page, 1);
+ err = write_one_page(page);
if (!err)
err = sync_inode_metadata(dir, 1);
} else {
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 489aaa1403e5..744fa3c079e6 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -711,7 +711,7 @@ void force_metapage(struct metapage *mp)
get_page(page);
lock_page(page);
set_page_dirty(page);
- write_one_page(page, 1);
+ write_one_page(page);
clear_bit(META_forcewrite, &mp->flag);
put_page(page);
}
@@ -756,7 +756,7 @@ void release_metapage(struct metapage * mp)
set_page_dirty(page);
if (test_bit(META_sync, &mp->flag)) {
clear_bit(META_sync, &mp->flag);
- write_one_page(page, 1);
+ write_one_page(page);
lock_page(page); /* write_one_page unlocks the page */
}
} else if (mp->lsn) /* discard_metapage doesn't remove it */
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 7edc9b395700..baa9721f1299 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -57,7 +57,7 @@ static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
mark_inode_dirty(dir);
}
if (IS_DIRSYNC(dir))
- err = write_one_page(page, 1);
+ err = write_one_page(page);
else
unlock_page(page);
return err;
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 5bdae85ceef7..f5191cb2c947 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -45,7 +45,7 @@ static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
mark_inode_dirty(dir);
}
if (IS_DIRSYNC(dir))
- err = write_one_page(page, 1);
+ err = write_one_page(page);
else
unlock_page(page);
return err;
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index de01b8f2aa78..48609f1d9580 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -53,7 +53,7 @@ static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
mark_inode_dirty(dir);
}
if (IS_DIRSYNC(dir))
- err = write_one_page(page, 1);
+ err = write_one_page(page);
else
unlock_page(page);
return err;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 00a8fa7e366a..403f78afee20 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2187,7 +2187,7 @@ extern void filemap_map_pages(struct vm_fault *vmf,
extern int filemap_page_mkwrite(struct vm_fault *vmf);
/* mm/page-writeback.c */
-int write_one_page(struct page *page, int wait);
+int __must_check write_one_page(struct page *page);
void task_dirty_inc(struct task_struct *tsk);
/* readahead.c */
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index d8ac2a7fb9e7..de0dbf12e2c1 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2361,15 +2361,16 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
}
/**
- * write_one_page - write out a single page and optionally wait on I/O
+ * write_one_page - write out a single page and wait on I/O
* @page: the page to write
- * @wait: if true, wait on writeout
*
* The page must be locked by the caller and will be unlocked upon return.
*
- * write_one_page() returns a negative error code if I/O failed.
+ * write_one_page() returns a negative error code if I/O failed. Note that
+ * the address_space is not marked for error. The caller must do this if
+ * needed.
*/
-int write_one_page(struct page *page, int wait)
+int write_one_page(struct page *page)
{
struct address_space *mapping = page->mapping;
int ret = 0;
@@ -2380,13 +2381,12 @@ int write_one_page(struct page *page, int wait)
BUG_ON(!PageLocked(page));
- if (wait)
- wait_on_page_writeback(page);
+ wait_on_page_writeback(page);
if (clear_page_dirty_for_io(page)) {
get_page(page);
ret = mapping->a_ops->writepage(page, &wbc);
- if (ret == 0 && wait) {
+ if (ret == 0) {
wait_on_page_writeback(page);
if (PageError(page))
ret = -EIO;
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 03/27] mm: fix mapping_set_error call in me_pagecache_dirty
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
The error code should be negative. Since this ends up in the default
case anyway, this is harmless, but it's less confusing to negate it.
Also, later patches will require a negative error code here.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Matthew Wilcox <mawilcox@microsoft.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
mm/memory-failure.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 27f7210e7fab..4b56e53e5378 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -674,7 +674,7 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
* the first EIO, but we're not worse than other parts
* of the kernel.
*/
- mapping_set_error(mapping, EIO);
+ mapping_set_error(mapping, -EIO);
}
return me_pagecache_clean(p, pfn);
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 04/27] buffer: use mapping_set_error instead of setting the flag
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Matthew Wilcox <mawilcox@microsoft.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fs/buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/buffer.c b/fs/buffer.c
index 9196f2a270da..70638941066d 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -483,7 +483,7 @@ static void __remove_assoc_queue(struct buffer_head *bh)
list_del_init(&bh->b_assoc_buffers);
WARN_ON(!bh->b_assoc_map);
if (buffer_write_io_error(bh))
- set_bit(AS_EIO, &bh->b_assoc_map->flags);
+ mapping_set_error(bh->b_assoc_map, -EIO);
bh->b_assoc_map = NULL;
}
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 05/27] btrfs: btrfs_wait_tree_block_writeback can be void return
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
Nothing checks its return value.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/btrfs/disk-io.c | 6 +++---
fs/btrfs/disk-io.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index eb1ee7b6f532..8c479bd5534a 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1222,10 +1222,10 @@ int btrfs_write_tree_block(struct extent_buffer *buf)
buf->start + buf->len - 1);
}
-int btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
+void btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
{
- return filemap_fdatawait_range(buf->pages[0]->mapping,
- buf->start, buf->start + buf->len - 1);
+ filemap_fdatawait_range(buf->pages[0]->mapping,
+ buf->start, buf->start + buf->len - 1);
}
struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 2e0ec29bfd69..9cc87835abb5 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -127,7 +127,7 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
extent_submit_bio_hook_t *submit_bio_done);
unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info);
int btrfs_write_tree_block(struct extent_buffer *buf);
-int btrfs_wait_tree_block_writeback(struct extent_buffer *buf);
+void btrfs_wait_tree_block_writeback(struct extent_buffer *buf);
int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info);
int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 06/27] fs: check for writeback errors after syncing out buffers in generic_file_fsync
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
ext2 currently does a test+clear of the AS_EIO flag, which is
is problematic for some coming changes.
What we really need to do instead is call filemap_check_errors
in __generic_file_fsync after syncing out the buffers. That
will be sufficient for this case, and help other callers detect
these errors properly as well.
With that, we don't need to twiddle it in ext2.
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
---
fs/ext2/file.c | 2 +-
fs/libfs.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index b21891a6bfca..ed00e7ae0ef3 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -177,7 +177,7 @@ int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
ret = generic_file_fsync(file, start, end, datasync);
- if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) {
+ if (ret == -EIO) {
/* We don't really know where the IO error happened... */
ext2_error(sb, __func__,
"detected IO error when writing metadata buffers");
diff --git a/fs/libfs.c b/fs/libfs.c
index a8b62e5d43a9..efd23040ab25 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -991,7 +991,8 @@ int __generic_file_fsync(struct file *file, loff_t start, loff_t end,
out:
inode_unlock(inode);
- return ret;
+ err = filemap_check_errors(inode->i_mapping);
+ return ret ? ret : err;
}
EXPORT_SYMBOL(__generic_file_fsync);
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 07/27] orangefs: don't call filemap_write_and_wait from fsync
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
Orangefs doesn't do buffered writes yet, so there's no point in
initiating and waiting for writeback.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Mike Marshall <hubcap@omnibond.com>
---
fs/orangefs/file.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c
index e6bbc8083d77..17ab42c4db52 100644
--- a/fs/orangefs/file.c
+++ b/fs/orangefs/file.c
@@ -646,14 +646,11 @@ static int orangefs_fsync(struct file *file,
loff_t end,
int datasync)
{
- int ret = -EINVAL;
+ int ret;
struct orangefs_inode_s *orangefs_inode =
ORANGEFS_I(file_inode(file));
struct orangefs_kernel_op_s *new_op = NULL;
- /* required call */
- filemap_write_and_wait_range(file->f_mapping, start, end);
-
new_op = op_alloc(ORANGEFS_VFS_OP_FSYNC);
if (!new_op)
return -ENOMEM;
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 08/27] dax: set errors in mapping when writeback fails
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
Jan's description for this patch is much better than mine, so I'm
quoting it verbatim here:
DAX currently doesn't set errors in the mapping when cache flushing
fails in dax_writeback_mapping_range(). Since this function can get
called only from fsync(2) or sync(2), this is actually as good as it can
currently get since we correctly propagate the error up from
dax_writeback_mapping_range() to filemap_fdatawrite(). However in the
future better writeback error handling will enable us to properly report
these errors on fsync(2) even if there are multiple file descriptors
open against the file or if sync(2) gets called before fsync(2). So
convert DAX to using standard error reporting through the mapping.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-and-Tested-by: Ross Zwisler <ross.zwisler@linux.intel.com>
---
fs/dax.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/dax.c b/fs/dax.c
index 85abd741253d..9b6b04030c3f 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -901,8 +901,10 @@ int dax_writeback_mapping_range(struct address_space *mapping,
ret = dax_writeback_one(bdev, mapping, indices[i],
pvec.pages[i]);
- if (ret < 0)
+ if (ret < 0) {
+ mapping_set_error(mapping, ret);
return ret;
+ }
}
}
return 0;
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 09/27] nilfs2: set the mapping error when calling SetPageError on writeback
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
In a later patch, we're going to want to make the fsync codepath not do
a TestClearPageError call as that can override the error set in the
address space. To do that though, we need to ensure that filesystems
that are relying on the PG_error bit for reporting writeback errors
also set an error in the address space.
Ensure that this is set in nilfs2.
Acked-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fs/nilfs2/segment.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index febed1217b3f..612d4b446793 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1745,6 +1745,7 @@ static void nilfs_end_page_io(struct page *page, int err)
} else {
__set_page_dirty_nobuffers(page);
SetPageError(page);
+ mapping_set_error(page_mapping(page), err);
}
end_page_writeback(page);
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 10/27] 9p: set mapping error when writeback fails in launder_page
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
launder_page is just writeback under the page lock. We still need to
mark the mapping for errors there when they occur.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fs/9p/vfs_addr.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index adaf6f6dd858..7af6e6501698 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -223,8 +223,11 @@ static int v9fs_launder_page(struct page *page)
v9fs_fscache_wait_on_page_write(inode, page);
if (clear_page_dirty_for_io(page)) {
retval = v9fs_vfs_writepage_locked(page);
- if (retval)
+ if (retval) {
+ if (retval != -EAGAIN)
+ mapping_set_error(page->mapping, retval);
return retval;
+ }
}
return 0;
}
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 11/27] fuse: set mapping error in writepage_locked when it fails
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
This ensures that we see errors on fsync when writeback fails.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fs/fuse/file.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index ec238fb5a584..07d0efcb050c 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1669,6 +1669,7 @@ static int fuse_writepage_locked(struct page *page)
err_free:
fuse_request_free(req);
err:
+ mapping_set_error(page->mapping, error);
end_page_writeback(page);
return error;
}
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 12/27] cifs: set mapping error when page writeback fails in writepage or launder_pages
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fs/cifs/file.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 21d404535739..0bee7f8d91ad 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2234,14 +2234,16 @@ cifs_writepage_locked(struct page *page, struct writeback_control *wbc)
set_page_writeback(page);
retry_write:
rc = cifs_partialpagewrite(page, 0, PAGE_SIZE);
- if (rc == -EAGAIN && wbc->sync_mode == WB_SYNC_ALL)
- goto retry_write;
- else if (rc == -EAGAIN)
+ if (rc == -EAGAIN) {
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ goto retry_write;
redirty_page_for_writepage(wbc, page);
- else if (rc != 0)
+ } else if (rc != 0) {
SetPageError(page);
- else
+ mapping_set_error(page->mapping, rc);
+ } else {
SetPageUptodate(page);
+ }
end_page_writeback(page);
put_page(page);
free_xid(xid);
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 13/27] lib: add errseq_t type and infrastructure for handling it
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
An errseq_t is a way of recording errors in one place, and allowing any
number of "subscribers" to tell whether an error has been set again
since a previous time.
It's implemented as an unsigned 32-bit value that is managed with atomic
operations. The low order bits are designated to hold an error code
(max size of MAX_ERRNO). The upper bits are used as a counter.
The API works with consumers sampling an errseq_t value at a particular
point in time. Later, that value can be used to tell whether new errors
have been set since that time.
Note that there is a 1 in 512k risk of collisions here if new errors
are being recorded frequently, since we have so few bits to use as a
counter. To mitigate this, one bit is used as a flag to tell whether the
value has been sampled since a new value was recorded. That allows
us to avoid bumping the counter if no one has sampled it since it
was last bumped.
Later patches will build on this infrastructure to change how writeback
errors are tracked in the kernel.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
include/linux/errseq.h | 19 +++++
lib/Makefile | 2 +-
lib/errseq.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 219 insertions(+), 1 deletion(-)
create mode 100644 include/linux/errseq.h
create mode 100644 lib/errseq.c
diff --git a/include/linux/errseq.h b/include/linux/errseq.h
new file mode 100644
index 000000000000..0d2555f310cd
--- /dev/null
+++ b/include/linux/errseq.h
@@ -0,0 +1,19 @@
+#ifndef _LINUX_ERRSEQ_H
+#define _LINUX_ERRSEQ_H
+
+/* See lib/errseq.c for more info */
+
+typedef u32 errseq_t;
+
+void __errseq_set(errseq_t *eseq, int err);
+static inline void errseq_set(errseq_t *eseq, int err)
+{
+ /* Optimize for the common case of no error */
+ if (unlikely(err))
+ __errseq_set(eseq, err);
+}
+
+errseq_t errseq_sample(errseq_t *eseq);
+int errseq_check(errseq_t *eseq, errseq_t since);
+int errseq_check_and_advance(errseq_t *eseq, errseq_t *since);
+#endif
diff --git a/lib/Makefile b/lib/Makefile
index 320ac46a8725..2423afef40f7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -41,7 +41,7 @@ obj-y += bcd.o div64.o sort.o parser.o debug_locks.o random32.o \
gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \
bsearch.o find_bit.o llist.o memweight.o kfifo.o \
percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \
- once.o refcount.o
+ once.o refcount.o errseq.o
obj-y += string_helpers.o
obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
obj-y += hexdump.o
diff --git a/lib/errseq.c b/lib/errseq.c
new file mode 100644
index 000000000000..0f8b4ed460f0
--- /dev/null
+++ b/lib/errseq.c
@@ -0,0 +1,199 @@
+#include <linux/err.h>
+#include <linux/bug.h>
+#include <linux/atomic.h>
+#include <linux/errseq.h>
+
+/*
+ * An errseq_t is a way of recording errors in one place, and allowing any
+ * number of "subscribers" to tell whether it has changed since an arbitrary
+ * time of their choosing.
+ *
+ * It's implemented as an unsigned 32-bit value. The low order bits are
+ * designated to hold an error code (between 0 and -MAX_ERRNO). The upper bits
+ * are used as a counter. This is done with atomics instead of locking so that
+ * these functions can be called from any context.
+ *
+ * The general idea is for consumers to sample an errseq_t value at a
+ * particular point in time. Later, that value can be used to tell whether any
+ * new errors have occurred since that time.
+ *
+ * Note that there is a risk of collisions, if new errors are being recorded
+ * frequently, since we have so few bits to use as a counter.
+ *
+ * To mitigate this, one bit is used as a flag to tell whether the value has
+ * been sampled since a new value was recorded. That allows us to avoid bumping
+ * the counter if no one has sampled it since the last time an error was
+ * recorded.
+ *
+ * A new errseq_t should always be zeroed out. A errseq_t value of all zeroes
+ * is the special (but common) case where there has never been an error. An all
+ * zero value thus serves as the "epoch" if one wishes to know whether there
+ * has ever been an error set since it was first initialized.
+ */
+
+/* The low bits are designated for error code (max of MAX_ERRNO) */
+#define ERRSEQ_SHIFT ilog2(MAX_ERRNO + 1)
+
+/* This bit is used as a flag to indicate whether the value has been seen */
+#define ERRSEQ_SEEN (1 << ERRSEQ_SHIFT)
+
+/* The "ones" bit for the counter */
+#define ERRSEQ_CTR_INC (1 << (ERRSEQ_SHIFT + 1))
+
+/**
+ * __errseq_set - set a errseq_t for later reporting
+ * @eseq: errseq_t field that should be set
+ * @err: error to set
+ *
+ * This function sets the error in *eseq, and increments the sequence counter
+ * if the last sequence was sampled at some point in the past.
+ *
+ * Any error set will always overwrite an existing error.
+ *
+ * Most callers will want to use the errseq_set inline wrapper to efficiently
+ * handle the common case where err is 0.
+ */
+void __errseq_set(errseq_t *eseq, int err)
+{
+ errseq_t old;
+
+ /* MAX_ERRNO must be able to serve as a mask */
+ BUILD_BUG_ON_NOT_POWER_OF_2(MAX_ERRNO + 1);
+
+ /*
+ * Ensure the error code actually fits where we want it to go. If it
+ * doesn't then just throw a warning and don't record anything. We
+ * also don't accept zero here as that would effectively clear a
+ * previous error.
+ */
+ if (WARN(unlikely(err == 0 || (unsigned int)-err > MAX_ERRNO),
+ "err = %d\n", err))
+ return;
+
+ old = READ_ONCE(*eseq);
+ for (;;) {
+ errseq_t new, cur;
+
+ /* Clear out error bits and set new error */
+ new = (old & ~(MAX_ERRNO|ERRSEQ_SEEN)) | -err;
+
+ /* Only increment if someone has looked at it */
+ if (old & ERRSEQ_SEEN)
+ new += ERRSEQ_CTR_INC;
+
+ /* If there would be no change, then call it done */
+ if (new == old)
+ break;
+
+ /* Try to swap the new value into place */
+ cur = cmpxchg(eseq, old, new);
+
+ /*
+ * Call it success if we did the swap or someone else beat us
+ * to it for the same value.
+ */
+ if (likely(cur == old || cur == new))
+ break;
+
+ /* Raced with an update, try again */
+ old = cur;
+ }
+}
+EXPORT_SYMBOL(__errseq_set);
+
+/**
+ * errseq_sample - grab current errseq_t value
+ * @eseq: pointer to errseq_t to be sampled
+ *
+ * This function allows callers to sample an errseq_t value, marking it as
+ * "seen" if required.
+ */
+errseq_t errseq_sample(errseq_t *eseq)
+{
+ errseq_t old = READ_ONCE(*eseq);
+ errseq_t new = old;
+
+ /*
+ * For the common case of no errors ever having been set, we can skip
+ * marking the SEEN bit. Once an error has been set, the value will
+ * never go back to zero.
+ */
+ if (old != 0) {
+ new |= ERRSEQ_SEEN;
+ if (old != new)
+ cmpxchg(eseq, old, new);
+ }
+ return new;
+}
+EXPORT_SYMBOL(errseq_sample);
+
+/**
+ * errseq_check - has an error occurred since a particular point in time?
+ * @eseq: pointer to errseq_t value to be checked
+ * @since: previously-sampled errseq_t from which to check
+ *
+ * Grab the value that eseq points to, and see if it has changed "since"
+ * the given value was sampled. The "since" value is not advanced, so there
+ * is no need to mark the value as seen.
+ *
+ * Returns the latest error set in the errseq_t or 0 if it hasn't changed.
+ */
+int errseq_check(errseq_t *eseq, errseq_t since)
+{
+ errseq_t cur = READ_ONCE(*eseq);
+
+ if (likely(cur == since))
+ return 0;
+ return -(cur & MAX_ERRNO);
+}
+EXPORT_SYMBOL(errseq_check);
+
+/**
+ * errseq_check_and_advance - check an errseq_t and advance it to the current value
+ * @eseq: pointer to value being checked reported
+ * @since: pointer to previously-sampled errseq_t to check against and advance
+ *
+ * Grab the eseq value, and see whether it matches the value that "since"
+ * points to. If it does, then just return 0.
+ *
+ * If it doesn't, then the value has changed. Set the "seen" flag, and try to
+ * swap it into place as the new eseq value. Then, set that value as the new
+ * "since" value, and return whatever the error portion is set to.
+ *
+ * Note that no locking is provided here for concurrent updates to the "since"
+ * value. The caller must provide that if necessary. Because of this, callers
+ * may want to do a lockless errseq_check before taking the lock and calling
+ * this.
+ */
+int errseq_check_and_advance(errseq_t *eseq, errseq_t *since)
+{
+ int err = 0;
+ errseq_t old, new;
+
+ /*
+ * Most callers will want to use the inline wrapper to check this,
+ * so that the common case of no error is handled without needing
+ * to lock.
+ */
+ old = READ_ONCE(*eseq);
+ if (old != *since) {
+ /*
+ * Set the flag and try to swap it into place if it has
+ * changed.
+ *
+ * We don't care about the outcome of the swap here. If the
+ * swap doesn't occur, then it has either been updated by a
+ * writer who is bumping the seq count anyway, or another
+ * reader who is just setting the "seen" flag. Either outcome
+ * is OK, and we can advance "since" and return an error based
+ * on what we have.
+ */
+ new = old | ERRSEQ_SEEN;
+ if (new != old)
+ cmpxchg(eseq, old, new);
+ *since = new;
+ err = -(new & MAX_ERRNO);
+ }
+ return err;
+}
+EXPORT_SYMBOL(errseq_check_and_advance);
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v4 14/27] fs: new infrastructure for writeback error handling and reporting
From: Jeff Layton @ 2017-05-09 15:49 UTC (permalink / raw)
To: linux-fsdevel, linux-kernel, linux-btrfs, linux-ext4, linux-cifs,
linux-nfs, linux-mm, jfs-discussion, linux-xfs, cluster-devel,
linux-f2fs-devel, v9fs-developer, linux-nilfs, linux-block
Cc: dhowells, akpm, hch, ross.zwisler, mawilcox, jack, viro, corbet,
neilb, clm, tytso, axboe, josef, hubcap, rpeterso, bo.li.liu
In-Reply-To: <20170509154930.29524-1-jlayton@redhat.com>
Most filesystems currently use mapping_set_error and
filemap_check_errors for setting and reporting/clearing writeback errors
at the mapping level. filemap_check_errors is indirectly called from
most of the filemap_fdatawait_* functions and from
filemap_write_and_wait*. These functions are called from all sorts of
contexts to wait on writeback to finish -- e.g. mostly in fsync, but
also in truncate calls, getattr, etc.
The non-fsync callers are problematic. We should be reporting writeback
errors during fsync, but many places spread over the tree clear out
errors before they can be properly reported, or report errors at
nonsensical times.
If I get -EIO on a stat() call, there is no reason for me to assume that
it is because some previous writeback failed. The fact that it also
clears out the error such that a subsequent fsync returns 0 is a bug,
and a nasty one since that's potentially silent data corruption.
This patch adds a small bit of new infrastructure for setting and
reporting errors during address_space writeback. While the above was my
original impetus for adding this, I think it's also the case that
current fsync semantics are just problematic for userland. Most
applications that call fsync do so to ensure that the data they wrote
has hit the backing store.
In the case where there are multiple writers to the file at the same
time, this is really hard to determine. The first one to call fsync will
see any stored error, and the rest get back 0. The processes with open
fds may not be associated with one another in any way. They could even
be in different containers, so ensuring coordination between all fsync
callers is not really an option.
One way to remedy this would be to track what file descriptor was used
to dirty the file, but that's rather cumbersome and would likely be
slow. However, there is a simpler way to improve the semantics here
without incurring too much overhead.
This set adds an errseq_t to struct address_space, and a corresponding
one is added to struct file. Writeback errors are recorded in the
mapping's errseq_t, and the one in struct file is used as the "since"
value.
This changes the semantics of the Linux fsync implementation such that
applications can now use it to determine whether there were any
writeback errors since fsync(fd) was last called (or since the file was
opened in the case of fsync having never been called).
Note that those writeback errors may have occurred when writing data
that was dirtied via an entirely different fd, but that's the case now
with the current mapping_set_error/filemap_check_error infrastructure.
This will at least prevent you from getting a false report of success.
The new behavior is still consistent with the POSIX spec, and is more
reliable for application developers. This patch just adds some basic
infrastructure for doing this. Later patches will change the existing
code to use this new infrastructure.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
Documentation/filesystems/vfs.txt | 10 +++++++++-
drivers/dax/dax.c | 1 +
fs/block_dev.c | 1 +
fs/file_table.c | 1 +
fs/open.c | 3 +++
include/linux/fs.h | 24 ++++++++++++++++++++++++
mm/filemap.c | 38 ++++++++++++++++++++++++++++++++++++++
7 files changed, 77 insertions(+), 1 deletion(-)
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 94dd27ef4a76..ed06fb39822b 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -576,6 +576,11 @@ should clear PG_Dirty and set PG_Writeback. It can be actually
written at any point after PG_Dirty is clear. Once it is known to be
safe, PG_Writeback is cleared.
+If there is an error during writeback, then the address_space should be
+marked with an error (typically using filemap_set_wb_error), in order to
+ensure that the error can later be reported to the application when an
+fsync is issued.
+
Writeback makes use of a writeback_control structure...
struct address_space_operations
@@ -888,7 +893,10 @@ otherwise noted.
release: called when the last reference to an open file is closed
- fsync: called by the fsync(2) system call
+ fsync: called by the fsync(2) system call. Filesystems that use the
+ pagecache should call filemap_report_wb_error before returning
+ to ensure that any errors that occurred during writeback are
+ reported and the file's error sequence advanced.
fasync: called by the fcntl(2) system call when asynchronous
(non-blocking) mode is enabled for a file
diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c
index 806f180c80d8..984d6ec35dda 100644
--- a/drivers/dax/dax.c
+++ b/drivers/dax/dax.c
@@ -668,6 +668,7 @@ static int dax_open(struct inode *inode, struct file *filp)
inode->i_mapping = dax_dev->inode->i_mapping;
inode->i_mapping->host = dax_dev->inode;
filp->f_mapping = inode->i_mapping;
+ filp->f_wb_err = filemap_sample_wb_error(filp->f_mapping);
filp->private_data = dax_dev;
inode->i_flags = S_DAX;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 2eca00ec4370..daab40c2e8af 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1857,6 +1857,7 @@ static int blkdev_open(struct inode * inode, struct file * filp)
return -ENOMEM;
filp->f_mapping = bdev->bd_inode->i_mapping;
+ filp->f_wb_err = filemap_sample_wb_error(filp->f_mapping);
return blkdev_get(bdev, filp->f_mode, filp);
}
diff --git a/fs/file_table.c b/fs/file_table.c
index 954d510b765a..d6138b6411ff 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -168,6 +168,7 @@ struct file *alloc_file(const struct path *path, fmode_t mode,
file->f_path = *path;
file->f_inode = path->dentry->d_inode;
file->f_mapping = path->dentry->d_inode->i_mapping;
+ file->f_wb_err = filemap_sample_wb_error(file->f_mapping);
if ((mode & FMODE_READ) &&
likely(fop->read || fop->read_iter))
mode |= FMODE_CAN_READ;
diff --git a/fs/open.c b/fs/open.c
index 949cef29c3bb..88bfed8d3c88 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -709,6 +709,9 @@ static int do_dentry_open(struct file *f,
f->f_inode = inode;
f->f_mapping = inode->i_mapping;
+ /* Ensure that we skip any errors that predate opening of the file */
+ f->f_wb_err = filemap_sample_wb_error(f->f_mapping);
+
if (unlikely(f->f_flags & O_PATH)) {
f->f_mode = FMODE_PATH;
f->f_op = &empty_fops;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 38adefd8e2a0..bab3333e8671 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -31,6 +31,7 @@
#include <linux/workqueue.h>
#include <linux/percpu-rwsem.h>
#include <linux/delayed_call.h>
+#include <linux/errseq.h>
#include <asm/byteorder.h>
#include <uapi/linux/fs.h>
@@ -394,6 +395,7 @@ struct address_space {
gfp_t gfp_mask; /* implicit gfp mask for allocations */
struct list_head private_list; /* ditto */
void *private_data; /* ditto */
+ errseq_t wb_err;
} __attribute__((aligned(sizeof(long))));
/*
* On most architectures that alignment is already the case; but
@@ -846,6 +848,7 @@ struct file {
* Must not be taken from IRQ context.
*/
spinlock_t f_lock;
+ errseq_t f_wb_err;
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
@@ -2519,6 +2522,27 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping,
extern int filemap_fdatawrite_range(struct address_space *mapping,
loff_t start, loff_t end);
extern int filemap_check_errors(struct address_space *mapping);
+extern int __must_check filemap_report_wb_error(struct file *file);
+
+/**
+ * filemap_check_wb_error - has an error occurred since the mark was sampled?
+ * @mapping: mapping to check for writeback errors
+ * @since: previously-sampled errseq_t
+ *
+ * Grab the errseq_t value from the mapping, and see if it has changed "since"
+ * the given value was sampled.
+ *
+ * If it has then report the latest error set, otherwise return 0.
+ */
+static inline int filemap_check_wb_error(struct address_space *mapping, errseq_t since)
+{
+ return errseq_check(&mapping->wb_err, since);
+}
+
+static inline errseq_t filemap_sample_wb_error(struct address_space *mapping)
+{
+ return errseq_sample(&mapping->wb_err);
+}
extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
int datasync);
diff --git a/mm/filemap.c b/mm/filemap.c
index 1694623a6289..ee1a798acfc1 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -546,6 +546,44 @@ int filemap_write_and_wait_range(struct address_space *mapping,
EXPORT_SYMBOL(filemap_write_and_wait_range);
/**
+ * filemap_report_wb_error - report wb error (if any) that was previously set
+ * @file: struct file on which the error is being reported
+ *
+ * When userland calls fsync (or something like nfsd does the equivalent), we
+ * want to report any writeback errors that occurred since the last fsync (or
+ * since the file was opened if there haven't been any).
+ *
+ * Grab the wb_err from the mapping. If it matches what we have in the file,
+ * then just quickly return 0. The file is all caught up.
+ *
+ * If it doesn't match, then take the mapping value, set the "seen" flag in
+ * it and try to swap it into place. If it works, or another task beat us
+ * to it with the new value, then update the f_wb_err and return the error
+ * portion. The error at this point must be reported via proper channels
+ * (a'la fsync, or NFS COMMIT operation, etc.).
+ *
+ * While we handle mapping->wb_err with atomic operations, the f_wb_err
+ * value is protected by the f_lock since we must ensure that it reflects
+ * the latest value swapped in for this file descriptor.
+ */
+int filemap_report_wb_error(struct file *file)
+{
+ int err = 0;
+ struct address_space *mapping = file->f_mapping;
+
+ /* Locklessly handle the common case where nothing has changed */
+ if (errseq_check(&mapping->wb_err, READ_ONCE(file->f_wb_err))) {
+ /* Something changed, must use slow path */
+ spin_lock(&file->f_lock);
+ err = errseq_check_and_advance(&mapping->wb_err,
+ &file->f_wb_err);
+ spin_unlock(&file->f_lock);
+ }
+ return err;
+}
+EXPORT_SYMBOL(filemap_report_wb_error);
+
+/**
* replace_page_cache_page - replace a pagecache page with a new one
* @old: page to be replaced
* @new: page to replace with
--
2.9.3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox