blob: da30cacc1ae57552062fa5ebaf4e100c650f73e1 [file] [log] [blame]
Miklos Szeredibc22e7b2001-10-23 19:26:04 +00001/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001 Miklos Szeredi (mszeredi@inf.bme.hu)
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse.h"
10#include "fuse_i.h"
11
12#include <linux/module.h>
13#include <linux/kernel.h>
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000014#include <linux/sched.h>
15#include <linux/file.h>
16
17#define FUSE_SUPER_MAGIC 0x65735546
18
19static void fuse_read_inode(struct inode *inode)
20{
21 printk(KERN_DEBUG "fuse_read_inode: %li\n", inode->i_ino);
22
23
24}
25
26static void fuse_put_super(struct super_block *sb)
27{
28 struct fuse_conn *fc = sb->u.generic_sbp;
29
Miklos Szeredi79b52f62001-10-24 14:37:13 +000030 printk(KERN_DEBUG "fuse_put_super[%i]\n", fc->id);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000031
Miklos Szeredi79b52f62001-10-24 14:37:13 +000032 spin_lock(&fuse_lock);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000033 fc->sb = NULL;
34 fuse_release_conn(fc);
Miklos Szeredi79b52f62001-10-24 14:37:13 +000035 spin_unlock(&fuse_lock);
36
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000037}
38
39static struct super_operations fuse_super_operations = {
40 read_inode: fuse_read_inode,
41 put_super: fuse_put_super,
42};
43
44
45static struct fuse_conn *get_conn(struct fuse_mount_data *d)
46{
47 struct fuse_conn *fc = NULL;
48 struct file *file;
49 struct inode *ino;
50
51 printk(KERN_DEBUG "fuse_read_super\n");
52
53 if(d == NULL) {
54 printk("fuse_read_super: Bad mount data\n");
55 return NULL;
56 }
57
58 if(d->version != FUSE_MOUNT_VERSION) {
59 printk("fuse_read_super: Bad mount version: %i\n", d->version);
60 return NULL;
61 }
62
63 file = fget(d->fd);
64 ino = NULL;
65 if(file)
66 ino = file->f_dentry->d_inode;
67
68 if(!ino || ino->u.generic_ip != proc_fuse_dev) {
69 printk("fuse_read_super: Bad file: %i\n", d->fd);
70 goto out;
71 }
72
73 fc = file->private_data;
74
75 out:
76 fput(file);
77 return fc;
78
79}
80
Miklos Szeredi79b52f62001-10-24 14:37:13 +000081static struct inode *get_root_inode(struct super_block *sb)
82{
83 struct inode *root ;
84
85 root = iget(sb, 1);
86 if(root) {
87 root->i_mode = S_IFDIR;
88 root->i_uid = 0;
89 root->i_gid = 0;
90 root->i_nlink = 2;
91 root->i_size = 0;
92 root->i_blksize = 1024;
93 root->i_blocks = 0;
94 root->i_atime = CURRENT_TIME;
95 root->i_mtime = CURRENT_TIME;
96 root->i_ctime = CURRENT_TIME;
97 fuse_dir_init(root);
98 }
99
100 return root;
101}
102
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000103static struct super_block *fuse_read_super(struct super_block *sb,
104 void *data, int silent)
105{
106 struct fuse_conn *fc;
107 struct inode *root;
108
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000109 sb->s_blocksize = 1024;
110 sb->s_blocksize_bits = 10;
111 sb->s_magic = FUSE_SUPER_MAGIC;
112 sb->s_op = &fuse_super_operations;
113
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000114 root = get_root_inode(sb);
115 if(root == NULL) {
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000116 printk("fuse_read_super: failed to get root inode\n");
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000117 return NULL;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000118 }
119
120 printk(KERN_DEBUG "root inode: %ld/%d\n", root->i_ino, root->i_dev);
121
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000122 spin_lock(&fuse_lock);
123 fc = get_conn(data);
124 if(fc == NULL)
125 goto err;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000126
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000127 if(fc->sb != NULL) {
128 printk("fuse_read_super: connection %i already mounted\n",
129 fc->id);
130 goto err;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000131 }
132
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000133 sb->u.generic_sbp = fc;
134 sb->s_root = d_alloc_root(root);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000135 fc->sb = sb;
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000136 spin_unlock(&fuse_lock);
137
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000138 return sb;
139
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000140 err:
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000141 spin_unlock(&fuse_lock);
142 iput(root);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000143 return NULL;
144}
145
146
147static DECLARE_FSTYPE(fuse_fs_type, "fuse", fuse_read_super, 0);
148
149int fuse_fs_init()
150{
151 int res;
152
153 res = register_filesystem(&fuse_fs_type);
154 if(res)
155 printk("fuse: failed to register filesystem\n");
156
157 return res;
158}
159
160void fuse_fs_cleanup()
161{
162 unregister_filesystem(&fuse_fs_type);
163}
164
165/*
166 * Local Variables:
167 * indent-tabs-mode: t
168 * c-basic-offset: 8
169 * End:
170 */
171