aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-06-07 15:29:45 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-06-11 21:36:12 -0400
commit05459ca81ac3064cb040d983342bc453cccec458 (patch)
tree3f563253b1d980a24659fcf0967be3b57ec020c5
parent0d7916d7e985da52cdd2989c900485e17b035972 (diff)
repair sysv_write_inode(), switch sysv to simple_fsync()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/sysv/dir.c2
-rw-r--r--fs/sysv/file.c17
-rw-r--r--fs/sysv/inode.c45
-rw-r--r--fs/sysv/sysv.h1
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);
24const struct file_operations sysv_dir_operations = { 24const 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
30static inline void dir_put_page(struct page *page) 30static 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
38int 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
250static struct buffer_head * sysv_update_inode(struct inode * inode) 250int 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)) {
290int 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
300int sysv_sync_inode(struct inode * inode) 302int 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
320static void sysv_delete_inode(struct inode *inode) 307static 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,
144extern struct inode *sysv_iget(struct super_block *, unsigned int); 144extern struct inode *sysv_iget(struct super_block *, unsigned int);
145extern int sysv_write_inode(struct inode *, int); 145extern int sysv_write_inode(struct inode *, int);
146extern int sysv_sync_inode(struct inode *); 146extern int sysv_sync_inode(struct inode *);
147extern int sysv_sync_file(struct file *, struct dentry *, int);
148extern void sysv_set_inode(struct inode *, dev_t); 147extern void sysv_set_inode(struct inode *, dev_t);
149extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); 148extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *);
150extern int sysv_init_icache(void); 149extern int sysv_init_icache(void);