diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 184 |
1 files changed, 65 insertions, 119 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index e76fcd80db6a..820d21ee4afd 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -18,124 +18,6 @@ static struct inode_operations btrfs_dir_inode_operations; | |||
18 | static struct super_operations btrfs_super_ops; | 18 | static struct super_operations btrfs_super_ops; |
19 | static struct file_operations btrfs_dir_file_operations; | 19 | static struct file_operations btrfs_dir_file_operations; |
20 | 20 | ||
21 | #if 0 | ||
22 | /* some random number */ | ||
23 | |||
24 | static struct super_operations ramfs_ops; | ||
25 | |||
26 | static struct backing_dev_info ramfs_backing_dev_info = { | ||
27 | .ra_pages = 0, /* No readahead */ | ||
28 | .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK | | ||
29 | BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | | ||
30 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, | ||
31 | }; | ||
32 | |||
33 | struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | ||
34 | { | ||
35 | struct inode * inode = new_inode(sb); | ||
36 | |||
37 | if (inode) { | ||
38 | inode->i_mode = mode; | ||
39 | inode->i_uid = current->fsuid; | ||
40 | inode->i_gid = current->fsgid; | ||
41 | inode->i_blocks = 0; | ||
42 | inode->i_mapping->a_ops = &ramfs_aops; | ||
43 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; | ||
44 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
45 | switch (mode & S_IFMT) { | ||
46 | default: | ||
47 | init_special_inode(inode, mode, dev); | ||
48 | break; | ||
49 | case S_IFREG: | ||
50 | inode->i_op = &ramfs_file_inode_operations; | ||
51 | inode->i_fop = &ramfs_file_operations; | ||
52 | break; | ||
53 | case S_IFDIR: | ||
54 | inode->i_op = &ramfs_dir_inode_operations; | ||
55 | inode->i_fop = &simple_dir_operations; | ||
56 | |||
57 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | ||
58 | inc_nlink(inode); | ||
59 | break; | ||
60 | case S_IFLNK: | ||
61 | inode->i_op = &page_symlink_inode_operations; | ||
62 | break; | ||
63 | } | ||
64 | } | ||
65 | return inode; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * File creation. Allocate an inode, and we're done.. | ||
70 | */ | ||
71 | /* SMP-safe */ | ||
72 | static int | ||
73 | ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | ||
74 | { | ||
75 | struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev); | ||
76 | int error = -ENOSPC; | ||
77 | |||
78 | if (inode) { | ||
79 | if (dir->i_mode & S_ISGID) { | ||
80 | inode->i_gid = dir->i_gid; | ||
81 | if (S_ISDIR(mode)) | ||
82 | inode->i_mode |= S_ISGID; | ||
83 | } | ||
84 | d_instantiate(dentry, inode); | ||
85 | dget(dentry); /* Extra count - pin the dentry in core */ | ||
86 | error = 0; | ||
87 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | ||
88 | } | ||
89 | return error; | ||
90 | } | ||
91 | |||
92 | static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) | ||
93 | { | ||
94 | int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); | ||
95 | if (!retval) | ||
96 | inc_nlink(dir); | ||
97 | return retval; | ||
98 | } | ||
99 | |||
100 | static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) | ||
101 | { | ||
102 | return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); | ||
103 | } | ||
104 | |||
105 | static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) | ||
106 | { | ||
107 | struct inode *inode; | ||
108 | int error = -ENOSPC; | ||
109 | |||
110 | inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); | ||
111 | if (inode) { | ||
112 | int l = strlen(symname)+1; | ||
113 | error = page_symlink(inode, symname, l); | ||
114 | if (!error) { | ||
115 | if (dir->i_mode & S_ISGID) | ||
116 | inode->i_gid = dir->i_gid; | ||
117 | d_instantiate(dentry, inode); | ||
118 | dget(dentry); | ||
119 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | ||
120 | } else | ||
121 | iput(inode); | ||
122 | } | ||
123 | return error; | ||
124 | } | ||
125 | |||
126 | static struct inode_operations ramfs_dir_inode_operations = { | ||
127 | .create = ramfs_create, | ||
128 | .lookup = simple_lookup, | ||
129 | .link = simple_link, | ||
130 | .unlink = simple_unlink, | ||
131 | .symlink = ramfs_symlink, | ||
132 | .mkdir = ramfs_mkdir, | ||
133 | .rmdir = simple_rmdir, | ||
134 | .mknod = ramfs_mknod, | ||
135 | .rename = simple_rename, | ||
136 | }; | ||
137 | #endif | ||
138 | |||
139 | static void btrfs_read_locked_inode(struct inode *inode) | 21 | static void btrfs_read_locked_inode(struct inode *inode) |
140 | { | 22 | { |
141 | struct btrfs_path path; | 23 | struct btrfs_path path; |
@@ -533,9 +415,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
533 | inode->i_ino = objectid; | 415 | inode->i_ino = objectid; |
534 | inode->i_blocks = 0; | 416 | inode->i_blocks = 0; |
535 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 417 | 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; | ||
536 | fill_inode_item(&inode_item, inode); | 421 | fill_inode_item(&inode_item, inode); |
537 | 422 | ||
538 | |||
539 | key.objectid = objectid; | 423 | key.objectid = objectid; |
540 | key.flags = 0; | 424 | key.flags = 0; |
541 | key.offset = 0; | 425 | key.offset = 0; |
@@ -603,6 +487,67 @@ out_unlock: | |||
603 | return err; | 487 | return err; |
604 | } | 488 | } |
605 | 489 | ||
490 | static int btrfs_make_empty_dir(struct btrfs_trans_handle *trans, | ||
491 | struct inode *inode, struct inode *dir) | ||
492 | { | ||
493 | struct btrfs_root *root = btrfs_sb(inode->i_sb); | ||
494 | int ret; | ||
495 | char buf[2]; | ||
496 | buf[0] = '.'; | ||
497 | buf[1] = '.'; | ||
498 | |||
499 | ret = btrfs_insert_dir_item(trans, root, buf, 1, inode->i_ino, | ||
500 | inode->i_ino, 1); | ||
501 | if (ret) | ||
502 | goto error; | ||
503 | ret = btrfs_insert_dir_item(trans, root, buf, 2, inode->i_ino, | ||
504 | dir->i_ino, 1); | ||
505 | error: | ||
506 | return ret; | ||
507 | } | ||
508 | |||
509 | static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||
510 | { | ||
511 | struct inode *inode; | ||
512 | struct btrfs_trans_handle *trans; | ||
513 | struct btrfs_root *root = btrfs_sb(dir->i_sb); | ||
514 | int err = 0; | ||
515 | int drop_on_err = 0; | ||
516 | |||
517 | mutex_lock(&root->fs_info->fs_mutex); | ||
518 | trans = btrfs_start_transaction(root, 1); | ||
519 | if (IS_ERR(trans)) { | ||
520 | err = PTR_ERR(trans); | ||
521 | goto out_unlock; | ||
522 | } | ||
523 | inode = btrfs_new_inode(trans, dir, S_IFDIR | mode); | ||
524 | if (IS_ERR(inode)) { | ||
525 | err = PTR_ERR(inode); | ||
526 | goto out_fail; | ||
527 | } | ||
528 | drop_on_err = 1; | ||
529 | inode->i_op = &btrfs_dir_inode_operations; | ||
530 | inode->i_fop = &btrfs_dir_file_operations; | ||
531 | |||
532 | err = btrfs_make_empty_dir(trans, inode, dir); | ||
533 | if (err) | ||
534 | goto out_fail; | ||
535 | err = btrfs_add_link(trans, dentry, inode); | ||
536 | if (err) | ||
537 | goto out_fail; | ||
538 | d_instantiate(dentry, inode); | ||
539 | mark_inode_dirty(inode); | ||
540 | drop_on_err = 0; | ||
541 | |||
542 | out_fail: | ||
543 | btrfs_end_transaction(trans, root); | ||
544 | out_unlock: | ||
545 | mutex_unlock(&root->fs_info->fs_mutex); | ||
546 | if (drop_on_err) | ||
547 | iput(inode); | ||
548 | return err; | ||
549 | } | ||
550 | |||
606 | static int btrfs_sync_fs(struct super_block *sb, int wait) | 551 | static int btrfs_sync_fs(struct super_block *sb, int wait) |
607 | { | 552 | { |
608 | struct btrfs_trans_handle *trans; | 553 | struct btrfs_trans_handle *trans; |
@@ -661,6 +606,7 @@ static struct inode_operations btrfs_dir_inode_operations = { | |||
661 | .lookup = btrfs_lookup, | 606 | .lookup = btrfs_lookup, |
662 | .create = btrfs_create, | 607 | .create = btrfs_create, |
663 | .unlink = btrfs_unlink, | 608 | .unlink = btrfs_unlink, |
609 | .mkdir = btrfs_mkdir, | ||
664 | }; | 610 | }; |
665 | 611 | ||
666 | static struct file_operations btrfs_dir_file_operations = { | 612 | static struct file_operations btrfs_dir_file_operations = { |