diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-08 00:44:42 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-11 21:36:13 -0400 |
commit | ffdc9064f8b4fa9db37a7d5180f41cce2ea2b7ad (patch) | |
tree | a7cc3f3940211682289983865e453b4d7083554b | |
parent | bea6b64c277f0824cdaea6190209b26a164419d6 (diff) |
repair adfs ->write_inode(), switch to simple_fsync()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/adfs/adfs.h | 4 | ||||
-rw-r--r-- | fs/adfs/dir.c | 10 | ||||
-rw-r--r-- | fs/adfs/dir_f.c | 17 | ||||
-rw-r--r-- | fs/adfs/dir_fplus.c | 17 | ||||
-rw-r--r-- | fs/adfs/file.c | 2 | ||||
-rw-r--r-- | fs/adfs/inode.c | 4 |
6 files changed, 48 insertions, 6 deletions
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h index e0a85dbeeb88..a6665f37f456 100644 --- a/fs/adfs/adfs.h +++ b/fs/adfs/adfs.h | |||
@@ -53,6 +53,7 @@ struct adfs_dir_ops { | |||
53 | int (*update)(struct adfs_dir *dir, struct object_info *obj); | 53 | int (*update)(struct adfs_dir *dir, struct object_info *obj); |
54 | int (*create)(struct adfs_dir *dir, struct object_info *obj); | 54 | int (*create)(struct adfs_dir *dir, struct object_info *obj); |
55 | int (*remove)(struct adfs_dir *dir, struct object_info *obj); | 55 | int (*remove)(struct adfs_dir *dir, struct object_info *obj); |
56 | int (*sync)(struct adfs_dir *dir); | ||
56 | void (*free)(struct adfs_dir *dir); | 57 | void (*free)(struct adfs_dir *dir); |
57 | }; | 58 | }; |
58 | 59 | ||
@@ -90,7 +91,8 @@ extern const struct dentry_operations adfs_dentry_operations; | |||
90 | extern struct adfs_dir_ops adfs_f_dir_ops; | 91 | extern struct adfs_dir_ops adfs_f_dir_ops; |
91 | extern struct adfs_dir_ops adfs_fplus_dir_ops; | 92 | extern struct adfs_dir_ops adfs_fplus_dir_ops; |
92 | 93 | ||
93 | extern int adfs_dir_update(struct super_block *sb, struct object_info *obj); | 94 | extern int adfs_dir_update(struct super_block *sb, struct object_info *obj, |
95 | int wait); | ||
94 | 96 | ||
95 | /* file.c */ | 97 | /* file.c */ |
96 | extern const struct inode_operations adfs_file_inode_operations; | 98 | extern const struct inode_operations adfs_file_inode_operations; |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index e867ccf37246..4d4073447d1a 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -83,7 +83,7 @@ out: | |||
83 | } | 83 | } |
84 | 84 | ||
85 | int | 85 | int |
86 | adfs_dir_update(struct super_block *sb, struct object_info *obj) | 86 | adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait) |
87 | { | 87 | { |
88 | int ret = -EINVAL; | 88 | int ret = -EINVAL; |
89 | #ifdef CONFIG_ADFS_FS_RW | 89 | #ifdef CONFIG_ADFS_FS_RW |
@@ -106,6 +106,12 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj) | |||
106 | ret = ops->update(&dir, obj); | 106 | ret = ops->update(&dir, obj); |
107 | write_unlock(&adfs_dir_lock); | 107 | write_unlock(&adfs_dir_lock); |
108 | 108 | ||
109 | if (wait) { | ||
110 | int err = ops->sync(&dir); | ||
111 | if (!ret) | ||
112 | ret = err; | ||
113 | } | ||
114 | |||
109 | ops->free(&dir); | 115 | ops->free(&dir); |
110 | out: | 116 | out: |
111 | #endif | 117 | #endif |
@@ -199,7 +205,7 @@ const struct file_operations adfs_dir_operations = { | |||
199 | .read = generic_read_dir, | 205 | .read = generic_read_dir, |
200 | .llseek = generic_file_llseek, | 206 | .llseek = generic_file_llseek, |
201 | .readdir = adfs_readdir, | 207 | .readdir = adfs_readdir, |
202 | .fsync = file_fsync, | 208 | .fsync = simple_fsync, |
203 | }; | 209 | }; |
204 | 210 | ||
205 | static int | 211 | static int |
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c index ea7df2146921..31df6adf0de6 100644 --- a/fs/adfs/dir_f.c +++ b/fs/adfs/dir_f.c | |||
@@ -437,6 +437,22 @@ bad_dir: | |||
437 | #endif | 437 | #endif |
438 | } | 438 | } |
439 | 439 | ||
440 | static int | ||
441 | adfs_f_sync(struct adfs_dir *dir) | ||
442 | { | ||
443 | int err = 0; | ||
444 | int i; | ||
445 | |||
446 | for (i = dir->nr_buffers - 1; i >= 0; i--) { | ||
447 | struct buffer_head *bh = dir->bh[i]; | ||
448 | sync_dirty_buffer(bh); | ||
449 | if (buffer_req(bh) && !buffer_uptodate(bh)) | ||
450 | err = -EIO; | ||
451 | } | ||
452 | |||
453 | return err; | ||
454 | } | ||
455 | |||
440 | static void | 456 | static void |
441 | adfs_f_free(struct adfs_dir *dir) | 457 | adfs_f_free(struct adfs_dir *dir) |
442 | { | 458 | { |
@@ -456,5 +472,6 @@ struct adfs_dir_ops adfs_f_dir_ops = { | |||
456 | .setpos = adfs_f_setpos, | 472 | .setpos = adfs_f_setpos, |
457 | .getnext = adfs_f_getnext, | 473 | .getnext = adfs_f_getnext, |
458 | .update = adfs_f_update, | 474 | .update = adfs_f_update, |
475 | .sync = adfs_f_sync, | ||
459 | .free = adfs_f_free | 476 | .free = adfs_f_free |
460 | }; | 477 | }; |
diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c index 1ec644e32df9..139e0f345f18 100644 --- a/fs/adfs/dir_fplus.c +++ b/fs/adfs/dir_fplus.c | |||
@@ -161,6 +161,22 @@ out: | |||
161 | return ret; | 161 | return ret; |
162 | } | 162 | } |
163 | 163 | ||
164 | static int | ||
165 | adfs_fplus_sync(struct adfs_dir *dir) | ||
166 | { | ||
167 | int err = 0; | ||
168 | int i; | ||
169 | |||
170 | for (i = dir->nr_buffers - 1; i >= 0; i--) { | ||
171 | struct buffer_head *bh = dir->bh[i]; | ||
172 | sync_dirty_buffer(bh); | ||
173 | if (buffer_req(bh) && !buffer_uptodate(bh)) | ||
174 | err = -EIO; | ||
175 | } | ||
176 | |||
177 | return err; | ||
178 | } | ||
179 | |||
164 | static void | 180 | static void |
165 | adfs_fplus_free(struct adfs_dir *dir) | 181 | adfs_fplus_free(struct adfs_dir *dir) |
166 | { | 182 | { |
@@ -175,5 +191,6 @@ struct adfs_dir_ops adfs_fplus_dir_ops = { | |||
175 | .read = adfs_fplus_read, | 191 | .read = adfs_fplus_read, |
176 | .setpos = adfs_fplus_setpos, | 192 | .setpos = adfs_fplus_setpos, |
177 | .getnext = adfs_fplus_getnext, | 193 | .getnext = adfs_fplus_getnext, |
194 | .sync = adfs_fplus_sync, | ||
178 | .free = adfs_fplus_free | 195 | .free = adfs_fplus_free |
179 | }; | 196 | }; |
diff --git a/fs/adfs/file.c b/fs/adfs/file.c index 36e381c6a99a..8224d54a2afb 100644 --- a/fs/adfs/file.c +++ b/fs/adfs/file.c | |||
@@ -30,7 +30,7 @@ const struct file_operations adfs_file_operations = { | |||
30 | .read = do_sync_read, | 30 | .read = do_sync_read, |
31 | .aio_read = generic_file_aio_read, | 31 | .aio_read = generic_file_aio_read, |
32 | .mmap = generic_file_mmap, | 32 | .mmap = generic_file_mmap, |
33 | .fsync = file_fsync, | 33 | .fsync = simple_fsync, |
34 | .write = do_sync_write, | 34 | .write = do_sync_write, |
35 | .aio_write = generic_file_aio_write, | 35 | .aio_write = generic_file_aio_write, |
36 | .splice_read = generic_file_splice_read, | 36 | .splice_read = generic_file_splice_read, |
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index e647200262a2..05b3a677201d 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c | |||
@@ -376,7 +376,7 @@ out: | |||
376 | * The adfs-specific inode data has already been updated by | 376 | * The adfs-specific inode data has already been updated by |
377 | * adfs_notify_change() | 377 | * adfs_notify_change() |
378 | */ | 378 | */ |
379 | int adfs_write_inode(struct inode *inode, int unused) | 379 | int adfs_write_inode(struct inode *inode, int wait) |
380 | { | 380 | { |
381 | struct super_block *sb = inode->i_sb; | 381 | struct super_block *sb = inode->i_sb; |
382 | struct object_info obj; | 382 | struct object_info obj; |
@@ -391,7 +391,7 @@ int adfs_write_inode(struct inode *inode, int unused) | |||
391 | obj.attr = ADFS_I(inode)->attr; | 391 | obj.attr = ADFS_I(inode)->attr; |
392 | obj.size = inode->i_size; | 392 | obj.size = inode->i_size; |
393 | 393 | ||
394 | ret = adfs_dir_update(sb, &obj); | 394 | ret = adfs_dir_update(sb, &obj, wait); |
395 | unlock_kernel(); | 395 | unlock_kernel(); |
396 | return ret; | 396 | return ret; |
397 | } | 397 | } |