aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/Makefile2
-rw-r--r--fs/ext2/dir.c2
-rw-r--r--fs/ext2/ext2.h3
-rw-r--r--fs/ext2/file.c4
-rw-r--r--fs/ext2/fsync.c50
-rw-r--r--fs/ext2/inode.c11
-rw-r--r--fs/ext2/super.c60
7 files changed, 49 insertions, 83 deletions
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile
index e0b2b43c1fdb..f42af45cfd88 100644
--- a/fs/ext2/Makefile
+++ b/fs/ext2/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-$(CONFIG_EXT2_FS) += ext2.o 5obj-$(CONFIG_EXT2_FS) += ext2.o
6 6
7ext2-y := balloc.o dir.o file.o fsync.o ialloc.o inode.o \ 7ext2-y := balloc.o dir.o file.o ialloc.o inode.o \
8 ioctl.o namei.o super.o symlink.o 8 ioctl.o namei.o super.o symlink.o
9 9
10ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o 10ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 2999d72153b7..003500498c22 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -720,5 +720,5 @@ const struct file_operations ext2_dir_operations = {
720#ifdef CONFIG_COMPAT 720#ifdef CONFIG_COMPAT
721 .compat_ioctl = ext2_compat_ioctl, 721 .compat_ioctl = ext2_compat_ioctl,
722#endif 722#endif
723 .fsync = ext2_sync_file, 723 .fsync = simple_fsync,
724}; 724};
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 3203042b36ef..b2bbf45039e0 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -113,9 +113,6 @@ extern int ext2_empty_dir (struct inode *);
113extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **); 113extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
114extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *); 114extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
115 115
116/* fsync.c */
117extern int ext2_sync_file (struct file *, struct dentry *, int);
118
119/* ialloc.c */ 116/* ialloc.c */
120extern struct inode * ext2_new_inode (struct inode *, int); 117extern struct inode * ext2_new_inode (struct inode *, int);
121extern void ext2_free_inode (struct inode *); 118extern void ext2_free_inode (struct inode *);
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 45ed07122182..2b9e47dc9222 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -55,7 +55,7 @@ const struct file_operations ext2_file_operations = {
55 .mmap = generic_file_mmap, 55 .mmap = generic_file_mmap,
56 .open = generic_file_open, 56 .open = generic_file_open,
57 .release = ext2_release_file, 57 .release = ext2_release_file,
58 .fsync = ext2_sync_file, 58 .fsync = simple_fsync,
59 .splice_read = generic_file_splice_read, 59 .splice_read = generic_file_splice_read,
60 .splice_write = generic_file_splice_write, 60 .splice_write = generic_file_splice_write,
61}; 61};
@@ -72,7 +72,7 @@ const struct file_operations ext2_xip_file_operations = {
72 .mmap = xip_file_mmap, 72 .mmap = xip_file_mmap,
73 .open = generic_file_open, 73 .open = generic_file_open,
74 .release = ext2_release_file, 74 .release = ext2_release_file,
75 .fsync = ext2_sync_file, 75 .fsync = simple_fsync,
76}; 76};
77#endif 77#endif
78 78
diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c
deleted file mode 100644
index fc66c93fcb5c..000000000000
--- a/fs/ext2/fsync.c
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * linux/fs/ext2/fsync.c
3 *
4 * Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk)
5 * from
6 * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
7 * Laboratoire MASI - Institut Blaise Pascal
8 * Universite Pierre et Marie Curie (Paris VI)
9 * from
10 * linux/fs/minix/truncate.c Copyright (C) 1991, 1992 Linus Torvalds
11 *
12 * ext2fs fsync primitive
13 *
14 * Big-endian to little-endian byte-swapping/bitmaps by
15 * David S. Miller (davem@caip.rutgers.edu), 1995
16 *
17 * Removed unnecessary code duplication for little endian machines
18 * and excessive __inline__s.
19 * Andi Kleen, 1997
20 *
21 * Major simplications and cleanup - we only need to do the metadata, because
22 * we can depend on generic_block_fdatasync() to sync the data blocks.
23 */
24
25#include "ext2.h"
26#include <linux/buffer_head.h> /* for sync_mapping_buffers() */
27
28
29/*
30 * File may be NULL when we are called. Perhaps we shouldn't
31 * even pass file to fsync ?
32 */
33
34int ext2_sync_file(struct file *file, struct dentry *dentry, int datasync)
35{
36 struct inode *inode = dentry->d_inode;
37 int err;
38 int ret;
39
40 ret = sync_mapping_buffers(inode->i_mapping);
41 if (!(inode->i_state & I_DIRTY))
42 return ret;
43 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
44 return ret;
45
46 err = ext2_sync_inode(inode);
47 if (ret == 0)
48 ret = err;
49 return ret;
50}
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index acf678831103..29ed682061f6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -41,8 +41,6 @@ MODULE_AUTHOR("Remy Card and others");
41MODULE_DESCRIPTION("Second Extended Filesystem"); 41MODULE_DESCRIPTION("Second Extended Filesystem");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43 43
44static int ext2_update_inode(struct inode * inode, int do_sync);
45
46/* 44/*
47 * Test whether an inode is a fast symlink. 45 * Test whether an inode is a fast symlink.
48 */ 46 */
@@ -66,7 +64,7 @@ void ext2_delete_inode (struct inode * inode)
66 goto no_delete; 64 goto no_delete;
67 EXT2_I(inode)->i_dtime = get_seconds(); 65 EXT2_I(inode)->i_dtime = get_seconds();
68 mark_inode_dirty(inode); 66 mark_inode_dirty(inode);
69 ext2_update_inode(inode, inode_needs_sync(inode)); 67 ext2_write_inode(inode, inode_needs_sync(inode));
70 68
71 inode->i_size = 0; 69 inode->i_size = 0;
72 if (inode->i_blocks) 70 if (inode->i_blocks)
@@ -1337,7 +1335,7 @@ bad_inode:
1337 return ERR_PTR(ret); 1335 return ERR_PTR(ret);
1338} 1336}
1339 1337
1340static int ext2_update_inode(struct inode * inode, int do_sync) 1338int ext2_write_inode(struct inode *inode, int do_sync)
1341{ 1339{
1342 struct ext2_inode_info *ei = EXT2_I(inode); 1340 struct ext2_inode_info *ei = EXT2_I(inode);
1343 struct super_block *sb = inode->i_sb; 1341 struct super_block *sb = inode->i_sb;
@@ -1442,11 +1440,6 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
1442 return err; 1440 return err;
1443} 1441}
1444 1442
1445int ext2_write_inode(struct inode *inode, int wait)
1446{
1447 return ext2_update_inode(inode, wait);
1448}
1449
1450int ext2_sync_inode(struct inode *inode) 1443int ext2_sync_inode(struct inode *inode)
1451{ 1444{
1452 struct writeback_control wbc = { 1445 struct writeback_control wbc = {
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index e3c748faf2db..458999638c3d 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -42,6 +42,7 @@ static void ext2_sync_super(struct super_block *sb,
42 struct ext2_super_block *es); 42 struct ext2_super_block *es);
43static int ext2_remount (struct super_block * sb, int * flags, char * data); 43static int ext2_remount (struct super_block * sb, int * flags, char * data);
44static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); 44static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
45static int ext2_sync_fs(struct super_block *sb, int wait);
45 46
46void ext2_error (struct super_block * sb, const char * function, 47void ext2_error (struct super_block * sb, const char * function,
47 const char * fmt, ...) 48 const char * fmt, ...)
@@ -114,6 +115,11 @@ static void ext2_put_super (struct super_block * sb)
114 int i; 115 int i;
115 struct ext2_sb_info *sbi = EXT2_SB(sb); 116 struct ext2_sb_info *sbi = EXT2_SB(sb);
116 117
118 lock_kernel();
119
120 if (sb->s_dirt)
121 ext2_write_super(sb);
122
117 ext2_xattr_put_super(sb); 123 ext2_xattr_put_super(sb);
118 if (!(sb->s_flags & MS_RDONLY)) { 124 if (!(sb->s_flags & MS_RDONLY)) {
119 struct ext2_super_block *es = sbi->s_es; 125 struct ext2_super_block *es = sbi->s_es;
@@ -135,7 +141,7 @@ static void ext2_put_super (struct super_block * sb)
135 kfree(sbi->s_blockgroup_lock); 141 kfree(sbi->s_blockgroup_lock);
136 kfree(sbi); 142 kfree(sbi);
137 143
138 return; 144 unlock_kernel();
139} 145}
140 146
141static struct kmem_cache * ext2_inode_cachep; 147static struct kmem_cache * ext2_inode_cachep;
@@ -304,6 +310,7 @@ static const struct super_operations ext2_sops = {
304 .delete_inode = ext2_delete_inode, 310 .delete_inode = ext2_delete_inode,
305 .put_super = ext2_put_super, 311 .put_super = ext2_put_super,
306 .write_super = ext2_write_super, 312 .write_super = ext2_write_super,
313 .sync_fs = ext2_sync_fs,
307 .statfs = ext2_statfs, 314 .statfs = ext2_statfs,
308 .remount_fs = ext2_remount, 315 .remount_fs = ext2_remount,
309 .clear_inode = ext2_clear_inode, 316 .clear_inode = ext2_clear_inode,
@@ -1127,25 +1134,36 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es)
1127 * set s_state to EXT2_VALID_FS after some corrections. 1134 * set s_state to EXT2_VALID_FS after some corrections.
1128 */ 1135 */
1129 1136
1130void ext2_write_super (struct super_block * sb) 1137static int ext2_sync_fs(struct super_block *sb, int wait)
1131{ 1138{
1132 struct ext2_super_block * es; 1139 struct ext2_super_block *es = EXT2_SB(sb)->s_es;
1140
1133 lock_kernel(); 1141 lock_kernel();
1134 if (!(sb->s_flags & MS_RDONLY)) { 1142 if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) {
1135 es = EXT2_SB(sb)->s_es; 1143 ext2_debug("setting valid to 0\n");
1136 1144 es->s_state &= cpu_to_le16(~EXT2_VALID_FS);
1137 if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { 1145 es->s_free_blocks_count =
1138 ext2_debug ("setting valid to 0\n"); 1146 cpu_to_le32(ext2_count_free_blocks(sb));
1139 es->s_state &= cpu_to_le16(~EXT2_VALID_FS); 1147 es->s_free_inodes_count =
1140 es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); 1148 cpu_to_le32(ext2_count_free_inodes(sb));
1141 es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); 1149 es->s_mtime = cpu_to_le32(get_seconds());
1142 es->s_mtime = cpu_to_le32(get_seconds()); 1150 ext2_sync_super(sb, es);
1143 ext2_sync_super(sb, es); 1151 } else {
1144 } else 1152 ext2_commit_super(sb, es);
1145 ext2_commit_super (sb, es);
1146 } 1153 }
1147 sb->s_dirt = 0; 1154 sb->s_dirt = 0;
1148 unlock_kernel(); 1155 unlock_kernel();
1156
1157 return 0;
1158}
1159
1160
1161void ext2_write_super(struct super_block *sb)
1162{
1163 if (!(sb->s_flags & MS_RDONLY))
1164 ext2_sync_fs(sb, 1);
1165 else
1166 sb->s_dirt = 0;
1149} 1167}
1150 1168
1151static int ext2_remount (struct super_block * sb, int * flags, char * data) 1169static int ext2_remount (struct super_block * sb, int * flags, char * data)
@@ -1157,6 +1175,8 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1157 unsigned long old_sb_flags; 1175 unsigned long old_sb_flags;
1158 int err; 1176 int err;
1159 1177
1178 lock_kernel();
1179
1160 /* Store the old options */ 1180 /* Store the old options */
1161 old_sb_flags = sb->s_flags; 1181 old_sb_flags = sb->s_flags;
1162 old_opts.s_mount_opt = sbi->s_mount_opt; 1182 old_opts.s_mount_opt = sbi->s_mount_opt;
@@ -1192,12 +1212,16 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1192 sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; 1212 sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
1193 sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; 1213 sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
1194 } 1214 }
1195 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 1215 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
1216 unlock_kernel();
1196 return 0; 1217 return 0;
1218 }
1197 if (*flags & MS_RDONLY) { 1219 if (*flags & MS_RDONLY) {
1198 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || 1220 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
1199 !(sbi->s_mount_state & EXT2_VALID_FS)) 1221 !(sbi->s_mount_state & EXT2_VALID_FS)) {
1222 unlock_kernel();
1200 return 0; 1223 return 0;
1224 }
1201 /* 1225 /*
1202 * OK, we are remounting a valid rw partition rdonly, so set 1226 * OK, we are remounting a valid rw partition rdonly, so set
1203 * the rdonly flag and then mark the partition as valid again. 1227 * the rdonly flag and then mark the partition as valid again.
@@ -1224,12 +1248,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1224 sb->s_flags &= ~MS_RDONLY; 1248 sb->s_flags &= ~MS_RDONLY;
1225 } 1249 }
1226 ext2_sync_super(sb, es); 1250 ext2_sync_super(sb, es);
1251 unlock_kernel();
1227 return 0; 1252 return 0;
1228restore_opts: 1253restore_opts:
1229 sbi->s_mount_opt = old_opts.s_mount_opt; 1254 sbi->s_mount_opt = old_opts.s_mount_opt;
1230 sbi->s_resuid = old_opts.s_resuid; 1255 sbi->s_resuid = old_opts.s_resuid;
1231 sbi->s_resgid = old_opts.s_resgid; 1256 sbi->s_resgid = old_opts.s_resgid;
1232 sb->s_flags = old_sb_flags; 1257 sb->s_flags = old_sb_flags;
1258 unlock_kernel();
1233 return err; 1259 return err;
1234} 1260}
1235 1261