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.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 620430825840..6080a8133d71 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -10,6 +10,7 @@
10#include <linux/backing-dev.h> 10#include <linux/backing-dev.h>
11#include "ctree.h" 11#include "ctree.h"
12#include "disk-io.h" 12#include "disk-io.h"
13#include "transaction.h"
13 14
14#define BTRFS_SUPER_MAGIC 0x9123682E 15#define BTRFS_SUPER_MAGIC 0x9123682E
15 16
@@ -357,6 +358,131 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
357 return 0; 358 return 0;
358} 359}
359 360
361static void fill_inode_item(struct btrfs_inode_item *item,
362 struct inode *inode)
363{
364 btrfs_set_inode_uid(item, inode->i_uid);
365 btrfs_set_inode_gid(item, inode->i_gid);
366 btrfs_set_inode_size(item, inode->i_size);
367 btrfs_set_inode_mode(item, inode->i_mode);
368 btrfs_set_inode_nlink(item, inode->i_nlink);
369 btrfs_set_timespec_sec(&item->atime, inode->i_atime.tv_sec);
370 btrfs_set_timespec_nsec(&item->atime, inode->i_atime.tv_nsec);
371 btrfs_set_timespec_sec(&item->mtime, inode->i_mtime.tv_sec);
372 btrfs_set_timespec_nsec(&item->mtime, inode->i_mtime.tv_nsec);
373 btrfs_set_timespec_sec(&item->ctime, inode->i_ctime.tv_sec);
374 btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec);
375 btrfs_set_inode_nblocks(item, inode->i_blocks);
376 btrfs_set_inode_generation(item, inode->i_generation);
377}
378
379static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
380 struct inode *dir, int mode)
381{
382 struct inode *inode;
383 struct btrfs_inode_item inode_item;
384 struct btrfs_root *root = btrfs_sb(dir->i_sb);
385 struct btrfs_key key;
386 int ret;
387 u64 objectid;
388
389 inode = new_inode(dir->i_sb);
390 if (!inode)
391 return ERR_PTR(-ENOMEM);
392
393 ret = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
394 BUG_ON(ret);
395
396 inode->i_uid = current->fsuid;
397 inode->i_gid = current->fsgid;
398 inode->i_mode = mode;
399 inode->i_ino = objectid;
400 inode->i_blocks = 0;
401 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
402 fill_inode_item(&inode_item, inode);
403
404
405 key.objectid = objectid;
406 key.flags = 0;
407 key.offset = 0;
408 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
409 ret = btrfs_insert_inode_map(trans, root, objectid, &key);
410 BUG_ON(ret);
411
412 ret = btrfs_insert_inode(trans, root, objectid, &inode_item);
413 BUG_ON(ret);
414
415 insert_inode_hash(inode);
416 // FIXME mark_inode_dirty(inode)
417 return inode;
418}
419
420static int btrfs_add_link(struct btrfs_trans_handle *trans,
421 struct dentry *dentry, struct inode *inode)
422{
423 int ret;
424 ret = btrfs_insert_dir_item(trans, btrfs_sb(inode->i_sb),
425 dentry->d_name.name, dentry->d_name.len,
426 dentry->d_parent->d_inode->i_ino,
427 inode->i_ino, 0);
428 BUG_ON(ret);
429 return ret;
430}
431
432static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
433 struct dentry *dentry, struct inode *inode)
434{
435 int err = btrfs_add_link(trans, dentry, inode);
436 if (!err) {
437 d_instantiate(dentry, inode);
438 return 0;
439 }
440 inode_dec_link_count(inode);
441 iput(inode);
442 return err;
443}
444
445static int btrfs_create(struct inode *dir, struct dentry *dentry,
446 int mode, struct nameidata *nd)
447{
448 struct btrfs_trans_handle *trans;
449 struct btrfs_root *root = btrfs_sb(dir->i_sb);
450 struct inode *inode;
451 int err;
452
453 trans = btrfs_start_transaction(root, 1);
454 inode = btrfs_new_inode(trans, dir, mode);
455 err = PTR_ERR(inode);
456 if (IS_ERR(inode))
457 return err;
458 // FIXME mark the inode dirty
459 err = btrfs_add_nondir(trans, dentry, inode);
460 dir->i_sb->s_dirt = 1;
461 btrfs_end_transaction(trans, root);
462 return err;
463}
464
465static void btrfs_write_super(struct super_block *sb)
466{
467 sb->s_dirt = 0;
468printk("btrfs write_super!\n");
469}
470
471static int btrfs_sync_fs(struct super_block *sb, int wait)
472{
473 struct btrfs_trans_handle *trans;
474 struct btrfs_root *root;
475 int ret;
476 sb->s_dirt = 0;
477 root = btrfs_sb(sb);
478 trans = btrfs_start_transaction(root, 1);
479 ret = btrfs_commit_transaction(trans, root);
480 sb->s_dirt = 0;
481 BUG_ON(ret);
482printk("btrfs sync_fs\n");
483 return 0;
484}
485
360static int btrfs_get_sb(struct file_system_type *fs_type, 486static int btrfs_get_sb(struct file_system_type *fs_type,
361 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 487 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
362{ 488{
@@ -377,10 +503,13 @@ static struct super_operations btrfs_super_ops = {
377 .drop_inode = generic_delete_inode, 503 .drop_inode = generic_delete_inode,
378 .put_super = btrfs_put_super, 504 .put_super = btrfs_put_super,
379 .read_inode = btrfs_read_locked_inode, 505 .read_inode = btrfs_read_locked_inode,
506 .write_super = btrfs_write_super,
507 .sync_fs = btrfs_sync_fs,
380}; 508};
381 509
382static struct inode_operations btrfs_dir_inode_operations = { 510static struct inode_operations btrfs_dir_inode_operations = {
383 .lookup = btrfs_lookup, 511 .lookup = btrfs_lookup,
512 .create = btrfs_create,
384}; 513};
385 514
386static struct file_operations btrfs_dir_file_operations = { 515static struct file_operations btrfs_dir_file_operations = {