From 45996492e5c85aa0ac93a95d1b2d1ed56851c865 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 25 Mar 2016 19:56:34 -0400 Subject: orangefs: fix orangefs_superblock locking * switch orangefs_remount() to taking ORANGEFS_SB(sb) instead of sb * remove from the list _before_ orangefs_unmount() - request_mutex in the latter will make sure that nothing observed in the loop in ORANGEFS_DEV_REMOUNT_ALL handling will get freed until the end of loop * on removal, keep the forward pointer and zero the back one. That way we can drop and regain the spinlock in the loop body (again, ORANGEFS_DEV_REMOUNT_ALL one) and still be able to get to the rest of the list. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) (limited to 'fs/orangefs/orangefs-kernel.h') diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index db258d2ccc6a..a9925e296ceb 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -462,7 +462,7 @@ struct dentry *orangefs_mount(struct file_system_type *fst, void *data); void orangefs_kill_sb(struct super_block *sb); -int orangefs_remount(struct super_block *sb); +int orangefs_remount(struct orangefs_sb_info_s *); int fsid_key_table_initialize(void); void fsid_key_table_finalize(void); @@ -598,38 +598,6 @@ int service_operation(struct orangefs_kernel_op_s *op, ((ORANGEFS_SB(inode->i_sb)->flags & ORANGEFS_OPT_INTR) ? \ ORANGEFS_OP_INTERRUPTIBLE : 0) -#define add_orangefs_sb(sb) \ -do { \ - gossip_debug(GOSSIP_SUPER_DEBUG, \ - "Adding SB %p to orangefs superblocks\n", \ - ORANGEFS_SB(sb)); \ - spin_lock(&orangefs_superblocks_lock); \ - list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks); \ - spin_unlock(&orangefs_superblocks_lock); \ -} while (0) - -#define remove_orangefs_sb(sb) \ -do { \ - struct list_head *tmp = NULL; \ - struct list_head *tmp_safe = NULL; \ - struct orangefs_sb_info_s *orangefs_sb = NULL; \ - \ - spin_lock(&orangefs_superblocks_lock); \ - list_for_each_safe(tmp, tmp_safe, &orangefs_superblocks) { \ - orangefs_sb = list_entry(tmp, \ - struct orangefs_sb_info_s, \ - list); \ - if (orangefs_sb && (orangefs_sb->sb == sb)) { \ - gossip_debug(GOSSIP_SUPER_DEBUG, \ - "Removing SB %p from orangefs superblocks\n", \ - orangefs_sb); \ - list_del(&orangefs_sb->list); \ - break; \ - } \ - } \ - spin_unlock(&orangefs_superblocks_lock); \ -} while (0) - #define fill_default_sys_attrs(sys_attr, type, mode) \ do { \ sys_attr.owner = from_kuid(current_user_ns(), current_fsuid()); \ -- cgit v1.2.3