Re: [PATCH v11 8/8] fsdax: set a CoW flag when associate reflink mappings

2022-02-27 Thread kernel test robot
Hi Shiyang,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on xfs-linux/for-next]
[also build test WARNING on linux/master]
[cannot apply to hnaz-mm/master linus/master v5.17-rc5 next-20220225]
[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]

url:
https://github.com/0day-ci/linux/commits/Shiyang-Ruan/fsdax-introduce-fs-query-to-support-reflink/20220227-200849
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: i386-randconfig-a013 
(https://download.01.org/0day-ci/archive/20220227/202202272359.2aiznpgb-...@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
d271fc04d5b97b12e6b797c6067d3c96a8d7470e)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/a0ac78065bbb4fbb3e5477c32686eca3b9f0e1ef
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Shiyang-Ruan/fsdax-introduce-fs-query-to-support-reflink/20220227-200849
git checkout a0ac78065bbb4fbb3e5477c32686eca3b9f0e1ef
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> fs/dax.c:337:67: warning: parameter 'mapping' set but not used 
>> [-Wunused-but-set-parameter]
   static inline void dax_mapping_set_cow_flag(struct address_space *mapping)
 ^
   1 warning generated.


vim +/mapping +337 fs/dax.c

   328  
   329  /*
   330   * Iterate through all mapped pfns represented by an entry, i.e. skip
   331   * 'empty' and 'zero' entries.
   332   */
   333  #define for_each_mapped_pfn(entry, pfn) \
   334  for (pfn = dax_to_pfn(entry); \
   335  pfn < dax_end_pfn(entry); pfn++)
   336  
 > 337  static inline void dax_mapping_set_cow_flag(struct address_space 
 > *mapping)
   338  {
   339  mapping = (struct address_space *)PAGE_MAPPING_DAX_COW;
   340  }
   341  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org



[PATCH v11 8/8] fsdax: set a CoW flag when associate reflink mappings

2022-02-27 Thread Shiyang Ruan
Introduce a PAGE_MAPPING_DAX_COW flag to support association with CoW file
mappings.  In this case, since the dax-rmap has already took the
responsibility to look up for shared files by given dax page,
the page->mapping is no longer to used for rmap but for marking that
this dax page is shared.  And to make sure disassociation works fine, we
use page->index as refcount, and clear page->mapping to the initial
state when page->index is decreased to 0.

With the help of this new flag, it is able to distinguish normal case
and CoW case, and keep the warning in normal case.

==
PS: The @cow added for dax_associate_entry(), is used to let it know
whether the entry is to be shared during iomap operation.  It is decided
by iomap,srcmap's flag, and will be used in another patchset(
fsdax,xfs: Add reflink support for fsdax[1]).

In this patch, we set @cow always false for now.

[1] 
https://lore.kernel.org/linux-xfs/20210928062311.4012070-1-ruansy.f...@fujitsu.com/
==

Signed-off-by: Shiyang Ruan 
---
 fs/dax.c   | 65 --
 include/linux/page-flags.h |  6 
 2 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index f164cf64c611..b97106a0a0b1 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -334,13 +334,46 @@ static unsigned long dax_end_pfn(void *entry)
for (pfn = dax_to_pfn(entry); \
pfn < dax_end_pfn(entry); pfn++)
 
+static inline void dax_mapping_set_cow_flag(struct address_space *mapping)
+{
+   mapping = (struct address_space *)PAGE_MAPPING_DAX_COW;
+}
+
+static inline bool dax_mapping_is_cow(struct address_space *mapping)
+{
+   return (unsigned long)mapping == PAGE_MAPPING_DAX_COW;
+}
+
 /*
- * TODO: for reflink+dax we need a way to associate a single page with
- * multiple address_space instances at different linear_page_index()
- * offsets.
+ * Set or Update the page->mapping with FS_DAX_MAPPING_COW flag.
+ * Return true if it is an Update.
+ */
+static inline bool dax_mapping_set_cow(struct page *page)
+{
+   if (page->mapping) {
+   /* flag already set */
+   if (dax_mapping_is_cow(page->mapping))
+   return false;
+
+   /*
+* This page has been mapped even before it is shared, just
+* need to set this FS_DAX_MAPPING_COW flag.
+*/
+   dax_mapping_set_cow_flag(page->mapping);
+   return true;
+   }
+   /* Newly associate CoW mapping */
+   dax_mapping_set_cow_flag(page->mapping);
+   return false;
+}
+
+/*
+ * When it is called in dax_insert_entry(), the cow flag will indicate that
+ * whether this entry is shared by multiple files.  If so, set the 
page->mapping
+ * to be FS_DAX_MAPPING_COW, and use page->index as refcount.
  */
 static void dax_associate_entry(void *entry, struct address_space *mapping,
-   struct vm_area_struct *vma, unsigned long address)
+   struct vm_area_struct *vma, unsigned long address, bool cow)
 {
unsigned long size = dax_entry_size(entry), pfn, index;
int i = 0;
@@ -352,9 +385,17 @@ static void dax_associate_entry(void *entry, struct 
address_space *mapping,
for_each_mapped_pfn(entry, pfn) {
struct page *page = pfn_to_page(pfn);
 
-   WARN_ON_ONCE(page->mapping);
-   page->mapping = mapping;
-   page->index = index + i++;
+   if (cow) {
+   if (dax_mapping_set_cow(page)) {
+   /* Was normal, now updated to CoW */
+   page->index = 2;
+   } else
+   page->index++;
+   } else {
+   WARN_ON_ONCE(page->mapping);
+   page->mapping = mapping;
+   page->index = index + i++;
+   }
}
 }
 
@@ -370,7 +411,12 @@ static void dax_disassociate_entry(void *entry, struct 
address_space *mapping,
struct page *page = pfn_to_page(pfn);
 
WARN_ON_ONCE(trunc && page_ref_count(page) > 1);
-   WARN_ON_ONCE(page->mapping && page->mapping != mapping);
+   if (!dax_mapping_is_cow(page->mapping)) {
+   /* keep the CoW flag if this page is still shared */
+   if (page->index-- > 0)
+   continue;
+   } else
+   WARN_ON_ONCE(page->mapping && page->mapping != mapping);
page->mapping = NULL;
page->index = 0;
}
@@ -829,7 +875,8 @@ static void *dax_insert_entry(struct xa_state *xas,
void *old;
 
dax_disassociate_entry(entry, mapping, false);
-   dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address);
+   dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address,
+