diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/reiserfs_fs.h | 71 | ||||
-rw-r--r-- | include/linux/reiserfs_fs_sb.h | 20 |
2 files changed, 83 insertions, 8 deletions
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index dd31e7bae35c..a05b4a20768d 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h | |||
@@ -52,11 +52,63 @@ | |||
52 | #define REISERFS_IOC32_GETVERSION FS_IOC32_GETVERSION | 52 | #define REISERFS_IOC32_GETVERSION FS_IOC32_GETVERSION |
53 | #define REISERFS_IOC32_SETVERSION FS_IOC32_SETVERSION | 53 | #define REISERFS_IOC32_SETVERSION FS_IOC32_SETVERSION |
54 | 54 | ||
55 | /* Locking primitives */ | 55 | /* |
56 | /* Right now we are still falling back to (un)lock_kernel, but eventually that | 56 | * Locking primitives. The write lock is a per superblock |
57 | would evolve into real per-fs locks */ | 57 | * special mutex that has properties close to the Big Kernel Lock |
58 | #define reiserfs_write_lock( sb ) lock_kernel() | 58 | * which was used in the previous locking scheme. |
59 | #define reiserfs_write_unlock( sb ) unlock_kernel() | 59 | */ |
60 | void reiserfs_write_lock(struct super_block *s); | ||
61 | void reiserfs_write_unlock(struct super_block *s); | ||
62 | int reiserfs_write_lock_once(struct super_block *s); | ||
63 | void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); | ||
64 | |||
65 | /* | ||
66 | * Several mutexes depend on the write lock. | ||
67 | * However sometimes we want to relax the write lock while we hold | ||
68 | * these mutexes, according to the release/reacquire on schedule() | ||
69 | * properties of the Bkl that were used. | ||
70 | * Reiserfs performances and locking were based on this scheme. | ||
71 | * Now that the write lock is a mutex and not the bkl anymore, doing so | ||
72 | * may result in a deadlock: | ||
73 | * | ||
74 | * A acquire write_lock | ||
75 | * A acquire j_commit_mutex | ||
76 | * A release write_lock and wait for something | ||
77 | * B acquire write_lock | ||
78 | * B can't acquire j_commit_mutex and sleep | ||
79 | * A can't acquire write lock anymore | ||
80 | * deadlock | ||
81 | * | ||
82 | * What we do here is avoiding such deadlock by playing the same game | ||
83 | * than the Bkl: if we can't acquire a mutex that depends on the write lock, | ||
84 | * we release the write lock, wait a bit and then retry. | ||
85 | * | ||
86 | * The mutexes concerned by this hack are: | ||
87 | * - The commit mutex of a journal list | ||
88 | * - The flush mutex | ||
89 | * - The journal lock | ||
90 | * - The inode mutex | ||
91 | */ | ||
92 | static inline void reiserfs_mutex_lock_safe(struct mutex *m, | ||
93 | struct super_block *s) | ||
94 | { | ||
95 | reiserfs_write_unlock(s); | ||
96 | mutex_lock(m); | ||
97 | reiserfs_write_lock(s); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * When we schedule, we usually want to also release the write lock, | ||
102 | * according to the previous bkl based locking scheme of reiserfs. | ||
103 | */ | ||
104 | static inline void reiserfs_cond_resched(struct super_block *s) | ||
105 | { | ||
106 | if (need_resched()) { | ||
107 | reiserfs_write_unlock(s); | ||
108 | schedule(); | ||
109 | reiserfs_write_lock(s); | ||
110 | } | ||
111 | } | ||
60 | 112 | ||
61 | struct fid; | 113 | struct fid; |
62 | 114 | ||
@@ -1329,7 +1381,11 @@ static inline loff_t max_reiserfs_offset(struct inode *inode) | |||
1329 | #define get_generation(s) atomic_read (&fs_generation(s)) | 1381 | #define get_generation(s) atomic_read (&fs_generation(s)) |
1330 | #define FILESYSTEM_CHANGED_TB(tb) (get_generation((tb)->tb_sb) != (tb)->fs_gen) | 1382 | #define FILESYSTEM_CHANGED_TB(tb) (get_generation((tb)->tb_sb) != (tb)->fs_gen) |
1331 | #define __fs_changed(gen,s) (gen != get_generation (s)) | 1383 | #define __fs_changed(gen,s) (gen != get_generation (s)) |
1332 | #define fs_changed(gen,s) ({cond_resched(); __fs_changed(gen, s);}) | 1384 | #define fs_changed(gen,s) \ |
1385 | ({ \ | ||
1386 | reiserfs_cond_resched(s); \ | ||
1387 | __fs_changed(gen, s); \ | ||
1388 | }) | ||
1333 | 1389 | ||
1334 | /***************************************************************************/ | 1390 | /***************************************************************************/ |
1335 | /* FIXATE NODES */ | 1391 | /* FIXATE NODES */ |
@@ -2258,8 +2314,7 @@ __u32 r5_hash(const signed char *msg, int len); | |||
2258 | #define SPARE_SPACE 500 | 2314 | #define SPARE_SPACE 500 |
2259 | 2315 | ||
2260 | /* prototypes from ioctl.c */ | 2316 | /* prototypes from ioctl.c */ |
2261 | int reiserfs_ioctl(struct inode *inode, struct file *filp, | 2317 | long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); |
2262 | unsigned int cmd, unsigned long arg); | ||
2263 | long reiserfs_compat_ioctl(struct file *filp, | 2318 | long reiserfs_compat_ioctl(struct file *filp, |
2264 | unsigned int cmd, unsigned long arg); | 2319 | unsigned int cmd, unsigned long arg); |
2265 | int reiserfs_unpack(struct inode *inode, struct file *filp); | 2320 | int reiserfs_unpack(struct inode *inode, struct file *filp); |
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index dab68bbed675..52c83b6a758a 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #ifdef __KERNEL__ | 7 | #ifdef __KERNEL__ |
8 | #include <linux/workqueue.h> | 8 | #include <linux/workqueue.h> |
9 | #include <linux/rwsem.h> | 9 | #include <linux/rwsem.h> |
10 | #include <linux/mutex.h> | ||
11 | #include <linux/sched.h> | ||
10 | #endif | 12 | #endif |
11 | 13 | ||
12 | typedef enum { | 14 | typedef enum { |
@@ -355,6 +357,13 @@ struct reiserfs_sb_info { | |||
355 | struct reiserfs_journal *s_journal; /* pointer to journal information */ | 357 | struct reiserfs_journal *s_journal; /* pointer to journal information */ |
356 | unsigned short s_mount_state; /* reiserfs state (valid, invalid) */ | 358 | unsigned short s_mount_state; /* reiserfs state (valid, invalid) */ |
357 | 359 | ||
360 | /* Serialize writers access, replace the old bkl */ | ||
361 | struct mutex lock; | ||
362 | /* Owner of the lock (can be recursive) */ | ||
363 | struct task_struct *lock_owner; | ||
364 | /* Depth of the lock, start from -1 like the bkl */ | ||
365 | int lock_depth; | ||
366 | |||
358 | /* Comment? -Hans */ | 367 | /* Comment? -Hans */ |
359 | void (*end_io_handler) (struct buffer_head *, int); | 368 | void (*end_io_handler) (struct buffer_head *, int); |
360 | hashf_t s_hash_function; /* pointer to function which is used | 369 | hashf_t s_hash_function; /* pointer to function which is used |
@@ -408,6 +417,17 @@ struct reiserfs_sb_info { | |||
408 | char *s_qf_names[MAXQUOTAS]; | 417 | char *s_qf_names[MAXQUOTAS]; |
409 | int s_jquota_fmt; | 418 | int s_jquota_fmt; |
410 | #endif | 419 | #endif |
420 | #ifdef CONFIG_REISERFS_CHECK | ||
421 | |||
422 | struct tree_balance *cur_tb; /* | ||
423 | * Detects whether more than one | ||
424 | * copy of tb exists per superblock | ||
425 | * as a means of checking whether | ||
426 | * do_balance is executing concurrently | ||
427 | * against another tree reader/writer | ||
428 | * on a same mount point. | ||
429 | */ | ||
430 | #endif | ||
411 | }; | 431 | }; |
412 | 432 | ||
413 | /* Definitions of reiserfs on-disk properties: */ | 433 | /* Definitions of reiserfs on-disk properties: */ |