aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysv/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysv/inode.c')
-rw-r--r--fs/sysv/inode.c75
1 files changed, 40 insertions, 35 deletions
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. */ 34static int sysv_sync_fs(struct super_block *sb, int wait)
35static 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 }
56clean: 54
57 sb->s_dirt = 0;
58 unlock_kernel(); 55 unlock_kernel();
56 unlock_super(sb);
57
58 return 0;
59}
60
61static 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
61static int sysv_remount(struct super_block *sb, int *flags, char *data) 69static 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
89static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) 106static 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
239static struct buffer_head * sysv_update_inode(struct inode * inode) 256int 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)) {
279int 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
289int sysv_sync_inode(struct inode * inode) 308int 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
309static void sysv_delete_inode(struct inode *inode) 313static 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};