aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c62
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
245static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 246static 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
396static 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]);
419failed:
420 btrfs_release_path(root, &path);
421 return 0;
422}
423
424static 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
395static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, 441static 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);
505error: 557error:
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
542out_fail: 593out_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
605static struct inode_operations btrfs_dir_inode_operations = { 657static struct inode_operations btrfs_dir_inode_operations = {