diff options
Diffstat (limited to 'fs/reiserfs/file.c')
-rw-r--r-- | fs/reiserfs/file.c | 64 |
1 files changed, 11 insertions, 53 deletions
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index b67ce9354048..373d862c3f87 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -74,7 +74,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) | |||
74 | igrab(inode); | 74 | igrab(inode); |
75 | reiserfs_warning(inode->i_sb, | 75 | reiserfs_warning(inode->i_sb, |
76 | "pinning inode %lu because the " | 76 | "pinning inode %lu because the " |
77 | "preallocation can't be freed"); | 77 | "preallocation can't be freed", |
78 | inode->i_ino); | ||
78 | goto out; | 79 | goto out; |
79 | } | 80 | } |
80 | } | 81 | } |
@@ -316,12 +317,11 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
316 | /* area filled with zeroes, to supply as list of zero blocknumbers | 317 | /* area filled with zeroes, to supply as list of zero blocknumbers |
317 | We allocate it outside of loop just in case loop would spin for | 318 | We allocate it outside of loop just in case loop would spin for |
318 | several iterations. */ | 319 | several iterations. */ |
319 | char *zeros = kmalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. | 320 | char *zeros = kzalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. |
320 | if (!zeros) { | 321 | if (!zeros) { |
321 | res = -ENOMEM; | 322 | res = -ENOMEM; |
322 | goto error_exit_free_blocks; | 323 | goto error_exit_free_blocks; |
323 | } | 324 | } |
324 | memset(zeros, 0, to_paste * UNFM_P_SIZE); | ||
325 | do { | 325 | do { |
326 | to_paste = | 326 | to_paste = |
327 | min_t(__u64, hole_size, | 327 | min_t(__u64, hole_size, |
@@ -406,6 +406,8 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
406 | we restart it. This will also free the path. */ | 406 | we restart it. This will also free the path. */ |
407 | if (journal_transaction_should_end | 407 | if (journal_transaction_should_end |
408 | (th, th->t_blocks_allocated)) { | 408 | (th, th->t_blocks_allocated)) { |
409 | inode->i_size = cpu_key_k_offset(&key) + | ||
410 | (to_paste << inode->i_blkbits); | ||
409 | res = | 411 | res = |
410 | restart_transaction(th, inode, | 412 | restart_transaction(th, inode, |
411 | &path); | 413 | &path); |
@@ -1044,6 +1046,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1044 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); | 1046 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); |
1045 | memset(kaddr, 0, from); | 1047 | memset(kaddr, 0, from); |
1046 | kunmap_atomic(kaddr, KM_USER0); | 1048 | kunmap_atomic(kaddr, KM_USER0); |
1049 | flush_dcache_page(prepared_pages[0]); | ||
1047 | } | 1050 | } |
1048 | if (to != PAGE_CACHE_SIZE) { /* Last page needs to be partially zeroed */ | 1051 | if (to != PAGE_CACHE_SIZE) { /* Last page needs to be partially zeroed */ |
1049 | char *kaddr = | 1052 | char *kaddr = |
@@ -1051,6 +1054,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1051 | KM_USER0); | 1054 | KM_USER0); |
1052 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); | 1055 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); |
1053 | kunmap_atomic(kaddr, KM_USER0); | 1056 | kunmap_atomic(kaddr, KM_USER0); |
1057 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1054 | } | 1058 | } |
1055 | 1059 | ||
1056 | /* Since all blocks are new - use already calculated value */ | 1060 | /* Since all blocks are new - use already calculated value */ |
@@ -1184,6 +1188,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1184 | memset(kaddr + block_start, 0, | 1188 | memset(kaddr + block_start, 0, |
1185 | from - block_start); | 1189 | from - block_start); |
1186 | kunmap_atomic(kaddr, KM_USER0); | 1190 | kunmap_atomic(kaddr, KM_USER0); |
1191 | flush_dcache_page(prepared_pages[0]); | ||
1187 | set_buffer_uptodate(bh); | 1192 | set_buffer_uptodate(bh); |
1188 | } | 1193 | } |
1189 | } | 1194 | } |
@@ -1221,6 +1226,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1221 | KM_USER0); | 1226 | KM_USER0); |
1222 | memset(kaddr + to, 0, block_end - to); | 1227 | memset(kaddr + to, 0, block_end - to); |
1223 | kunmap_atomic(kaddr, KM_USER0); | 1228 | kunmap_atomic(kaddr, KM_USER0); |
1229 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1224 | set_buffer_uptodate(bh); | 1230 | set_buffer_uptodate(bh); |
1225 | } | 1231 | } |
1226 | } | 1232 | } |
@@ -1306,56 +1312,8 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1306 | count = MAX_NON_LFS - (unsigned long)*ppos; | 1312 | count = MAX_NON_LFS - (unsigned long)*ppos; |
1307 | } | 1313 | } |
1308 | 1314 | ||
1309 | if (file->f_flags & O_DIRECT) { // Direct IO needs treatment | 1315 | if (file->f_flags & O_DIRECT) |
1310 | ssize_t result, after_file_end = 0; | 1316 | return do_sync_write(file, buf, count, ppos); |
1311 | if ((*ppos + count >= inode->i_size) | ||
1312 | || (file->f_flags & O_APPEND)) { | ||
1313 | /* If we are appending a file, we need to put this savelink in here. | ||
1314 | If we will crash while doing direct io, finish_unfinished will | ||
1315 | cut the garbage from the file end. */ | ||
1316 | reiserfs_write_lock(inode->i_sb); | ||
1317 | err = | ||
1318 | journal_begin(&th, inode->i_sb, | ||
1319 | JOURNAL_PER_BALANCE_CNT); | ||
1320 | if (err) { | ||
1321 | reiserfs_write_unlock(inode->i_sb); | ||
1322 | return err; | ||
1323 | } | ||
1324 | reiserfs_update_inode_transaction(inode); | ||
1325 | add_save_link(&th, inode, 1 /* Truncate */ ); | ||
1326 | after_file_end = 1; | ||
1327 | err = | ||
1328 | journal_end(&th, inode->i_sb, | ||
1329 | JOURNAL_PER_BALANCE_CNT); | ||
1330 | reiserfs_write_unlock(inode->i_sb); | ||
1331 | if (err) | ||
1332 | return err; | ||
1333 | } | ||
1334 | result = do_sync_write(file, buf, count, ppos); | ||
1335 | |||
1336 | if (after_file_end) { /* Now update i_size and remove the savelink */ | ||
1337 | struct reiserfs_transaction_handle th; | ||
1338 | reiserfs_write_lock(inode->i_sb); | ||
1339 | err = journal_begin(&th, inode->i_sb, 1); | ||
1340 | if (err) { | ||
1341 | reiserfs_write_unlock(inode->i_sb); | ||
1342 | return err; | ||
1343 | } | ||
1344 | reiserfs_update_inode_transaction(inode); | ||
1345 | mark_inode_dirty(inode); | ||
1346 | err = journal_end(&th, inode->i_sb, 1); | ||
1347 | if (err) { | ||
1348 | reiserfs_write_unlock(inode->i_sb); | ||
1349 | return err; | ||
1350 | } | ||
1351 | err = remove_save_link(inode, 1 /* truncate */ ); | ||
1352 | reiserfs_write_unlock(inode->i_sb); | ||
1353 | if (err) | ||
1354 | return err; | ||
1355 | } | ||
1356 | |||
1357 | return result; | ||
1358 | } | ||
1359 | 1317 | ||
1360 | if (unlikely((ssize_t) count < 0)) | 1318 | if (unlikely((ssize_t) count < 0)) |
1361 | return -EINVAL; | 1319 | return -EINVAL; |