diff options
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 67fd0b025858..b754b7721f51 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1413,10 +1413,22 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1413 | frame->at = entries; | 1413 | frame->at = entries; |
1414 | frame->bh = bh; | 1414 | frame->bh = bh; |
1415 | bh = bh2; | 1415 | bh = bh2; |
1416 | |||
1417 | ext4_handle_dirty_metadata(handle, dir, frame->bh); | ||
1418 | ext4_handle_dirty_metadata(handle, dir, bh); | ||
1419 | |||
1416 | de = do_split(handle,dir, &bh, frame, &hinfo, &retval); | 1420 | de = do_split(handle,dir, &bh, frame, &hinfo, &retval); |
1417 | dx_release (frames); | 1421 | if (!de) { |
1418 | if (!(de)) | 1422 | /* |
1423 | * Even if the block split failed, we have to properly write | ||
1424 | * out all the changes we did so far. Otherwise we can end up | ||
1425 | * with corrupted filesystem. | ||
1426 | */ | ||
1427 | ext4_mark_inode_dirty(handle, dir); | ||
1428 | dx_release(frames); | ||
1419 | return retval; | 1429 | return retval; |
1430 | } | ||
1431 | dx_release(frames); | ||
1420 | 1432 | ||
1421 | retval = add_dirent_to_buf(handle, dentry, inode, de, bh); | 1433 | retval = add_dirent_to_buf(handle, dentry, inode, de, bh); |
1422 | brelse(bh); | 1434 | brelse(bh); |
@@ -2240,6 +2252,7 @@ static int ext4_symlink(struct inode *dir, | |||
2240 | handle_t *handle; | 2252 | handle_t *handle; |
2241 | struct inode *inode; | 2253 | struct inode *inode; |
2242 | int l, err, retries = 0; | 2254 | int l, err, retries = 0; |
2255 | int credits; | ||
2243 | 2256 | ||
2244 | l = strlen(symname)+1; | 2257 | l = strlen(symname)+1; |
2245 | if (l > dir->i_sb->s_blocksize) | 2258 | if (l > dir->i_sb->s_blocksize) |
@@ -2247,10 +2260,26 @@ static int ext4_symlink(struct inode *dir, | |||
2247 | 2260 | ||
2248 | dquot_initialize(dir); | 2261 | dquot_initialize(dir); |
2249 | 2262 | ||
2263 | if (l > EXT4_N_BLOCKS * 4) { | ||
2264 | /* | ||
2265 | * For non-fast symlinks, we just allocate inode and put it on | ||
2266 | * orphan list in the first transaction => we need bitmap, | ||
2267 | * group descriptor, sb, inode block, quota blocks. | ||
2268 | */ | ||
2269 | credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); | ||
2270 | } else { | ||
2271 | /* | ||
2272 | * Fast symlink. We have to add entry to directory | ||
2273 | * (EXT4_DATA_TRANS_BLOCKS + EXT4_INDEX_EXTRA_TRANS_BLOCKS), | ||
2274 | * allocate new inode (bitmap, group descriptor, inode block, | ||
2275 | * quota blocks, sb is already counted in previous macros). | ||
2276 | */ | ||
2277 | credits = EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + | ||
2278 | EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 + | ||
2279 | EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); | ||
2280 | } | ||
2250 | retry: | 2281 | retry: |
2251 | handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + | 2282 | handle = ext4_journal_start(dir, credits); |
2252 | EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 + | ||
2253 | EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); | ||
2254 | if (IS_ERR(handle)) | 2283 | if (IS_ERR(handle)) |
2255 | return PTR_ERR(handle); | 2284 | return PTR_ERR(handle); |
2256 | 2285 | ||
@@ -2263,21 +2292,44 @@ retry: | |||
2263 | if (IS_ERR(inode)) | 2292 | if (IS_ERR(inode)) |
2264 | goto out_stop; | 2293 | goto out_stop; |
2265 | 2294 | ||
2266 | if (l > sizeof(EXT4_I(inode)->i_data)) { | 2295 | if (l > EXT4_N_BLOCKS * 4) { |
2267 | inode->i_op = &ext4_symlink_inode_operations; | 2296 | inode->i_op = &ext4_symlink_inode_operations; |
2268 | ext4_set_aops(inode); | 2297 | ext4_set_aops(inode); |
2269 | /* | 2298 | /* |
2270 | * page_symlink() calls into ext4_prepare/commit_write. | 2299 | * We cannot call page_symlink() with transaction started |
2271 | * We have a transaction open. All is sweetness. It also sets | 2300 | * because it calls into ext4_write_begin() which can wait |
2272 | * i_size in generic_commit_write(). | 2301 | * for transaction commit if we are running out of space |
2302 | * and thus we deadlock. So we have to stop transaction now | ||
2303 | * and restart it when symlink contents is written. | ||
2304 | * | ||
2305 | * To keep fs consistent in case of crash, we have to put inode | ||
2306 | * to orphan list in the mean time. | ||
2273 | */ | 2307 | */ |
2308 | drop_nlink(inode); | ||
2309 | err = ext4_orphan_add(handle, inode); | ||
2310 | ext4_journal_stop(handle); | ||
2311 | if (err) | ||
2312 | goto err_drop_inode; | ||
2274 | err = __page_symlink(inode, symname, l, 1); | 2313 | err = __page_symlink(inode, symname, l, 1); |
2314 | if (err) | ||
2315 | goto err_drop_inode; | ||
2316 | /* | ||
2317 | * Now inode is being linked into dir (EXT4_DATA_TRANS_BLOCKS | ||
2318 | * + EXT4_INDEX_EXTRA_TRANS_BLOCKS), inode is also modified | ||
2319 | */ | ||
2320 | handle = ext4_journal_start(dir, | ||
2321 | EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + | ||
2322 | EXT4_INDEX_EXTRA_TRANS_BLOCKS + 1); | ||
2323 | if (IS_ERR(handle)) { | ||
2324 | err = PTR_ERR(handle); | ||
2325 | goto err_drop_inode; | ||
2326 | } | ||
2327 | inc_nlink(inode); | ||
2328 | err = ext4_orphan_del(handle, inode); | ||
2275 | if (err) { | 2329 | if (err) { |
2330 | ext4_journal_stop(handle); | ||
2276 | clear_nlink(inode); | 2331 | clear_nlink(inode); |
2277 | unlock_new_inode(inode); | 2332 | goto err_drop_inode; |
2278 | ext4_mark_inode_dirty(handle, inode); | ||
2279 | iput(inode); | ||
2280 | goto out_stop; | ||
2281 | } | 2333 | } |
2282 | } else { | 2334 | } else { |
2283 | /* clear the extent format for fast symlink */ | 2335 | /* clear the extent format for fast symlink */ |
@@ -2293,6 +2345,10 @@ out_stop: | |||
2293 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) | 2345 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) |
2294 | goto retry; | 2346 | goto retry; |
2295 | return err; | 2347 | return err; |
2348 | err_drop_inode: | ||
2349 | unlock_new_inode(inode); | ||
2350 | iput(inode); | ||
2351 | return err; | ||
2296 | } | 2352 | } |
2297 | 2353 | ||
2298 | static int ext4_link(struct dentry *old_dentry, | 2354 | static int ext4_link(struct dentry *old_dentry, |