Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "In this one: - d_move fixes (Eric Biederman) - UFS fixes (me; locking is mostly sane now, a bunch of bugs in error handling ought to be fixed) - switch of sb_writers to percpu rwsem (Oleg Nesterov) - superblock scalability (Josef Bacik and Dave Chinner) - swapon(2) race fix (Hugh Dickins)" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (65 commits) vfs: Test for and handle paths that are unreachable from their mnt_root dcache: Reduce the scope of i_lock in d_splice_alias dcache: Handle escaped paths in prepend_path mm: fix potential data race in SyS_swapon inode: don't softlockup when evicting inodes inode: rename i_wb_list to i_io_list sync: serialise per-superblock sync operations inode: convert inode_sb_list_lock to per-sb inode: add hlist_fake to avoid the inode hash lock in evict writeback: plug writeback at a high level change sb_writers to use percpu_rw_semaphore shift percpu_counter_destroy() into destroy_super_work() percpu-rwsem: kill CONFIG_PERCPU_RWSEM percpu-rwsem: introduce percpu_rwsem_release() and percpu_rwsem_acquire() percpu-rwsem: introduce percpu_down_read_trylock() document rwsem_release() in sb_wait_write() fix the broken lockdep logic in __sb_start_write() introduce __sb_writers_{acquired,release}() helpers ufs_inode_get{frag,block}(): get rid of 'phys' argument ufs_getfrag_block(): tidy up a bit ...
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#ifndef _LINUX_FS_H
|
||||
#define _LINUX_FS_H
|
||||
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/kdev_t.h>
|
||||
@@ -30,6 +29,8 @@
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/percpu-rwsem.h>
|
||||
#include <linux/blk_types.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/percpu-rwsem.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <uapi/linux/fs.h>
|
||||
@@ -636,7 +637,7 @@ struct inode {
|
||||
unsigned long dirtied_time_when;
|
||||
|
||||
struct hlist_node i_hash;
|
||||
struct list_head i_wb_list; /* backing dev IO list */
|
||||
struct list_head i_io_list; /* backing dev IO list */
|
||||
#ifdef CONFIG_CGROUP_WRITEBACK
|
||||
struct bdi_writeback *i_wb; /* the associated cgroup wb */
|
||||
|
||||
@@ -1281,16 +1282,9 @@ enum {
|
||||
#define SB_FREEZE_LEVELS (SB_FREEZE_COMPLETE - 1)
|
||||
|
||||
struct sb_writers {
|
||||
/* Counters for counting writers at each level */
|
||||
struct percpu_counter counter[SB_FREEZE_LEVELS];
|
||||
wait_queue_head_t wait; /* queue for waiting for
|
||||
writers / faults to finish */
|
||||
int frozen; /* Is sb frozen? */
|
||||
wait_queue_head_t wait_unfrozen; /* queue for waiting for
|
||||
sb to be thawed */
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
struct lockdep_map lock_map[SB_FREEZE_LEVELS];
|
||||
#endif
|
||||
int frozen; /* Is sb frozen? */
|
||||
wait_queue_head_t wait_unfrozen; /* for get_super_thawed() */
|
||||
struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS];
|
||||
};
|
||||
|
||||
struct super_block {
|
||||
@@ -1316,7 +1310,6 @@ struct super_block {
|
||||
#endif
|
||||
const struct xattr_handler **s_xattr;
|
||||
|
||||
struct list_head s_inodes; /* all inodes */
|
||||
struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
|
||||
struct list_head s_mounts; /* list of mounts; _not_ for fs use */
|
||||
struct block_device *s_bdev;
|
||||
@@ -1382,11 +1375,18 @@ struct super_block {
|
||||
struct list_lru s_dentry_lru ____cacheline_aligned_in_smp;
|
||||
struct list_lru s_inode_lru ____cacheline_aligned_in_smp;
|
||||
struct rcu_head rcu;
|
||||
struct work_struct destroy_work;
|
||||
|
||||
struct mutex s_sync_lock; /* sync serialisation lock */
|
||||
|
||||
/*
|
||||
* Indicates how deep in a filesystem stack this SB is
|
||||
*/
|
||||
int s_stack_depth;
|
||||
|
||||
/* s_inode_list_lock protects s_inodes */
|
||||
spinlock_t s_inode_list_lock ____cacheline_aligned_in_smp;
|
||||
struct list_head s_inodes; /* all inodes */
|
||||
};
|
||||
|
||||
extern struct timespec current_fs_time(struct super_block *sb);
|
||||
@@ -1398,6 +1398,11 @@ extern struct timespec current_fs_time(struct super_block *sb);
|
||||
void __sb_end_write(struct super_block *sb, int level);
|
||||
int __sb_start_write(struct super_block *sb, int level, bool wait);
|
||||
|
||||
#define __sb_writers_acquired(sb, lev) \
|
||||
percpu_rwsem_acquire(&(sb)->s_writers.rw_sem[(lev)-1], 1, _THIS_IP_)
|
||||
#define __sb_writers_release(sb, lev) \
|
||||
percpu_rwsem_release(&(sb)->s_writers.rw_sem[(lev)-1], 1, _THIS_IP_)
|
||||
|
||||
/**
|
||||
* sb_end_write - drop write access to a superblock
|
||||
* @sb: the super we wrote to
|
||||
@@ -2614,7 +2619,7 @@ static inline void insert_inode_hash(struct inode *inode)
|
||||
extern void __remove_inode_hash(struct inode *);
|
||||
static inline void remove_inode_hash(struct inode *inode)
|
||||
{
|
||||
if (!inode_unhashed(inode))
|
||||
if (!inode_unhashed(inode) && !hlist_fake(&inode->i_hash))
|
||||
__remove_inode_hash(inode);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user