]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.18-lvm-VFSlock.patch
- added description of djurban's branch
[packages/kernel.git] / linux-2.4.18-lvm-VFSlock.patch
CommitLineData
8ac6a477
JR
1diff -urNp linux-1253/fs/buffer.c linux-1255/fs/buffer.c
2--- linux-1253/fs/buffer.c
3+++ linux-1255/fs/buffer.c
4@@ -366,6 +366,34 @@ void sync_dev(kdev_t dev)
5 fsync_dev(dev);
6 }
7
8+int fsync_dev_lockfs(kdev_t dev)
9+{
10+ /* you are not allowed to try locking all the filesystems
11+ ** on the system, your chances of getting through without
12+ ** total deadlock are slim to none.
13+ */
14+ if (!dev)
15+ return fsync_dev(dev) ;
16+
17+ sync_buffers(dev, 0);
18+
19+ lock_kernel();
20+ /* note, the FS might need to start transactions to
21+ ** sync the inodes, or the quota, no locking until
22+ ** after these are done
23+ */
24+ sync_inodes(dev);
25+ DQUOT_SYNC_DEV(dev);
26+ /* if inodes or quotas could be dirtied during the
27+ ** sync_supers_lockfs call, the FS is responsible for getting
28+ ** them on disk, without deadlocking against the lock
29+ */
30+ sync_supers_lockfs(dev) ;
31+ unlock_kernel();
32+
33+ return sync_buffers(dev, 1) ;
34+}
35+
36 asmlinkage long sys_sync(void)
37 {
38 fsync_dev(0);
39diff -urNp linux-1253/fs/reiserfs/super.c linux-1255/fs/reiserfs/super.c
40--- linux-1253/fs/reiserfs/super.c
41+++ linux-1255/fs/reiserfs/super.c
42@@ -44,7 +44,7 @@ static void reiserfs_write_super_lockfs
43 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
44 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
45 reiserfs_block_writes(&th) ;
46- journal_end(&th, s, 1) ;
47+ journal_end_sync(&th, s, 1) ;
48 }
49 s->s_dirt = dirty;
50 unlock_kernel() ;
51diff -urNp linux-1253/fs/super.c linux-1255/fs/super.c
52--- linux-1253/fs/super.c
53+++ linux-1255/fs/super.c
54@@ -38,6 +38,13 @@
55 LIST_HEAD(super_blocks);
56 spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
57
58+/*
59+ * lock/unlockfs grab a read lock on s_umount, but you need this lock to
60+ * make sure no lockfs runs are in progress before inserting/removing
61+ * supers from the list.
62+ */
63+static DECLARE_MUTEX(lockfs_sem);
64+
65 /*
66 * Handling of filesystem drivers list.
67 * Rules:
68@@ -451,6 +458,19 @@ void drop_super(struct super_block *sb)
69 put_super(sb);
70 }
71
72+static void write_super_lockfs(struct super_block *sb)
73+{
74+ lock_super(sb);
75+ if (sb->s_root && sb->s_op) {
76+ if (sb->s_dirt && sb->s_op->write_super)
77+ sb->s_op->write_super(sb);
78+ if (sb->s_op->write_super_lockfs) {
79+ sb->s_op->write_super_lockfs(sb);
80+ }
81+ }
82+ unlock_super(sb);
83+}
84+
85 static inline void write_super(struct super_block *sb)
86 {
87 lock_super(sb);
88@@ -498,6 +518,39 @@ restart:
89 spin_unlock(&sb_lock);
90 }
91
92+/*
93+ * Note: don't check the dirty flag before waiting, we want the lock
94+ * to happen every time this is called. dev must be non-zero
95+ */
96+void sync_supers_lockfs(kdev_t dev)
97+{
98+ struct super_block * sb;
99+
100+ down(&lockfs_sem);
101+ if (dev) {
102+ sb = get_super(dev);
103+ if (sb) {
104+ write_super_lockfs(sb);
105+ drop_super(sb);
106+ }
107+ }
108+}
109+
110+void unlockfs(kdev_t dev)
111+{
112+ struct super_block * sb;
113+
114+ if (dev) {
115+ sb = get_super(dev);
116+ if (sb) {
117+ if (sb->s_op && sb->s_op->unlockfs)
118+ sb->s_op->unlockfs(sb) ;
119+ drop_super(sb);
120+ }
121+ }
122+ up(&lockfs_sem);
123+}
124+
125 /**
126 * get_super - get the superblock of a device
127 * @dev: device to get the superblock for
128@@ -741,6 +794,7 @@ static struct super_block *get_sb_bdev(s
129 goto out1;
130
131 error = -EBUSY;
132+ down(&lockfs_sem);
133 restart:
134 spin_lock(&sb_lock);
135
136@@ -751,11 +805,13 @@ restart:
137 if (old->s_type != fs_type ||
138 ((flags ^ old->s_flags) & MS_RDONLY)) {
139 spin_unlock(&sb_lock);
140+ up(&lockfs_sem);
141 destroy_super(s);
142 goto out1;
143 }
144 if (!grab_super(old))
145 goto restart;
146+ up(&lockfs_sem);
147 destroy_super(s);
148 blkdev_put(bdev, BDEV_FS);
149 path_release(&nd);
150@@ -765,6 +821,7 @@ restart:
151 s->s_bdev = bdev;
152 s->s_flags = flags;
153 insert_super(s, fs_type);
154+ up(&lockfs_sem);
155 if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
156 goto Einval;
157 s->s_flags |= MS_ACTIVE;
158@@ -872,7 +929,10 @@ void kill_super(struct super_block *sb)
159 if (!deactivate_super(sb))
160 return;
161
162+ down(&lockfs_sem);
163 down_write(&sb->s_umount);
164+ up(&lockfs_sem);
165+
166 sb->s_root = NULL;
167 /* Need to clean after the sucker */
168 if (fs->fs_flags & FS_LITTER)
169diff -urNp linux-1253/include/linux/fs.h linux-1255/include/linux/fs.h
170--- linux-1253/include/linux/fs.h
171+++ linux-1255/include/linux/fs.h
172@@ -1275,6 +1275,7 @@ extern void write_inode_now(struct inode
173 extern int sync_buffers(kdev_t, int);
174 extern void sync_dev(kdev_t);
175 extern int fsync_dev(kdev_t);
176+extern int fsync_dev_lockfs(kdev_t);
177 extern int fsync_super(struct super_block *);
178 extern int fsync_no_super(kdev_t);
179 extern void sync_inodes_sb(struct super_block *);
180@@ -1291,6 +1292,8 @@ extern int inode_has_buffers(struct inod
181 extern int filemap_fdatasync(struct address_space *);
182 extern int filemap_fdatawait(struct address_space *);
183 extern void sync_supers(kdev_t);
184+extern void sync_supers_lockfs(kdev_t);
185+extern void unlockfs(kdev_t);
186 extern int bmap(struct inode *, int);
187 extern int notify_change(struct dentry *, struct iattr *);
188 extern int permission(struct inode *, int);
189diff -urNp linux-1253/kernel/ksyms.c linux-1255/kernel/ksyms.c
190--- linux-1253/kernel/ksyms.c
191+++ linux-1255/kernel/ksyms.c
192@@ -208,6 +208,8 @@ EXPORT_SYMBOL(invalidate_device);
193 EXPORT_SYMBOL(invalidate_inode_pages);
194 EXPORT_SYMBOL(truncate_inode_pages);
195 EXPORT_SYMBOL(fsync_dev);
196+EXPORT_SYMBOL_GPL(fsync_dev_lockfs);
197+EXPORT_SYMBOL_GPL(unlockfs);
198 EXPORT_SYMBOL(fsync_no_super);
199 EXPORT_SYMBOL(permission);
200 EXPORT_SYMBOL(vfs_permission);
This page took 0.380381 seconds and 4 git commands to generate.