diff options
Diffstat (limited to 'fs/reiserfs/inode.c')
-rw-r--r-- | fs/reiserfs/inode.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 5f82352b97e1..ffa34b861bdb 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -32,6 +32,7 @@ void reiserfs_delete_inode(struct inode *inode) | |||
32 | JOURNAL_PER_BALANCE_CNT * 2 + | 32 | JOURNAL_PER_BALANCE_CNT * 2 + |
33 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); | 33 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); |
34 | struct reiserfs_transaction_handle th; | 34 | struct reiserfs_transaction_handle th; |
35 | int err; | ||
35 | 36 | ||
36 | truncate_inode_pages(&inode->i_data, 0); | 37 | truncate_inode_pages(&inode->i_data, 0); |
37 | 38 | ||
@@ -39,32 +40,36 @@ void reiserfs_delete_inode(struct inode *inode) | |||
39 | 40 | ||
40 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ | 41 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ |
41 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ | 42 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ |
42 | down(&inode->i_sem); | 43 | mutex_lock(&inode->i_mutex); |
43 | 44 | ||
44 | reiserfs_delete_xattrs(inode); | 45 | reiserfs_delete_xattrs(inode); |
45 | 46 | ||
46 | if (journal_begin(&th, inode->i_sb, jbegin_count)) { | 47 | if (journal_begin(&th, inode->i_sb, jbegin_count)) { |
47 | up(&inode->i_sem); | 48 | mutex_unlock(&inode->i_mutex); |
48 | goto out; | 49 | goto out; |
49 | } | 50 | } |
50 | reiserfs_update_inode_transaction(inode); | 51 | reiserfs_update_inode_transaction(inode); |
51 | 52 | ||
52 | if (reiserfs_delete_object(&th, inode)) { | 53 | err = reiserfs_delete_object(&th, inode); |
53 | up(&inode->i_sem); | ||
54 | goto out; | ||
55 | } | ||
56 | 54 | ||
57 | /* Do quota update inside a transaction for journaled quotas. We must do that | 55 | /* Do quota update inside a transaction for journaled quotas. We must do that |
58 | * after delete_object so that quota updates go into the same transaction as | 56 | * after delete_object so that quota updates go into the same transaction as |
59 | * stat data deletion */ | 57 | * stat data deletion */ |
60 | DQUOT_FREE_INODE(inode); | 58 | if (!err) |
59 | DQUOT_FREE_INODE(inode); | ||
61 | 60 | ||
62 | if (journal_end(&th, inode->i_sb, jbegin_count)) { | 61 | if (journal_end(&th, inode->i_sb, jbegin_count)) { |
63 | up(&inode->i_sem); | 62 | mutex_unlock(&inode->i_mutex); |
64 | goto out; | 63 | goto out; |
65 | } | 64 | } |
66 | 65 | ||
67 | up(&inode->i_sem); | 66 | mutex_unlock(&inode->i_mutex); |
67 | |||
68 | /* check return value from reiserfs_delete_object after | ||
69 | * ending the transaction | ||
70 | */ | ||
71 | if (err) | ||
72 | goto out; | ||
68 | 73 | ||
69 | /* all items of file are deleted, so we can remove "save" link */ | 74 | /* all items of file are deleted, so we can remove "save" link */ |
70 | remove_save_link(inode, 0 /* not truncate */ ); /* we can't do anything | 75 | remove_save_link(inode, 0 /* not truncate */ ); /* we can't do anything |
@@ -546,7 +551,7 @@ static int convert_tail_for_hole(struct inode *inode, | |||
546 | 551 | ||
547 | /* we don't have to make sure the conversion did not happen while | 552 | /* we don't have to make sure the conversion did not happen while |
548 | ** we were locking the page because anyone that could convert | 553 | ** we were locking the page because anyone that could convert |
549 | ** must first take i_sem. | 554 | ** must first take i_mutex. |
550 | ** | 555 | ** |
551 | ** We must fix the tail page for writing because it might have buffers | 556 | ** We must fix the tail page for writing because it might have buffers |
552 | ** that are mapped, but have a block number of 0. This indicates tail | 557 | ** that are mapped, but have a block number of 0. This indicates tail |
@@ -581,7 +586,7 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th, | |||
581 | BUG_ON(!th->t_trans_id); | 586 | BUG_ON(!th->t_trans_id); |
582 | 587 | ||
583 | #ifdef REISERFS_PREALLOCATE | 588 | #ifdef REISERFS_PREALLOCATE |
584 | if (!(flags & GET_BLOCK_NO_ISEM)) { | 589 | if (!(flags & GET_BLOCK_NO_IMUX)) { |
585 | return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, | 590 | return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, |
586 | path, block); | 591 | path, block); |
587 | } | 592 | } |
@@ -2099,6 +2104,7 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) | |||
2099 | struct page *page = NULL; | 2104 | struct page *page = NULL; |
2100 | int error; | 2105 | int error; |
2101 | struct buffer_head *bh = NULL; | 2106 | struct buffer_head *bh = NULL; |
2107 | int err2; | ||
2102 | 2108 | ||
2103 | reiserfs_write_lock(p_s_inode->i_sb); | 2109 | reiserfs_write_lock(p_s_inode->i_sb); |
2104 | 2110 | ||
@@ -2136,14 +2142,18 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) | |||
2136 | transaction of truncating gets committed - on reboot the file | 2142 | transaction of truncating gets committed - on reboot the file |
2137 | either appears truncated properly or not truncated at all */ | 2143 | either appears truncated properly or not truncated at all */ |
2138 | add_save_link(&th, p_s_inode, 1); | 2144 | add_save_link(&th, p_s_inode, 1); |
2139 | error = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps); | 2145 | err2 = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps); |
2140 | if (error) | ||
2141 | goto out; | ||
2142 | error = | 2146 | error = |
2143 | journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1); | 2147 | journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1); |
2144 | if (error) | 2148 | if (error) |
2145 | goto out; | 2149 | goto out; |
2146 | 2150 | ||
2151 | /* check reiserfs_do_truncate after ending the transaction */ | ||
2152 | if (err2) { | ||
2153 | error = err2; | ||
2154 | goto out; | ||
2155 | } | ||
2156 | |||
2147 | if (update_timestamps) { | 2157 | if (update_timestamps) { |
2148 | error = remove_save_link(p_s_inode, 1 /* truncate */ ); | 2158 | error = remove_save_link(p_s_inode, 1 /* truncate */ ); |
2149 | if (error) | 2159 | if (error) |
@@ -2194,7 +2204,7 @@ static int map_block_for_writepage(struct inode *inode, | |||
2194 | INITIALIZE_PATH(path); | 2204 | INITIALIZE_PATH(path); |
2195 | int pos_in_item; | 2205 | int pos_in_item; |
2196 | int jbegin_count = JOURNAL_PER_BALANCE_CNT; | 2206 | int jbegin_count = JOURNAL_PER_BALANCE_CNT; |
2197 | loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1; | 2207 | loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1; |
2198 | int retval; | 2208 | int retval; |
2199 | int use_get_block = 0; | 2209 | int use_get_block = 0; |
2200 | int bytes_copied = 0; | 2210 | int bytes_copied = 0; |
@@ -2308,7 +2318,7 @@ static int map_block_for_writepage(struct inode *inode, | |||
2308 | /* this is where we fill in holes in the file. */ | 2318 | /* this is where we fill in holes in the file. */ |
2309 | if (use_get_block) { | 2319 | if (use_get_block) { |
2310 | retval = reiserfs_get_block(inode, block, bh_result, | 2320 | retval = reiserfs_get_block(inode, block, bh_result, |
2311 | GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM | 2321 | GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX |
2312 | | GET_BLOCK_NO_DANGLE); | 2322 | | GET_BLOCK_NO_DANGLE); |
2313 | if (!retval) { | 2323 | if (!retval) { |
2314 | if (!buffer_mapped(bh_result) | 2324 | if (!buffer_mapped(bh_result) |