blob: 3a780403f2fdeb359150a55b1c88ebe29824cac6 [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
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000011#include <linux/sched.h>
Miklos Szeredi85c74fc2001-10-28 19:44:14 +000012#include <linux/slab.h>
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000013#include <linux/file.h>
14
15#define FUSE_SUPER_MAGIC 0x65735546
16
17static void fuse_read_inode(struct inode *inode)
18{
Miklos Szeredi90d8bef2001-10-26 14:55:42 +000019 /* No op */
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000020}
21
Miklos Szeredi85c74fc2001-10-28 19:44:14 +000022static void fuse_clear_inode(struct inode *inode)
23{
Miklos Szeredi5e183482001-10-31 14:52:35 +000024 struct fuse_conn *fc = INO_FC(inode);
Miklos Szeredia181e612001-11-06 12:03:23 +000025 struct fuse_in in = FUSE_IN_INIT;
26 struct fuse_forget_in arg;
27
28 arg.version = inode->i_version;
29
30 in.h.opcode = FUSE_FORGET;
31 in.h.ino = inode->i_ino;
32 in.argsize = sizeof(arg);
33 in.arg = &arg;
34
35 request_send(fc, &in, NULL);
Miklos Szeredi85c74fc2001-10-28 19:44:14 +000036}
37
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000038static void fuse_put_super(struct super_block *sb)
39{
40 struct fuse_conn *fc = sb->u.generic_sbp;
41
Miklos Szeredi79b52f62001-10-24 14:37:13 +000042 spin_lock(&fuse_lock);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000043 fc->sb = NULL;
Miklos Szeredi8cffdb92001-11-09 14:49:18 +000044 fc->uid = 0;
45 fc->flags = 0;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000046 fuse_release_conn(fc);
Miklos Szeredi79b52f62001-10-24 14:37:13 +000047 spin_unlock(&fuse_lock);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000048}
49
50static struct super_operations fuse_super_operations = {
51 read_inode: fuse_read_inode,
Miklos Szeredi85c74fc2001-10-28 19:44:14 +000052 clear_inode: fuse_clear_inode,
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000053 put_super: fuse_put_super,
54};
55
56
57static struct fuse_conn *get_conn(struct fuse_mount_data *d)
58{
59 struct fuse_conn *fc = NULL;
60 struct file *file;
61 struct inode *ino;
62
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000063 if(d == NULL) {
64 printk("fuse_read_super: Bad mount data\n");
65 return NULL;
66 }
67
Miklos Szeredi2df1c042001-11-06 15:07:17 +000068 if(d->version != FUSE_KERNEL_VERSION) {
69 printk("fuse_read_super: Bad version: %i\n", d->version);
Miklos Szeredibc22e7b2001-10-23 19:26:04 +000070 return NULL;
71 }
72
73 file = fget(d->fd);
74 ino = NULL;
75 if(file)
76 ino = file->f_dentry->d_inode;
77
78 if(!ino || ino->u.generic_ip != proc_fuse_dev) {
79 printk("fuse_read_super: Bad file: %i\n", d->fd);
80 goto out;
81 }
82
83 fc = file->private_data;
84
85 out:
86 fput(file);
87 return fc;
88
89}
90
Miklos Szeredi2df1c042001-11-06 15:07:17 +000091static struct inode *get_root_inode(struct super_block *sb, unsigned int mode)
Miklos Szeredi79b52f62001-10-24 14:37:13 +000092{
Miklos Szeredi5e183482001-10-31 14:52:35 +000093 struct fuse_attr attr;
94 memset(&attr, 0, sizeof(attr));
Miklos Szeredi79b52f62001-10-24 14:37:13 +000095
Miklos Szeredi2df1c042001-11-06 15:07:17 +000096 attr.mode = mode;
Miklos Szeredia181e612001-11-06 12:03:23 +000097 return fuse_iget(sb, 1, &attr, 0);
Miklos Szeredi79b52f62001-10-24 14:37:13 +000098}
99
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000100static struct super_block *fuse_read_super(struct super_block *sb,
101 void *data, int silent)
102{
103 struct fuse_conn *fc;
104 struct inode *root;
Miklos Szeredi2df1c042001-11-06 15:07:17 +0000105 struct fuse_mount_data *d = data;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000106
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000107 sb->s_blocksize = 1024;
108 sb->s_blocksize_bits = 10;
109 sb->s_magic = FUSE_SUPER_MAGIC;
110 sb->s_op = &fuse_super_operations;
111
Miklos Szeredi2df1c042001-11-06 15:07:17 +0000112 root = get_root_inode(sb, d->rootmode);
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000113 if(root == NULL) {
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000114 printk("fuse_read_super: failed to get root inode\n");
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000115 return NULL;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000116 }
117
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000118 spin_lock(&fuse_lock);
Miklos Szeredi2df1c042001-11-06 15:07:17 +0000119 fc = get_conn(d);
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000120 if(fc == NULL)
121 goto err;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000122
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000123 if(fc->sb != NULL) {
Miklos Szeredia181e612001-11-06 12:03:23 +0000124 printk("fuse_read_super: connection already mounted\n");
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000125 goto err;
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000126 }
127
Miklos Szeredi79b52f62001-10-24 14:37:13 +0000128 sb->u.generic_sbp = fc;
129 sb->s_root = d_alloc_root(root);
Miklos Szeredi19dff1b2001-10-30 15:06:52 +0000130 if(!sb->s_root)
131 goto err;
132
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000133 fc->sb = sb;
Miklos Szeredi8cffdb92001-11-09 14:49:18 +0000134 fc->flags = d->flags;
135 fc->uid = d->uid;
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
Miklos Szeredia181e612001-11-06 12:03:23 +0000169 * End: */
Miklos Szeredibc22e7b2001-10-23 19:26:04 +0000170