[PATCH] dax: Remove usage of the deprecated ida_simple_xxx API

2022-09-25 Thread Bo Liu
Use ida_alloc_xxx()/ida_free() instead of
ida_simple_get()/ida_simple_remove().
The latter is deprecated and more verbose.

Signed-off-by: Bo Liu 
---
 drivers/dax/super.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 9b5e2a5eb0ae..da4438f3188c 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -363,7 +363,7 @@ static void dax_free_inode(struct inode *inode)
 {
struct dax_device *dax_dev = to_dax_dev(inode);
if (inode->i_rdev)
-   ida_simple_remove(_minor_ida, iminor(inode));
+   ida_free(_minor_ida, iminor(inode));
kmem_cache_free(dax_cache, dax_dev);
 }
 
@@ -445,7 +445,7 @@ struct dax_device *alloc_dax(void *private, const struct 
dax_operations *ops)
if (WARN_ON_ONCE(ops && !ops->zero_page_range))
return ERR_PTR(-EINVAL);
 
-   minor = ida_simple_get(_minor_ida, 0, MINORMASK+1, GFP_KERNEL);
+   minor = ida_alloc_max(_minor_ida, MINORMASK, GFP_KERNEL);
if (minor < 0)
return ERR_PTR(-ENOMEM);
 
@@ -459,7 +459,7 @@ struct dax_device *alloc_dax(void *private, const struct 
dax_operations *ops)
return dax_dev;
 
  err_dev:
-   ida_simple_remove(_minor_ida, minor);
+   ida_free(_minor_ida, minor);
return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL_GPL(alloc_dax);
-- 
2.27.0




[PATCH -next] nvdimm: make nd_class static

2022-09-25 Thread ruanjinjie
The symbol is not used outside of the file, so mark it static.

Fixes the following warning:

drivers/nvdimm/bus.c:28:14: warning: symbol 'nd_class' was not declared. Should 
it be static?

Signed-off-by: ruanjinjie 
---
 drivers/nvdimm/bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index b38d0355b0ac..1bf5f77e6f76 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -25,7 +25,7 @@
 
 int nvdimm_major;
 static int nvdimm_bus_major;
-struct class *nd_class;
+static struct class *nd_class;
 static DEFINE_IDA(nd_ida);
 
 static int to_nd_device_type(struct device *dev)
-- 
2.25.1




Re: [GIT PULL] NVDIMM and DAX fixes for 6.0-final

2022-09-25 Thread pr-tracker-bot
The pull request you sent on Sat, 24 Sep 2022 18:33:50 -0700:

> git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm 
> tags/dax-and-nvdimm-fixes-v6.0-final

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/4207d59567c017be284dbebc5d3fb5a2037a5df5

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html



[PATCH 3/3] mm, pmem, xfs: Introduce MF_MEM_REMOVE for unbind

2022-09-25 Thread Shiyang Ruan
This patch is inspired by Dan's "mm, dax, pmem: Introduce
dev_pagemap_failure()"[1].  With the help of dax_holder and
->notify_failure() mechanism, the pmem driver is able to ask filesystem
(or mapped device) on it to unmap all files in use and notify processes
who are using those files.

Call trace:
trigger unbind
 -> unbind_store()
  -> ... (skip)
   -> devres_release_all()   # was pmem driver ->remove() in v1
-> kill_dax()
 -> dax_holder_notify_failure(dax_dev, 0, U64_MAX, MF_MEM_PRE_REMOVE)
  -> xfs_dax_notify_failure()

Introduce MF_MEM_PRE_REMOVE to let filesystem know this is a remove
event.  So do not shutdown filesystem directly if something not
supported, or if failure range includes metadata area.  Make sure all
files and processes are handled correctly.

[1]: 
https://lore.kernel.org/linux-mm/161604050314.1463742.14151665140035795571.st...@dwillia2-desk3.amr.corp.intel.com/

Signed-off-by: Shiyang Ruan 
---
 drivers/dax/super.c |  3 ++-
 fs/xfs/xfs_notify_failure.c | 28 +++-
 include/linux/mm.h  |  1 +
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 9b5e2a5eb0ae..cf9a64563fbe 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -323,7 +323,8 @@ void kill_dax(struct dax_device *dax_dev)
return;
 
if (dax_dev->holder_data != NULL)
-   dax_holder_notify_failure(dax_dev, 0, U64_MAX, 0);
+   dax_holder_notify_failure(dax_dev, 0, U64_MAX,
+   MF_MEM_PRE_REMOVE);
 
clear_bit(DAXDEV_ALIVE, _dev->flags);
synchronize_srcu(_srcu);
diff --git a/fs/xfs/xfs_notify_failure.c b/fs/xfs/xfs_notify_failure.c
index 3830f908e215..5c1e678a1285 100644
--- a/fs/xfs/xfs_notify_failure.c
+++ b/fs/xfs/xfs_notify_failure.c
@@ -22,6 +22,7 @@
 
 #include 
 #include 
+#include 
 
 struct xfs_failure_info {
xfs_agblock_t   startblock;
@@ -77,6 +78,9 @@ xfs_dax_failure_fn(
 
if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) ||
(rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))) {
+   /* The device is about to be removed.  Not a really failure. */
+   if (notify->mf_flags & MF_MEM_PRE_REMOVE)
+   return 0;
notify->want_shutdown = true;
return 0;
}
@@ -168,7 +172,9 @@ xfs_dax_notify_ddev_failure(
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_ONDISK);
if (!error)
error = -EFSCORRUPTED;
-   }
+   } else if (mf_flags & MF_MEM_PRE_REMOVE)
+   xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
+
return error;
 }
 
@@ -182,12 +188,24 @@ xfs_dax_notify_failure(
struct xfs_mount*mp = dax_holder(dax_dev);
u64 ddev_start;
u64 ddev_end;
+   int error;
 
if (!(mp->m_super->s_flags & SB_BORN)) {
xfs_warn(mp, "filesystem is not ready for notify_failure()!");
return -EIO;
}
 
+   if (mf_flags & MF_MEM_PRE_REMOVE) {
+   xfs_info(mp, "device is about to be removed!");
+   down_write(>m_super->s_umount);
+   error = sync_filesystem(mp->m_super);
+   /* invalidate_inode_pages2() invalidates dax mapping */
+   super_drop_pagecache(mp->m_super, invalidate_inode_pages2);
+   up_write(>m_super->s_umount);
+   if (error)
+   return error;
+   }
+
if (mp->m_rtdev_targp && mp->m_rtdev_targp->bt_daxdev == dax_dev) {
xfs_debug(mp,
 "notify_failure() not supported on realtime device!");
@@ -196,6 +214,8 @@ xfs_dax_notify_failure(
 
if (mp->m_logdev_targp && mp->m_logdev_targp->bt_daxdev == dax_dev &&
mp->m_logdev_targp != mp->m_ddev_targp) {
+   if (mf_flags & MF_MEM_PRE_REMOVE)
+   return 0;
xfs_err(mp, "ondisk log corrupt, shutting down fs!");
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_ONDISK);
return -EFSCORRUPTED;
@@ -209,6 +229,12 @@ xfs_dax_notify_failure(
ddev_start = mp->m_ddev_targp->bt_dax_part_off;
ddev_end = ddev_start + bdev_nr_bytes(mp->m_ddev_targp->bt_bdev) - 1;
 
+   /* Notify failure on the whole device */
+   if (offset == 0 && len == U64_MAX) {
+   offset = ddev_start;
+   len = bdev_nr_bytes(mp->m_ddev_targp->bt_bdev);
+   }
+
/* Ignore the range out of filesystem area */
if (offset + len - 1 < ddev_start)
return -ENXIO;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 21f8b27bd9fd..9122a1c57dd2 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3183,6 +3183,7 @@ enum mf_flags {
MF_UNPOISON = 1 << 4,
MF_SW_SIMULATED 

[PATCH 2/3] fs: move drop_pagecache_sb() for others to use

2022-09-25 Thread Shiyang Ruan
xfs_notify_failure.c requires a method to invalidate all dax mappings.
drop_pagecache_sb() can do this but it is a static function and only
build with CONFIG_SYSCTL.  Now, move it to super.c and make it available
for others.  And use its second argument to choose which invalidate
method to use.

Signed-off-by: Shiyang Ruan 
---
 fs/drop_caches.c| 35 ++---
 fs/super.c  | 43 +
 include/linux/fs.h  |  1 +
 include/linux/pagemap.h |  1 +
 mm/truncate.c   | 20 +--
 5 files changed, 65 insertions(+), 35 deletions(-)

diff --git a/fs/drop_caches.c b/fs/drop_caches.c
index e619c31b6bd9..4c9281885077 100644
--- a/fs/drop_caches.c
+++ b/fs/drop_caches.c
@@ -15,38 +15,6 @@
 /* A global variable is a bit ugly, but it keeps the code simple */
 int sysctl_drop_caches;
 
-static void drop_pagecache_sb(struct super_block *sb, void *unused)
-{
-   struct inode *inode, *toput_inode = NULL;
-
-   spin_lock(>s_inode_list_lock);
-   list_for_each_entry(inode, >s_inodes, i_sb_list) {
-   spin_lock(>i_lock);
-   /*
-* We must skip inodes in unusual state. We may also skip
-* inodes without pages but we deliberately won't in case
-* we need to reschedule to avoid softlockups.
-*/
-   if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
-   (mapping_empty(inode->i_mapping) && !need_resched())) {
-   spin_unlock(>i_lock);
-   continue;
-   }
-   __iget(inode);
-   spin_unlock(>i_lock);
-   spin_unlock(>s_inode_list_lock);
-
-   invalidate_mapping_pages(inode->i_mapping, 0, -1);
-   iput(toput_inode);
-   toput_inode = inode;
-
-   cond_resched();
-   spin_lock(>s_inode_list_lock);
-   }
-   spin_unlock(>s_inode_list_lock);
-   iput(toput_inode);
-}
-
 int drop_caches_sysctl_handler(struct ctl_table *table, int write,
void *buffer, size_t *length, loff_t *ppos)
 {
@@ -59,7 +27,8 @@ int drop_caches_sysctl_handler(struct ctl_table *table, int 
write,
static int stfu;
 
if (sysctl_drop_caches & 1) {
-   iterate_supers(drop_pagecache_sb, NULL);
+   iterate_supers(super_drop_pagecache,
+  invalidate_inode_pages);
count_vm_event(DROP_PAGECACHE);
}
if (sysctl_drop_caches & 2) {
diff --git a/fs/super.c b/fs/super.c
index 734ed584a946..7cdbf146bc31 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "internal.h"
 
@@ -677,6 +678,48 @@ void drop_super_exclusive(struct super_block *sb)
 }
 EXPORT_SYMBOL(drop_super_exclusive);
 
+/*
+ * super_drop_pagecache - drop all page caches of a filesystem
+ * @sb: superblock to invalidate
+ * @arg: invalidate method, such as invalidate_inode_pages(),
+ * invalidate_inode_pages2()
+ *
+ * Scans the inodes of a filesystem, drop all page caches.
+ */
+void super_drop_pagecache(struct super_block *sb, void *arg)
+{
+   struct inode *inode, *toput_inode = NULL;
+   int (*invalidator)(struct address_space *) = arg;
+
+   spin_lock(>s_inode_list_lock);
+   list_for_each_entry(inode, >s_inodes, i_sb_list) {
+   spin_lock(>i_lock);
+   /*
+* We must skip inodes in unusual state. We may also skip
+* inodes without pages but we deliberately won't in case
+* we need to reschedule to avoid softlockups.
+*/
+   if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
+   (mapping_empty(inode->i_mapping) && !need_resched())) {
+   spin_unlock(>i_lock);
+   continue;
+   }
+   __iget(inode);
+   spin_unlock(>i_lock);
+   spin_unlock(>s_inode_list_lock);
+
+   invalidator(inode->i_mapping);
+   iput(toput_inode);
+   toput_inode = inode;
+
+   cond_resched();
+   spin_lock(>s_inode_list_lock);
+   }
+   spin_unlock(>s_inode_list_lock);
+   iput(toput_inode);
+}
+EXPORT_SYMBOL(super_drop_pagecache);
+
 static void __iterate_supers(void (*f)(struct super_block *))
 {
struct super_block *sb, *p = NULL;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9eced4cc286e..0e60c494688e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3292,6 +3292,7 @@ extern struct super_block *get_super(struct block_device 
*);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
 extern 

[PATCH 1/3] xfs: fix the calculation of length and end

2022-09-25 Thread Shiyang Ruan
The end should be start + length - 1.  Also fix the calculation of the
length when seeking for intersection of notify range and device.

Signed-off-by: Shiyang Ruan 
Reviewed-by: Darrick J. Wong 
---
 fs/xfs/xfs_notify_failure.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/xfs/xfs_notify_failure.c b/fs/xfs/xfs_notify_failure.c
index c4078d0ec108..3830f908e215 100644
--- a/fs/xfs/xfs_notify_failure.c
+++ b/fs/xfs/xfs_notify_failure.c
@@ -114,7 +114,7 @@ xfs_dax_notify_ddev_failure(
int error = 0;
xfs_fsblock_t   fsbno = XFS_DADDR_TO_FSB(mp, daddr);
xfs_agnumber_t  agno = XFS_FSB_TO_AGNO(mp, fsbno);
-   xfs_fsblock_t   end_fsbno = XFS_DADDR_TO_FSB(mp, daddr + bblen);
+   xfs_fsblock_t   end_fsbno = XFS_DADDR_TO_FSB(mp, daddr + bblen 
- 1);
xfs_agnumber_t  end_agno = XFS_FSB_TO_AGNO(mp, end_fsbno);
 
error = xfs_trans_alloc_empty(mp, );
@@ -210,7 +210,7 @@ xfs_dax_notify_failure(
ddev_end = ddev_start + bdev_nr_bytes(mp->m_ddev_targp->bt_bdev) - 1;
 
/* Ignore the range out of filesystem area */
-   if (offset + len < ddev_start)
+   if (offset + len - 1 < ddev_start)
return -ENXIO;
if (offset > ddev_end)
return -ENXIO;
@@ -222,8 +222,8 @@ xfs_dax_notify_failure(
len -= ddev_start - offset;
offset = 0;
}
-   if (offset + len > ddev_end)
-   len -= ddev_end - offset;
+   if (offset + len - 1 > ddev_end)
+   len -= offset + len - 1 - ddev_end;
 
return xfs_dax_notify_ddev_failure(mp, BTOBB(offset), BTOBB(len),
mf_flags);
-- 
2.37.3




[PATCH v9 0/3] mm, pmem, xfs: Introduce MF_MEM_REMOVE for unbind

2022-09-25 Thread Shiyang Ruan
Changes since v8:
  1. P2: rename drop_pagecache_sb() to super_drop_pagecache().
  2. P2: let super_drop_pagecache() accept invalidate method.
  3. P3: invalidate all dax mappings by invalidate_inode_pages2().
  4. P3: shutdown the filesystem when it is to be removed.
  5. Rebase on 6.0-rc6 + Darrick's patch[1] + Dan's patch[2].

[1]: https://lore.kernel.org/linux-xfs/Yv5wIa2crHioYeRr@magnolia/
[2]: 
https://lore.kernel.org/linux-xfs/166153426798.2758201.15108211981034512993.st...@dwillia2-xfh.jf.intel.com/

Shiyang Ruan (3):
  xfs: fix the calculation of length and end
  fs: move drop_pagecache_sb() for others to use
  mm, pmem, xfs: Introduce MF_MEM_REMOVE for unbind

 drivers/dax/super.c |  3 ++-
 fs/drop_caches.c| 35 ++
 fs/super.c  | 43 +
 fs/xfs/xfs_notify_failure.c | 36 ++-
 include/linux/fs.h  |  1 +
 include/linux/mm.h  |  1 +
 include/linux/pagemap.h |  1 +
 mm/truncate.c   | 20 +++--
 8 files changed, 99 insertions(+), 41 deletions(-)

-- 
2.37.3