[PATCH] dax: Remove usage of the deprecated ida_simple_xxx API
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
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
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
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
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
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
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