3 * vboxsf - VBox Linux Shared Folders, Regular file inode and file operations.
7 * Copyright (C) 2006-2016 Oracle Corporation
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 * Limitations: only COW memory mapping is supported
24 static void *alloc_bounce_buffer(size_t *tmp_sizep
, PRTCCPHYS physp
, size_t
25 xfer_size
, const char *caller
)
30 /* try for big first. */
31 tmp_size
= RT_ALIGN_Z(xfer_size
, PAGE_SIZE
);
32 if (tmp_size
> 16U*_1K
)
34 tmp
= kmalloc(tmp_size
, GFP_KERNEL
);
37 /* fall back on a page sized buffer. */
38 tmp
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
41 LogRel(("%s: could not allocate bounce buffer for xfer_size=%zu %s\n", caller
, xfer_size
));
47 *tmp_sizep
= tmp_size
;
48 *physp
= virt_to_phys(tmp
);
52 static void free_bounce_buffer(void *tmp
)
59 static int sf_reg_read_aux(const char *caller
, struct sf_glob_info
*sf_g
,
60 struct sf_reg_info
*sf_r
, void *buf
,
61 uint32_t *nread
, uint64_t pos
)
63 /** @todo bird: yes, kmap() and kmalloc() input only. Since the buffer is
64 * contiguous in physical memory (kmalloc or single page), we should
65 * use a physical address here to speed things up. */
66 int rc
= VbglR0SfRead(&client_handle
, &sf_g
->map
, sf_r
->handle
,
67 pos
, nread
, buf
, false /* already locked? */);
70 LogFunc(("VbglR0SfRead failed. caller=%s, rc=%Rrc\n", caller
, rc
));
76 static int sf_reg_write_aux(const char *caller
, struct sf_glob_info
*sf_g
,
77 struct sf_reg_info
*sf_r
, void *buf
,
78 uint32_t *nwritten
, uint64_t pos
)
80 /** @todo bird: yes, kmap() and kmalloc() input only. Since the buffer is
81 * contiguous in physical memory (kmalloc or single page), we should
82 * use a physical address here to speed things up. */
83 int rc
= VbglR0SfWrite(&client_handle
, &sf_g
->map
, sf_r
->handle
,
84 pos
, nwritten
, buf
, false /* already locked? */);
87 LogFunc(("VbglR0SfWrite failed. caller=%s, rc=%Rrc\n",
95 * Read from a regular file.
97 * @param file the file
98 * @param buf the buffer
99 * @param size length of the buffer
100 * @param off offset within the file
101 * @returns the number of read bytes on success, Linux error code otherwise
103 static ssize_t
sf_reg_read(struct file
*file
, char *buf
, size_t size
, loff_t
*off
)
110 ssize_t total_bytes_read
= 0;
111 struct inode
*inode
= GET_F_DENTRY(file
)->d_inode
;
112 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
113 struct sf_reg_info
*sf_r
= file
->private_data
;
117 if (!S_ISREG(inode
->i_mode
))
119 LogFunc(("read from non regular file %d\n", inode
->i_mode
));
123 /** XXX Check read permission according to inode->i_mode! */
128 tmp
= alloc_bounce_buffer(&tmp_size
, &tmp_phys
, size
, __PRETTY_FUNCTION__
);
134 uint32_t to_read
, nread
;
138 to_read
= (uint32_t) left
;
142 err
= sf_reg_read_aux(__func__
, sf_g
, sf_r
, tmp
, &nread
, pos
);
146 if (copy_to_user(buf
, tmp
, nread
))
155 total_bytes_read
+= nread
;
156 if (nread
!= to_read
)
160 *off
+= total_bytes_read
;
161 free_bounce_buffer(tmp
);
162 return total_bytes_read
;
165 free_bounce_buffer(tmp
);
170 * Write to a regular file.
172 * @param file the file
173 * @param buf the buffer
174 * @param size length of the buffer
175 * @param off offset within the file
176 * @returns the number of written bytes on success, Linux error code otherwise
178 static ssize_t
sf_reg_write(struct file
*file
, const char *buf
, size_t size
, loff_t
*off
)
185 ssize_t total_bytes_written
= 0;
186 struct inode
*inode
= GET_F_DENTRY(file
)->d_inode
;
187 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
188 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
189 struct sf_reg_info
*sf_r
= file
->private_data
;
197 if (!S_ISREG(inode
->i_mode
))
199 LogFunc(("write to non regular file %d\n", inode
->i_mode
));
204 if (file
->f_flags
& O_APPEND
)
210 /** XXX Check write permission according to inode->i_mode! */
215 tmp
= alloc_bounce_buffer(&tmp_size
, &tmp_phys
, size
, __PRETTY_FUNCTION__
);
221 uint32_t to_write
, nwritten
;
225 to_write
= (uint32_t) left
;
229 if (copy_from_user(tmp
, buf
, to_write
))
235 err
= VbglR0SfWritePhysCont(&client_handle
, &sf_g
->map
, sf_r
->handle
,
236 pos
, &nwritten
, tmp_phys
);
243 total_bytes_written
+= nwritten
;
244 if (nwritten
!= to_write
)
248 *off
+= total_bytes_written
;
249 if (*off
> inode
->i_size
)
250 inode
->i_size
= *off
;
252 sf_i
->force_restat
= 1;
253 free_bounce_buffer(tmp
);
254 return total_bytes_written
;
257 free_bounce_buffer(tmp
);
262 * Open a regular file.
264 * @param inode the inode
265 * @param file the file
266 * @returns 0 on success, Linux error code otherwise
268 static int sf_reg_open(struct inode
*inode
, struct file
*file
)
270 int rc
, rc_linux
= 0;
271 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
272 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
273 struct sf_reg_info
*sf_r
;
274 SHFLCREATEPARMS params
;
280 LogFunc(("open %s\n", sf_i
->path
->String
.utf8
));
282 sf_r
= kmalloc(sizeof(*sf_r
), GFP_KERNEL
);
285 LogRelFunc(("could not allocate reg info\n"));
290 if (sf_i
->handle
!= SHFL_HANDLE_NIL
)
293 * This inode was created with sf_create_aux(). Check the CreateFlags:
294 * O_CREAT, O_TRUNC: inherent true (file was just created). Not sure
295 * about the access flags (SHFL_CF_ACCESS_*).
297 sf_i
->force_restat
= 1;
298 sf_r
->handle
= sf_i
->handle
;
299 sf_i
->handle
= SHFL_HANDLE_NIL
;
301 file
->private_data
= sf_r
;
306 params
.Handle
= SHFL_HANDLE_NIL
;
307 /* We check the value of params.Handle afterwards to find out if
308 * the call succeeded or failed, as the API does not seem to cleanly
309 * distinguish error and informational messages.
311 * Furthermore, we must set params.Handle to SHFL_HANDLE_NIL to
312 * make the shared folders host service use our fMode parameter */
314 if (file
->f_flags
& O_CREAT
)
316 LogFunc(("O_CREAT set\n"));
317 params
.CreateFlags
|= SHFL_CF_ACT_CREATE_IF_NEW
;
318 /* We ignore O_EXCL, as the Linux kernel seems to call create
319 beforehand itself, so O_EXCL should always fail. */
320 if (file
->f_flags
& O_TRUNC
)
322 LogFunc(("O_TRUNC set\n"));
323 params
.CreateFlags
|= SHFL_CF_ACT_OVERWRITE_IF_EXISTS
;
326 params
.CreateFlags
|= SHFL_CF_ACT_OPEN_IF_EXISTS
;
330 params
.CreateFlags
|= SHFL_CF_ACT_FAIL_IF_NEW
;
331 if (file
->f_flags
& O_TRUNC
)
333 LogFunc(("O_TRUNC set\n"));
334 params
.CreateFlags
|= SHFL_CF_ACT_OVERWRITE_IF_EXISTS
;
338 switch (file
->f_flags
& O_ACCMODE
)
341 params
.CreateFlags
|= SHFL_CF_ACCESS_READ
;
345 params
.CreateFlags
|= SHFL_CF_ACCESS_WRITE
;
349 params
.CreateFlags
|= SHFL_CF_ACCESS_READWRITE
;
356 if (file
->f_flags
& O_APPEND
)
358 LogFunc(("O_APPEND set\n"));
359 params
.CreateFlags
|= SHFL_CF_ACCESS_APPEND
;
362 params
.Info
.Attr
.fMode
= inode
->i_mode
;
363 LogFunc(("sf_reg_open: calling VbglR0SfCreate, file %s, flags=%#x, %#x\n",
364 sf_i
->path
->String
.utf8
, file
->f_flags
, params
.CreateFlags
));
365 rc
= VbglR0SfCreate(&client_handle
, &sf_g
->map
, sf_i
->path
, ¶ms
);
368 LogFunc(("VbglR0SfCreate failed flags=%d,%#x rc=%Rrc\n",
369 file
->f_flags
, params
.CreateFlags
, rc
));
371 return -RTErrConvertToErrno(rc
);
374 if (SHFL_HANDLE_NIL
== params
.Handle
)
376 switch (params
.Result
)
378 case SHFL_PATH_NOT_FOUND
:
379 case SHFL_FILE_NOT_FOUND
:
382 case SHFL_FILE_EXISTS
:
390 sf_i
->force_restat
= 1;
391 sf_r
->handle
= params
.Handle
;
393 file
->private_data
= sf_r
;
398 * Close a regular file.
400 * @param inode the inode
401 * @param file the file
402 * @returns 0 on success, Linux error code otherwise
404 static int sf_reg_release(struct inode
*inode
, struct file
*file
)
407 struct sf_reg_info
*sf_r
;
408 struct sf_glob_info
*sf_g
;
409 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
412 sf_g
= GET_GLOB_INFO(inode
->i_sb
);
413 sf_r
= file
->private_data
;
418 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
419 /* See the smbfs source (file.c). mmap in particular can cause data to be
420 * written to the file after it is closed, which we can't cope with. We
421 * copy and paste the body of filemap_write_and_wait() here as it was not
422 * defined before 2.6.6 and not exported until quite a bit later. */
423 /* filemap_write_and_wait(inode->i_mapping); */
424 if ( inode
->i_mapping
->nrpages
425 && filemap_fdatawrite(inode
->i_mapping
) != -EIO
)
426 filemap_fdatawait(inode
->i_mapping
);
428 rc
= VbglR0SfClose(&client_handle
, &sf_g
->map
, sf_r
->handle
);
430 LogFunc(("VbglR0SfClose failed rc=%Rrc\n", rc
));
434 sf_i
->handle
= SHFL_HANDLE_NIL
;
435 file
->private_data
= NULL
;
439 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
440 static int sf_reg_fault(struct vm_fault
*vmf
)
441 #elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
442 static int sf_reg_fault(struct vm_area_struct
*vma
, struct vm_fault
*vmf
)
443 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
444 static struct page
*sf_reg_nopage(struct vm_area_struct
*vma
, unsigned long vaddr
, int *type
)
445 # define SET_TYPE(t) *type = (t)
446 #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */
447 static struct page
*sf_reg_nopage(struct vm_area_struct
*vma
, unsigned long vaddr
, int unused
)
454 uint32_t nread
= PAGE_SIZE
;
456 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
457 struct vm_area_struct
*vma
= vmf
->vma
;
459 struct file
*file
= vma
->vm_file
;
460 struct inode
*inode
= GET_F_DENTRY(file
)->d_inode
;
461 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
462 struct sf_reg_info
*sf_r
= file
->private_data
;
465 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
466 if (vmf
->pgoff
> vma
->vm_end
)
467 return VM_FAULT_SIGBUS
;
469 if (vaddr
> vma
->vm_end
)
471 SET_TYPE(VM_FAULT_SIGBUS
);
472 return NOPAGE_SIGBUS
;
476 /* Don't use GFP_HIGHUSER as long as sf_reg_read_aux() calls VbglR0SfRead()
477 * which works on virtual addresses. On Linux cannot reliably determine the
478 * physical address for high memory, see rtR0MemObjNativeLockKernel(). */
479 page
= alloc_page(GFP_USER
);
481 LogRelFunc(("failed to allocate page\n"));
482 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
485 SET_TYPE(VM_FAULT_OOM
);
491 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
492 off
= (vmf
->pgoff
<< PAGE_SHIFT
);
494 off
= (vaddr
- vma
->vm_start
) + (vma
->vm_pgoff
<< PAGE_SHIFT
);
496 err
= sf_reg_read_aux(__func__
, sf_g
, sf_r
, buf
, &nread
, off
);
501 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
502 return VM_FAULT_SIGBUS
;
504 SET_TYPE(VM_FAULT_SIGBUS
);
505 return NOPAGE_SIGBUS
;
509 BUG_ON (nread
> PAGE_SIZE
);
512 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
513 clear_user_page(page_address(page
), vmf
->pgoff
, page
);
514 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
515 clear_user_page(page_address(page
), vaddr
, page
);
517 clear_user_page(page_address(page
), vaddr
);
521 memset(buf
+ nread
, 0, PAGE_SIZE
- nread
);
523 flush_dcache_page(page
);
525 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
529 SET_TYPE(VM_FAULT_MAJOR
);
534 static struct vm_operations_struct sf_vma_ops
=
536 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
537 .fault
= sf_reg_fault
539 .nopage
= sf_reg_nopage
543 static int sf_reg_mmap(struct file
*file
, struct vm_area_struct
*vma
)
546 if (vma
->vm_flags
& VM_SHARED
)
548 LogFunc(("shared mmapping not available\n"));
552 vma
->vm_ops
= &sf_vma_ops
;
556 struct file_operations sf_reg_fops
=
560 .write
= sf_reg_write
,
561 .release
= sf_reg_release
,
563 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
564 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
565 .splice_read
= generic_file_splice_read
,
567 .sendfile
= generic_file_sendfile
,
569 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
570 .read_iter
= generic_file_read_iter
,
571 .write_iter
= generic_file_write_iter
,
573 .aio_read
= generic_file_aio_read
,
574 .aio_write
= generic_file_aio_write
,
576 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
579 .fsync
= simple_sync_file
,
581 .llseek
= generic_file_llseek
,
586 struct inode_operations sf_reg_iops
=
588 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
589 .revalidate
= sf_inode_revalidate
591 .getattr
= sf_getattr
,
592 .setattr
= sf_setattr
597 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
598 static int sf_readpage(struct file
*file
, struct page
*page
)
600 struct inode
*inode
= GET_F_DENTRY(file
)->d_inode
;
601 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
602 struct sf_reg_info
*sf_r
= file
->private_data
;
603 uint32_t nread
= PAGE_SIZE
;
605 loff_t off
= ((loff_t
)page
->index
) << PAGE_SHIFT
;
611 ret
= sf_reg_read_aux(__func__
, sf_g
, sf_r
, buf
, &nread
, off
);
615 if (PageLocked(page
))
619 BUG_ON(nread
> PAGE_SIZE
);
620 memset(&buf
[nread
], 0, PAGE_SIZE
- nread
);
621 flush_dcache_page(page
);
623 SetPageUptodate(page
);
629 sf_writepage(struct page
*page
, struct writeback_control
*wbc
)
631 struct address_space
*mapping
= page
->mapping
;
632 struct inode
*inode
= mapping
->host
;
633 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
634 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
635 struct file
*file
= sf_i
->file
;
636 struct sf_reg_info
*sf_r
= file
->private_data
;
638 uint32_t nwritten
= PAGE_SIZE
;
639 int end_index
= inode
->i_size
>> PAGE_SHIFT
;
640 loff_t off
= ((loff_t
) page
->index
) << PAGE_SHIFT
;
645 if (page
->index
>= end_index
)
646 nwritten
= inode
->i_size
& (PAGE_SIZE
-1);
650 err
= sf_reg_write_aux(__func__
, sf_g
, sf_r
, buf
, &nwritten
, off
);
653 ClearPageUptodate(page
);
657 if (off
> inode
->i_size
)
661 ClearPageError(page
);
671 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
672 int sf_write_begin(struct file
*file
, struct address_space
*mapping
, loff_t pos
,
673 unsigned len
, unsigned flags
, struct page
**pagep
, void **fsdata
)
677 return simple_write_begin(file
, mapping
, pos
, len
, flags
, pagep
, fsdata
);
680 int sf_write_end(struct file
*file
, struct address_space
*mapping
, loff_t pos
,
681 unsigned len
, unsigned copied
, struct page
*page
, void *fsdata
)
683 struct inode
*inode
= mapping
->host
;
684 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
685 struct sf_reg_info
*sf_r
= file
->private_data
;
687 unsigned from
= pos
& (PAGE_SIZE
- 1);
688 uint32_t nwritten
= len
;
694 err
= sf_reg_write_aux(__func__
, sf_g
, sf_r
, buf
+from
, &nwritten
, pos
);
697 if (!PageUptodate(page
) && err
== PAGE_SIZE
)
698 SetPageUptodate(page
);
702 if (pos
> inode
->i_size
)
707 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
710 page_cache_release(page
);
716 # endif /* KERNEL_VERSION >= 2.6.24 */
718 struct address_space_operations sf_reg_aops
=
720 .readpage
= sf_readpage
,
721 .writepage
= sf_writepage
,
722 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
723 .write_begin
= sf_write_begin
,
724 .write_end
= sf_write_end
,
726 .prepare_write
= simple_prepare_write
,
727 .commit_write
= simple_commit_write
,