summaryrefslogtreecommitdiffstats
path: root/fs/fat
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/file.c50
-rw-r--r--fs/fat/misc.c14
2 files changed, 25 insertions, 39 deletions
diff --git a/fs/fat/file.c b/fs/fat/file.c
index e99c5a73b39e..88aa1ae13f9f 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -210,10 +210,30 @@ static int fat_free(struct inode *inode, int skip)
if (MSDOS_I(inode)->i_start == 0)
return 0;
- /*
- * Write a new EOF, and get the remaining cluster chain for freeing.
- */
+ fat_cache_inval_inode(inode);
+
wait = IS_DIRSYNC(inode);
+ i_start = free_start = MSDOS_I(inode)->i_start;
+ i_logstart = MSDOS_I(inode)->i_logstart;
+
+ /* First, we write the new file size. */
+ if (!skip) {
+ MSDOS_I(inode)->i_start = 0;
+ MSDOS_I(inode)->i_logstart = 0;
+ }
+ MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
+ if (wait) {
+ err = fat_sync_inode(inode);
+ if (err) {
+ MSDOS_I(inode)->i_start = i_start;
+ MSDOS_I(inode)->i_logstart = i_logstart;
+ return err;
+ }
+ } else
+ mark_inode_dirty(inode);
+
+ /* Write a new EOF, and get the remaining cluster chain for freeing. */
if (skip) {
struct fat_entry fatent;
int ret, fclus, dclus;
@@ -244,35 +264,11 @@ static int fat_free(struct inode *inode, int skip)
return ret;
free_start = ret;
- i_start = i_logstart = 0;
- fat_cache_inval_inode(inode);
- } else {
- fat_cache_inval_inode(inode);
-
- i_start = free_start = MSDOS_I(inode)->i_start;
- i_logstart = MSDOS_I(inode)->i_logstart;
- MSDOS_I(inode)->i_start = 0;
- MSDOS_I(inode)->i_logstart = 0;
}
- MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
- if (wait) {
- err = fat_sync_inode(inode);
- if (err)
- goto error;
- } else
- mark_inode_dirty(inode);
inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9);
/* Freeing the remained cluster chain */
return fat_free_clusters(inode, free_start);
-
-error:
- if (i_start) {
- MSDOS_I(inode)->i_start = i_start;
- MSDOS_I(inode)->i_logstart = i_logstart;
- }
- return err;
}
void fat_truncate(struct inode *inode)
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 32fb0a3f1da4..944652e9dde1 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -196,19 +196,9 @@ EXPORT_SYMBOL_GPL(fat_date_unix2dos);
int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
{
- int i, e, err = 0;
+ int i, err = 0;
- for (i = 0; i < nr_bhs; i++) {
- lock_buffer(bhs[i]);
- if (test_clear_buffer_dirty(bhs[i])) {
- get_bh(bhs[i]);
- bhs[i]->b_end_io = end_buffer_write_sync;
- e = submit_bh(WRITE, bhs[i]);
- if (!err && e)
- err = e;
- } else
- unlock_buffer(bhs[i]);
- }
+ ll_rw_block(SWRITE, nr_bhs, bhs);
for (i = 0; i < nr_bhs; i++) {
wait_on_buffer(bhs[i]);
if (buffer_eopnotsupp(bhs[i])) {