aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-09-09 16:10:28 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 17:03:45 -0400
commite5e5558e923f35839108a12718494ecb73fb782f (patch)
treec410d6826e9df13f7ea9e382a26589b66ec0989c /fs/fuse/inode.c
parent334f485df85ac7736ebe14940bf0a059c5f26d7d (diff)
[PATCH] FUSE - read-only operations
This patch adds the read-only filesystem operations of FUSE. This contains the following files: o dir.c - directory, symlink and file-inode operations The following operations are added: o lookup o getattr o readlink o follow_link o directory open o readdir o directory release o permission o dentry revalidate o statfs Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 33fad334ba7..41498a1952a 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -51,12 +51,20 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
51 fi = get_fuse_inode(inode); 51 fi = get_fuse_inode(inode);
52 fi->i_time = jiffies - 1; 52 fi->i_time = jiffies - 1;
53 fi->nodeid = 0; 53 fi->nodeid = 0;
54 fi->forget_req = fuse_request_alloc();
55 if (!fi->forget_req) {
56 kmem_cache_free(fuse_inode_cachep, inode);
57 return NULL;
58 }
54 59
55 return inode; 60 return inode;
56} 61}
57 62
58static void fuse_destroy_inode(struct inode *inode) 63static void fuse_destroy_inode(struct inode *inode)
59{ 64{
65 struct fuse_inode *fi = get_fuse_inode(inode);
66 if (fi->forget_req)
67 fuse_request_free(fi->forget_req);
60 kmem_cache_free(fuse_inode_cachep, inode); 68 kmem_cache_free(fuse_inode_cachep, inode);
61} 69}
62 70
@@ -65,8 +73,27 @@ static void fuse_read_inode(struct inode *inode)
65 /* No op */ 73 /* No op */
66} 74}
67 75
76void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
77 unsigned long nodeid, int version)
78{
79 struct fuse_forget_in *inarg = &req->misc.forget_in;
80 inarg->version = version;
81 req->in.h.opcode = FUSE_FORGET;
82 req->in.h.nodeid = nodeid;
83 req->in.numargs = 1;
84 req->in.args[0].size = sizeof(struct fuse_forget_in);
85 req->in.args[0].value = inarg;
86 request_send_noreply(fc, req);
87}
88
68static void fuse_clear_inode(struct inode *inode) 89static void fuse_clear_inode(struct inode *inode)
69{ 90{
91 struct fuse_conn *fc = get_fuse_conn(inode);
92 if (fc) {
93 struct fuse_inode *fi = get_fuse_inode(inode);
94 fuse_send_forget(fc, fi->forget_req, fi->nodeid, inode->i_version);
95 fi->forget_req = NULL;
96 }
70} 97}
71 98
72void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) 99void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
@@ -94,6 +121,22 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
94{ 121{
95 inode->i_mode = attr->mode & S_IFMT; 122 inode->i_mode = attr->mode & S_IFMT;
96 i_size_write(inode, attr->size); 123 i_size_write(inode, attr->size);
124 if (S_ISREG(inode->i_mode)) {
125 fuse_init_common(inode);
126 } else if (S_ISDIR(inode->i_mode))
127 fuse_init_dir(inode);
128 else if (S_ISLNK(inode->i_mode))
129 fuse_init_symlink(inode);
130 else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
131 S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
132 fuse_init_common(inode);
133 init_special_inode(inode, inode->i_mode,
134 new_decode_dev(attr->rdev));
135 } else {
136 /* Don't let user create weird files */
137 inode->i_mode = S_IFREG;
138 fuse_init_common(inode);
139 }
97} 140}
98 141
99static int fuse_inode_eq(struct inode *inode, void *_nodeidp) 142static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
@@ -158,6 +201,43 @@ static void fuse_put_super(struct super_block *sb)
158 spin_unlock(&fuse_lock); 201 spin_unlock(&fuse_lock);
159} 202}
160 203
204static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
205{
206 stbuf->f_type = FUSE_SUPER_MAGIC;
207 stbuf->f_bsize = attr->bsize;
208 stbuf->f_blocks = attr->blocks;
209 stbuf->f_bfree = attr->bfree;
210 stbuf->f_bavail = attr->bavail;
211 stbuf->f_files = attr->files;
212 stbuf->f_ffree = attr->ffree;
213 stbuf->f_namelen = attr->namelen;
214 /* fsid is left zero */
215}
216
217static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
218{
219 struct fuse_conn *fc = get_fuse_conn_super(sb);
220 struct fuse_req *req;
221 struct fuse_statfs_out outarg;
222 int err;
223
224 req = fuse_get_request(fc);
225 if (!req)
226 return -ERESTARTSYS;
227
228 req->in.numargs = 0;
229 req->in.h.opcode = FUSE_STATFS;
230 req->out.numargs = 1;
231 req->out.args[0].size = sizeof(outarg);
232 req->out.args[0].value = &outarg;
233 request_send(fc, req);
234 err = req->out.h.error;
235 if (!err)
236 convert_fuse_statfs(buf, &outarg.st);
237 fuse_put_request(fc, req);
238 return err;
239}
240
161enum { 241enum {
162 OPT_FD, 242 OPT_FD,
163 OPT_ROOTMODE, 243 OPT_ROOTMODE,
@@ -318,6 +398,7 @@ static struct super_operations fuse_super_operations = {
318 .read_inode = fuse_read_inode, 398 .read_inode = fuse_read_inode,
319 .clear_inode = fuse_clear_inode, 399 .clear_inode = fuse_clear_inode,
320 .put_super = fuse_put_super, 400 .put_super = fuse_put_super,
401 .statfs = fuse_statfs,
321 .show_options = fuse_show_options, 402 .show_options = fuse_show_options,
322}; 403};
323 404