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 static struct file_operations fuse_direct_io_file_operations
;
17 int fuse_open_common(struct inode
*inode
, struct file
*file
, int isdir
)
19 struct fuse_conn
*fc
= get_fuse_conn(inode
);
21 struct fuse_open_in inarg
;
22 struct fuse_open_out outarg
;
26 err
= generic_file_open(inode
, file
);
30 /* If opening the root node, no lookup has been performed on
31 it, so the attributes must be refreshed */
32 if (get_node_id(inode
) == FUSE_ROOT_ID
) {
33 int err
= fuse_do_getattr(inode
);
38 req
= fuse_get_request(fc
);
43 ff
= kmalloc(sizeof(struct fuse_file
), GFP_KERNEL
);
47 ff
->release_req
= fuse_request_alloc();
48 if (!ff
->release_req
) {
53 memset(&inarg
, 0, sizeof(inarg
));
54 inarg
.flags
= file
->f_flags
& ~(O_CREAT
| O_EXCL
| O_NOCTTY
| O_TRUNC
);
55 req
->in
.h
.opcode
= isdir
? FUSE_OPENDIR
: FUSE_OPEN
;
56 req
->in
.h
.nodeid
= get_node_id(inode
);
59 req
->in
.args
[0].size
= sizeof(inarg
);
60 req
->in
.args
[0].value
= &inarg
;
62 req
->out
.args
[0].size
= sizeof(outarg
);
63 req
->out
.args
[0].value
= &outarg
;
64 request_send(fc
, req
);
65 err
= req
->out
.h
.error
;
67 fuse_request_free(ff
->release_req
);
70 if (!isdir
&& (outarg
.open_flags
& FOPEN_DIRECT_IO
))
71 file
->f_op
= &fuse_direct_io_file_operations
;
72 if (!(outarg
.open_flags
& FOPEN_KEEP_CACHE
))
73 invalidate_inode_pages(inode
->i_mapping
);
75 file
->private_data
= ff
;
79 fuse_put_request(fc
, req
);
83 int fuse_release_common(struct inode
*inode
, struct file
*file
, int isdir
)
85 struct fuse_conn
*fc
= get_fuse_conn(inode
);
86 struct fuse_file
*ff
= file
->private_data
;
87 struct fuse_req
*req
= ff
->release_req
;
88 struct fuse_release_in
*inarg
= &req
->misc
.release_in
;
91 inarg
->flags
= file
->f_flags
& ~O_EXCL
;
92 req
->in
.h
.opcode
= isdir
? FUSE_RELEASEDIR
: FUSE_RELEASE
;
93 req
->in
.h
.nodeid
= get_node_id(inode
);
96 req
->in
.args
[0].size
= sizeof(struct fuse_release_in
);
97 req
->in
.args
[0].value
= inarg
;
98 request_send_background(fc
, req
);
101 /* Return value is ignored by VFS */
105 static int fuse_open(struct inode
*inode
, struct file
*file
)
107 return fuse_open_common(inode
, file
, 0);
110 static int fuse_release(struct inode
*inode
, struct file
*file
)
112 return fuse_release_common(inode
, file
, 0);
115 static int fuse_flush(struct file
*file
)
117 struct inode
*inode
= file
->f_dentry
->d_inode
;
118 struct fuse_conn
*fc
= get_fuse_conn(inode
);
119 struct fuse_file
*ff
= file
->private_data
;
120 struct fuse_req
*req
;
121 struct fuse_flush_in inarg
;
127 req
= fuse_get_request(fc
);
131 memset(&inarg
, 0, sizeof(inarg
));
133 req
->in
.h
.opcode
= FUSE_FLUSH
;
134 req
->in
.h
.nodeid
= get_node_id(inode
);
138 req
->in
.args
[0].size
= sizeof(inarg
);
139 req
->in
.args
[0].value
= &inarg
;
140 request_send(fc
, req
);
141 err
= req
->out
.h
.error
;
142 fuse_put_request(fc
, req
);
143 if (err
== -ENOSYS
) {
150 int fuse_fsync_common(struct file
*file
, struct dentry
*de
, int datasync
,
153 struct inode
*inode
= de
->d_inode
;
154 struct fuse_conn
*fc
= get_fuse_conn(inode
);
155 struct fuse_file
*ff
= file
->private_data
;
156 struct fuse_req
*req
;
157 struct fuse_fsync_in inarg
;
160 if ((!isdir
&& fc
->no_fsync
) || (isdir
&& fc
->no_fsyncdir
))
163 req
= fuse_get_request(fc
);
167 memset(&inarg
, 0, sizeof(inarg
));
169 inarg
.fsync_flags
= datasync
? 1 : 0;
170 req
->in
.h
.opcode
= isdir
? FUSE_FSYNCDIR
: FUSE_FSYNC
;
171 req
->in
.h
.nodeid
= get_node_id(inode
);
175 req
->in
.args
[0].size
= sizeof(inarg
);
176 req
->in
.args
[0].value
= &inarg
;
177 request_send(fc
, req
);
178 err
= req
->out
.h
.error
;
179 fuse_put_request(fc
, req
);
180 if (err
== -ENOSYS
) {
190 static int fuse_fsync(struct file
*file
, struct dentry
*de
, int datasync
)
192 return fuse_fsync_common(file
, de
, datasync
, 0);
195 size_t fuse_send_read_common(struct fuse_req
*req
, struct file
*file
,
196 struct inode
*inode
, loff_t pos
, size_t count
,
199 struct fuse_conn
*fc
= get_fuse_conn(inode
);
200 struct fuse_file
*ff
= file
->private_data
;
201 struct fuse_read_in inarg
;
203 memset(&inarg
, 0, sizeof(struct fuse_read_in
));
207 req
->in
.h
.opcode
= isdir
? FUSE_READDIR
: FUSE_READ
;
208 req
->in
.h
.nodeid
= get_node_id(inode
);
212 req
->in
.args
[0].size
= sizeof(struct fuse_read_in
);
213 req
->in
.args
[0].value
= &inarg
;
214 req
->out
.argpages
= 1;
216 req
->out
.numargs
= 1;
217 req
->out
.args
[0].size
= count
;
218 request_send(fc
, req
);
219 return req
->out
.args
[0].size
;
222 static inline size_t fuse_send_read(struct fuse_req
*req
, struct file
*file
,
223 struct inode
*inode
, loff_t pos
,
226 return fuse_send_read_common(req
, file
, inode
, pos
, count
, 0);
229 static int fuse_readpage(struct file
*file
, struct page
*page
)
231 struct inode
*inode
= page
->mapping
->host
;
232 struct fuse_conn
*fc
= get_fuse_conn(inode
);
233 loff_t pos
= (loff_t
) page
->index
<< PAGE_CACHE_SHIFT
;
234 struct fuse_req
*req
= fuse_get_request(fc
);
239 req
->out
.page_zeroing
= 1;
241 req
->pages
[0] = page
;
242 fuse_send_read(req
, file
, inode
, pos
, PAGE_CACHE_SIZE
);
243 err
= req
->out
.h
.error
;
244 fuse_put_request(fc
, req
);
246 SetPageUptodate(page
);
247 fuse_invalidate_attr(inode
); /* atime changed */
253 static int fuse_send_readpages(struct fuse_req
*req
, struct file
*file
,
256 loff_t pos
= (loff_t
) req
->pages
[0]->index
<< PAGE_CACHE_SHIFT
;
257 size_t count
= req
->num_pages
<< PAGE_CACHE_SHIFT
;
259 req
->out
.page_zeroing
= 1;
260 fuse_send_read(req
, file
, inode
, pos
, count
);
261 for (i
= 0; i
< req
->num_pages
; i
++) {
262 struct page
*page
= req
->pages
[i
];
263 if (!req
->out
.h
.error
)
264 SetPageUptodate(page
);
267 return req
->out
.h
.error
;
270 struct fuse_readpages_data
{
271 struct fuse_req
*req
;
276 static int fuse_readpages_fill(void *_data
, struct page
*page
)
278 struct fuse_readpages_data
*data
= _data
;
279 struct fuse_req
*req
= data
->req
;
280 struct inode
*inode
= data
->inode
;
281 struct fuse_conn
*fc
= get_fuse_conn(inode
);
283 if (req
->num_pages
&&
284 (req
->num_pages
== FUSE_MAX_PAGES_PER_REQ
||
285 (req
->num_pages
+ 1) * PAGE_CACHE_SIZE
> fc
->max_read
||
286 req
->pages
[req
->num_pages
- 1]->index
+ 1 != page
->index
)) {
287 int err
= fuse_send_readpages(req
, data
->file
, inode
);
292 fuse_reset_request(req
);
294 req
->pages
[req
->num_pages
] = page
;
299 static int fuse_readpages(struct file
*file
, struct address_space
*mapping
,
300 struct list_head
*pages
, unsigned nr_pages
)
302 struct inode
*inode
= mapping
->host
;
303 struct fuse_conn
*fc
= get_fuse_conn(inode
);
304 struct fuse_readpages_data data
;
308 data
.req
= fuse_get_request(fc
);
312 err
= read_cache_pages(mapping
, pages
, fuse_readpages_fill
, &data
);
313 if (!err
&& data
.req
->num_pages
)
314 err
= fuse_send_readpages(data
.req
, file
, inode
);
315 fuse_put_request(fc
, data
.req
);
316 fuse_invalidate_attr(inode
); /* atime changed */
320 static size_t fuse_send_write(struct fuse_req
*req
, struct file
*file
,
321 struct inode
*inode
, loff_t pos
, size_t count
)
323 struct fuse_conn
*fc
= get_fuse_conn(inode
);
324 struct fuse_file
*ff
= file
->private_data
;
325 struct fuse_write_in inarg
;
326 struct fuse_write_out outarg
;
328 memset(&inarg
, 0, sizeof(struct fuse_write_in
));
332 req
->in
.h
.opcode
= FUSE_WRITE
;
333 req
->in
.h
.nodeid
= get_node_id(inode
);
336 req
->in
.argpages
= 1;
338 req
->in
.args
[0].size
= sizeof(struct fuse_write_in
);
339 req
->in
.args
[0].value
= &inarg
;
340 req
->in
.args
[1].size
= count
;
341 req
->out
.numargs
= 1;
342 req
->out
.args
[0].size
= sizeof(struct fuse_write_out
);
343 req
->out
.args
[0].value
= &outarg
;
344 request_send(fc
, req
);
348 static int fuse_prepare_write(struct file
*file
, struct page
*page
,
349 unsigned offset
, unsigned to
)
355 static int fuse_commit_write(struct file
*file
, struct page
*page
,
356 unsigned offset
, unsigned to
)
360 unsigned count
= to
- offset
;
361 struct inode
*inode
= page
->mapping
->host
;
362 struct fuse_conn
*fc
= get_fuse_conn(inode
);
363 loff_t pos
= ((loff_t
) page
->index
<< PAGE_CACHE_SHIFT
) + offset
;
364 struct fuse_req
*req
= fuse_get_request(fc
);
369 req
->pages
[0] = page
;
370 req
->page_offset
= offset
;
371 nres
= fuse_send_write(req
, file
, inode
, pos
, count
);
372 err
= req
->out
.h
.error
;
373 fuse_put_request(fc
, req
);
374 if (!err
&& nres
!= count
)
378 if (pos
> i_size_read(inode
))
379 i_size_write(inode
, pos
);
381 if (offset
== 0 && to
== PAGE_CACHE_SIZE
) {
382 clear_page_dirty(page
);
383 SetPageUptodate(page
);
386 fuse_invalidate_attr(inode
);
390 static void fuse_release_user_pages(struct fuse_req
*req
, int write
)
394 for (i
= 0; i
< req
->num_pages
; i
++) {
395 struct page
*page
= req
->pages
[i
];
397 set_page_dirty_lock(page
);
402 static int fuse_get_user_pages(struct fuse_req
*req
, const char __user
*buf
,
403 unsigned nbytes
, int write
)
405 unsigned long user_addr
= (unsigned long) buf
;
406 unsigned offset
= user_addr
& ~PAGE_MASK
;
409 /* This doesn't work with nfsd */
413 nbytes
= min(nbytes
, (unsigned) FUSE_MAX_PAGES_PER_REQ
<< PAGE_SHIFT
);
414 npages
= (nbytes
+ offset
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
;
415 npages
= min(npages
, FUSE_MAX_PAGES_PER_REQ
);
416 down_read(¤t
->mm
->mmap_sem
);
417 npages
= get_user_pages(current
, current
->mm
, user_addr
, npages
, write
,
418 0, req
->pages
, NULL
);
419 up_read(¤t
->mm
->mmap_sem
);
423 req
->num_pages
= npages
;
424 req
->page_offset
= offset
;
428 static ssize_t
fuse_direct_io(struct file
*file
, const char __user
*buf
,
429 size_t count
, loff_t
*ppos
, int write
)
431 struct inode
*inode
= file
->f_dentry
->d_inode
;
432 struct fuse_conn
*fc
= get_fuse_conn(inode
);
433 size_t nmax
= write
? fc
->max_write
: fc
->max_read
;
436 struct fuse_req
*req
= fuse_get_request(fc
);
443 size_t nbytes
= min(count
, nmax
);
444 int err
= fuse_get_user_pages(req
, buf
, nbytes
, !write
);
449 tmp
= (req
->num_pages
<< PAGE_SHIFT
) - req
->page_offset
;
450 nbytes
= min(nbytes
, tmp
);
452 nres
= fuse_send_write(req
, file
, inode
, pos
, nbytes
);
454 nres
= fuse_send_read(req
, file
, inode
, pos
, nbytes
);
455 fuse_release_user_pages(req
, !write
);
456 if (req
->out
.h
.error
) {
458 res
= req
->out
.h
.error
;
460 } else if (nres
> nbytes
) {
471 fuse_reset_request(req
);
473 fuse_put_request(fc
, req
);
475 if (write
&& pos
> i_size_read(inode
))
476 i_size_write(inode
, pos
);
479 fuse_invalidate_attr(inode
);
484 static ssize_t
fuse_direct_read(struct file
*file
, char __user
*buf
,
485 size_t count
, loff_t
*ppos
)
487 return fuse_direct_io(file
, buf
, count
, ppos
, 0);
490 static ssize_t
fuse_direct_write(struct file
*file
, const char __user
*buf
,
491 size_t count
, loff_t
*ppos
)
493 struct inode
*inode
= file
->f_dentry
->d_inode
;
495 /* Don't allow parallel writes to the same file */
497 res
= fuse_direct_io(file
, buf
, count
, ppos
, 1);
502 static int fuse_file_mmap(struct file
*file
, struct vm_area_struct
*vma
)
504 if ((vma
->vm_flags
& VM_SHARED
)) {
505 if ((vma
->vm_flags
& VM_WRITE
))
508 vma
->vm_flags
&= ~VM_MAYWRITE
;
510 return generic_file_mmap(file
, vma
);
513 static int fuse_set_page_dirty(struct page
*page
)
515 printk("fuse_set_page_dirty: should not happen\n");
520 static struct file_operations fuse_file_operations
= {
521 .llseek
= generic_file_llseek
,
522 .read
= generic_file_read
,
523 .write
= generic_file_write
,
524 .mmap
= fuse_file_mmap
,
527 .release
= fuse_release
,
529 .sendfile
= generic_file_sendfile
,
532 static struct file_operations fuse_direct_io_file_operations
= {
533 .llseek
= generic_file_llseek
,
534 .read
= fuse_direct_read
,
535 .write
= fuse_direct_write
,
538 .release
= fuse_release
,
540 /* no mmap and sendfile */
543 static struct address_space_operations fuse_file_aops
= {
544 .readpage
= fuse_readpage
,
545 .prepare_write
= fuse_prepare_write
,
546 .commit_write
= fuse_commit_write
,
547 .readpages
= fuse_readpages
,
548 .set_page_dirty
= fuse_set_page_dirty
,
551 void fuse_init_file_inode(struct inode
*inode
)
553 inode
->i_fop
= &fuse_file_operations
;
554 inode
->i_data
.a_ops
= &fuse_file_aops
;