aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-08-05 11:18:09 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:06 -0400
commit00e4e6b33a0f78aab4b788d6d31c884fd8bf88da (patch)
tree726c1b05385f15566aa5c14ff694870f6eb6def2 /fs/btrfs/inode.c
parent7d2b4daa67379960477568abda62b8ba9ee3a8aa (diff)
Get rid of BTRFS_I(inode)->index and use local vars instead
rename and link don't always have a lock on the source inode, and our use of a per-inode index variable was racy. This changes things to store the index in a local variable instead. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 99121a55ffbe..4d8ffc01931e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2153,7 +2153,8 @@ out:
2153 return ret; 2153 return ret;
2154} 2154}
2155 2155
2156static int btrfs_set_inode_index(struct inode *dir, struct inode *inode) 2156static int btrfs_set_inode_index(struct inode *dir, struct inode *inode,
2157 u64 *index)
2157{ 2158{
2158 int ret = 0; 2159 int ret = 0;
2159 2160
@@ -2163,7 +2164,7 @@ static int btrfs_set_inode_index(struct inode *dir, struct inode *inode)
2163 return ret; 2164 return ret;
2164 } 2165 }
2165 2166
2166 BTRFS_I(inode)->index = BTRFS_I(dir)->index_cnt; 2167 *index = BTRFS_I(dir)->index_cnt;
2167 BTRFS_I(dir)->index_cnt++; 2168 BTRFS_I(dir)->index_cnt++;
2168 2169
2169 return ret; 2170 return ret;
@@ -2176,7 +2177,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
2176 u64 ref_objectid, 2177 u64 ref_objectid,
2177 u64 objectid, 2178 u64 objectid,
2178 struct btrfs_block_group_cache *group, 2179 struct btrfs_block_group_cache *group,
2179 int mode) 2180 int mode, u64 *index)
2180{ 2181{
2181 struct inode *inode; 2182 struct inode *inode;
2182 struct btrfs_inode_item *inode_item; 2183 struct btrfs_inode_item *inode_item;
@@ -2198,11 +2199,9 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
2198 return ERR_PTR(-ENOMEM); 2199 return ERR_PTR(-ENOMEM);
2199 2200
2200 if (dir) { 2201 if (dir) {
2201 ret = btrfs_set_inode_index(dir, inode); 2202 ret = btrfs_set_inode_index(dir, inode, index);
2202 if (ret) 2203 if (ret)
2203 return ERR_PTR(ret); 2204 return ERR_PTR(ret);
2204 } else {
2205 BTRFS_I(inode)->index = 0;
2206 } 2205 }
2207 /* 2206 /*
2208 * index_cnt is ignored for everything but a dir, 2207 * index_cnt is ignored for everything but a dir,
@@ -2268,7 +2267,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
2268 ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1, 2267 ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1,
2269 struct btrfs_inode_ref); 2268 struct btrfs_inode_ref);
2270 btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); 2269 btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
2271 btrfs_set_inode_ref_index(path->nodes[0], ref, BTRFS_I(inode)->index); 2270 btrfs_set_inode_ref_index(path->nodes[0], ref, *index);
2272 ptr = (unsigned long)(ref + 1); 2271 ptr = (unsigned long)(ref + 1);
2273 write_extent_buffer(path->nodes[0], name, ptr, name_len); 2272 write_extent_buffer(path->nodes[0], name, ptr, name_len);
2274 2273
@@ -2296,7 +2295,7 @@ static inline u8 btrfs_inode_type(struct inode *inode)
2296 2295
2297static int btrfs_add_link(struct btrfs_trans_handle *trans, 2296static int btrfs_add_link(struct btrfs_trans_handle *trans,
2298 struct dentry *dentry, struct inode *inode, 2297 struct dentry *dentry, struct inode *inode,
2299 int add_backref) 2298 int add_backref, u64 index)
2300{ 2299{
2301 int ret; 2300 int ret;
2302 struct btrfs_key key; 2301 struct btrfs_key key;
@@ -2311,7 +2310,7 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
2311 dentry->d_name.name, dentry->d_name.len, 2310 dentry->d_name.name, dentry->d_name.len,
2312 dentry->d_parent->d_inode->i_ino, 2311 dentry->d_parent->d_inode->i_ino,
2313 &key, btrfs_inode_type(inode), 2312 &key, btrfs_inode_type(inode),
2314 BTRFS_I(inode)->index); 2313 index);
2315 if (ret == 0) { 2314 if (ret == 0) {
2316 if (add_backref) { 2315 if (add_backref) {
2317 ret = btrfs_insert_inode_ref(trans, root, 2316 ret = btrfs_insert_inode_ref(trans, root,
@@ -2319,7 +2318,7 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
2319 dentry->d_name.len, 2318 dentry->d_name.len,
2320 inode->i_ino, 2319 inode->i_ino,
2321 parent_inode->i_ino, 2320 parent_inode->i_ino,
2322 BTRFS_I(inode)->index); 2321 index);
2323 } 2322 }
2324 btrfs_i_size_write(parent_inode, parent_inode->i_size + 2323 btrfs_i_size_write(parent_inode, parent_inode->i_size +
2325 dentry->d_name.len * 2); 2324 dentry->d_name.len * 2);
@@ -2332,9 +2331,9 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
2332 2331
2333static int btrfs_add_nondir(struct btrfs_trans_handle *trans, 2332static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
2334 struct dentry *dentry, struct inode *inode, 2333 struct dentry *dentry, struct inode *inode,
2335 int backref) 2334 int backref, u64 index)
2336{ 2335{
2337 int err = btrfs_add_link(trans, dentry, inode, backref); 2336 int err = btrfs_add_link(trans, dentry, inode, backref, index);
2338 if (!err) { 2337 if (!err) {
2339 d_instantiate(dentry, inode); 2338 d_instantiate(dentry, inode);
2340 return 0; 2339 return 0;
@@ -2354,6 +2353,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
2354 int drop_inode = 0; 2353 int drop_inode = 0;
2355 u64 objectid; 2354 u64 objectid;
2356 unsigned long nr = 0; 2355 unsigned long nr = 0;
2356 u64 index = 0;
2357 2357
2358 if (!new_valid_dev(rdev)) 2358 if (!new_valid_dev(rdev))
2359 return -EINVAL; 2359 return -EINVAL;
@@ -2374,7 +2374,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
2374 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, 2374 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
2375 dentry->d_name.len, 2375 dentry->d_name.len,
2376 dentry->d_parent->d_inode->i_ino, objectid, 2376 dentry->d_parent->d_inode->i_ino, objectid,
2377 BTRFS_I(dir)->block_group, mode); 2377 BTRFS_I(dir)->block_group, mode, &index);
2378 err = PTR_ERR(inode); 2378 err = PTR_ERR(inode);
2379 if (IS_ERR(inode)) 2379 if (IS_ERR(inode))
2380 goto out_unlock; 2380 goto out_unlock;
@@ -2386,7 +2386,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
2386 } 2386 }
2387 2387
2388 btrfs_set_trans_block_group(trans, inode); 2388 btrfs_set_trans_block_group(trans, inode);
2389 err = btrfs_add_nondir(trans, dentry, inode, 0); 2389 err = btrfs_add_nondir(trans, dentry, inode, 0, index);
2390 if (err) 2390 if (err)
2391 drop_inode = 1; 2391 drop_inode = 1;
2392 else { 2392 else {
@@ -2419,6 +2419,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
2419 int drop_inode = 0; 2419 int drop_inode = 0;
2420 unsigned long nr = 0; 2420 unsigned long nr = 0;
2421 u64 objectid; 2421 u64 objectid;
2422 u64 index = 0;
2422 2423
2423 err = btrfs_check_free_space(root, 1, 0); 2424 err = btrfs_check_free_space(root, 1, 0);
2424 if (err) 2425 if (err)
@@ -2435,7 +2436,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
2435 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, 2436 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
2436 dentry->d_name.len, 2437 dentry->d_name.len,
2437 dentry->d_parent->d_inode->i_ino, 2438 dentry->d_parent->d_inode->i_ino,
2438 objectid, BTRFS_I(dir)->block_group, mode); 2439 objectid, BTRFS_I(dir)->block_group, mode,
2440 &index);
2439 err = PTR_ERR(inode); 2441 err = PTR_ERR(inode);
2440 if (IS_ERR(inode)) 2442 if (IS_ERR(inode))
2441 goto out_unlock; 2443 goto out_unlock;
@@ -2447,7 +2449,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
2447 } 2449 }
2448 2450
2449 btrfs_set_trans_block_group(trans, inode); 2451 btrfs_set_trans_block_group(trans, inode);
2450 err = btrfs_add_nondir(trans, dentry, inode, 0); 2452 err = btrfs_add_nondir(trans, dentry, inode, 0, index);
2451 if (err) 2453 if (err)
2452 drop_inode = 1; 2454 drop_inode = 1;
2453 else { 2455 else {
@@ -2489,6 +2491,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
2489 struct btrfs_trans_handle *trans; 2491 struct btrfs_trans_handle *trans;
2490 struct btrfs_root *root = BTRFS_I(dir)->root; 2492 struct btrfs_root *root = BTRFS_I(dir)->root;
2491 struct inode *inode = old_dentry->d_inode; 2493 struct inode *inode = old_dentry->d_inode;
2494 u64 index;
2492 unsigned long nr = 0; 2495 unsigned long nr = 0;
2493 int err; 2496 int err;
2494 int drop_inode = 0; 2497 int drop_inode = 0;
@@ -2504,7 +2507,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
2504 err = btrfs_check_free_space(root, 1, 0); 2507 err = btrfs_check_free_space(root, 1, 0);
2505 if (err) 2508 if (err)
2506 goto fail; 2509 goto fail;
2507 err = btrfs_set_inode_index(dir, inode); 2510 err = btrfs_set_inode_index(dir, inode, &index);
2508 if (err) 2511 if (err)
2509 goto fail; 2512 goto fail;
2510 2513
@@ -2513,7 +2516,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
2513 btrfs_set_trans_block_group(trans, dir); 2516 btrfs_set_trans_block_group(trans, dir);
2514 atomic_inc(&inode->i_count); 2517 atomic_inc(&inode->i_count);
2515 2518
2516 err = btrfs_add_nondir(trans, dentry, inode, 1); 2519 err = btrfs_add_nondir(trans, dentry, inode, 1, index);
2517 2520
2518 if (err) 2521 if (err)
2519 drop_inode = 1; 2522 drop_inode = 1;
@@ -2544,6 +2547,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2544 int err = 0; 2547 int err = 0;
2545 int drop_on_err = 0; 2548 int drop_on_err = 0;
2546 u64 objectid = 0; 2549 u64 objectid = 0;
2550 u64 index = 0;
2547 unsigned long nr = 1; 2551 unsigned long nr = 1;
2548 2552
2549 err = btrfs_check_free_space(root, 1, 0); 2553 err = btrfs_check_free_space(root, 1, 0);
@@ -2567,7 +2571,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2567 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, 2571 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
2568 dentry->d_name.len, 2572 dentry->d_name.len,
2569 dentry->d_parent->d_inode->i_ino, objectid, 2573 dentry->d_parent->d_inode->i_ino, objectid,
2570 BTRFS_I(dir)->block_group, S_IFDIR | mode); 2574 BTRFS_I(dir)->block_group, S_IFDIR | mode,
2575 &index);
2571 if (IS_ERR(inode)) { 2576 if (IS_ERR(inode)) {
2572 err = PTR_ERR(inode); 2577 err = PTR_ERR(inode);
2573 goto out_fail; 2578 goto out_fail;
@@ -2588,7 +2593,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2588 if (err) 2593 if (err)
2589 goto out_fail; 2594 goto out_fail;
2590 2595
2591 err = btrfs_add_link(trans, dentry, inode, 0); 2596 err = btrfs_add_link(trans, dentry, inode, 0, index);
2592 if (err) 2597 if (err)
2593 goto out_fail; 2598 goto out_fail;
2594 2599
@@ -3203,9 +3208,10 @@ int btrfs_create_subvol_root(struct btrfs_root *new_root,
3203 struct btrfs_block_group_cache *block_group) 3208 struct btrfs_block_group_cache *block_group)
3204{ 3209{
3205 struct inode *inode; 3210 struct inode *inode;
3211 u64 index = 0;
3206 3212
3207 inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, 3213 inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
3208 new_dirid, block_group, S_IFDIR | 0700); 3214 new_dirid, block_group, S_IFDIR | 0700, &index);
3209 if (IS_ERR(inode)) 3215 if (IS_ERR(inode))
3210 return PTR_ERR(inode); 3216 return PTR_ERR(inode);
3211 inode->i_op = &btrfs_dir_inode_operations; 3217 inode->i_op = &btrfs_dir_inode_operations;
@@ -3384,6 +3390,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
3384 struct inode *new_inode = new_dentry->d_inode; 3390 struct inode *new_inode = new_dentry->d_inode;
3385 struct inode *old_inode = old_dentry->d_inode; 3391 struct inode *old_inode = old_dentry->d_inode;
3386 struct timespec ctime = CURRENT_TIME; 3392 struct timespec ctime = CURRENT_TIME;
3393 u64 index = 0;
3387 int ret; 3394 int ret;
3388 3395
3389 if (S_ISDIR(old_inode->i_mode) && new_inode && 3396 if (S_ISDIR(old_inode->i_mode) && new_inode &&
@@ -3419,11 +3426,11 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
3419 goto out_fail; 3426 goto out_fail;
3420 } 3427 }
3421 } 3428 }
3422 ret = btrfs_set_inode_index(new_dir, old_inode); 3429 ret = btrfs_set_inode_index(new_dir, old_inode, &index);
3423 if (ret) 3430 if (ret)
3424 goto out_fail; 3431 goto out_fail;
3425 3432
3426 ret = btrfs_add_link(trans, new_dentry, old_inode, 1); 3433 ret = btrfs_add_link(trans, new_dentry, old_inode, 1, index);
3427 if (ret) 3434 if (ret)
3428 goto out_fail; 3435 goto out_fail;
3429 3436
@@ -3464,6 +3471,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
3464 int err; 3471 int err;
3465 int drop_inode = 0; 3472 int drop_inode = 0;
3466 u64 objectid; 3473 u64 objectid;
3474 u64 index = 0 ;
3467 int name_len; 3475 int name_len;
3468 int datasize; 3476 int datasize;
3469 unsigned long ptr; 3477 unsigned long ptr;
@@ -3491,7 +3499,8 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
3491 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, 3499 inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
3492 dentry->d_name.len, 3500 dentry->d_name.len,
3493 dentry->d_parent->d_inode->i_ino, objectid, 3501 dentry->d_parent->d_inode->i_ino, objectid,
3494 BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO); 3502 BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO,
3503 &index);
3495 err = PTR_ERR(inode); 3504 err = PTR_ERR(inode);
3496 if (IS_ERR(inode)) 3505 if (IS_ERR(inode))
3497 goto out_unlock; 3506 goto out_unlock;
@@ -3503,7 +3512,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
3503 } 3512 }
3504 3513
3505 btrfs_set_trans_block_group(trans, inode); 3514 btrfs_set_trans_block_group(trans, inode);
3506 err = btrfs_add_nondir(trans, dentry, inode, 0); 3515 err = btrfs_add_nondir(trans, dentry, inode, 0, index);
3507 if (err) 3516 if (err)
3508 drop_inode = 1; 3517 drop_inode = 1;
3509 else { 3518 else {