diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-07 15:29:45 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-11 21:36:12 -0400 |
commit | 05459ca81ac3064cb040d983342bc453cccec458 (patch) | |
tree | 3f563253b1d980a24659fcf0967be3b57ec020c5 /fs/sysv | |
parent | 0d7916d7e985da52cdd2989c900485e17b035972 (diff) |
repair sysv_write_inode(), switch sysv to simple_fsync()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
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 | 45 | ||||
-rw-r--r-- | fs/sysv/sysv.h | 1 |
4 files changed, 18 insertions, 47 deletions
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 56f655254bf..c7798079e64 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 589be21d884..96340c01f4a 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 a3f45fc626a..425c976cfcd 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -247,7 +247,7 @@ bad_inode: | |||
247 | return ERR_PTR(-EIO); | 247 | return ERR_PTR(-EIO); |
248 | } | 248 | } |
249 | 249 | ||
250 | static struct buffer_head * sysv_update_inode(struct inode * inode) | 250 | int sysv_write_inode(struct inode *inode, int wait) |
251 | { | 251 | { |
252 | struct super_block * sb = inode->i_sb; | 252 | struct super_block * sb = inode->i_sb; |
253 | struct sysv_sb_info * sbi = SYSV_SB(sb); | 253 | struct sysv_sb_info * sbi = SYSV_SB(sb); |
@@ -255,19 +255,21 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) | |||
255 | struct sysv_inode * raw_inode; | 255 | struct sysv_inode * raw_inode; |
256 | struct sysv_inode_info * si; | 256 | struct sysv_inode_info * si; |
257 | unsigned int ino, block; | 257 | unsigned int ino, block; |
258 | int err = 0; | ||
258 | 259 | ||
259 | ino = inode->i_ino; | 260 | ino = inode->i_ino; |
260 | if (!ino || ino > sbi->s_ninodes) { | 261 | if (!ino || ino > sbi->s_ninodes) { |
261 | printk("Bad inode number on dev %s: %d is out of range\n", | 262 | printk("Bad inode number on dev %s: %d is out of range\n", |
262 | inode->i_sb->s_id, ino); | 263 | inode->i_sb->s_id, ino); |
263 | return NULL; | 264 | return -EIO; |
264 | } | 265 | } |
265 | raw_inode = sysv_raw_inode(sb, ino, &bh); | 266 | raw_inode = sysv_raw_inode(sb, ino, &bh); |
266 | if (!raw_inode) { | 267 | if (!raw_inode) { |
267 | printk("unable to read i-node block\n"); | 268 | printk("unable to read i-node block\n"); |
268 | return NULL; | 269 | return -EIO; |
269 | } | 270 | } |
270 | 271 | ||
272 | lock_kernel(); | ||
271 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); | 273 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); |
272 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); | 274 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); |
273 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); | 275 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); |
@@ -283,38 +285,23 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) | |||
283 | for (block = 0; block < 10+1+1+1; block++) | 285 | for (block = 0; block < 10+1+1+1; block++) |
284 | write3byte(sbi, (u8 *)&si->i_data[block], | 286 | write3byte(sbi, (u8 *)&si->i_data[block], |
285 | &raw_inode->i_data[3*block]); | 287 | &raw_inode->i_data[3*block]); |
288 | unlock_kernel(); | ||
286 | mark_buffer_dirty(bh); | 289 | mark_buffer_dirty(bh); |
287 | return bh; | 290 | if (wait) { |
288 | } | 291 | sync_dirty_buffer(bh); |
289 | 292 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | |
290 | int sysv_write_inode(struct inode * inode, int wait) | 293 | printk ("IO error syncing sysv inode [%s:%08x]\n", |
291 | { | 294 | sb->s_id, ino); |
292 | struct buffer_head *bh; | 295 | err = -EIO; |
293 | lock_kernel(); | 296 | } |
294 | bh = sysv_update_inode(inode); | 297 | } |
295 | brelse(bh); | 298 | brelse(bh); |
296 | unlock_kernel(); | ||
297 | return 0; | 299 | return 0; |
298 | } | 300 | } |
299 | 301 | ||
300 | int sysv_sync_inode(struct inode * inode) | 302 | int sysv_sync_inode(struct inode *inode) |
301 | { | 303 | { |
302 | int err = 0; | 304 | return sysv_write_inode(inode, 1); |
303 | struct buffer_head *bh; | ||
304 | |||
305 | bh = sysv_update_inode(inode); | ||
306 | if (bh && buffer_dirty(bh)) { | ||
307 | sync_dirty_buffer(bh); | ||
308 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | ||
309 | printk ("IO error syncing sysv inode [%s:%08lx]\n", | ||
310 | inode->i_sb->s_id, inode->i_ino); | ||
311 | err = -1; | ||
312 | } | ||
313 | } | ||
314 | else if (!bh) | ||
315 | err = -1; | ||
316 | brelse (bh); | ||
317 | return err; | ||
318 | } | 305 | } |
319 | 306 | ||
320 | static void sysv_delete_inode(struct inode *inode) | 307 | static void sysv_delete_inode(struct inode *inode) |
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index 5784a318c88..53786eb5cf6 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); |