diff options
Diffstat (limited to 'fs/reiserfs/file.c')
-rw-r--r-- | fs/reiserfs/file.c | 65 |
1 files changed, 11 insertions, 54 deletions
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index ac14318c81ba..99b6f329ba23 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -317,12 +317,11 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
317 | /* area filled with zeroes, to supply as list of zero blocknumbers | 317 | /* area filled with zeroes, to supply as list of zero blocknumbers |
318 | 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 |
319 | several iterations. */ | 319 | several iterations. */ |
320 | 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. |
321 | if (!zeros) { | 321 | if (!zeros) { |
322 | res = -ENOMEM; | 322 | res = -ENOMEM; |
323 | goto error_exit_free_blocks; | 323 | goto error_exit_free_blocks; |
324 | } | 324 | } |
325 | memset(zeros, 0, to_paste * UNFM_P_SIZE); | ||
326 | do { | 325 | do { |
327 | to_paste = | 326 | to_paste = |
328 | min_t(__u64, hole_size, | 327 | min_t(__u64, hole_size, |
@@ -407,6 +406,8 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
407 | we restart it. This will also free the path. */ | 406 | we restart it. This will also free the path. */ |
408 | if (journal_transaction_should_end | 407 | if (journal_transaction_should_end |
409 | (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); | ||
410 | res = | 411 | res = |
411 | restart_transaction(th, inode, | 412 | restart_transaction(th, inode, |
412 | &path); | 413 | &path); |
@@ -1045,6 +1046,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1045 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); | 1046 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); |
1046 | memset(kaddr, 0, from); | 1047 | memset(kaddr, 0, from); |
1047 | kunmap_atomic(kaddr, KM_USER0); | 1048 | kunmap_atomic(kaddr, KM_USER0); |
1049 | flush_dcache_page(prepared_pages[0]); | ||
1048 | } | 1050 | } |
1049 | 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 */ |
1050 | char *kaddr = | 1052 | char *kaddr = |
@@ -1052,6 +1054,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1052 | KM_USER0); | 1054 | KM_USER0); |
1053 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); | 1055 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); |
1054 | kunmap_atomic(kaddr, KM_USER0); | 1056 | kunmap_atomic(kaddr, KM_USER0); |
1057 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1055 | } | 1058 | } |
1056 | 1059 | ||
1057 | /* Since all blocks are new - use already calculated value */ | 1060 | /* Since all blocks are new - use already calculated value */ |
@@ -1185,6 +1188,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1185 | memset(kaddr + block_start, 0, | 1188 | memset(kaddr + block_start, 0, |
1186 | from - block_start); | 1189 | from - block_start); |
1187 | kunmap_atomic(kaddr, KM_USER0); | 1190 | kunmap_atomic(kaddr, KM_USER0); |
1191 | flush_dcache_page(prepared_pages[0]); | ||
1188 | set_buffer_uptodate(bh); | 1192 | set_buffer_uptodate(bh); |
1189 | } | 1193 | } |
1190 | } | 1194 | } |
@@ -1222,6 +1226,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1222 | KM_USER0); | 1226 | KM_USER0); |
1223 | memset(kaddr + to, 0, block_end - to); | 1227 | memset(kaddr + to, 0, block_end - to); |
1224 | kunmap_atomic(kaddr, KM_USER0); | 1228 | kunmap_atomic(kaddr, KM_USER0); |
1229 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1225 | set_buffer_uptodate(bh); | 1230 | set_buffer_uptodate(bh); |
1226 | } | 1231 | } |
1227 | } | 1232 | } |
@@ -1283,7 +1288,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1283 | loff_t pos; // Current position in the file. | 1288 | loff_t pos; // Current position in the file. |
1284 | ssize_t res; // return value of various functions that we call. | 1289 | ssize_t res; // return value of various functions that we call. |
1285 | int err = 0; | 1290 | int err = 0; |
1286 | struct inode *inode = file->f_dentry->d_inode; // Inode of the file that we are writing to. | 1291 | struct inode *inode = file->f_path.dentry->d_inode; // Inode of the file that we are writing to. |
1287 | /* To simplify coding at this time, we store | 1292 | /* To simplify coding at this time, we store |
1288 | locked pages in array for now */ | 1293 | locked pages in array for now */ |
1289 | struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME]; | 1294 | struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME]; |
@@ -1307,56 +1312,8 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1307 | count = MAX_NON_LFS - (unsigned long)*ppos; | 1312 | count = MAX_NON_LFS - (unsigned long)*ppos; |
1308 | } | 1313 | } |
1309 | 1314 | ||
1310 | if (file->f_flags & O_DIRECT) { // Direct IO needs treatment | 1315 | if (file->f_flags & O_DIRECT) |
1311 | ssize_t result, after_file_end = 0; | 1316 | return do_sync_write(file, buf, count, ppos); |
1312 | if ((*ppos + count >= inode->i_size) | ||
1313 | || (file->f_flags & O_APPEND)) { | ||
1314 | /* If we are appending a file, we need to put this savelink in here. | ||
1315 | If we will crash while doing direct io, finish_unfinished will | ||
1316 | cut the garbage from the file end. */ | ||
1317 | reiserfs_write_lock(inode->i_sb); | ||
1318 | err = | ||
1319 | journal_begin(&th, inode->i_sb, | ||
1320 | JOURNAL_PER_BALANCE_CNT); | ||
1321 | if (err) { | ||
1322 | reiserfs_write_unlock(inode->i_sb); | ||
1323 | return err; | ||
1324 | } | ||
1325 | reiserfs_update_inode_transaction(inode); | ||
1326 | add_save_link(&th, inode, 1 /* Truncate */ ); | ||
1327 | after_file_end = 1; | ||
1328 | err = | ||
1329 | journal_end(&th, inode->i_sb, | ||
1330 | JOURNAL_PER_BALANCE_CNT); | ||
1331 | reiserfs_write_unlock(inode->i_sb); | ||
1332 | if (err) | ||
1333 | return err; | ||
1334 | } | ||
1335 | result = do_sync_write(file, buf, count, ppos); | ||
1336 | |||
1337 | if (after_file_end) { /* Now update i_size and remove the savelink */ | ||
1338 | struct reiserfs_transaction_handle th; | ||
1339 | reiserfs_write_lock(inode->i_sb); | ||
1340 | err = journal_begin(&th, inode->i_sb, 1); | ||
1341 | if (err) { | ||
1342 | reiserfs_write_unlock(inode->i_sb); | ||
1343 | return err; | ||
1344 | } | ||
1345 | reiserfs_update_inode_transaction(inode); | ||
1346 | mark_inode_dirty(inode); | ||
1347 | err = journal_end(&th, inode->i_sb, 1); | ||
1348 | if (err) { | ||
1349 | reiserfs_write_unlock(inode->i_sb); | ||
1350 | return err; | ||
1351 | } | ||
1352 | err = remove_save_link(inode, 1 /* truncate */ ); | ||
1353 | reiserfs_write_unlock(inode->i_sb); | ||
1354 | if (err) | ||
1355 | return err; | ||
1356 | } | ||
1357 | |||
1358 | return result; | ||
1359 | } | ||
1360 | 1317 | ||
1361 | if (unlikely((ssize_t) count < 0)) | 1318 | if (unlikely((ssize_t) count < 0)) |
1362 | return -EINVAL; | 1319 | return -EINVAL; |
@@ -1378,7 +1335,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1378 | if (count == 0) | 1335 | if (count == 0) |
1379 | goto out; | 1336 | goto out; |
1380 | 1337 | ||
1381 | res = remove_suid(file->f_dentry); | 1338 | res = remove_suid(file->f_path.dentry); |
1382 | if (res) | 1339 | if (res) |
1383 | goto out; | 1340 | goto out; |
1384 | 1341 | ||