diff options
Diffstat (limited to 'fs/sysv')
-rw-r--r-- | fs/sysv/dir.c | 7 | ||||
-rw-r--r-- | fs/sysv/file.c | 17 | ||||
-rw-r--r-- | fs/sysv/inode.c | 74 | ||||
-rw-r--r-- | fs/sysv/sysv.h | 1 |
4 files changed, 37 insertions, 62 deletions
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 56f655254bfe..4e50286a4cc3 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c | |||
@@ -15,16 +15,16 @@ | |||
15 | 15 | ||
16 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/swap.h> | 18 | #include <linux/swap.h> |
20 | #include "sysv.h" | 19 | #include "sysv.h" |
21 | 20 | ||
22 | static int sysv_readdir(struct file *, void *, filldir_t); | 21 | static int sysv_readdir(struct file *, void *, filldir_t); |
23 | 22 | ||
24 | const struct file_operations sysv_dir_operations = { | 23 | const struct file_operations sysv_dir_operations = { |
24 | .llseek = generic_file_llseek, | ||
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) |
@@ -74,8 +74,6 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
74 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 74 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
75 | unsigned long npages = dir_pages(inode); | 75 | unsigned long npages = dir_pages(inode); |
76 | 76 | ||
77 | lock_kernel(); | ||
78 | |||
79 | pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1); | 77 | pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1); |
80 | if (pos >= inode->i_size) | 78 | if (pos >= inode->i_size) |
81 | goto done; | 79 | goto done; |
@@ -113,7 +111,6 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
113 | 111 | ||
114 | done: | 112 | done: |
115 | filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset; | 113 | filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset; |
116 | unlock_kernel(); | ||
117 | return 0; | 114 | return 0; |
118 | } | 115 | } |
119 | 116 | ||
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..9824743832a7 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -21,7 +21,6 @@ | |||
21 | * the superblock. | 21 | * the superblock. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/highuid.h> | 24 | #include <linux/highuid.h> |
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -31,15 +30,12 @@ | |||
31 | #include <asm/byteorder.h> | 30 | #include <asm/byteorder.h> |
32 | #include "sysv.h" | 31 | #include "sysv.h" |
33 | 32 | ||
34 | /* This is only called on sync() and umount(), when s_dirt=1. */ | 33 | static int sysv_sync_fs(struct super_block *sb, int wait) |
35 | static void sysv_write_super(struct super_block *sb) | ||
36 | { | 34 | { |
37 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 35 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
38 | unsigned long time = get_seconds(), old_time; | 36 | unsigned long time = get_seconds(), old_time; |
39 | 37 | ||
40 | lock_kernel(); | 38 | lock_super(sb); |
41 | if (sb->s_flags & MS_RDONLY) | ||
42 | goto clean; | ||
43 | 39 | ||
44 | /* | 40 | /* |
45 | * If we are going to write out the super block, | 41 | * If we are going to write out the super block, |
@@ -53,18 +49,29 @@ static void sysv_write_super(struct super_block *sb) | |||
53 | *sbi->s_sb_time = cpu_to_fs32(sbi, time); | 49 | *sbi->s_sb_time = cpu_to_fs32(sbi, time); |
54 | mark_buffer_dirty(sbi->s_bh2); | 50 | mark_buffer_dirty(sbi->s_bh2); |
55 | } | 51 | } |
56 | clean: | 52 | |
57 | sb->s_dirt = 0; | 53 | unlock_super(sb); |
58 | unlock_kernel(); | 54 | |
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static void sysv_write_super(struct super_block *sb) | ||
59 | { | ||
60 | if (!(sb->s_flags & MS_RDONLY)) | ||
61 | sysv_sync_fs(sb, 1); | ||
62 | else | ||
63 | sb->s_dirt = 0; | ||
59 | } | 64 | } |
60 | 65 | ||
61 | static int sysv_remount(struct super_block *sb, int *flags, char *data) | 66 | static int sysv_remount(struct super_block *sb, int *flags, char *data) |
62 | { | 67 | { |
63 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 68 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
69 | lock_super(sb); | ||
64 | if (sbi->s_forced_ro) | 70 | if (sbi->s_forced_ro) |
65 | *flags |= MS_RDONLY; | 71 | *flags |= MS_RDONLY; |
66 | if (!(*flags & MS_RDONLY)) | 72 | if (!(*flags & MS_RDONLY)) |
67 | sb->s_dirt = 1; | 73 | sb->s_dirt = 1; |
74 | unlock_super(sb); | ||
68 | return 0; | 75 | return 0; |
69 | } | 76 | } |
70 | 77 | ||
@@ -72,6 +79,9 @@ static void sysv_put_super(struct super_block *sb) | |||
72 | { | 79 | { |
73 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 80 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
74 | 81 | ||
82 | if (sb->s_dirt) | ||
83 | sysv_write_super(sb); | ||
84 | |||
75 | if (!(sb->s_flags & MS_RDONLY)) { | 85 | if (!(sb->s_flags & MS_RDONLY)) { |
76 | /* XXX ext2 also updates the state here */ | 86 | /* XXX ext2 also updates the state here */ |
77 | mark_buffer_dirty(sbi->s_bh1); | 87 | mark_buffer_dirty(sbi->s_bh1); |
@@ -236,7 +246,7 @@ bad_inode: | |||
236 | return ERR_PTR(-EIO); | 246 | return ERR_PTR(-EIO); |
237 | } | 247 | } |
238 | 248 | ||
239 | static struct buffer_head * sysv_update_inode(struct inode * inode) | 249 | int sysv_write_inode(struct inode *inode, int wait) |
240 | { | 250 | { |
241 | struct super_block * sb = inode->i_sb; | 251 | struct super_block * sb = inode->i_sb; |
242 | struct sysv_sb_info * sbi = SYSV_SB(sb); | 252 | struct sysv_sb_info * sbi = SYSV_SB(sb); |
@@ -244,17 +254,18 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) | |||
244 | struct sysv_inode * raw_inode; | 254 | struct sysv_inode * raw_inode; |
245 | struct sysv_inode_info * si; | 255 | struct sysv_inode_info * si; |
246 | unsigned int ino, block; | 256 | unsigned int ino, block; |
257 | int err = 0; | ||
247 | 258 | ||
248 | ino = inode->i_ino; | 259 | ino = inode->i_ino; |
249 | if (!ino || ino > sbi->s_ninodes) { | 260 | if (!ino || ino > sbi->s_ninodes) { |
250 | printk("Bad inode number on dev %s: %d is out of range\n", | 261 | printk("Bad inode number on dev %s: %d is out of range\n", |
251 | inode->i_sb->s_id, ino); | 262 | inode->i_sb->s_id, ino); |
252 | return NULL; | 263 | return -EIO; |
253 | } | 264 | } |
254 | raw_inode = sysv_raw_inode(sb, ino, &bh); | 265 | raw_inode = sysv_raw_inode(sb, ino, &bh); |
255 | if (!raw_inode) { | 266 | if (!raw_inode) { |
256 | printk("unable to read i-node block\n"); | 267 | printk("unable to read i-node block\n"); |
257 | return NULL; | 268 | return -EIO; |
258 | } | 269 | } |
259 | 270 | ||
260 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); | 271 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); |
@@ -273,37 +284,21 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) | |||
273 | write3byte(sbi, (u8 *)&si->i_data[block], | 284 | write3byte(sbi, (u8 *)&si->i_data[block], |
274 | &raw_inode->i_data[3*block]); | 285 | &raw_inode->i_data[3*block]); |
275 | mark_buffer_dirty(bh); | 286 | mark_buffer_dirty(bh); |
276 | return bh; | 287 | if (wait) { |
277 | } | 288 | sync_dirty_buffer(bh); |
278 | 289 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | |
279 | int sysv_write_inode(struct inode * inode, int wait) | 290 | printk ("IO error syncing sysv inode [%s:%08x]\n", |
280 | { | 291 | sb->s_id, ino); |
281 | struct buffer_head *bh; | 292 | err = -EIO; |
282 | lock_kernel(); | 293 | } |
283 | bh = sysv_update_inode(inode); | 294 | } |
284 | brelse(bh); | 295 | brelse(bh); |
285 | unlock_kernel(); | ||
286 | return 0; | 296 | return 0; |
287 | } | 297 | } |
288 | 298 | ||
289 | int sysv_sync_inode(struct inode * inode) | 299 | int sysv_sync_inode(struct inode *inode) |
290 | { | 300 | { |
291 | int err = 0; | 301 | 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 | } | 302 | } |
308 | 303 | ||
309 | static void sysv_delete_inode(struct inode *inode) | 304 | static void sysv_delete_inode(struct inode *inode) |
@@ -311,9 +306,7 @@ static void sysv_delete_inode(struct inode *inode) | |||
311 | truncate_inode_pages(&inode->i_data, 0); | 306 | truncate_inode_pages(&inode->i_data, 0); |
312 | inode->i_size = 0; | 307 | inode->i_size = 0; |
313 | sysv_truncate(inode); | 308 | sysv_truncate(inode); |
314 | lock_kernel(); | ||
315 | sysv_free_inode(inode); | 309 | sysv_free_inode(inode); |
316 | unlock_kernel(); | ||
317 | } | 310 | } |
318 | 311 | ||
319 | static struct kmem_cache *sysv_inode_cachep; | 312 | static struct kmem_cache *sysv_inode_cachep; |
@@ -347,6 +340,7 @@ const struct super_operations sysv_sops = { | |||
347 | .delete_inode = sysv_delete_inode, | 340 | .delete_inode = sysv_delete_inode, |
348 | .put_super = sysv_put_super, | 341 | .put_super = sysv_put_super, |
349 | .write_super = sysv_write_super, | 342 | .write_super = sysv_write_super, |
343 | .sync_fs = sysv_sync_fs, | ||
350 | .remount_fs = sysv_remount, | 344 | .remount_fs = sysv_remount, |
351 | .statfs = sysv_statfs, | 345 | .statfs = sysv_statfs, |
352 | }; | 346 | }; |
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); |