aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
commita0e881b7c189fa2bd76c024dbff91e79511c971d (patch)
tree0c801918565b08921d21aceee5b326f64d998f5f /fs/ext2
parenteff0d13f3823f35d70228cd151d2a2c89288ff32 (diff)
parentdbc6e0222d79e78925fe20733844a796a4b72cf9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs pile from Al Viro: "The stuff in there: fsfreeze deadlock fixes by Jan (essentially, the deadlock reproduced by xfstests 068), symlink and hardlink restriction patches, plus assorted cleanups and fixes. Note that another fsfreeze deadlock (emergency thaw one) is *not* dealt with - the series by Fernando conflicts a lot with Jan's, breaks userland ABI (FIFREEZE semantics gets changed) and trades the deadlock for massive vfsmount leak; this is going to be handled next cycle. There probably will be another pull request, but that stuff won't be in it." Fix up trivial conflicts due to unrelated changes next to each other in drivers/{staging/gdm72xx/usb_boot.c, usb/gadget/storage_common.c} * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (54 commits) delousing target_core_file a bit Documentation: Correct s_umount state for freeze_fs/unfreeze_fs fs: Remove old freezing mechanism ext2: Implement freezing btrfs: Convert to new freezing mechanism nilfs2: Convert to new freezing mechanism ntfs: Convert to new freezing mechanism fuse: Convert to new freezing mechanism gfs2: Convert to new freezing mechanism ocfs2: Convert to new freezing mechanism xfs: Convert to new freezing code ext4: Convert to new freezing mechanism fs: Protect write paths by sb_start_write - sb_end_write fs: Skip atime update on frozen filesystem fs: Add freezing handling to mnt_want_write() / mnt_drop_write() fs: Improve filesystem freezing handling switch the protection of percpu_counter list to spinlock nfsd: Push mnt_want_write() outside of i_mutex btrfs: Push mnt_want_write() outside of i_mutex fat: Push mnt_want_write() outside of i_mutex ...
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/inode.c5
-rw-r--r--fs/ext2/super.c33
2 files changed, 37 insertions, 1 deletions
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 264d315f6c47..6363ac66fafa 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -79,6 +79,7 @@ void ext2_evict_inode(struct inode * inode)
79 truncate_inode_pages(&inode->i_data, 0); 79 truncate_inode_pages(&inode->i_data, 0);
80 80
81 if (want_delete) { 81 if (want_delete) {
82 sb_start_intwrite(inode->i_sb);
82 /* set dtime */ 83 /* set dtime */
83 EXT2_I(inode)->i_dtime = get_seconds(); 84 EXT2_I(inode)->i_dtime = get_seconds();
84 mark_inode_dirty(inode); 85 mark_inode_dirty(inode);
@@ -98,8 +99,10 @@ void ext2_evict_inode(struct inode * inode)
98 if (unlikely(rsv)) 99 if (unlikely(rsv))
99 kfree(rsv); 100 kfree(rsv);
100 101
101 if (want_delete) 102 if (want_delete) {
102 ext2_free_inode(inode); 103 ext2_free_inode(inode);
104 sb_end_intwrite(inode->i_sb);
105 }
103} 106}
104 107
105typedef struct { 108typedef struct {
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 9f311d27b16f..af74d9e27b71 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -42,6 +42,8 @@ static void ext2_sync_super(struct super_block *sb,
42static int ext2_remount (struct super_block * sb, int * flags, char * data); 42static int ext2_remount (struct super_block * sb, int * flags, char * data);
43static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); 43static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
44static int ext2_sync_fs(struct super_block *sb, int wait); 44static int ext2_sync_fs(struct super_block *sb, int wait);
45static int ext2_freeze(struct super_block *sb);
46static int ext2_unfreeze(struct super_block *sb);
45 47
46void ext2_error(struct super_block *sb, const char *function, 48void ext2_error(struct super_block *sb, const char *function,
47 const char *fmt, ...) 49 const char *fmt, ...)
@@ -305,6 +307,8 @@ static const struct super_operations ext2_sops = {
305 .evict_inode = ext2_evict_inode, 307 .evict_inode = ext2_evict_inode,
306 .put_super = ext2_put_super, 308 .put_super = ext2_put_super,
307 .sync_fs = ext2_sync_fs, 309 .sync_fs = ext2_sync_fs,
310 .freeze_fs = ext2_freeze,
311 .unfreeze_fs = ext2_unfreeze,
308 .statfs = ext2_statfs, 312 .statfs = ext2_statfs,
309 .remount_fs = ext2_remount, 313 .remount_fs = ext2_remount,
310 .show_options = ext2_show_options, 314 .show_options = ext2_show_options,
@@ -1200,6 +1204,35 @@ static int ext2_sync_fs(struct super_block *sb, int wait)
1200 return 0; 1204 return 0;
1201} 1205}
1202 1206
1207static int ext2_freeze(struct super_block *sb)
1208{
1209 struct ext2_sb_info *sbi = EXT2_SB(sb);
1210
1211 /*
1212 * Open but unlinked files present? Keep EXT2_VALID_FS flag cleared
1213 * because we have unattached inodes and thus filesystem is not fully
1214 * consistent.
1215 */
1216 if (atomic_long_read(&sb->s_remove_count)) {
1217 ext2_sync_fs(sb, 1);
1218 return 0;
1219 }
1220 /* Set EXT2_FS_VALID flag */
1221 spin_lock(&sbi->s_lock);
1222 sbi->s_es->s_state = cpu_to_le16(sbi->s_mount_state);
1223 spin_unlock(&sbi->s_lock);
1224 ext2_sync_super(sb, sbi->s_es, 1);
1225
1226 return 0;
1227}
1228
1229static int ext2_unfreeze(struct super_block *sb)
1230{
1231 /* Just write sb to clear EXT2_VALID_FS flag */
1232 ext2_write_super(sb);
1233
1234 return 0;
1235}
1203 1236
1204void ext2_write_super(struct super_block *sb) 1237void ext2_write_super(struct super_block *sb)
1205{ 1238{