diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 129 |
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 | ||
361 | static 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 | |||
379 | static 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 | |||
420 | static 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 | |||
432 | static 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 | |||
445 | static 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 | |||
465 | static void btrfs_write_super(struct super_block *sb) | ||
466 | { | ||
467 | sb->s_dirt = 0; | ||
468 | printk("btrfs write_super!\n"); | ||
469 | } | ||
470 | |||
471 | static 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); | ||
482 | printk("btrfs sync_fs\n"); | ||
483 | return 0; | ||
484 | } | ||
485 | |||
360 | static int btrfs_get_sb(struct file_system_type *fs_type, | 486 | static 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 | ||
382 | static struct inode_operations btrfs_dir_inode_operations = { | 510 | static struct inode_operations btrfs_dir_inode_operations = { |
383 | .lookup = btrfs_lookup, | 511 | .lookup = btrfs_lookup, |
512 | .create = btrfs_create, | ||
384 | }; | 513 | }; |
385 | 514 | ||
386 | static struct file_operations btrfs_dir_file_operations = { | 515 | static struct file_operations btrfs_dir_file_operations = { |