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
;
25 /* Restarting the syscall is not allowed if O_CREAT and O_EXCL
26 are both set, because creation will fail on the restart */
27 int excl
= (file
->f_flags
& (O_CREAT
|O_EXCL
)) == (O_CREAT
|O_EXCL
);
29 err
= generic_file_open(inode
, file
);
33 /* If opening the root node, no lookup has been performed on
34 it, so the attributes must be refreshed */
35 if (get_node_id(inode
) == FUSE_ROOT_ID
) {
36 int err
= fuse_do_getattr(inode
);
42 req
= fuse_get_request_nonint(fc
);
44 req
= fuse_get_request(fc
);
46 return excl
? -EINTR
: -ERESTARTSYS
;
49 ff
= kmalloc(sizeof(struct fuse_file
), GFP_KERNEL
);
53 ff
->release_req
= fuse_request_alloc();
54 if (!ff
->release_req
) {
59 memset(&inarg
, 0, sizeof(inarg
));
60 inarg
.flags
= file
->f_flags
& ~(O_CREAT
| O_EXCL
| O_NOCTTY
| O_TRUNC
);
61 req
->in
.h
.opcode
= isdir
? FUSE_OPENDIR
: FUSE_OPEN
;
62 req
->in
.h
.nodeid
= get_node_id(inode
);
65 req
->in
.args
[0].size
= sizeof(inarg
);
66 req
->in
.args
[0].value
= &inarg
;
68 req
->out
.args
[0].size
= sizeof(outarg
);
69 req
->out
.args
[0].value
= &outarg
;
71 request_send_nonint(fc
, req
);
73 request_send(fc
, req
);
74 err
= req
->out
.h
.error
;
76 fuse_request_free(ff
->release_req
);
79 if (!isdir
&& (outarg
.open_flags
& FOPEN_DIRECT_IO
))
80 file
->f_op
= &fuse_direct_io_file_operations
;
81 if (!(outarg
.open_flags
& FOPEN_KEEP_CACHE
))
82 invalidate_inode_pages(inode
->i_mapping
);
84 file
->private_data
= ff
;
88 fuse_put_request(fc
, req
);
92 int fuse_release_common(struct inode
*inode
, struct file
*file
, int isdir
)
94 struct fuse_conn
*fc
= get_fuse_conn(inode
);
95 struct fuse_file
*ff
= file
->private_data
;
96 struct fuse_req
*req
= ff
->release_req
;
97 struct fuse_release_in
*inarg
= &req
->misc
.release_in
;
100 inarg
->flags
= file
->f_flags
& ~O_EXCL
;
101 req
->in
.h
.opcode
= isdir
? FUSE_RELEASEDIR
: FUSE_RELEASE
;
102 req
->in
.h
.nodeid
= get_node_id(inode
);
105 req
->in
.args
[0].size
= sizeof(struct fuse_release_in
);
106 req
->in
.args
[0].value
= inarg
;
107 request_send_background(fc
, req
);
110 /* Return value is ignored by VFS */
114 static int fuse_open(struct inode
*inode
, struct file
*file
)
116 return fuse_open_common(inode
, file
, 0);
119 static int fuse_release(struct inode
*inode
, struct file
*file
)
121 return fuse_release_common(inode
, file
, 0);
124 static int fuse_flush(struct file
*file
)
126 struct inode
*inode
= file
->f_dentry
->d_inode
;
127 struct fuse_conn
*fc
= get_fuse_conn(inode
);
128 struct fuse_file
*ff
= file
->private_data
;
129 struct fuse_req
*req
;
130 struct fuse_flush_in inarg
;
136 req
= fuse_get_request_nonint(fc
);
140 memset(&inarg
, 0, sizeof(inarg
));
142 req
->in
.h
.opcode
= FUSE_FLUSH
;
143 req
->in
.h
.nodeid
= get_node_id(inode
);
147 req
->in
.args
[0].size
= sizeof(inarg
);
148 req
->in
.args
[0].value
= &inarg
;
149 request_send_nonint(fc
, req
);
150 err
= req
->out
.h
.error
;
151 fuse_put_request(fc
, req
);
152 if (err
== -ENOSYS
) {
159 static int fuse_fsync(struct file
*file
, struct dentry
*de
, int datasync
)
161 struct inode
*inode
= de
->d_inode
;
162 struct fuse_conn
*fc
= get_fuse_conn(inode
);
163 struct fuse_file
*ff
= file
->private_data
;
164 struct fuse_req
*req
;
165 struct fuse_fsync_in inarg
;
171 req
= fuse_get_request(fc
);
175 memset(&inarg
, 0, sizeof(inarg
));
177 inarg
.fsync_flags
= datasync
? 1 : 0;
178 req
->in
.h
.opcode
= FUSE_FSYNC
;
179 req
->in
.h
.nodeid
= get_node_id(inode
);
183 req
->in
.args
[0].size
= sizeof(inarg
);
184 req
->in
.args
[0].value
= &inarg
;
185 request_send(fc
, req
);
186 err
= req
->out
.h
.error
;
187 fuse_put_request(fc
, req
);
188 if (err
== -ENOSYS
) {
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_nonint(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_nonint(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
);
252 static int fuse_send_readpages(struct fuse_req
*req
, struct file
*file
,
255 loff_t pos
= (loff_t
) req
->pages
[0]->index
<< PAGE_CACHE_SHIFT
;
256 size_t count
= req
->num_pages
<< PAGE_CACHE_SHIFT
;
258 req
->out
.page_zeroing
= 1;
259 fuse_send_read(req
, file
, inode
, pos
, count
);
260 for (i
= 0; i
< req
->num_pages
; i
++) {
261 struct page
*page
= req
->pages
[i
];
262 if (!req
->out
.h
.error
)
263 SetPageUptodate(page
);
266 return req
->out
.h
.error
;
269 struct fuse_readpages_data
{
270 struct fuse_req
*req
;
275 static int fuse_readpages_fill(void *_data
, struct page
*page
)
277 struct fuse_readpages_data
*data
= _data
;
278 struct fuse_req
*req
= data
->req
;
279 struct inode
*inode
= data
->inode
;
280 struct fuse_conn
*fc
= get_fuse_conn(inode
);
282 if (req
->num_pages
&&
283 (req
->num_pages
== FUSE_MAX_PAGES_PER_REQ
||
284 (req
->num_pages
+ 1) * PAGE_CACHE_SIZE
> fc
->max_read
||
285 req
->pages
[req
->num_pages
- 1]->index
+ 1 != page
->index
)) {
286 int err
= fuse_send_readpages(req
, data
->file
, inode
);
291 fuse_reset_request(req
);
293 req
->pages
[req
->num_pages
] = page
;
298 static int fuse_readpages(struct file
*file
, struct address_space
*mapping
,
299 struct list_head
*pages
, unsigned nr_pages
)
301 struct inode
*inode
= mapping
->host
;
302 struct fuse_conn
*fc
= get_fuse_conn(inode
);
303 struct fuse_readpages_data data
;
307 data
.req
= fuse_get_request_nonint(fc
);
311 err
= read_cache_pages(mapping
, pages
, fuse_readpages_fill
, &data
);
312 if (!err
&& data
.req
->num_pages
)
313 err
= fuse_send_readpages(data
.req
, file
, inode
);
314 fuse_put_request(fc
, data
.req
);
318 static size_t fuse_send_write(struct fuse_req
*req
, struct file
*file
,
319 struct inode
*inode
, loff_t pos
, size_t count
)
321 struct fuse_conn
*fc
= get_fuse_conn(inode
);
322 struct fuse_file
*ff
= file
->private_data
;
323 struct fuse_write_in inarg
;
324 struct fuse_write_out outarg
;
326 memset(&inarg
, 0, sizeof(struct fuse_write_in
));
330 req
->in
.h
.opcode
= FUSE_WRITE
;
331 req
->in
.h
.nodeid
= get_node_id(inode
);
334 req
->in
.argpages
= 1;
336 req
->in
.args
[0].size
= sizeof(struct fuse_write_in
);
337 req
->in
.args
[0].value
= &inarg
;
338 req
->in
.args
[1].size
= count
;
339 req
->out
.numargs
= 1;
340 req
->out
.args
[0].size
= sizeof(struct fuse_write_out
);
341 req
->out
.args
[0].value
= &outarg
;
342 request_send_nonint(fc
, req
);
346 static int fuse_prepare_write(struct file
*file
, struct page
*page
,
347 unsigned offset
, unsigned to
)
353 static int fuse_commit_write(struct file
*file
, struct page
*page
,
354 unsigned offset
, unsigned to
)
358 unsigned count
= to
- offset
;
359 struct inode
*inode
= page
->mapping
->host
;
360 struct fuse_conn
*fc
= get_fuse_conn(inode
);
361 loff_t pos
= ((loff_t
) page
->index
<< PAGE_CACHE_SHIFT
) + offset
;
362 struct fuse_req
*req
= fuse_get_request_nonint(fc
);
367 req
->pages
[0] = page
;
368 req
->page_offset
= offset
;
369 nres
= fuse_send_write(req
, file
, inode
, pos
, count
);
370 err
= req
->out
.h
.error
;
371 fuse_put_request(fc
, req
);
372 if (!err
&& nres
!= count
)
376 if (pos
> i_size_read(inode
))
377 i_size_write(inode
, pos
);
379 if (offset
== 0 && to
== PAGE_CACHE_SIZE
) {
380 clear_page_dirty(page
);
381 SetPageUptodate(page
);
383 } else if (err
== -EINTR
|| err
== -EIO
)
384 fuse_invalidate_attr(inode
);
388 static void fuse_release_user_pages(struct fuse_req
*req
, int write
)
392 for (i
= 0; i
< req
->num_pages
; i
++) {
393 struct page
*page
= req
->pages
[i
];
395 set_page_dirty_lock(page
);
400 static int fuse_get_user_pages(struct fuse_req
*req
, const char __user
*buf
,
401 unsigned nbytes
, int write
)
403 unsigned long user_addr
= (unsigned long) buf
;
404 unsigned offset
= user_addr
& ~PAGE_MASK
;
407 /* This doesn't work with nfsd */
411 nbytes
= min(nbytes
, (unsigned) FUSE_MAX_PAGES_PER_REQ
<< PAGE_SHIFT
);
412 npages
= (nbytes
+ offset
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
;
413 npages
= min(npages
, FUSE_MAX_PAGES_PER_REQ
);
414 down_read(¤t
->mm
->mmap_sem
);
415 npages
= get_user_pages(current
, current
->mm
, user_addr
, npages
, write
,
416 0, req
->pages
, NULL
);
417 up_read(¤t
->mm
->mmap_sem
);
421 req
->num_pages
= npages
;
422 req
->page_offset
= offset
;
426 static ssize_t
fuse_direct_io(struct file
*file
, const char __user
*buf
,
427 size_t count
, loff_t
*ppos
, int write
)
429 struct inode
*inode
= file
->f_dentry
->d_inode
;
430 struct fuse_conn
*fc
= get_fuse_conn(inode
);
431 size_t nmax
= write
? fc
->max_write
: fc
->max_read
;
434 struct fuse_req
*req
= fuse_get_request(fc
);
441 size_t nbytes
= min(count
, nmax
);
442 int err
= fuse_get_user_pages(req
, buf
, nbytes
, !write
);
447 tmp
= (req
->num_pages
<< PAGE_SHIFT
) - req
->page_offset
;
448 nbytes
= min(nbytes
, tmp
);
450 nres
= fuse_send_write(req
, file
, inode
, pos
, nbytes
);
452 nres
= fuse_send_read(req
, file
, inode
, pos
, nbytes
);
453 fuse_release_user_pages(req
, !write
);
454 if (req
->out
.h
.error
) {
456 res
= req
->out
.h
.error
;
458 } else if (nres
> nbytes
) {
469 fuse_reset_request(req
);
471 fuse_put_request(fc
, req
);
473 if (write
&& pos
> i_size_read(inode
))
474 i_size_write(inode
, pos
);
476 } else if (write
&& (res
== -EINTR
|| res
== -EIO
))
477 fuse_invalidate_attr(inode
);
482 static ssize_t
fuse_direct_read(struct file
*file
, char __user
*buf
,
483 size_t count
, loff_t
*ppos
)
485 return fuse_direct_io(file
, buf
, count
, ppos
, 0);
488 static ssize_t
fuse_direct_write(struct file
*file
, const char __user
*buf
,
489 size_t count
, loff_t
*ppos
)
491 struct inode
*inode
= file
->f_dentry
->d_inode
;
493 /* Don't allow parallel writes to the same file */
495 res
= fuse_direct_io(file
, buf
, count
, ppos
, 1);
500 static int fuse_file_mmap(struct file
*file
, struct vm_area_struct
*vma
)
502 if ((vma
->vm_flags
& VM_SHARED
)) {
503 if ((vma
->vm_flags
& VM_WRITE
))
506 vma
->vm_flags
&= ~VM_MAYWRITE
;
508 return generic_file_mmap(file
, vma
);
511 static int fuse_set_page_dirty(struct page
*page
)
513 printk("fuse_set_page_dirty: should not happen\n");
518 static struct file_operations fuse_file_operations
= {
519 .llseek
= generic_file_llseek
,
520 .read
= generic_file_read
,
521 .write
= generic_file_write
,
522 .mmap
= fuse_file_mmap
,
525 .release
= fuse_release
,
527 .sendfile
= generic_file_sendfile
,
530 static struct file_operations fuse_direct_io_file_operations
= {
531 .llseek
= generic_file_llseek
,
532 .read
= fuse_direct_read
,
533 .write
= fuse_direct_write
,
536 .release
= fuse_release
,
538 /* no mmap and sendfile */
541 static struct address_space_operations fuse_file_aops
= {
542 .readpage
= fuse_readpage
,
543 .prepare_write
= fuse_prepare_write
,
544 .commit_write
= fuse_commit_write
,
545 .readpages
= fuse_readpages
,
546 .set_page_dirty
= fuse_set_page_dirty
,
549 void fuse_init_file_inode(struct inode
*inode
)
551 inode
->i_fop
= &fuse_file_operations
;
552 inode
->i_data
.a_ops
= &fuse_file_aops
;