diff options
-rw-r--r-- | fs/fat/dir.c | 16 | ||||
-rw-r--r-- | fs/fat/fat.h | 6 | ||||
-rw-r--r-- | fs/fat/fatent.c | 13 | ||||
-rw-r--r-- | fs/fat/file.c | 14 | ||||
-rw-r--r-- | fs/fat/inode.c | 11 | ||||
-rw-r--r-- | fs/fat/namei_msdos.c | 4 | ||||
-rw-r--r-- | fs/fat/namei_vfat.c | 4 |
7 files changed, 49 insertions, 19 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 3a7f603b6982..f3500294eec5 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -840,7 +840,7 @@ const struct file_operations fat_dir_operations = { | |||
840 | #ifdef CONFIG_COMPAT | 840 | #ifdef CONFIG_COMPAT |
841 | .compat_ioctl = fat_compat_dir_ioctl, | 841 | .compat_ioctl = fat_compat_dir_ioctl, |
842 | #endif | 842 | #endif |
843 | .fsync = file_fsync, | 843 | .fsync = fat_file_fsync, |
844 | }; | 844 | }; |
845 | 845 | ||
846 | static int fat_get_short_entry(struct inode *dir, loff_t *pos, | 846 | static int fat_get_short_entry(struct inode *dir, loff_t *pos, |
@@ -967,7 +967,7 @@ static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) | |||
967 | de++; | 967 | de++; |
968 | nr_slots--; | 968 | nr_slots--; |
969 | } | 969 | } |
970 | mark_buffer_dirty(bh); | 970 | mark_buffer_dirty_inode(bh, dir); |
971 | if (IS_DIRSYNC(dir)) | 971 | if (IS_DIRSYNC(dir)) |
972 | err = sync_dirty_buffer(bh); | 972 | err = sync_dirty_buffer(bh); |
973 | brelse(bh); | 973 | brelse(bh); |
@@ -1001,7 +1001,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) | |||
1001 | de--; | 1001 | de--; |
1002 | nr_slots--; | 1002 | nr_slots--; |
1003 | } | 1003 | } |
1004 | mark_buffer_dirty(bh); | 1004 | mark_buffer_dirty_inode(bh, dir); |
1005 | if (IS_DIRSYNC(dir)) | 1005 | if (IS_DIRSYNC(dir)) |
1006 | err = sync_dirty_buffer(bh); | 1006 | err = sync_dirty_buffer(bh); |
1007 | brelse(bh); | 1007 | brelse(bh); |
@@ -1051,7 +1051,7 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, | |||
1051 | } | 1051 | } |
1052 | memset(bhs[n]->b_data, 0, sb->s_blocksize); | 1052 | memset(bhs[n]->b_data, 0, sb->s_blocksize); |
1053 | set_buffer_uptodate(bhs[n]); | 1053 | set_buffer_uptodate(bhs[n]); |
1054 | mark_buffer_dirty(bhs[n]); | 1054 | mark_buffer_dirty_inode(bhs[n], dir); |
1055 | 1055 | ||
1056 | n++; | 1056 | n++; |
1057 | blknr++; | 1057 | blknr++; |
@@ -1131,7 +1131,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec *ts) | |||
1131 | de[0].size = de[1].size = 0; | 1131 | de[0].size = de[1].size = 0; |
1132 | memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); | 1132 | memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); |
1133 | set_buffer_uptodate(bhs[0]); | 1133 | set_buffer_uptodate(bhs[0]); |
1134 | mark_buffer_dirty(bhs[0]); | 1134 | mark_buffer_dirty_inode(bhs[0], dir); |
1135 | 1135 | ||
1136 | err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE); | 1136 | err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE); |
1137 | if (err) | 1137 | if (err) |
@@ -1193,7 +1193,7 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots, | |||
1193 | slots += copy; | 1193 | slots += copy; |
1194 | size -= copy; | 1194 | size -= copy; |
1195 | set_buffer_uptodate(bhs[n]); | 1195 | set_buffer_uptodate(bhs[n]); |
1196 | mark_buffer_dirty(bhs[n]); | 1196 | mark_buffer_dirty_inode(bhs[n], dir); |
1197 | if (!size) | 1197 | if (!size) |
1198 | break; | 1198 | break; |
1199 | n++; | 1199 | n++; |
@@ -1293,7 +1293,7 @@ found: | |||
1293 | for (i = 0; i < long_bhs; i++) { | 1293 | for (i = 0; i < long_bhs; i++) { |
1294 | int copy = min_t(int, sb->s_blocksize - offset, size); | 1294 | int copy = min_t(int, sb->s_blocksize - offset, size); |
1295 | memcpy(bhs[i]->b_data + offset, slots, copy); | 1295 | memcpy(bhs[i]->b_data + offset, slots, copy); |
1296 | mark_buffer_dirty(bhs[i]); | 1296 | mark_buffer_dirty_inode(bhs[i], dir); |
1297 | offset = 0; | 1297 | offset = 0; |
1298 | slots += copy; | 1298 | slots += copy; |
1299 | size -= copy; | 1299 | size -= copy; |
@@ -1304,7 +1304,7 @@ found: | |||
1304 | /* Fill the short name slot. */ | 1304 | /* Fill the short name slot. */ |
1305 | int copy = min_t(int, sb->s_blocksize - offset, size); | 1305 | int copy = min_t(int, sb->s_blocksize - offset, size); |
1306 | memcpy(bhs[i]->b_data + offset, slots, copy); | 1306 | memcpy(bhs[i]->b_data + offset, slots, copy); |
1307 | mark_buffer_dirty(bhs[i]); | 1307 | mark_buffer_dirty_inode(bhs[i], dir); |
1308 | if (IS_DIRSYNC(dir)) | 1308 | if (IS_DIRSYNC(dir)) |
1309 | err = sync_dirty_buffer(bhs[i]); | 1309 | err = sync_dirty_buffer(bhs[i]); |
1310 | } | 1310 | } |
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index ea440d65819c..e4d88527b5dd 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -74,6 +74,7 @@ struct msdos_sb_info { | |||
74 | 74 | ||
75 | int fatent_shift; | 75 | int fatent_shift; |
76 | struct fatent_operations *fatent_ops; | 76 | struct fatent_operations *fatent_ops; |
77 | struct inode *fat_inode; | ||
77 | 78 | ||
78 | spinlock_t inode_hash_lock; | 79 | spinlock_t inode_hash_lock; |
79 | struct hlist_head inode_hashtable[FAT_HASH_SIZE]; | 80 | struct hlist_head inode_hashtable[FAT_HASH_SIZE]; |
@@ -251,6 +252,7 @@ struct fat_entry { | |||
251 | } u; | 252 | } u; |
252 | int nr_bhs; | 253 | int nr_bhs; |
253 | struct buffer_head *bhs[2]; | 254 | struct buffer_head *bhs[2]; |
255 | struct inode *fat_inode; | ||
254 | }; | 256 | }; |
255 | 257 | ||
256 | static inline void fatent_init(struct fat_entry *fatent) | 258 | static inline void fatent_init(struct fat_entry *fatent) |
@@ -259,6 +261,7 @@ static inline void fatent_init(struct fat_entry *fatent) | |||
259 | fatent->entry = 0; | 261 | fatent->entry = 0; |
260 | fatent->u.ent32_p = NULL; | 262 | fatent->u.ent32_p = NULL; |
261 | fatent->bhs[0] = fatent->bhs[1] = NULL; | 263 | fatent->bhs[0] = fatent->bhs[1] = NULL; |
264 | fatent->fat_inode = NULL; | ||
262 | } | 265 | } |
263 | 266 | ||
264 | static inline void fatent_set_entry(struct fat_entry *fatent, int entry) | 267 | static inline void fatent_set_entry(struct fat_entry *fatent, int entry) |
@@ -275,6 +278,7 @@ static inline void fatent_brelse(struct fat_entry *fatent) | |||
275 | brelse(fatent->bhs[i]); | 278 | brelse(fatent->bhs[i]); |
276 | fatent->nr_bhs = 0; | 279 | fatent->nr_bhs = 0; |
277 | fatent->bhs[0] = fatent->bhs[1] = NULL; | 280 | fatent->bhs[0] = fatent->bhs[1] = NULL; |
281 | fatent->fat_inode = NULL; | ||
278 | } | 282 | } |
279 | 283 | ||
280 | extern void fat_ent_access_init(struct super_block *sb); | 284 | extern void fat_ent_access_init(struct super_block *sb); |
@@ -296,6 +300,8 @@ extern int fat_setattr(struct dentry * dentry, struct iattr * attr); | |||
296 | extern void fat_truncate(struct inode *inode); | 300 | extern void fat_truncate(struct inode *inode); |
297 | extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, | 301 | extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, |
298 | struct kstat *stat); | 302 | struct kstat *stat); |
303 | extern int fat_file_fsync(struct file *file, struct dentry *dentry, | ||
304 | int datasync); | ||
299 | 305 | ||
300 | /* fat/inode.c */ | 306 | /* fat/inode.c */ |
301 | extern void fat_attach(struct inode *inode, loff_t i_pos); | 307 | extern void fat_attach(struct inode *inode, loff_t i_pos); |
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index da6eea47872f..618f5305c2e4 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c | |||
@@ -73,6 +73,8 @@ static int fat12_ent_bread(struct super_block *sb, struct fat_entry *fatent, | |||
73 | struct buffer_head **bhs = fatent->bhs; | 73 | struct buffer_head **bhs = fatent->bhs; |
74 | 74 | ||
75 | WARN_ON(blocknr < MSDOS_SB(sb)->fat_start); | 75 | WARN_ON(blocknr < MSDOS_SB(sb)->fat_start); |
76 | fatent->fat_inode = MSDOS_SB(sb)->fat_inode; | ||
77 | |||
76 | bhs[0] = sb_bread(sb, blocknr); | 78 | bhs[0] = sb_bread(sb, blocknr); |
77 | if (!bhs[0]) | 79 | if (!bhs[0]) |
78 | goto err; | 80 | goto err; |
@@ -103,6 +105,7 @@ static int fat_ent_bread(struct super_block *sb, struct fat_entry *fatent, | |||
103 | struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops; | 105 | struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops; |
104 | 106 | ||
105 | WARN_ON(blocknr < MSDOS_SB(sb)->fat_start); | 107 | WARN_ON(blocknr < MSDOS_SB(sb)->fat_start); |
108 | fatent->fat_inode = MSDOS_SB(sb)->fat_inode; | ||
106 | fatent->bhs[0] = sb_bread(sb, blocknr); | 109 | fatent->bhs[0] = sb_bread(sb, blocknr); |
107 | if (!fatent->bhs[0]) { | 110 | if (!fatent->bhs[0]) { |
108 | printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n", | 111 | printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n", |
@@ -167,9 +170,9 @@ static void fat12_ent_put(struct fat_entry *fatent, int new) | |||
167 | } | 170 | } |
168 | spin_unlock(&fat12_entry_lock); | 171 | spin_unlock(&fat12_entry_lock); |
169 | 172 | ||
170 | mark_buffer_dirty(fatent->bhs[0]); | 173 | mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode); |
171 | if (fatent->nr_bhs == 2) | 174 | if (fatent->nr_bhs == 2) |
172 | mark_buffer_dirty(fatent->bhs[1]); | 175 | mark_buffer_dirty_inode(fatent->bhs[1], fatent->fat_inode); |
173 | } | 176 | } |
174 | 177 | ||
175 | static void fat16_ent_put(struct fat_entry *fatent, int new) | 178 | static void fat16_ent_put(struct fat_entry *fatent, int new) |
@@ -178,7 +181,7 @@ static void fat16_ent_put(struct fat_entry *fatent, int new) | |||
178 | new = EOF_FAT16; | 181 | new = EOF_FAT16; |
179 | 182 | ||
180 | *fatent->u.ent16_p = cpu_to_le16(new); | 183 | *fatent->u.ent16_p = cpu_to_le16(new); |
181 | mark_buffer_dirty(fatent->bhs[0]); | 184 | mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode); |
182 | } | 185 | } |
183 | 186 | ||
184 | static void fat32_ent_put(struct fat_entry *fatent, int new) | 187 | static void fat32_ent_put(struct fat_entry *fatent, int new) |
@@ -189,7 +192,7 @@ static void fat32_ent_put(struct fat_entry *fatent, int new) | |||
189 | WARN_ON(new & 0xf0000000); | 192 | WARN_ON(new & 0xf0000000); |
190 | new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff; | 193 | new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff; |
191 | *fatent->u.ent32_p = cpu_to_le32(new); | 194 | *fatent->u.ent32_p = cpu_to_le32(new); |
192 | mark_buffer_dirty(fatent->bhs[0]); | 195 | mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode); |
193 | } | 196 | } |
194 | 197 | ||
195 | static int fat12_ent_next(struct fat_entry *fatent) | 198 | static int fat12_ent_next(struct fat_entry *fatent) |
@@ -381,7 +384,7 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs, | |||
381 | } | 384 | } |
382 | memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize); | 385 | memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize); |
383 | set_buffer_uptodate(c_bh); | 386 | set_buffer_uptodate(c_bh); |
384 | mark_buffer_dirty(c_bh); | 387 | mark_buffer_dirty_inode(c_bh, sbi->fat_inode); |
385 | if (sb->s_flags & MS_SYNCHRONOUS) | 388 | if (sb->s_flags & MS_SYNCHRONOUS) |
386 | err = sync_dirty_buffer(c_bh); | 389 | err = sync_dirty_buffer(c_bh); |
387 | brelse(c_bh); | 390 | brelse(c_bh); |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 0a7f4a9918b3..e955a56b4e5e 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -133,6 +133,18 @@ static int fat_file_release(struct inode *inode, struct file *filp) | |||
133 | return 0; | 133 | return 0; |
134 | } | 134 | } |
135 | 135 | ||
136 | int fat_file_fsync(struct file *filp, struct dentry *dentry, int datasync) | ||
137 | { | ||
138 | struct inode *inode = dentry->d_inode; | ||
139 | int res, err; | ||
140 | |||
141 | res = simple_fsync(filp, dentry, datasync); | ||
142 | err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping); | ||
143 | |||
144 | return res ? res : err; | ||
145 | } | ||
146 | |||
147 | |||
136 | const struct file_operations fat_file_operations = { | 148 | const struct file_operations fat_file_operations = { |
137 | .llseek = generic_file_llseek, | 149 | .llseek = generic_file_llseek, |
138 | .read = do_sync_read, | 150 | .read = do_sync_read, |
@@ -142,7 +154,7 @@ const struct file_operations fat_file_operations = { | |||
142 | .mmap = generic_file_mmap, | 154 | .mmap = generic_file_mmap, |
143 | .release = fat_file_release, | 155 | .release = fat_file_release, |
144 | .ioctl = fat_generic_ioctl, | 156 | .ioctl = fat_generic_ioctl, |
145 | .fsync = file_fsync, | 157 | .fsync = fat_file_fsync, |
146 | .splice_read = generic_file_splice_read, | 158 | .splice_read = generic_file_splice_read, |
147 | }; | 159 | }; |
148 | 160 | ||
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 2292cbf7d364..476f80b175fe 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -458,6 +458,8 @@ static void fat_put_super(struct super_block *sb) | |||
458 | if (sb->s_dirt) | 458 | if (sb->s_dirt) |
459 | fat_write_super(sb); | 459 | fat_write_super(sb); |
460 | 460 | ||
461 | iput(sbi->fat_inode); | ||
462 | |||
461 | if (sbi->nls_disk) { | 463 | if (sbi->nls_disk) { |
462 | unload_nls(sbi->nls_disk); | 464 | unload_nls(sbi->nls_disk); |
463 | sbi->nls_disk = NULL; | 465 | sbi->nls_disk = NULL; |
@@ -1183,7 +1185,7 @@ static int fat_read_root(struct inode *inode) | |||
1183 | int fat_fill_super(struct super_block *sb, void *data, int silent, | 1185 | int fat_fill_super(struct super_block *sb, void *data, int silent, |
1184 | const struct inode_operations *fs_dir_inode_ops, int isvfat) | 1186 | const struct inode_operations *fs_dir_inode_ops, int isvfat) |
1185 | { | 1187 | { |
1186 | struct inode *root_inode = NULL; | 1188 | struct inode *root_inode = NULL, *fat_inode = NULL; |
1187 | struct buffer_head *bh; | 1189 | struct buffer_head *bh; |
1188 | struct fat_boot_sector *b; | 1190 | struct fat_boot_sector *b; |
1189 | struct msdos_sb_info *sbi; | 1191 | struct msdos_sb_info *sbi; |
@@ -1423,6 +1425,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1423 | } | 1425 | } |
1424 | 1426 | ||
1425 | error = -ENOMEM; | 1427 | error = -ENOMEM; |
1428 | fat_inode = new_inode(sb); | ||
1429 | if (!fat_inode) | ||
1430 | goto out_fail; | ||
1431 | MSDOS_I(fat_inode)->i_pos = 0; | ||
1432 | sbi->fat_inode = fat_inode; | ||
1426 | root_inode = new_inode(sb); | 1433 | root_inode = new_inode(sb); |
1427 | if (!root_inode) | 1434 | if (!root_inode) |
1428 | goto out_fail; | 1435 | goto out_fail; |
@@ -1448,6 +1455,8 @@ out_invalid: | |||
1448 | " on dev %s.\n", sb->s_id); | 1455 | " on dev %s.\n", sb->s_id); |
1449 | 1456 | ||
1450 | out_fail: | 1457 | out_fail: |
1458 | if (fat_inode) | ||
1459 | iput(fat_inode); | ||
1451 | if (root_inode) | 1460 | if (root_inode) |
1452 | iput(root_inode); | 1461 | iput(root_inode); |
1453 | if (sbi->nls_io) | 1462 | if (sbi->nls_io) |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index da3f361a37dd..20f522861355 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -544,7 +544,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
544 | int start = MSDOS_I(new_dir)->i_logstart; | 544 | int start = MSDOS_I(new_dir)->i_logstart; |
545 | dotdot_de->start = cpu_to_le16(start); | 545 | dotdot_de->start = cpu_to_le16(start); |
546 | dotdot_de->starthi = cpu_to_le16(start >> 16); | 546 | dotdot_de->starthi = cpu_to_le16(start >> 16); |
547 | mark_buffer_dirty(dotdot_bh); | 547 | mark_buffer_dirty_inode(dotdot_bh, old_inode); |
548 | if (IS_DIRSYNC(new_dir)) { | 548 | if (IS_DIRSYNC(new_dir)) { |
549 | err = sync_dirty_buffer(dotdot_bh); | 549 | err = sync_dirty_buffer(dotdot_bh); |
550 | if (err) | 550 | if (err) |
@@ -586,7 +586,7 @@ error_dotdot: | |||
586 | int start = MSDOS_I(old_dir)->i_logstart; | 586 | int start = MSDOS_I(old_dir)->i_logstart; |
587 | dotdot_de->start = cpu_to_le16(start); | 587 | dotdot_de->start = cpu_to_le16(start); |
588 | dotdot_de->starthi = cpu_to_le16(start >> 16); | 588 | dotdot_de->starthi = cpu_to_le16(start >> 16); |
589 | mark_buffer_dirty(dotdot_bh); | 589 | mark_buffer_dirty_inode(dotdot_bh, old_inode); |
590 | corrupt |= sync_dirty_buffer(dotdot_bh); | 590 | corrupt |= sync_dirty_buffer(dotdot_bh); |
591 | } | 591 | } |
592 | error_inode: | 592 | error_inode: |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index a0e00e3a46e9..b50ecbe97f83 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -965,7 +965,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
965 | int start = MSDOS_I(new_dir)->i_logstart; | 965 | int start = MSDOS_I(new_dir)->i_logstart; |
966 | dotdot_de->start = cpu_to_le16(start); | 966 | dotdot_de->start = cpu_to_le16(start); |
967 | dotdot_de->starthi = cpu_to_le16(start >> 16); | 967 | dotdot_de->starthi = cpu_to_le16(start >> 16); |
968 | mark_buffer_dirty(dotdot_bh); | 968 | mark_buffer_dirty_inode(dotdot_bh, old_inode); |
969 | if (IS_DIRSYNC(new_dir)) { | 969 | if (IS_DIRSYNC(new_dir)) { |
970 | err = sync_dirty_buffer(dotdot_bh); | 970 | err = sync_dirty_buffer(dotdot_bh); |
971 | if (err) | 971 | if (err) |
@@ -1009,7 +1009,7 @@ error_dotdot: | |||
1009 | int start = MSDOS_I(old_dir)->i_logstart; | 1009 | int start = MSDOS_I(old_dir)->i_logstart; |
1010 | dotdot_de->start = cpu_to_le16(start); | 1010 | dotdot_de->start = cpu_to_le16(start); |
1011 | dotdot_de->starthi = cpu_to_le16(start >> 16); | 1011 | dotdot_de->starthi = cpu_to_le16(start >> 16); |
1012 | mark_buffer_dirty(dotdot_bh); | 1012 | mark_buffer_dirty_inode(dotdot_bh, old_inode); |
1013 | corrupt |= sync_dirty_buffer(dotdot_bh); | 1013 | corrupt |= sync_dirty_buffer(dotdot_bh); |
1014 | } | 1014 | } |
1015 | error_inode: | 1015 | error_inode: |