]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.21-lvm-VFSlock.patch
- added description of djurban's branch
[packages/kernel.git] / linux-2.4.21-lvm-VFSlock.patch
1 diff -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);
39 diff -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() ;
51 diff -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)
169 diff -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 dev, int wait);
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);
189 diff -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(fsync_dev_lockfs);
197 +EXPORT_SYMBOL(unlockfs);
198  EXPORT_SYMBOL(fsync_no_super);
199  EXPORT_SYMBOL(permission);
200  EXPORT_SYMBOL(vfs_permission);
This page took 0.104135 seconds and 3 git commands to generate.