blob: 5c2b743f80e2ef7c0b4dac06209f4ef990978054 [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
Miklos Szeredibc22e7b2001-10-23 19:26:04 +00009#include "fuse_i.h"
10
11#include <linux/module.h>
12#include <linux/kernel.h>
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000013#include <linux/sched.h>
14#include <linux/file.h>
15
16#define FUSE_SUPER_MAGIC 0x65735546
17
18static void fuse_read_inode(struct inode *inode)
19{
Miklos Szeredi90d8bef2001-10-26 14:55:42 +000020 /* No op */
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000021}
22
23static void fuse_put_super(struct super_block *sb)
24{
25 struct fuse_conn *fc = sb->u.generic_sbp;
26
Miklos Szeredi79b52f62001-10-24 14:37:13 +000027 spin_lock(&fuse_lock);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000028 fc->sb = NULL;
29 fuse_release_conn(fc);
Miklos Szeredi79b52f62001-10-24 14:37:13 +000030 spin_unlock(&fuse_lock);
31
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000032}
33
34static struct super_operations fuse_super_operations = {
35 read_inode: fuse_read_inode,
36 put_super: fuse_put_super,
37};
38
39
40static struct fuse_conn *get_conn(struct fuse_mount_data *d)
41{
42 struct fuse_conn *fc = NULL;
43 struct file *file;
44 struct inode *ino;
45
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000046 if(d == NULL) {
47 printk("fuse_read_super: Bad mount data\n");
48 return NULL;
49 }
50
51 if(d->version != FUSE_MOUNT_VERSION) {
52 printk("fuse_read_super: Bad mount version: %i\n", d->version);
53 return NULL;
54 }
55
56 file = fget(d->fd);
57 ino = NULL;
58 if(file)
59 ino = file->f_dentry->d_inode;
60
61 if(!ino || ino->u.generic_ip != proc_fuse_dev) {
62 printk("fuse_read_super: Bad file: %i\n", d->fd);
63 goto out;
64 }
65
66 fc = file->private_data;
67
68 out:
69 fput(file);
70 return fc;
71
72}
73
Miklos Szeredi79b52f62001-10-24 14:37:13 +000074static struct inode *get_root_inode(struct super_block *sb)
75{
76 struct inode *root ;
77
78 root = iget(sb, 1);
79 if(root) {
80 root->i_mode = S_IFDIR;
81 root->i_uid = 0;
82 root->i_gid = 0;
83 root->i_nlink = 2;
84 root->i_size = 0;
85 root->i_blksize = 1024;
86 root->i_blocks = 0;
87 root->i_atime = CURRENT_TIME;
88 root->i_mtime = CURRENT_TIME;
89 root->i_ctime = CURRENT_TIME;
90 fuse_dir_init(root);
91 }
92
93 return root;
94}
95
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000096static struct super_block *fuse_read_super(struct super_block *sb,
97 void *data, int silent)
98{
99 struct fuse_conn *fc;
100 struct inode *root;
101
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000102 sb->s_blocksize = 1024;
103 sb->s_blocksize_bits = 10;
104 sb->s_magic = FUSE_SUPER_MAGIC;
105 sb->s_op = &fuse_super_operations;
106
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000107 root = get_root_inode(sb);
108 if(root == NULL) {
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000109 printk("fuse_read_super: failed to get root inode\n");
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000110 return NULL;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000111 }
112
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000113 spin_lock(&fuse_lock);
114 fc = get_conn(data);
115 if(fc == NULL)
116 goto err;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000117
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000118 if(fc->sb != NULL) {
119 printk("fuse_read_super: connection %i already mounted\n",
120 fc->id);
121 goto err;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000122 }
123
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000124 sb->u.generic_sbp = fc;
125 sb->s_root = d_alloc_root(root);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000126 fc->sb = sb;
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000127 spin_unlock(&fuse_lock);
128
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000129 return sb;
130
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000131 err:
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000132 spin_unlock(&fuse_lock);
133 iput(root);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000134 return NULL;
135}
136
137
138static DECLARE_FSTYPE(fuse_fs_type, "fuse", fuse_read_super, 0);
139
140int fuse_fs_init()
141{
142 int res;
143
144 res = register_filesystem(&fuse_fs_type);
145 if(res)
146 printk("fuse: failed to register filesystem\n");
147
148 return res;
149}
150
151void fuse_fs_cleanup()
152{
153 unregister_filesystem(&fuse_fs_type);
154}
155
156/*
157 * Local Variables:
158 * indent-tabs-mode: t
159 * c-basic-offset: 8
160 * End:
161 */
162