diff options
Diffstat (limited to 'fs/sysv')
-rw-r--r-- | fs/sysv/dir.c | 2 | ||||
-rw-r--r-- | fs/sysv/file.c | 17 | ||||
-rw-r--r-- | fs/sysv/inode.c | 75 | ||||
-rw-r--r-- | fs/sysv/sysv.h | 1 |
4 files changed, 42 insertions, 53 deletions
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 56f655254bfe..c7798079e644 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c | |||
@@ -24,7 +24,7 @@ static int sysv_readdir(struct file *, void *, filldir_t); | |||
24 | const struct file_operations sysv_dir_operations = { | 24 | const struct file_operations sysv_dir_operations = { |
25 | .read = generic_read_dir, | 25 | .read = generic_read_dir, |
26 | .readdir = sysv_readdir, | 26 | .readdir = sysv_readdir, |
27 | .fsync = sysv_sync_file, | 27 | .fsync = simple_fsync, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static inline void dir_put_page(struct page *page) | 30 | static inline void dir_put_page(struct page *page) |
diff --git a/fs/sysv/file.c b/fs/sysv/file.c index 589be21d884e..96340c01f4a7 100644 --- a/fs/sysv/file.c +++ b/fs/sysv/file.c | |||
@@ -26,7 +26,7 @@ const struct file_operations sysv_file_operations = { | |||
26 | .write = do_sync_write, | 26 | .write = do_sync_write, |
27 | .aio_write = generic_file_aio_write, | 27 | .aio_write = generic_file_aio_write, |
28 | .mmap = generic_file_mmap, | 28 | .mmap = generic_file_mmap, |
29 | .fsync = sysv_sync_file, | 29 | .fsync = simple_fsync, |
30 | .splice_read = generic_file_splice_read, | 30 | .splice_read = generic_file_splice_read, |
31 | }; | 31 | }; |
32 | 32 | ||
@@ -34,18 +34,3 @@ const struct inode_operations sysv_file_inode_operations = { | |||
34 | .truncate = sysv_truncate, | 34 | .truncate = sysv_truncate, |
35 | .getattr = sysv_getattr, | 35 | .getattr = sysv_getattr, |
36 | }; | 36 | }; |
37 | |||
38 | int sysv_sync_file(struct file * file, struct dentry *dentry, int datasync) | ||
39 | { | ||
40 | struct inode *inode = dentry->d_inode; | ||
41 | int err; | ||
42 | |||
43 | err = sync_mapping_buffers(inode->i_mapping); | ||
44 | if (!(inode->i_state & I_DIRTY)) | ||
45 | return err; | ||
46 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) | ||
47 | return err; | ||
48 | |||
49 | err |= sysv_sync_inode(inode); | ||
50 | return err ? -EIO : 0; | ||
51 | } | ||
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index da20b48d350f..479923456a54 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -31,15 +31,13 @@ | |||
31 | #include <asm/byteorder.h> | 31 | #include <asm/byteorder.h> |
32 | #include "sysv.h" | 32 | #include "sysv.h" |
33 | 33 | ||
34 | /* This is only called on sync() and umount(), when s_dirt=1. */ | 34 | static int sysv_sync_fs(struct super_block *sb, int wait) |
35 | static void sysv_write_super(struct super_block *sb) | ||
36 | { | 35 | { |
37 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 36 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
38 | unsigned long time = get_seconds(), old_time; | 37 | unsigned long time = get_seconds(), old_time; |
39 | 38 | ||
39 | lock_super(sb); | ||
40 | lock_kernel(); | 40 | lock_kernel(); |
41 | if (sb->s_flags & MS_RDONLY) | ||
42 | goto clean; | ||
43 | 41 | ||
44 | /* | 42 | /* |
45 | * If we are going to write out the super block, | 43 | * If we are going to write out the super block, |
@@ -53,18 +51,30 @@ static void sysv_write_super(struct super_block *sb) | |||
53 | *sbi->s_sb_time = cpu_to_fs32(sbi, time); | 51 | *sbi->s_sb_time = cpu_to_fs32(sbi, time); |
54 | mark_buffer_dirty(sbi->s_bh2); | 52 | mark_buffer_dirty(sbi->s_bh2); |
55 | } | 53 | } |
56 | clean: | 54 | |
57 | sb->s_dirt = 0; | ||
58 | unlock_kernel(); | 55 | unlock_kernel(); |
56 | unlock_super(sb); | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static void sysv_write_super(struct super_block *sb) | ||
62 | { | ||
63 | if (!(sb->s_flags & MS_RDONLY)) | ||
64 | sysv_sync_fs(sb, 1); | ||
65 | else | ||
66 | sb->s_dirt = 0; | ||
59 | } | 67 | } |
60 | 68 | ||
61 | static int sysv_remount(struct super_block *sb, int *flags, char *data) | 69 | static int sysv_remount(struct super_block *sb, int *flags, char *data) |
62 | { | 70 | { |
63 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 71 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
72 | lock_super(sb); | ||
64 | if (sbi->s_forced_ro) | 73 | if (sbi->s_forced_ro) |
65 | *flags |= MS_RDONLY; | 74 | *flags |= MS_RDONLY; |
66 | if (!(*flags & MS_RDONLY)) | 75 | if (!(*flags & MS_RDONLY)) |
67 | sb->s_dirt = 1; | 76 | sb->s_dirt = 1; |
77 | unlock_super(sb); | ||
68 | return 0; | 78 | return 0; |
69 | } | 79 | } |
70 | 80 | ||
@@ -72,6 +82,11 @@ static void sysv_put_super(struct super_block *sb) | |||
72 | { | 82 | { |
73 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 83 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
74 | 84 | ||
85 | lock_kernel(); | ||
86 | |||
87 | if (sb->s_dirt) | ||
88 | sysv_write_super(sb); | ||
89 | |||
75 | if (!(sb->s_flags & MS_RDONLY)) { | 90 | if (!(sb->s_flags & MS_RDONLY)) { |
76 | /* XXX ext2 also updates the state here */ | 91 | /* XXX ext2 also updates the state here */ |
77 | mark_buffer_dirty(sbi->s_bh1); | 92 | mark_buffer_dirty(sbi->s_bh1); |
@@ -84,6 +99,8 @@ static void sysv_put_super(struct super_block *sb) | |||
84 | brelse(sbi->s_bh2); | 99 | brelse(sbi->s_bh2); |
85 | 100 | ||
86 | kfree(sbi); | 101 | kfree(sbi); |
102 | |||
103 | unlock_kernel(); | ||
87 | } | 104 | } |
88 | 105 | ||
89 | static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) | 106 | static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) |
@@ -236,7 +253,7 @@ bad_inode: | |||
236 | return ERR_PTR(-EIO); | 253 | return ERR_PTR(-EIO); |
237 | } | 254 | } |
238 | 255 | ||
239 | static struct buffer_head * sysv_update_inode(struct inode * inode) | 256 | int sysv_write_inode(struct inode *inode, int wait) |
240 | { | 257 | { |
241 | struct super_block * sb = inode->i_sb; | 258 | struct super_block * sb = inode->i_sb; |
242 | struct sysv_sb_info * sbi = SYSV_SB(sb); | 259 | struct sysv_sb_info * sbi = SYSV_SB(sb); |
@@ -244,19 +261,21 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) | |||
244 | struct sysv_inode * raw_inode; | 261 | struct sysv_inode * raw_inode; |
245 | struct sysv_inode_info * si; | 262 | struct sysv_inode_info * si; |
246 | unsigned int ino, block; | 263 | unsigned int ino, block; |
264 | int err = 0; | ||
247 | 265 | ||
248 | ino = inode->i_ino; | 266 | ino = inode->i_ino; |
249 | if (!ino || ino > sbi->s_ninodes) { | 267 | if (!ino || ino > sbi->s_ninodes) { |
250 | printk("Bad inode number on dev %s: %d is out of range\n", | 268 | printk("Bad inode number on dev %s: %d is out of range\n", |
251 | inode->i_sb->s_id, ino); | 269 | inode->i_sb->s_id, ino); |
252 | return NULL; | 270 | return -EIO; |
253 | } | 271 | } |
254 | raw_inode = sysv_raw_inode(sb, ino, &bh); | 272 | raw_inode = sysv_raw_inode(sb, ino, &bh); |
255 | if (!raw_inode) { | 273 | if (!raw_inode) { |
256 | printk("unable to read i-node block\n"); | 274 | printk("unable to read i-node block\n"); |
257 | return NULL; | 275 | return -EIO; |
258 | } | 276 | } |
259 | 277 | ||
278 | lock_kernel(); | ||
260 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); | 279 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); |
261 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); | 280 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); |
262 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); | 281 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); |
@@ -272,38 +291,23 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) | |||
272 | for (block = 0; block < 10+1+1+1; block++) | 291 | for (block = 0; block < 10+1+1+1; block++) |
273 | write3byte(sbi, (u8 *)&si->i_data[block], | 292 | write3byte(sbi, (u8 *)&si->i_data[block], |
274 | &raw_inode->i_data[3*block]); | 293 | &raw_inode->i_data[3*block]); |
294 | unlock_kernel(); | ||
275 | mark_buffer_dirty(bh); | 295 | mark_buffer_dirty(bh); |
276 | return bh; | 296 | if (wait) { |
277 | } | 297 | sync_dirty_buffer(bh); |
278 | 298 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | |
279 | int sysv_write_inode(struct inode * inode, int wait) | 299 | printk ("IO error syncing sysv inode [%s:%08x]\n", |
280 | { | 300 | sb->s_id, ino); |
281 | struct buffer_head *bh; | 301 | err = -EIO; |
282 | lock_kernel(); | 302 | } |
283 | bh = sysv_update_inode(inode); | 303 | } |
284 | brelse(bh); | 304 | brelse(bh); |
285 | unlock_kernel(); | ||
286 | return 0; | 305 | return 0; |
287 | } | 306 | } |
288 | 307 | ||
289 | int sysv_sync_inode(struct inode * inode) | 308 | int sysv_sync_inode(struct inode *inode) |
290 | { | 309 | { |
291 | int err = 0; | 310 | return sysv_write_inode(inode, 1); |
292 | struct buffer_head *bh; | ||
293 | |||
294 | bh = sysv_update_inode(inode); | ||
295 | if (bh && buffer_dirty(bh)) { | ||
296 | sync_dirty_buffer(bh); | ||
297 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | ||
298 | printk ("IO error syncing sysv inode [%s:%08lx]\n", | ||
299 | inode->i_sb->s_id, inode->i_ino); | ||
300 | err = -1; | ||
301 | } | ||
302 | } | ||
303 | else if (!bh) | ||
304 | err = -1; | ||
305 | brelse (bh); | ||
306 | return err; | ||
307 | } | 311 | } |
308 | 312 | ||
309 | static void sysv_delete_inode(struct inode *inode) | 313 | static void sysv_delete_inode(struct inode *inode) |
@@ -347,6 +351,7 @@ const struct super_operations sysv_sops = { | |||
347 | .delete_inode = sysv_delete_inode, | 351 | .delete_inode = sysv_delete_inode, |
348 | .put_super = sysv_put_super, | 352 | .put_super = sysv_put_super, |
349 | .write_super = sysv_write_super, | 353 | .write_super = sysv_write_super, |
354 | .sync_fs = sysv_sync_fs, | ||
350 | .remount_fs = sysv_remount, | 355 | .remount_fs = sysv_remount, |
351 | .statfs = sysv_statfs, | 356 | .statfs = sysv_statfs, |
352 | }; | 357 | }; |
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index 5784a318c883..53786eb5cf60 100644 --- a/fs/sysv/sysv.h +++ b/fs/sysv/sysv.h | |||
@@ -144,7 +144,6 @@ extern int __sysv_write_begin(struct file *file, struct address_space *mapping, | |||
144 | extern struct inode *sysv_iget(struct super_block *, unsigned int); | 144 | extern struct inode *sysv_iget(struct super_block *, unsigned int); |
145 | extern int sysv_write_inode(struct inode *, int); | 145 | extern int sysv_write_inode(struct inode *, int); |
146 | extern int sysv_sync_inode(struct inode *); | 146 | extern int sysv_sync_inode(struct inode *); |
147 | extern int sysv_sync_file(struct file *, struct dentry *, int); | ||
148 | extern void sysv_set_inode(struct inode *, dev_t); | 147 | extern void sysv_set_inode(struct inode *, dev_t); |
149 | extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 148 | extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
150 | extern int sysv_init_icache(void); | 149 | extern int sysv_init_icache(void); |