diff mbox series

[08/10] ntfs3: Use a folio to read UpCase

Message ID 20240417170941.797116-9-willy@infradead.org (mailing list archive)
State New
Headers show
Series ntfs3: Convert (most of) ntfs3 to use folios | expand

Commit Message

Matthew Wilcox April 17, 2024, 5:09 p.m. UTC
Add a memcpy_from_folio_le16() which does the byteswapping.
This is now large folio safe and avoids kmap().

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 fs/ntfs3/super.c        | 25 +++++++++++--------------
 include/linux/highmem.h | 31 +++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 14 deletions(-)

Comments

Matthew Wilcox April 17, 2024, 5:32 p.m. UTC | #1
On Wed, Apr 17, 2024 at 06:09:36PM +0100, Matthew Wilcox (Oracle) wrote:
> Add a memcpy_from_folio_le16() which does the byteswapping.
> This is now large folio safe and avoids kmap().

This patch is missing:

@@ -476,6 +476,7 @@ static inline void memcpy_from_folio_le16(u16 *to, struct folio *folio,
        do {
                const __le16 *from = kmap_local_folio(folio, offset);
                size_t chunk = len;
+               int i;

                if (folio_test_highmem(folio) &&
                    chunk > PAGE_SIZE - offset_in_page(offset))

I'll send a new version if needed, but I'll wait for other feedback
first.
kernel test robot April 19, 2024, 12:30 a.m. UTC | #2
Hi Matthew,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.9-rc4]
[cannot apply to next-20240418]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/ntfs3-Convert-ntfs_read_folio-to-use-a-folio/20240418-011140
base:   linus/master
patch link:    https://lore.kernel.org/r/20240417170941.797116-9-willy%40infradead.org
patch subject: [PATCH 08/10] ntfs3: Use a folio to read UpCase
config: openrisc-allnoconfig (https://download.01.org/0day-ci/archive/20240419/202404190823.2p1A9tNE-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240419/202404190823.2p1A9tNE-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404190823.2p1A9tNE-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/linux/pagemap.h:11,
                    from lib/buildid.c:7:
   include/linux/highmem.h: In function 'memcpy_from_folio_le16':
>> include/linux/highmem.h:484:22: error: 'i' undeclared (first use in this function)
     484 |                 for (i = 0; i < chunk / sizeof(*to); i++)
         |                      ^
   include/linux/highmem.h:484:22: note: each undeclared identifier is reported only once for each function it appears in
--
   In file included from include/linux/bvec.h:10,
                    from include/linux/skbuff.h:17,
                    from include/linux/tcp.h:17,
                    from include/linux/ipv6.h:101,
                    from include/net/addrconf.h:61,
                    from lib/vsprintf.c:41:
   include/linux/highmem.h: In function 'memcpy_from_folio_le16':
>> include/linux/highmem.h:484:22: error: 'i' undeclared (first use in this function)
     484 |                 for (i = 0; i < chunk / sizeof(*to); i++)
         |                      ^
   include/linux/highmem.h:484:22: note: each undeclared identifier is reported only once for each function it appears in
   lib/vsprintf.c: In function 'va_format':
   lib/vsprintf.c:1683:9: warning: function 'va_format' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
    1683 |         buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
         |         ^~~


vim +/i +484 include/linux/highmem.h

   469	
   470	#ifdef __BIG_ENDIAN
   471	static inline void memcpy_from_folio_le16(u16 *to, struct folio *folio,
   472			size_t offset, size_t len)
   473	{
   474		VM_BUG_ON(offset + len > folio_size(folio));
   475	
   476		do {
   477			const __le16 *from = kmap_local_folio(folio, offset);
   478			size_t chunk = len;
   479	
   480			if (folio_test_highmem(folio) &&
   481			    chunk > PAGE_SIZE - offset_in_page(offset))
   482				chunk = PAGE_SIZE - offset_in_page(offset);
   483	
 > 484			for (i = 0; i < chunk / sizeof(*to); i++)
   485				*to++ = le16_to_cpu(*from++);
   486			kunmap_local(from);
   487	
   488			to += chunk / sizeof(*to);
   489			offset += chunk;
   490			len -= chunk;
   491		} while (len > 0);
   492	}
   493	#else
   494	static inline void memcpy_from_folio_le16(u16 *to, struct folio *folio,
   495			size_t offset, size_t len)
   496	{
   497		memcpy_from_folio((char *)to, folio, offset, len);
   498	}
   499	#endif
   500
kernel test robot April 19, 2024, 1:12 a.m. UTC | #3
Hi Matthew,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.9-rc4]
[cannot apply to next-20240418]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/ntfs3-Convert-ntfs_read_folio-to-use-a-folio/20240418-011140
base:   linus/master
patch link:    https://lore.kernel.org/r/20240417170941.797116-9-willy%40infradead.org
patch subject: [PATCH 08/10] ntfs3: Use a folio to read UpCase
config: s390-allnoconfig (https://download.01.org/0day-ci/archive/20240419/202404190841.KPS2VQgB-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 7089c359a3845323f6f30c44a47dd901f2edfe63)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240419/202404190841.KPS2VQgB-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404190841.KPS2VQgB-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/s390/kernel/asm-offsets.c:11:
   In file included from include/linux/kvm_host.h:16:
   In file included from include/linux/mm.h:2208:
   include/linux/vmstat.h:522:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     522 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   In file included from arch/s390/kernel/asm-offsets.c:11:
   In file included from include/linux/kvm_host.h:19:
   In file included from include/linux/msi.h:27:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:78:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     547 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     560 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
         |                                                           ^
   include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
     102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
         |                                                      ^
   In file included from arch/s390/kernel/asm-offsets.c:11:
   In file included from include/linux/kvm_host.h:19:
   In file included from include/linux/msi.h:27:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:78:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     573 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
         |                                                           ^
   include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
     115 | #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
         |                                                      ^
   In file included from arch/s390/kernel/asm-offsets.c:11:
   In file included from include/linux/kvm_host.h:19:
   In file included from include/linux/msi.h:27:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:78:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     584 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     594 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     604 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     692 |         readsb(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     700 |         readsw(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     708 |         readsl(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     717 |         writesb(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     726 |         writesw(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     735 |         writesl(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   In file included from arch/s390/kernel/asm-offsets.c:11:
   In file included from include/linux/kvm_host.h:41:
   In file included from include/linux/kvm_para.h:5:
   In file included from include/uapi/linux/kvm_para.h:37:
   In file included from arch/s390/include/asm/kvm_para.h:25:
   In file included from arch/s390/include/asm/diag.h:12:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
>> include/linux/highmem.h:484:8: error: use of undeclared identifier 'i'
     484 |                 for (i = 0; i < chunk / sizeof(*to); i++)
         |                      ^
   include/linux/highmem.h:484:15: error: use of undeclared identifier 'i'
     484 |                 for (i = 0; i < chunk / sizeof(*to); i++)
         |                             ^
   include/linux/highmem.h:484:40: error: use of undeclared identifier 'i'
     484 |                 for (i = 0; i < chunk / sizeof(*to); i++)
         |                                                      ^
   13 warnings and 3 errors generated.
   make[3]: *** [scripts/Makefile.build:117: arch/s390/kernel/asm-offsets.s] Error 1
   make[3]: Target 'prepare' not remade because of errors.
   make[2]: *** [Makefile:1197: prepare0] Error 2
   make[2]: Target 'prepare' not remade because of errors.
   make[1]: *** [Makefile:240: __sub-make] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:240: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +/i +484 include/linux/highmem.h

   469	
   470	#ifdef __BIG_ENDIAN
   471	static inline void memcpy_from_folio_le16(u16 *to, struct folio *folio,
   472			size_t offset, size_t len)
   473	{
   474		VM_BUG_ON(offset + len > folio_size(folio));
   475	
   476		do {
   477			const __le16 *from = kmap_local_folio(folio, offset);
   478			size_t chunk = len;
   479	
   480			if (folio_test_highmem(folio) &&
   481			    chunk > PAGE_SIZE - offset_in_page(offset))
   482				chunk = PAGE_SIZE - offset_in_page(offset);
   483	
 > 484			for (i = 0; i < chunk / sizeof(*to); i++)
   485				*to++ = le16_to_cpu(*from++);
   486			kunmap_local(from);
   487	
   488			to += chunk / sizeof(*to);
   489			offset += chunk;
   490			len -= chunk;
   491		} while (len > 0);
   492	}
   493	#else
   494	static inline void memcpy_from_folio_le16(u16 *to, struct folio *folio,
   495			size_t offset, size_t len)
   496	{
   497		memcpy_from_folio((char *)to, folio, offset, len);
   498	}
   499	#endif
   500
diff mbox series

Patch

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index f6a9ab0f5cad..00700598a717 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -1493,26 +1493,23 @@  static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
 		goto put_inode_out;
 	}
 
-	for (idx = 0; idx < (0x10000 * sizeof(short) >> PAGE_SHIFT); idx++) {
-		const __le16 *src;
+	idx = 0;
+	while (idx < (0x10000 * sizeof(u16) >> PAGE_SHIFT)) {
 		u16 *dst = Add2Ptr(sbi->upcase, idx << PAGE_SHIFT);
-		struct page *page = ntfs_map_page(inode->i_mapping, idx);
+		struct folio *folio = read_mapping_folio(inode->i_mapping,
+				idx, NULL);
+		size_t limit = 0x10000 * sizeof(u16) - idx * PAGE_SIZE;
 
-		if (IS_ERR(page)) {
-			err = PTR_ERR(page);
+		if (IS_ERR(folio)) {
+			err = PTR_ERR(folio);
 			ntfs_err(sb, "Failed to read $UpCase (%d).", err);
 			goto put_inode_out;
 		}
 
-		src = page_address(page);
-
-#ifdef __BIG_ENDIAN
-		for (i = 0; i < PAGE_SIZE / sizeof(u16); i++)
-			*dst++ = le16_to_cpu(*src++);
-#else
-		memcpy(dst, src, PAGE_SIZE);
-#endif
-		ntfs_unmap_page(page);
+		memcpy_from_folio_le16(dst, folio, 0,
+				min(limit, folio_size(folio)));
+		idx += folio_nr_pages(folio);
+		folio_put(folio);
 	}
 
 	shared = ntfs_set_shared(sbi->upcase, 0x10000 * sizeof(short));
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 00341b56d291..20b5d5a5feaf 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -467,6 +467,37 @@  static inline void memcpy_from_folio(char *to, struct folio *folio,
 	} while (len > 0);
 }
 
+#ifdef __BIG_ENDIAN
+static inline void memcpy_from_folio_le16(u16 *to, struct folio *folio,
+		size_t offset, size_t len)
+{
+	VM_BUG_ON(offset + len > folio_size(folio));
+
+	do {
+		const __le16 *from = kmap_local_folio(folio, offset);
+		size_t chunk = len;
+
+		if (folio_test_highmem(folio) &&
+		    chunk > PAGE_SIZE - offset_in_page(offset))
+			chunk = PAGE_SIZE - offset_in_page(offset);
+
+		for (i = 0; i < chunk / sizeof(*to); i++)
+			*to++ = le16_to_cpu(*from++);
+		kunmap_local(from);
+
+		to += chunk / sizeof(*to);
+		offset += chunk;
+		len -= chunk;
+	} while (len > 0);
+}
+#else
+static inline void memcpy_from_folio_le16(u16 *to, struct folio *folio,
+		size_t offset, size_t len)
+{
+	memcpy_from_folio((char *)to, folio, offset, len);
+}
+#endif
+
 /**
  * memcpy_to_folio - Copy a range of bytes to a folio.
  * @folio: The folio to write to.