diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-18 12:35:08 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-18 12:35:08 -0400 |
| commit | 145c3ae46b37993b0debb0b3da6256daea4a6ec5 (patch) | |
| tree | 0dbff382ce36b23b3d2dbff87d3eaab73a07a2a4 /include | |
| parent | 81ca03a0e2ea0207b2df80e0edcf4c775c07a505 (diff) | |
| parent | 99b7db7b8ffd6bb755eb0a175596421a0b581cb2 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
fs: brlock vfsmount_lock
fs: scale files_lock
lglock: introduce special lglock and brlock spin locks
tty: fix fu_list abuse
fs: cleanup files_lock locking
fs: remove extra lookup in __lookup_hash
fs: fs_struct rwlock to spinlock
apparmor: use task path helpers
fs: dentry allocation consolidation
fs: fix do_lookup false negative
mbcache: Limit the maximum number of cache entries
hostfs ->follow_link() braino
hostfs: dumb (and usually harmless) tpyo - strncpy instead of strlcpy
remove SWRITE* I/O types
kill BH_Ordered flag
vfs: update ctime when changing the file's permission by setfacl
cramfs: only unlock new inodes
fix reiserfs_evict_inode end_writeback second call
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/buffer_head.h | 4 | ||||
| -rw-r--r-- | include/linux/fs.h | 21 | ||||
| -rw-r--r-- | include/linux/fs_struct.h | 14 | ||||
| -rw-r--r-- | include/linux/lglock.h | 172 | ||||
| -rw-r--r-- | include/linux/tty.h | 9 |
5 files changed, 197 insertions, 23 deletions
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 43e649a72529..ec94c12f21da 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
| @@ -32,7 +32,6 @@ enum bh_state_bits { | |||
| 32 | BH_Delay, /* Buffer is not yet allocated on disk */ | 32 | BH_Delay, /* Buffer is not yet allocated on disk */ |
| 33 | BH_Boundary, /* Block is followed by a discontiguity */ | 33 | BH_Boundary, /* Block is followed by a discontiguity */ |
| 34 | BH_Write_EIO, /* I/O error on write */ | 34 | BH_Write_EIO, /* I/O error on write */ |
| 35 | BH_Ordered, /* ordered write */ | ||
| 36 | BH_Eopnotsupp, /* operation not supported (barrier) */ | 35 | BH_Eopnotsupp, /* operation not supported (barrier) */ |
| 37 | BH_Unwritten, /* Buffer is allocated on disk but not written */ | 36 | BH_Unwritten, /* Buffer is allocated on disk but not written */ |
| 38 | BH_Quiet, /* Buffer Error Prinks to be quiet */ | 37 | BH_Quiet, /* Buffer Error Prinks to be quiet */ |
| @@ -125,7 +124,6 @@ BUFFER_FNS(Async_Write, async_write) | |||
| 125 | BUFFER_FNS(Delay, delay) | 124 | BUFFER_FNS(Delay, delay) |
| 126 | BUFFER_FNS(Boundary, boundary) | 125 | BUFFER_FNS(Boundary, boundary) |
| 127 | BUFFER_FNS(Write_EIO, write_io_error) | 126 | BUFFER_FNS(Write_EIO, write_io_error) |
| 128 | BUFFER_FNS(Ordered, ordered) | ||
| 129 | BUFFER_FNS(Eopnotsupp, eopnotsupp) | 127 | BUFFER_FNS(Eopnotsupp, eopnotsupp) |
| 130 | BUFFER_FNS(Unwritten, unwritten) | 128 | BUFFER_FNS(Unwritten, unwritten) |
| 131 | 129 | ||
| @@ -183,6 +181,8 @@ void unlock_buffer(struct buffer_head *bh); | |||
| 183 | void __lock_buffer(struct buffer_head *bh); | 181 | void __lock_buffer(struct buffer_head *bh); |
| 184 | void ll_rw_block(int, int, struct buffer_head * bh[]); | 182 | void ll_rw_block(int, int, struct buffer_head * bh[]); |
| 185 | int sync_dirty_buffer(struct buffer_head *bh); | 183 | int sync_dirty_buffer(struct buffer_head *bh); |
| 184 | int __sync_dirty_buffer(struct buffer_head *bh, int rw); | ||
| 185 | void write_dirty_buffer(struct buffer_head *bh, int rw); | ||
| 186 | int submit_bh(int, struct buffer_head *); | 186 | int submit_bh(int, struct buffer_head *); |
| 187 | void write_boundary_block(struct block_device *bdev, | 187 | void write_boundary_block(struct block_device *bdev, |
| 188 | sector_t bblock, unsigned blocksize); | 188 | sector_t bblock, unsigned blocksize); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 9a96b4d83fc1..76041b614758 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -125,9 +125,6 @@ struct inodes_stat_t { | |||
| 125 | * block layer could (in theory) choose to ignore this | 125 | * block layer could (in theory) choose to ignore this |
| 126 | * request if it runs into resource problems. | 126 | * request if it runs into resource problems. |
| 127 | * WRITE A normal async write. Device will be plugged. | 127 | * WRITE A normal async write. Device will be plugged. |
| 128 | * SWRITE Like WRITE, but a special case for ll_rw_block() that | ||
| 129 | * tells it to lock the buffer first. Normally a buffer | ||
| 130 | * must be locked before doing IO. | ||
| 131 | * WRITE_SYNC_PLUG Synchronous write. Identical to WRITE, but passes down | 128 | * WRITE_SYNC_PLUG Synchronous write. Identical to WRITE, but passes down |
| 132 | * the hint that someone will be waiting on this IO | 129 | * the hint that someone will be waiting on this IO |
| 133 | * shortly. The device must still be unplugged explicitly, | 130 | * shortly. The device must still be unplugged explicitly, |
| @@ -138,9 +135,6 @@ struct inodes_stat_t { | |||
| 138 | * immediately after submission. The write equivalent | 135 | * immediately after submission. The write equivalent |
| 139 | * of READ_SYNC. | 136 | * of READ_SYNC. |
| 140 | * WRITE_ODIRECT_PLUG Special case write for O_DIRECT only. | 137 | * WRITE_ODIRECT_PLUG Special case write for O_DIRECT only. |
| 141 | * SWRITE_SYNC | ||
| 142 | * SWRITE_SYNC_PLUG Like WRITE_SYNC/WRITE_SYNC_PLUG, but locks the buffer. | ||
| 143 | * See SWRITE. | ||
| 144 | * WRITE_BARRIER Like WRITE_SYNC, but tells the block layer that all | 138 | * WRITE_BARRIER Like WRITE_SYNC, but tells the block layer that all |
| 145 | * previously submitted writes must be safely on storage | 139 | * previously submitted writes must be safely on storage |
| 146 | * before this one is started. Also guarantees that when | 140 | * before this one is started. Also guarantees that when |
| @@ -155,7 +149,6 @@ struct inodes_stat_t { | |||
| 155 | #define READ 0 | 149 | #define READ 0 |
| 156 | #define WRITE RW_MASK | 150 | #define WRITE RW_MASK |
| 157 | #define READA RWA_MASK | 151 | #define READA RWA_MASK |
| 158 | #define SWRITE (WRITE | READA) | ||
| 159 | 152 | ||
| 160 | #define READ_SYNC (READ | REQ_SYNC | REQ_UNPLUG) | 153 | #define READ_SYNC (READ | REQ_SYNC | REQ_UNPLUG) |
| 161 | #define READ_META (READ | REQ_META) | 154 | #define READ_META (READ | REQ_META) |
| @@ -165,8 +158,6 @@ struct inodes_stat_t { | |||
| 165 | #define WRITE_META (WRITE | REQ_META) | 158 | #define WRITE_META (WRITE | REQ_META) |
| 166 | #define WRITE_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \ | 159 | #define WRITE_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \ |
| 167 | REQ_HARDBARRIER) | 160 | REQ_HARDBARRIER) |
| 168 | #define SWRITE_SYNC_PLUG (SWRITE | REQ_SYNC | REQ_NOIDLE) | ||
| 169 | #define SWRITE_SYNC (SWRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG) | ||
| 170 | 161 | ||
| 171 | /* | 162 | /* |
| 172 | * These aren't really reads or writes, they pass down information about | 163 | * These aren't really reads or writes, they pass down information about |
| @@ -929,6 +920,9 @@ struct file { | |||
| 929 | #define f_vfsmnt f_path.mnt | 920 | #define f_vfsmnt f_path.mnt |
| 930 | const struct file_operations *f_op; | 921 | const struct file_operations *f_op; |
| 931 | spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */ | 922 | spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */ |
| 923 | #ifdef CONFIG_SMP | ||
| 924 | int f_sb_list_cpu; | ||
| 925 | #endif | ||
| 932 | atomic_long_t f_count; | 926 | atomic_long_t f_count; |
| 933 | unsigned int f_flags; | 927 | unsigned int f_flags; |
| 934 | fmode_t f_mode; | 928 | fmode_t f_mode; |
| @@ -953,9 +947,6 @@ struct file { | |||
| 953 | unsigned long f_mnt_write_state; | 947 | unsigned long f_mnt_write_state; |
| 954 | #endif | 948 | #endif |
| 955 | }; | 949 | }; |
| 956 | extern spinlock_t files_lock; | ||
| 957 | #define file_list_lock() spin_lock(&files_lock); | ||
| 958 | #define file_list_unlock() spin_unlock(&files_lock); | ||
| 959 | 950 | ||
| 960 | #define get_file(x) atomic_long_inc(&(x)->f_count) | 951 | #define get_file(x) atomic_long_inc(&(x)->f_count) |
| 961 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) | 952 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) |
| @@ -1346,7 +1337,11 @@ struct super_block { | |||
| 1346 | 1337 | ||
| 1347 | struct list_head s_inodes; /* all inodes */ | 1338 | struct list_head s_inodes; /* all inodes */ |
| 1348 | struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ | 1339 | struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ |
| 1340 | #ifdef CONFIG_SMP | ||
| 1341 | struct list_head __percpu *s_files; | ||
| 1342 | #else | ||
| 1349 | struct list_head s_files; | 1343 | struct list_head s_files; |
| 1344 | #endif | ||
| 1350 | /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */ | 1345 | /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */ |
| 1351 | struct list_head s_dentry_lru; /* unused dentry lru */ | 1346 | struct list_head s_dentry_lru; /* unused dentry lru */ |
| 1352 | int s_nr_dentry_unused; /* # of dentry on lru */ | 1347 | int s_nr_dentry_unused; /* # of dentry on lru */ |
| @@ -2197,8 +2192,6 @@ static inline void insert_inode_hash(struct inode *inode) { | |||
| 2197 | __insert_inode_hash(inode, inode->i_ino); | 2192 | __insert_inode_hash(inode, inode->i_ino); |
| 2198 | } | 2193 | } |
| 2199 | 2194 | ||
| 2200 | extern void file_move(struct file *f, struct list_head *list); | ||
| 2201 | extern void file_kill(struct file *f); | ||
| 2202 | #ifdef CONFIG_BLOCK | 2195 | #ifdef CONFIG_BLOCK |
| 2203 | extern void submit_bio(int, struct bio *); | 2196 | extern void submit_bio(int, struct bio *); |
| 2204 | extern int bdev_read_only(struct block_device *); | 2197 | extern int bdev_read_only(struct block_device *); |
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index eca3d5202138..a42b5bf02f8b 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | struct fs_struct { | 6 | struct fs_struct { |
| 7 | int users; | 7 | int users; |
| 8 | rwlock_t lock; | 8 | spinlock_t lock; |
| 9 | int umask; | 9 | int umask; |
| 10 | int in_exec; | 10 | int in_exec; |
| 11 | struct path root, pwd; | 11 | struct path root, pwd; |
| @@ -23,29 +23,29 @@ extern int unshare_fs_struct(void); | |||
| 23 | 23 | ||
| 24 | static inline void get_fs_root(struct fs_struct *fs, struct path *root) | 24 | static inline void get_fs_root(struct fs_struct *fs, struct path *root) |
| 25 | { | 25 | { |
| 26 | read_lock(&fs->lock); | 26 | spin_lock(&fs->lock); |
| 27 | *root = fs->root; | 27 | *root = fs->root; |
| 28 | path_get(root); | 28 | path_get(root); |
| 29 | read_unlock(&fs->lock); | 29 | spin_unlock(&fs->lock); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) | 32 | static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) |
| 33 | { | 33 | { |
| 34 | read_lock(&fs->lock); | 34 | spin_lock(&fs->lock); |
| 35 | *pwd = fs->pwd; | 35 | *pwd = fs->pwd; |
| 36 | path_get(pwd); | 36 | path_get(pwd); |
| 37 | read_unlock(&fs->lock); | 37 | spin_unlock(&fs->lock); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, | 40 | static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, |
| 41 | struct path *pwd) | 41 | struct path *pwd) |
| 42 | { | 42 | { |
| 43 | read_lock(&fs->lock); | 43 | spin_lock(&fs->lock); |
| 44 | *root = fs->root; | 44 | *root = fs->root; |
| 45 | path_get(root); | 45 | path_get(root); |
| 46 | *pwd = fs->pwd; | 46 | *pwd = fs->pwd; |
| 47 | path_get(pwd); | 47 | path_get(pwd); |
| 48 | read_unlock(&fs->lock); | 48 | spin_unlock(&fs->lock); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | #endif /* _LINUX_FS_STRUCT_H */ | 51 | #endif /* _LINUX_FS_STRUCT_H */ |
diff --git a/include/linux/lglock.h b/include/linux/lglock.h new file mode 100644 index 000000000000..b288cb713b90 --- /dev/null +++ b/include/linux/lglock.h | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | /* | ||
| 2 | * Specialised local-global spinlock. Can only be declared as global variables | ||
| 3 | * to avoid overhead and keep things simple (and we don't want to start using | ||
| 4 | * these inside dynamically allocated structures). | ||
| 5 | * | ||
| 6 | * "local/global locks" (lglocks) can be used to: | ||
| 7 | * | ||
| 8 | * - Provide fast exclusive access to per-CPU data, with exclusive access to | ||
| 9 | * another CPU's data allowed but possibly subject to contention, and to | ||
| 10 | * provide very slow exclusive access to all per-CPU data. | ||
| 11 | * - Or to provide very fast and scalable read serialisation, and to provide | ||
| 12 | * very slow exclusive serialisation of data (not necessarily per-CPU data). | ||
| 13 | * | ||
| 14 | * Brlocks are also implemented as a short-hand notation for the latter use | ||
| 15 | * case. | ||
| 16 | * | ||
| 17 | * Copyright 2009, 2010, Nick Piggin, Novell Inc. | ||
| 18 | */ | ||
| 19 | #ifndef __LINUX_LGLOCK_H | ||
| 20 | #define __LINUX_LGLOCK_H | ||
| 21 | |||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/lockdep.h> | ||
| 24 | #include <linux/percpu.h> | ||
| 25 | |||
| 26 | /* can make br locks by using local lock for read side, global lock for write */ | ||
| 27 | #define br_lock_init(name) name##_lock_init() | ||
| 28 | #define br_read_lock(name) name##_local_lock() | ||
| 29 | #define br_read_unlock(name) name##_local_unlock() | ||
| 30 | #define br_write_lock(name) name##_global_lock_online() | ||
| 31 | #define br_write_unlock(name) name##_global_unlock_online() | ||
| 32 | |||
| 33 | #define DECLARE_BRLOCK(name) DECLARE_LGLOCK(name) | ||
| 34 | #define DEFINE_BRLOCK(name) DEFINE_LGLOCK(name) | ||
| 35 | |||
| 36 | |||
| 37 | #define lg_lock_init(name) name##_lock_init() | ||
| 38 | #define lg_local_lock(name) name##_local_lock() | ||
| 39 | #define lg_local_unlock(name) name##_local_unlock() | ||
| 40 | #define lg_local_lock_cpu(name, cpu) name##_local_lock_cpu(cpu) | ||
| 41 | #define lg_local_unlock_cpu(name, cpu) name##_local_unlock_cpu(cpu) | ||
| 42 | #define lg_global_lock(name) name##_global_lock() | ||
| 43 | #define lg_global_unlock(name) name##_global_unlock() | ||
| 44 | #define lg_global_lock_online(name) name##_global_lock_online() | ||
| 45 | #define lg_global_unlock_online(name) name##_global_unlock_online() | ||
| 46 | |||
| 47 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 48 | #define LOCKDEP_INIT_MAP lockdep_init_map | ||
| 49 | |||
| 50 | #define DEFINE_LGLOCK_LOCKDEP(name) \ | ||
| 51 | struct lock_class_key name##_lock_key; \ | ||
| 52 | struct lockdep_map name##_lock_dep_map; \ | ||
| 53 | EXPORT_SYMBOL(name##_lock_dep_map) | ||
| 54 | |||
| 55 | #else | ||
| 56 | #define LOCKDEP_INIT_MAP(a, b, c, d) | ||
| 57 | |||
| 58 | #define DEFINE_LGLOCK_LOCKDEP(name) | ||
| 59 | #endif | ||
| 60 | |||
| 61 | |||
| 62 | #define DECLARE_LGLOCK(name) \ | ||
| 63 | extern void name##_lock_init(void); \ | ||
| 64 | extern void name##_local_lock(void); \ | ||
| 65 | extern void name##_local_unlock(void); \ | ||
| 66 | extern void name##_local_lock_cpu(int cpu); \ | ||
| 67 | extern void name##_local_unlock_cpu(int cpu); \ | ||
| 68 | extern void name##_global_lock(void); \ | ||
| 69 | extern void name##_global_unlock(void); \ | ||
| 70 | extern void name##_global_lock_online(void); \ | ||
| 71 | extern void name##_global_unlock_online(void); \ | ||
| 72 | |||
| 73 | #define DEFINE_LGLOCK(name) \ | ||
| 74 | \ | ||
| 75 | DEFINE_PER_CPU(arch_spinlock_t, name##_lock); \ | ||
| 76 | DEFINE_LGLOCK_LOCKDEP(name); \ | ||
| 77 | \ | ||
| 78 | void name##_lock_init(void) { \ | ||
| 79 | int i; \ | ||
| 80 | LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \ | ||
| 81 | for_each_possible_cpu(i) { \ | ||
| 82 | arch_spinlock_t *lock; \ | ||
| 83 | lock = &per_cpu(name##_lock, i); \ | ||
| 84 | *lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; \ | ||
| 85 | } \ | ||
| 86 | } \ | ||
| 87 | EXPORT_SYMBOL(name##_lock_init); \ | ||
| 88 | \ | ||
| 89 | void name##_local_lock(void) { \ | ||
| 90 | arch_spinlock_t *lock; \ | ||
| 91 | preempt_disable(); \ | ||
| 92 | rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \ | ||
| 93 | lock = &__get_cpu_var(name##_lock); \ | ||
| 94 | arch_spin_lock(lock); \ | ||
| 95 | } \ | ||
| 96 | EXPORT_SYMBOL(name##_local_lock); \ | ||
| 97 | \ | ||
| 98 | void name##_local_unlock(void) { \ | ||
| 99 | arch_spinlock_t *lock; \ | ||
| 100 | rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \ | ||
| 101 | lock = &__get_cpu_var(name##_lock); \ | ||
| 102 | arch_spin_unlock(lock); \ | ||
| 103 | preempt_enable(); \ | ||
| 104 | } \ | ||
| 105 | EXPORT_SYMBOL(name##_local_unlock); \ | ||
| 106 | \ | ||
| 107 | void name##_local_lock_cpu(int cpu) { \ | ||
| 108 | arch_spinlock_t *lock; \ | ||
| 109 | preempt_disable(); \ | ||
| 110 | rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \ | ||
| 111 | lock = &per_cpu(name##_lock, cpu); \ | ||
| 112 | arch_spin_lock(lock); \ | ||
| 113 | } \ | ||
| 114 | EXPORT_SYMBOL(name##_local_lock_cpu); \ | ||
| 115 | \ | ||
| 116 | void name##_local_unlock_cpu(int cpu) { \ | ||
| 117 | arch_spinlock_t *lock; \ | ||
| 118 | rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \ | ||
| 119 | lock = &per_cpu(name##_lock, cpu); \ | ||
| 120 | arch_spin_unlock(lock); \ | ||
| 121 | preempt_enable(); \ | ||
| 122 | } \ | ||
| 123 | EXPORT_SYMBOL(name##_local_unlock_cpu); \ | ||
| 124 | \ | ||
| 125 | void name##_global_lock_online(void) { \ | ||
| 126 | int i; \ | ||
| 127 | preempt_disable(); \ | ||
| 128 | rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ | ||
| 129 | for_each_online_cpu(i) { \ | ||
| 130 | arch_spinlock_t *lock; \ | ||
| 131 | lock = &per_cpu(name##_lock, i); \ | ||
| 132 | arch_spin_lock(lock); \ | ||
| 133 | } \ | ||
| 134 | } \ | ||
| 135 | EXPORT_SYMBOL(name##_global_lock_online); \ | ||
| 136 | \ | ||
| 137 | void name##_global_unlock_online(void) { \ | ||
| 138 | int i; \ | ||
| 139 | rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ | ||
| 140 | for_each_online_cpu(i) { \ | ||
| 141 | arch_spinlock_t *lock; \ | ||
| 142 | lock = &per_cpu(name##_lock, i); \ | ||
| 143 | arch_spin_unlock(lock); \ | ||
| 144 | } \ | ||
| 145 | preempt_enable(); \ | ||
| 146 | } \ | ||
| 147 | EXPORT_SYMBOL(name##_global_unlock_online); \ | ||
| 148 | \ | ||
| 149 | void name##_global_lock(void) { \ | ||
| 150 | int i; \ | ||
| 151 | preempt_disable(); \ | ||
| 152 | rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ | ||
| 153 | for_each_online_cpu(i) { \ | ||
| 154 | arch_spinlock_t *lock; \ | ||
| 155 | lock = &per_cpu(name##_lock, i); \ | ||
| 156 | arch_spin_lock(lock); \ | ||
| 157 | } \ | ||
| 158 | } \ | ||
| 159 | EXPORT_SYMBOL(name##_global_lock); \ | ||
| 160 | \ | ||
| 161 | void name##_global_unlock(void) { \ | ||
| 162 | int i; \ | ||
| 163 | rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ | ||
| 164 | for_each_online_cpu(i) { \ | ||
| 165 | arch_spinlock_t *lock; \ | ||
| 166 | lock = &per_cpu(name##_lock, i); \ | ||
| 167 | arch_spin_unlock(lock); \ | ||
| 168 | } \ | ||
| 169 | preempt_enable(); \ | ||
| 170 | } \ | ||
| 171 | EXPORT_SYMBOL(name##_global_unlock); | ||
| 172 | #endif | ||
diff --git a/include/linux/tty.h b/include/linux/tty.h index 1437da3ddc62..67d64e6efe7a 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -329,6 +329,13 @@ struct tty_struct { | |||
| 329 | struct tty_port *port; | 329 | struct tty_port *port; |
| 330 | }; | 330 | }; |
| 331 | 331 | ||
| 332 | /* Each of a tty's open files has private_data pointing to tty_file_private */ | ||
| 333 | struct tty_file_private { | ||
| 334 | struct tty_struct *tty; | ||
| 335 | struct file *file; | ||
| 336 | struct list_head list; | ||
| 337 | }; | ||
| 338 | |||
| 332 | /* tty magic number */ | 339 | /* tty magic number */ |
| 333 | #define TTY_MAGIC 0x5401 | 340 | #define TTY_MAGIC 0x5401 |
| 334 | 341 | ||
| @@ -458,6 +465,7 @@ extern void proc_clear_tty(struct task_struct *p); | |||
| 458 | extern struct tty_struct *get_current_tty(void); | 465 | extern struct tty_struct *get_current_tty(void); |
| 459 | extern void tty_default_fops(struct file_operations *fops); | 466 | extern void tty_default_fops(struct file_operations *fops); |
| 460 | extern struct tty_struct *alloc_tty_struct(void); | 467 | extern struct tty_struct *alloc_tty_struct(void); |
| 468 | extern void tty_add_file(struct tty_struct *tty, struct file *file); | ||
| 461 | extern void free_tty_struct(struct tty_struct *tty); | 469 | extern void free_tty_struct(struct tty_struct *tty); |
| 462 | extern void initialize_tty_struct(struct tty_struct *tty, | 470 | extern void initialize_tty_struct(struct tty_struct *tty, |
| 463 | struct tty_driver *driver, int idx); | 471 | struct tty_driver *driver, int idx); |
| @@ -470,6 +478,7 @@ extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty); | |||
| 470 | extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); | 478 | extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); |
| 471 | 479 | ||
| 472 | extern struct mutex tty_mutex; | 480 | extern struct mutex tty_mutex; |
| 481 | extern spinlock_t tty_files_lock; | ||
| 473 | 482 | ||
| 474 | extern void tty_write_unlock(struct tty_struct *tty); | 483 | extern void tty_write_unlock(struct tty_struct *tty); |
| 475 | extern int tty_write_lock(struct tty_struct *tty, int ndelay); | 484 | extern int tty_write_lock(struct tty_struct *tty, int ndelay); |
