2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU GPL.
11 #include <linux/pagemap.h>
12 #include <linux/slab.h>
13 #include <linux/kernel.h>
15 int fuse_open_common(struct inode
*inode
, struct file
*file
, int isdir
)
17 struct fuse_conn
*fc
= get_fuse_conn(inode
);
19 struct fuse_open_in inarg
;
20 struct fuse_open_out outarg
;
23 /* Restarting the syscall is not allowed if O_CREAT and O_EXCL
24 are both set, because creation will fail on the restart */
25 int excl
= (file
->f_flags
& (O_CREAT
|O_EXCL
)) == (O_CREAT
|O_EXCL
);
27 err
= generic_file_open(inode
, file
);
31 /* If opening the root node, no lookup has been performed on
32 it, so the attributes must be refreshed */
33 if (get_node_id(inode
) == FUSE_ROOT_ID
) {
34 int err
= fuse_do_getattr(inode
);
40 req
= fuse_get_request_nonint(fc
);
42 req
= fuse_get_request(fc
);
44 return excl
? -EINTR
: -ERESTARTSYS
;
47 ff
= kmalloc(sizeof(struct fuse_file
), GFP_KERNEL
);
51 ff
->release_req
= fuse_request_alloc();
52 if (!ff
->release_req
) {
57 memset(&inarg
, 0, sizeof(inarg
));
58 inarg
.flags
= file
->f_flags
& ~(O_CREAT
| O_EXCL
| O_NOCTTY
| O_TRUNC
);
59 req
->in
.h
.opcode
= isdir
? FUSE_OPENDIR
: FUSE_OPEN
;
60 req
->in
.h
.nodeid
= get_node_id(inode
);
63 req
->in
.args
[0].size
= sizeof(inarg
);
64 req
->in
.args
[0].value
= &inarg
;
66 req
->out
.args
[0].size
= sizeof(outarg
);
67 req
->out
.args
[0].value
= &outarg
;
69 request_send_nonint(fc
, req
);
71 request_send(fc
, req
);
72 err
= req
->out
.h
.error
;
73 if (!err
&& !(fc
->flags
& FUSE_KERNEL_CACHE
))
74 invalidate_inode_pages(inode
->i_mapping
);
76 fuse_request_free(ff
->release_req
);
80 file
->private_data
= ff
;
84 fuse_put_request(fc
, req
);
88 int fuse_release_common(struct inode
*inode
, struct file
*file
, int isdir
)
90 struct fuse_conn
*fc
= get_fuse_conn(inode
);
91 struct fuse_file
*ff
= file
->private_data
;
92 struct fuse_req
*req
= ff
->release_req
;
93 struct fuse_release_in
*inarg
= &req
->misc
.release_in
;
96 inarg
->flags
= file
->f_flags
& ~O_EXCL
;
97 req
->in
.h
.opcode
= isdir
? FUSE_RELEASEDIR
: FUSE_RELEASE
;
98 req
->in
.h
.nodeid
= get_node_id(inode
);
101 req
->in
.args
[0].size
= sizeof(struct fuse_release_in
);
102 req
->in
.args
[0].value
= inarg
;
103 request_send_background(fc
, req
);
106 /* Return value is ignored by VFS */
110 static int fuse_open(struct inode
*inode
, struct file
*file
)
112 return fuse_open_common(inode
, file
, 0);
115 static int fuse_release(struct inode
*inode
, struct file
*file
)
117 return fuse_release_common(inode
, file
, 0);
120 static int fuse_flush(struct file
*file
)
122 struct inode
*inode
= file
->f_dentry
->d_inode
;
123 struct fuse_conn
*fc
= get_fuse_conn(inode
);
124 struct fuse_file
*ff
= file
->private_data
;
125 struct fuse_req
*req
;
126 struct fuse_flush_in inarg
;
132 req
= fuse_get_request_nonint(fc
);
136 memset(&inarg
, 0, sizeof(inarg
));
138 req
->in
.h
.opcode
= FUSE_FLUSH
;
139 req
->in
.h
.nodeid
= get_node_id(inode
);
143 req
->in
.args
[0].size
= sizeof(inarg
);
144 req
->in
.args
[0].value
= &inarg
;
145 request_send_nonint(fc
, req
);
146 err
= req
->out
.h
.error
;
147 fuse_put_request(fc
, req
);
148 if (err
== -ENOSYS
) {
155 static int fuse_fsync(struct file
*file
, struct dentry
*de
, int datasync
)
157 struct inode
*inode
= de
->d_inode
;
158 struct fuse_conn
*fc
= get_fuse_conn(inode
);
159 struct fuse_file
*ff
= file
->private_data
;
160 struct fuse_req
*req
;
161 struct fuse_fsync_in inarg
;
167 req
= fuse_get_request(fc
);
171 memset(&inarg
, 0, sizeof(inarg
));
173 inarg
.fsync_flags
= datasync
? 1 : 0;
174 req
->in
.h
.opcode
= FUSE_FSYNC
;
175 req
->in
.h
.nodeid
= get_node_id(inode
);
179 req
->in
.args
[0].size
= sizeof(inarg
);
180 req
->in
.args
[0].value
= &inarg
;
181 request_send(fc
, req
);
182 err
= req
->out
.h
.error
;
183 fuse_put_request(fc
, req
);
184 if (err
== -ENOSYS
) {
191 size_t fuse_send_read_common(struct fuse_req
*req
, struct file
*file
,
192 struct inode
*inode
, loff_t pos
, size_t count
,
195 struct fuse_conn
*fc
= get_fuse_conn(inode
);
196 struct fuse_file
*ff
= file
->private_data
;
197 struct fuse_read_in inarg
;
199 memset(&inarg
, 0, sizeof(struct fuse_read_in
));
203 req
->in
.h
.opcode
= isdir
? FUSE_READDIR
: FUSE_READ
;
204 req
->in
.h
.nodeid
= get_node_id(inode
);
208 req
->in
.args
[0].size
= sizeof(struct fuse_read_in
);
209 req
->in
.args
[0].value
= &inarg
;
210 req
->out
.argpages
= 1;
212 req
->out
.numargs
= 1;
213 req
->out
.args
[0].size
= count
;
214 request_send_nonint(fc
, req
);
215 return req
->out
.args
[0].size
;
218 static inline size_t fuse_send_read(struct fuse_req
*req
, struct file
*file
,
219 struct inode
*inode
, loff_t pos
,
222 return fuse_send_read_common(req
, file
, inode
, pos
, count
, 0);
225 static int fuse_readpage(struct file
*file
, struct page
*page
)
227 struct inode
*inode
= page
->mapping
->host
;
228 struct fuse_conn
*fc
= get_fuse_conn(inode
);
229 loff_t pos
= (loff_t
) page
->index
<< PAGE_CACHE_SHIFT
;
230 struct fuse_req
*req
= fuse_get_request_nonint(fc
);
235 req
->out
.page_zeroing
= 1;
237 req
->pages
[0] = page
;
238 fuse_send_read(req
, file
, inode
, pos
, PAGE_CACHE_SIZE
);
239 err
= req
->out
.h
.error
;
240 fuse_put_request(fc
, req
);
242 SetPageUptodate(page
);
248 static int fuse_send_readpages(struct fuse_req
*req
, struct file
*file
,
251 loff_t pos
= (loff_t
) req
->pages
[0]->index
<< PAGE_CACHE_SHIFT
;
252 size_t count
= req
->num_pages
<< PAGE_CACHE_SHIFT
;
254 req
->out
.page_zeroing
= 1;
255 fuse_send_read(req
, file
, inode
, pos
, count
);
256 for (i
= 0; i
< req
->num_pages
; i
++) {
257 struct page
*page
= req
->pages
[i
];
258 if (!req
->out
.h
.error
)
259 SetPageUptodate(page
);
262 return req
->out
.h
.error
;
265 struct fuse_readpages_data
{
266 struct fuse_req
*req
;
271 static int fuse_readpages_fill(void *_data
, struct page
*page
)
273 struct fuse_readpages_data
*data
= _data
;
274 struct fuse_req
*req
= data
->req
;
275 struct inode
*inode
= data
->inode
;
276 struct fuse_conn
*fc
= get_fuse_conn(inode
);
278 if (req
->num_pages
&&
279 (req
->num_pages
== FUSE_MAX_PAGES_PER_REQ
||
280 (req
->num_pages
+ 1) * PAGE_CACHE_SIZE
> fc
->max_read
||
281 req
->pages
[req
->num_pages
- 1]->index
+ 1 != page
->index
)) {
282 int err
= fuse_send_readpages(req
, data
->file
, inode
);
287 fuse_reset_request(req
);
289 req
->pages
[req
->num_pages
] = page
;
294 static int fuse_readpages(struct file
*file
, struct address_space
*mapping
,
295 struct list_head
*pages
, unsigned nr_pages
)
297 struct inode
*inode
= mapping
->host
;
298 struct fuse_conn
*fc
= get_fuse_conn(inode
);
299 struct fuse_readpages_data data
;
303 data
.req
= fuse_get_request_nonint(fc
);
307 err
= read_cache_pages(mapping
, pages
, fuse_readpages_fill
, &data
);
308 if (!err
&& data
.req
->num_pages
)
309 err
= fuse_send_readpages(data
.req
, file
, inode
);
310 fuse_put_request(fc
, data
.req
);
314 static size_t fuse_send_write(struct fuse_req
*req
, struct file
*file
,
315 struct inode
*inode
, loff_t pos
, size_t count
)
317 struct fuse_conn
*fc
= get_fuse_conn(inode
);
318 struct fuse_file
*ff
= file
->private_data
;
319 struct fuse_write_in inarg
;
320 struct fuse_write_out outarg
;
322 memset(&inarg
, 0, sizeof(struct fuse_write_in
));
326 req
->in
.h
.opcode
= FUSE_WRITE
;
327 req
->in
.h
.nodeid
= get_node_id(inode
);
330 req
->in
.argpages
= 1;
332 req
->in
.args
[0].size
= sizeof(struct fuse_write_in
);
333 req
->in
.args
[0].value
= &inarg
;
334 req
->in
.args
[1].size
= count
;
335 req
->out
.numargs
= 1;
336 req
->out
.args
[0].size
= sizeof(struct fuse_write_out
);
337 req
->out
.args
[0].value
= &outarg
;
338 request_send_nonint(fc
, req
);
342 static int fuse_prepare_write(struct file
*file
, struct page
*page
,
343 unsigned offset
, unsigned to
)
349 static int fuse_commit_write(struct file
*file
, struct page
*page
,
350 unsigned offset
, unsigned to
)
354 unsigned count
= to
- offset
;
355 struct inode
*inode
= page
->mapping
->host
;
356 struct fuse_conn
*fc
= get_fuse_conn(inode
);
357 loff_t pos
= ((loff_t
) page
->index
<< PAGE_CACHE_SHIFT
) + offset
;
358 struct fuse_req
*req
= fuse_get_request_nonint(fc
);
363 req
->pages
[0] = page
;
364 req
->page_offset
= offset
;
365 nres
= fuse_send_write(req
, file
, inode
, pos
, count
);
366 err
= req
->out
.h
.error
;
367 fuse_put_request(fc
, req
);
368 if (!err
&& nres
!= count
)
372 if (pos
> i_size_read(inode
))
373 i_size_write(inode
, pos
);
375 if (offset
== 0 && to
== PAGE_CACHE_SIZE
) {
376 clear_page_dirty(page
);
377 SetPageUptodate(page
);
379 } else if (err
== -EINTR
|| err
== -EIO
)
380 fuse_invalidate_attr(inode
);
384 static void fuse_release_user_pages(struct fuse_req
*req
, int write
)
388 for (i
= 0; i
< req
->num_pages
; i
++) {
389 struct page
*page
= req
->pages
[i
];
391 set_page_dirty_lock(page
);
396 static int fuse_get_user_pages(struct fuse_req
*req
, const char __user
*buf
,
397 unsigned nbytes
, int write
)
399 unsigned long user_addr
= (unsigned long) buf
;
400 unsigned offset
= user_addr
& ~PAGE_MASK
;
403 /* This doesn't work with nfsd */
407 nbytes
= min(nbytes
, (unsigned) FUSE_MAX_PAGES_PER_REQ
<< PAGE_SHIFT
);
408 npages
= (nbytes
+ offset
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
;
409 npages
= min(npages
, FUSE_MAX_PAGES_PER_REQ
);
410 down_read(¤t
->mm
->mmap_sem
);
411 npages
= get_user_pages(current
, current
->mm
, user_addr
, npages
, write
,
412 0, req
->pages
, NULL
);
413 up_read(¤t
->mm
->mmap_sem
);
417 req
->num_pages
= npages
;
418 req
->page_offset
= offset
;
422 static ssize_t
fuse_direct_io(struct file
*file
, const char __user
*buf
,
423 size_t count
, loff_t
*ppos
, int write
)
425 struct inode
*inode
= file
->f_dentry
->d_inode
;
426 struct fuse_conn
*fc
= get_fuse_conn(inode
);
427 size_t nmax
= write
? fc
->max_write
: fc
->max_read
;
430 struct fuse_req
*req
= fuse_get_request(fc
);
437 size_t nbytes
= min(count
, nmax
);
438 int err
= fuse_get_user_pages(req
, buf
, nbytes
, !write
);
443 tmp
= (req
->num_pages
<< PAGE_SHIFT
) - req
->page_offset
;
444 nbytes
= min(nbytes
, tmp
);
446 nres
= fuse_send_write(req
, file
, inode
, pos
, nbytes
);
448 nres
= fuse_send_read(req
, file
, inode
, pos
, nbytes
);
449 fuse_release_user_pages(req
, !write
);
450 if (req
->out
.h
.error
) {
452 res
= req
->out
.h
.error
;
454 } else if (nres
> nbytes
) {
465 fuse_reset_request(req
);
467 fuse_put_request(fc
, req
);
469 if (write
&& pos
> i_size_read(inode
))
470 i_size_write(inode
, pos
);
472 } else if (write
&& (res
== -EINTR
|| res
== -EIO
))
473 fuse_invalidate_attr(inode
);
478 static ssize_t
fuse_direct_read(struct file
*file
, char __user
*buf
,
479 size_t count
, loff_t
*ppos
)
481 return fuse_direct_io(file
, buf
, count
, ppos
, 0);
484 static ssize_t
fuse_direct_write(struct file
*file
, const char __user
*buf
,
485 size_t count
, loff_t
*ppos
)
487 struct inode
*inode
= file
->f_dentry
->d_inode
;
489 /* Don't allow parallel writes to the same file */
491 res
= fuse_direct_io(file
, buf
, count
, ppos
, 1);
496 static int fuse_file_mmap(struct file
*file
, struct vm_area_struct
*vma
)
498 if ((vma
->vm_flags
& VM_SHARED
)) {
499 if ((vma
->vm_flags
& VM_WRITE
))
502 vma
->vm_flags
&= ~VM_MAYWRITE
;
504 return generic_file_mmap(file
, vma
);
507 static int fuse_set_page_dirty(struct page
*page
)
509 printk("fuse_set_page_dirty: should not happen\n");
514 static struct file_operations fuse_file_operations
= {
515 .llseek
= generic_file_llseek
,
516 .read
= generic_file_read
,
517 .write
= generic_file_write
,
518 .mmap
= fuse_file_mmap
,
521 .release
= fuse_release
,
523 .sendfile
= generic_file_sendfile
,
526 static struct file_operations fuse_direct_io_file_operations
= {
527 .llseek
= generic_file_llseek
,
528 .read
= fuse_direct_read
,
529 .write
= fuse_direct_write
,
532 .release
= fuse_release
,
534 /* no mmap and sendfile */
537 static struct address_space_operations fuse_file_aops
= {
538 .readpage
= fuse_readpage
,
539 .prepare_write
= fuse_prepare_write
,
540 .commit_write
= fuse_commit_write
,
541 .readpages
= fuse_readpages
,
542 .set_page_dirty
= fuse_set_page_dirty
,
545 void fuse_init_file_inode(struct inode
*inode
)
547 struct fuse_conn
*fc
= get_fuse_conn(inode
);
549 if (fc
->flags
& FUSE_DIRECT_IO
)
550 inode
->i_fop
= &fuse_direct_io_file_operations
;
552 inode
->i_fop
= &fuse_file_operations
;
553 inode
->i_data
.a_ops
= &fuse_file_aops
;