diff options
Diffstat (limited to 'fs/bfs/inode.c')
-rw-r--r-- | fs/bfs/inode.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index cc4062d12ca2..6f60336c6628 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -30,6 +30,7 @@ MODULE_LICENSE("GPL"); | |||
30 | #define dprintf(x...) | 30 | #define dprintf(x...) |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | static void bfs_write_super(struct super_block *s); | ||
33 | void dump_imap(const char *prefix, struct super_block *s); | 34 | void dump_imap(const char *prefix, struct super_block *s); |
34 | 35 | ||
35 | struct inode *bfs_iget(struct super_block *sb, unsigned long ino) | 36 | struct inode *bfs_iget(struct super_block *sb, unsigned long ino) |
@@ -97,14 +98,15 @@ error: | |||
97 | return ERR_PTR(-EIO); | 98 | return ERR_PTR(-EIO); |
98 | } | 99 | } |
99 | 100 | ||
100 | static int bfs_write_inode(struct inode *inode, int unused) | 101 | static int bfs_write_inode(struct inode *inode, int wait) |
101 | { | 102 | { |
103 | struct bfs_sb_info *info = BFS_SB(inode->i_sb); | ||
102 | unsigned int ino = (u16)inode->i_ino; | 104 | unsigned int ino = (u16)inode->i_ino; |
103 | unsigned long i_sblock; | 105 | unsigned long i_sblock; |
104 | struct bfs_inode *di; | 106 | struct bfs_inode *di; |
105 | struct buffer_head *bh; | 107 | struct buffer_head *bh; |
106 | int block, off; | 108 | int block, off; |
107 | struct bfs_sb_info *info = BFS_SB(inode->i_sb); | 109 | int err = 0; |
108 | 110 | ||
109 | dprintf("ino=%08x\n", ino); | 111 | dprintf("ino=%08x\n", ino); |
110 | 112 | ||
@@ -145,9 +147,14 @@ static int bfs_write_inode(struct inode *inode, int unused) | |||
145 | di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); | 147 | di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); |
146 | 148 | ||
147 | mark_buffer_dirty(bh); | 149 | mark_buffer_dirty(bh); |
150 | if (wait) { | ||
151 | sync_dirty_buffer(bh); | ||
152 | if (buffer_req(bh) && !buffer_uptodate(bh)) | ||
153 | err = -EIO; | ||
154 | } | ||
148 | brelse(bh); | 155 | brelse(bh); |
149 | mutex_unlock(&info->bfs_lock); | 156 | mutex_unlock(&info->bfs_lock); |
150 | return 0; | 157 | return err; |
151 | } | 158 | } |
152 | 159 | ||
153 | static void bfs_delete_inode(struct inode *inode) | 160 | static void bfs_delete_inode(struct inode *inode) |
@@ -209,6 +216,26 @@ static void bfs_delete_inode(struct inode *inode) | |||
209 | clear_inode(inode); | 216 | clear_inode(inode); |
210 | } | 217 | } |
211 | 218 | ||
219 | static int bfs_sync_fs(struct super_block *sb, int wait) | ||
220 | { | ||
221 | struct bfs_sb_info *info = BFS_SB(sb); | ||
222 | |||
223 | mutex_lock(&info->bfs_lock); | ||
224 | mark_buffer_dirty(info->si_sbh); | ||
225 | sb->s_dirt = 0; | ||
226 | mutex_unlock(&info->bfs_lock); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static void bfs_write_super(struct super_block *sb) | ||
232 | { | ||
233 | if (!(sb->s_flags & MS_RDONLY)) | ||
234 | bfs_sync_fs(sb, 1); | ||
235 | else | ||
236 | sb->s_dirt = 0; | ||
237 | } | ||
238 | |||
212 | static void bfs_put_super(struct super_block *s) | 239 | static void bfs_put_super(struct super_block *s) |
213 | { | 240 | { |
214 | struct bfs_sb_info *info = BFS_SB(s); | 241 | struct bfs_sb_info *info = BFS_SB(s); |
@@ -216,11 +243,18 @@ static void bfs_put_super(struct super_block *s) | |||
216 | if (!info) | 243 | if (!info) |
217 | return; | 244 | return; |
218 | 245 | ||
246 | lock_kernel(); | ||
247 | |||
248 | if (s->s_dirt) | ||
249 | bfs_write_super(s); | ||
250 | |||
219 | brelse(info->si_sbh); | 251 | brelse(info->si_sbh); |
220 | mutex_destroy(&info->bfs_lock); | 252 | mutex_destroy(&info->bfs_lock); |
221 | kfree(info->si_imap); | 253 | kfree(info->si_imap); |
222 | kfree(info); | 254 | kfree(info); |
223 | s->s_fs_info = NULL; | 255 | s->s_fs_info = NULL; |
256 | |||
257 | unlock_kernel(); | ||
224 | } | 258 | } |
225 | 259 | ||
226 | static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 260 | static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
@@ -240,17 +274,6 @@ static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
240 | return 0; | 274 | return 0; |
241 | } | 275 | } |
242 | 276 | ||
243 | static void bfs_write_super(struct super_block *s) | ||
244 | { | ||
245 | struct bfs_sb_info *info = BFS_SB(s); | ||
246 | |||
247 | mutex_lock(&info->bfs_lock); | ||
248 | if (!(s->s_flags & MS_RDONLY)) | ||
249 | mark_buffer_dirty(info->si_sbh); | ||
250 | s->s_dirt = 0; | ||
251 | mutex_unlock(&info->bfs_lock); | ||
252 | } | ||
253 | |||
254 | static struct kmem_cache *bfs_inode_cachep; | 277 | static struct kmem_cache *bfs_inode_cachep; |
255 | 278 | ||
256 | static struct inode *bfs_alloc_inode(struct super_block *sb) | 279 | static struct inode *bfs_alloc_inode(struct super_block *sb) |
@@ -298,6 +321,7 @@ static const struct super_operations bfs_sops = { | |||
298 | .delete_inode = bfs_delete_inode, | 321 | .delete_inode = bfs_delete_inode, |
299 | .put_super = bfs_put_super, | 322 | .put_super = bfs_put_super, |
300 | .write_super = bfs_write_super, | 323 | .write_super = bfs_write_super, |
324 | .sync_fs = bfs_sync_fs, | ||
301 | .statfs = bfs_statfs, | 325 | .statfs = bfs_statfs, |
302 | }; | 326 | }; |
303 | 327 | ||