diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 820d21ee4afd..905b093a85fe 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -242,6 +242,7 @@ static void reada_leaves(struct btrfs_root *root, struct btrfs_path *path) | |||
242 | } | 242 | } |
243 | 243 | ||
244 | } | 244 | } |
245 | |||
245 | static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 246 | static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
246 | { | 247 | { |
247 | struct inode *inode = filp->f_path.dentry->d_inode; | 248 | struct inode *inode = filp->f_path.dentry->d_inode; |
@@ -392,6 +393,51 @@ static void fill_inode_item(struct btrfs_inode_item *item, | |||
392 | btrfs_set_inode_generation(item, inode->i_generation); | 393 | btrfs_set_inode_generation(item, inode->i_generation); |
393 | } | 394 | } |
394 | 395 | ||
396 | static int btrfs_update_inode(struct btrfs_trans_handle *trans, | ||
397 | struct btrfs_root *root, | ||
398 | struct inode *inode) | ||
399 | { | ||
400 | struct btrfs_inode_item *inode_item; | ||
401 | struct btrfs_path path; | ||
402 | int ret; | ||
403 | |||
404 | btrfs_init_path(&path); | ||
405 | |||
406 | ret = btrfs_lookup_inode(trans, root, &path, inode->i_ino, 1); | ||
407 | if (ret) { | ||
408 | if (ret > 0) | ||
409 | ret = -ENOENT; | ||
410 | goto failed; | ||
411 | } | ||
412 | |||
413 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | ||
414 | path.slots[0], | ||
415 | struct btrfs_inode_item); | ||
416 | |||
417 | fill_inode_item(inode_item, inode); | ||
418 | mark_buffer_dirty(path.nodes[0]); | ||
419 | failed: | ||
420 | btrfs_release_path(root, &path); | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | static int btrfs_write_inode(struct inode *inode, int wait) | ||
425 | { | ||
426 | struct btrfs_root *root = btrfs_sb(inode->i_sb); | ||
427 | struct btrfs_trans_handle *trans; | ||
428 | int ret; | ||
429 | |||
430 | mutex_lock(&root->fs_info->fs_mutex); | ||
431 | trans = btrfs_start_transaction(root, 1); | ||
432 | ret = btrfs_update_inode(trans, root, inode); | ||
433 | if (wait) | ||
434 | btrfs_commit_transaction(trans, root); | ||
435 | else | ||
436 | btrfs_end_transaction(trans, root); | ||
437 | mutex_unlock(&root->fs_info->fs_mutex); | ||
438 | return ret; | ||
439 | } | ||
440 | |||
395 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | 441 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, |
396 | struct inode *dir, int mode) | 442 | struct inode *dir, int mode) |
397 | { | 443 | { |
@@ -415,9 +461,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
415 | inode->i_ino = objectid; | 461 | inode->i_ino = objectid; |
416 | inode->i_blocks = 0; | 462 | inode->i_blocks = 0; |
417 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 463 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
418 | /* FIXME do this on link */ | ||
419 | if (mode & S_IFDIR) | ||
420 | inode->i_size = 3; | ||
421 | fill_inode_item(&inode_item, inode); | 464 | fill_inode_item(&inode_item, inode); |
422 | 465 | ||
423 | key.objectid = objectid; | 466 | key.objectid = objectid; |
@@ -431,7 +474,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
431 | BUG_ON(ret); | 474 | BUG_ON(ret); |
432 | 475 | ||
433 | insert_inode_hash(inode); | 476 | insert_inode_hash(inode); |
434 | // FIXME mark_inode_dirty(inode) | ||
435 | return inode; | 477 | return inode; |
436 | } | 478 | } |
437 | 479 | ||
@@ -443,6 +485,12 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
443 | dentry->d_name.name, dentry->d_name.len, | 485 | dentry->d_name.name, dentry->d_name.len, |
444 | dentry->d_parent->d_inode->i_ino, | 486 | dentry->d_parent->d_inode->i_ino, |
445 | inode->i_ino, 0); | 487 | inode->i_ino, 0); |
488 | if (ret == 0) { | ||
489 | dentry->d_parent->d_inode->i_size += dentry->d_name.len; | ||
490 | ret = btrfs_update_inode(trans, btrfs_sb(inode->i_sb), | ||
491 | dentry->d_parent->d_inode); | ||
492 | } | ||
493 | |||
446 | return ret; | 494 | return ret; |
447 | } | 495 | } |
448 | 496 | ||
@@ -502,6 +550,10 @@ static int btrfs_make_empty_dir(struct btrfs_trans_handle *trans, | |||
502 | goto error; | 550 | goto error; |
503 | ret = btrfs_insert_dir_item(trans, root, buf, 2, inode->i_ino, | 551 | ret = btrfs_insert_dir_item(trans, root, buf, 2, inode->i_ino, |
504 | dir->i_ino, 1); | 552 | dir->i_ino, 1); |
553 | if (ret) | ||
554 | goto error; | ||
555 | inode->i_size = 3; | ||
556 | ret = btrfs_update_inode(trans, root, inode); | ||
505 | error: | 557 | error: |
506 | return ret; | 558 | return ret; |
507 | } | 559 | } |
@@ -536,7 +588,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
536 | if (err) | 588 | if (err) |
537 | goto out_fail; | 589 | goto out_fail; |
538 | d_instantiate(dentry, inode); | 590 | d_instantiate(dentry, inode); |
539 | mark_inode_dirty(inode); | ||
540 | drop_on_err = 0; | 591 | drop_on_err = 0; |
541 | 592 | ||
542 | out_fail: | 593 | out_fail: |
@@ -600,6 +651,7 @@ static struct super_operations btrfs_super_ops = { | |||
600 | .read_inode = btrfs_read_locked_inode, | 651 | .read_inode = btrfs_read_locked_inode, |
601 | .write_super = btrfs_write_super, | 652 | .write_super = btrfs_write_super, |
602 | .sync_fs = btrfs_sync_fs, | 653 | .sync_fs = btrfs_sync_fs, |
654 | .write_inode = btrfs_write_inode, | ||
603 | }; | 655 | }; |
604 | 656 | ||
605 | static struct inode_operations btrfs_dir_inode_operations = { | 657 | static struct inode_operations btrfs_dir_inode_operations = { |