Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

repair sysv_write_inode(), switch sysv to simple_fsync()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 05459ca8 0d7916d7

+19 -48
+1 -1
fs/sysv/dir.c
··· 24 24 const struct file_operations sysv_dir_operations = { 25 25 .read = generic_read_dir, 26 26 .readdir = sysv_readdir, 27 - .fsync = sysv_sync_file, 27 + .fsync = simple_fsync, 28 28 }; 29 29 30 30 static inline void dir_put_page(struct page *page)
+1 -16
fs/sysv/file.c
··· 26 26 .write = do_sync_write, 27 27 .aio_write = generic_file_aio_write, 28 28 .mmap = generic_file_mmap, 29 - .fsync = sysv_sync_file, 29 + .fsync = simple_fsync, 30 30 .splice_read = generic_file_splice_read, 31 31 }; 32 32 ··· 34 34 .truncate = sysv_truncate, 35 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 - }
+17 -30
fs/sysv/inode.c
··· 247 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 252 struct super_block * sb = inode->i_sb; 253 253 struct sysv_sb_info * sbi = SYSV_SB(sb); ··· 255 255 struct sysv_inode * raw_inode; 256 256 struct sysv_inode_info * si; 257 257 unsigned int ino, block; 258 + int err = 0; 258 259 259 260 ino = inode->i_ino; 260 261 if (!ino || ino > sbi->s_ninodes) { 261 262 printk("Bad inode number on dev %s: %d is out of range\n", 262 263 inode->i_sb->s_id, ino); 263 - return NULL; 264 + return -EIO; 264 265 } 265 266 raw_inode = sysv_raw_inode(sb, ino, &bh); 266 267 if (!raw_inode) { 267 268 printk("unable to read i-node block\n"); 268 - return NULL; 269 + return -EIO; 269 270 } 270 271 272 + lock_kernel(); 271 273 raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); 272 274 raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); 273 275 raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); ··· 285 283 for (block = 0; block < 10+1+1+1; block++) 286 284 write3byte(sbi, (u8 *)&si->i_data[block], 287 285 &raw_inode->i_data[3*block]); 288 - mark_buffer_dirty(bh); 289 - return bh; 290 - } 291 - 292 - int sysv_write_inode(struct inode * inode, int wait) 293 - { 294 - struct buffer_head *bh; 295 - lock_kernel(); 296 - bh = sysv_update_inode(inode); 297 - brelse(bh); 298 286 unlock_kernel(); 287 + mark_buffer_dirty(bh); 288 + if (wait) { 289 + sync_dirty_buffer(bh); 290 + if (buffer_req(bh) && !buffer_uptodate(bh)) { 291 + printk ("IO error syncing sysv inode [%s:%08x]\n", 292 + sb->s_id, ino); 293 + err = -EIO; 294 + } 295 + } 296 + brelse(bh); 299 297 return 0; 300 298 } 301 299 302 - int sysv_sync_inode(struct inode * inode) 300 + int sysv_sync_inode(struct inode *inode) 303 301 { 304 - int err = 0; 305 - struct buffer_head *bh; 306 - 307 - bh = sysv_update_inode(inode); 308 - if (bh && buffer_dirty(bh)) { 309 - sync_dirty_buffer(bh); 310 - if (buffer_req(bh) && !buffer_uptodate(bh)) { 311 - printk ("IO error syncing sysv inode [%s:%08lx]\n", 312 - inode->i_sb->s_id, inode->i_ino); 313 - err = -1; 314 - } 315 - } 316 - else if (!bh) 317 - err = -1; 318 - brelse (bh); 319 - return err; 302 + return sysv_write_inode(inode, 1); 320 303 } 321 304 322 305 static void sysv_delete_inode(struct inode *inode)
-1
fs/sysv/sysv.h
··· 144 144 extern struct inode *sysv_iget(struct super_block *, unsigned int); 145 145 extern int sysv_write_inode(struct inode *, int); 146 146 extern int sysv_sync_inode(struct inode *); 147 - extern int sysv_sync_file(struct file *, struct dentry *, int); 148 147 extern void sysv_set_inode(struct inode *, dev_t); 149 148 extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); 150 149 extern int sysv_init_icache(void);