aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/super.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-15 06:02:23 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-15 06:02:23 -0400
commit9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (patch)
tree8d104ec2a459346b99413b0b77421ca7b9936c1a /fs/ext2/super.c
parentca44d6e60f9de26281fda203f58b570e1748c015 (diff)
parent45e3e1935e2857c54783291107d33323b3ef33c8 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: Documentation/feature-removal-schedule.txt drivers/scsi/fcoe/fcoe.c net/core/drop_monitor.c net/core/net-traces.c
Diffstat (limited to 'fs/ext2/super.c')
-rw-r--r--fs/ext2/super.c61
1 files changed, 44 insertions, 17 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 5c4afe652245..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,
@@ -1093,6 +1100,7 @@ failed_mount:
1093 brelse(bh); 1100 brelse(bh);
1094failed_sbi: 1101failed_sbi:
1095 sb->s_fs_info = NULL; 1102 sb->s_fs_info = NULL;
1103 kfree(sbi->s_blockgroup_lock);
1096 kfree(sbi); 1104 kfree(sbi);
1097 return ret; 1105 return ret;
1098} 1106}
@@ -1126,25 +1134,36 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es)
1126 * set s_state to EXT2_VALID_FS after some corrections. 1134 * set s_state to EXT2_VALID_FS after some corrections.
1127 */ 1135 */
1128 1136
1129void ext2_write_super (struct super_block * sb) 1137static int ext2_sync_fs(struct super_block *sb, int wait)
1130{ 1138{
1131 struct ext2_super_block * es; 1139 struct ext2_super_block *es = EXT2_SB(sb)->s_es;
1140
1132 lock_kernel(); 1141 lock_kernel();
1133 if (!(sb->s_flags & MS_RDONLY)) { 1142 if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) {
1134 es = EXT2_SB(sb)->s_es; 1143 ext2_debug("setting valid to 0\n");
1135 1144 es->s_state &= cpu_to_le16(~EXT2_VALID_FS);
1136 if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { 1145 es->s_free_blocks_count =
1137 ext2_debug ("setting valid to 0\n"); 1146 cpu_to_le32(ext2_count_free_blocks(sb));
1138 es->s_state &= cpu_to_le16(~EXT2_VALID_FS); 1147 es->s_free_inodes_count =
1139 es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); 1148 cpu_to_le32(ext2_count_free_inodes(sb));
1140 es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); 1149 es->s_mtime = cpu_to_le32(get_seconds());
1141 es->s_mtime = cpu_to_le32(get_seconds()); 1150 ext2_sync_super(sb, es);
1142 ext2_sync_super(sb, es); 1151 } else {
1143 } else 1152 ext2_commit_super(sb, es);
1144 ext2_commit_super (sb, es);
1145 } 1153 }
1146 sb->s_dirt = 0; 1154 sb->s_dirt = 0;
1147 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;
1148} 1167}
1149 1168
1150static int ext2_remount (struct super_block * sb, int * flags, char * data) 1169static int ext2_remount (struct super_block * sb, int * flags, char * data)
@@ -1156,6 +1175,8 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1156 unsigned long old_sb_flags; 1175 unsigned long old_sb_flags;
1157 int err; 1176 int err;
1158 1177
1178 lock_kernel();
1179
1159 /* Store the old options */ 1180 /* Store the old options */
1160 old_sb_flags = sb->s_flags; 1181 old_sb_flags = sb->s_flags;
1161 old_opts.s_mount_opt = sbi->s_mount_opt; 1182 old_opts.s_mount_opt = sbi->s_mount_opt;
@@ -1191,12 +1212,16 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1191 sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; 1212 sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
1192 sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; 1213 sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
1193 } 1214 }
1194 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 1215 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
1216 unlock_kernel();
1195 return 0; 1217 return 0;
1218 }
1196 if (*flags & MS_RDONLY) { 1219 if (*flags & MS_RDONLY) {
1197 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || 1220 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
1198 !(sbi->s_mount_state & EXT2_VALID_FS)) 1221 !(sbi->s_mount_state & EXT2_VALID_FS)) {
1222 unlock_kernel();
1199 return 0; 1223 return 0;
1224 }
1200 /* 1225 /*
1201 * OK, we are remounting a valid rw partition rdonly, so set 1226 * OK, we are remounting a valid rw partition rdonly, so set
1202 * the rdonly flag and then mark the partition as valid again. 1227 * the rdonly flag and then mark the partition as valid again.
@@ -1223,12 +1248,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
1223 sb->s_flags &= ~MS_RDONLY; 1248 sb->s_flags &= ~MS_RDONLY;
1224 } 1249 }
1225 ext2_sync_super(sb, es); 1250 ext2_sync_super(sb, es);
1251 unlock_kernel();
1226 return 0; 1252 return 0;
1227restore_opts: 1253restore_opts:
1228 sbi->s_mount_opt = old_opts.s_mount_opt; 1254 sbi->s_mount_opt = old_opts.s_mount_opt;
1229 sbi->s_resuid = old_opts.s_resuid; 1255 sbi->s_resuid = old_opts.s_resuid;
1230 sbi->s_resgid = old_opts.s_resgid; 1256 sbi->s_resgid = old_opts.s_resgid;
1231 sb->s_flags = old_sb_flags; 1257 sb->s_flags = old_sb_flags;
1258 unlock_kernel();
1232 return err; 1259 return err;
1233} 1260}
1234 1261