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
))
236 if (VbglR0CanUsePhysPageList())
238 err
= VbglR0SfWritePhysCont(&client_handle
, &sf_g
->map
, sf_r
->handle
,
239 pos
, &nwritten
, tmp_phys
);
240 err
= RT_FAILURE(err
) ? -EPROTO
: 0;
244 err
= sf_reg_write_aux(__func__
, sf_g
, sf_r
, tmp
, &nwritten
, pos
);
251 total_bytes_written
+= nwritten
;
252 if (nwritten
!= to_write
)
256 *off
+= total_bytes_written
;
257 if (*off
> inode
->i_size
)
258 inode
->i_size
= *off
;
260 sf_i
->force_restat
= 1;
261 free_bounce_buffer(tmp
);
262 return total_bytes_written
;
265 free_bounce_buffer(tmp
);
270 * Open a regular file.
272 * @param inode the inode
273 * @param file the file
274 * @returns 0 on success, Linux error code otherwise
276 static int sf_reg_open(struct inode
*inode
, struct file
*file
)
278 int rc
, rc_linux
= 0;
279 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
280 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
281 struct sf_reg_info
*sf_r
;
282 SHFLCREATEPARMS params
;
288 LogFunc(("open %s\n", sf_i
->path
->String
.utf8
));
290 sf_r
= kmalloc(sizeof(*sf_r
), GFP_KERNEL
);
293 LogRelFunc(("could not allocate reg info\n"));
298 if (sf_i
->handle
!= SHFL_HANDLE_NIL
)
301 * This inode was created with sf_create_aux(). Check the CreateFlags:
302 * O_CREAT, O_TRUNC: inherent true (file was just created). Not sure
303 * about the access flags (SHFL_CF_ACCESS_*).
305 sf_i
->force_restat
= 1;
306 sf_r
->handle
= sf_i
->handle
;
307 sf_i
->handle
= SHFL_HANDLE_NIL
;
309 file
->private_data
= sf_r
;
314 params
.Handle
= SHFL_HANDLE_NIL
;
315 /* We check the value of params.Handle afterwards to find out if
316 * the call succeeded or failed, as the API does not seem to cleanly
317 * distinguish error and informational messages.
319 * Furthermore, we must set params.Handle to SHFL_HANDLE_NIL to
320 * make the shared folders host service use our fMode parameter */
322 if (file
->f_flags
& O_CREAT
)
324 LogFunc(("O_CREAT set\n"));
325 params
.CreateFlags
|= SHFL_CF_ACT_CREATE_IF_NEW
;
326 /* We ignore O_EXCL, as the Linux kernel seems to call create
327 beforehand itself, so O_EXCL should always fail. */
328 if (file
->f_flags
& O_TRUNC
)
330 LogFunc(("O_TRUNC set\n"));
331 params
.CreateFlags
|= ( SHFL_CF_ACT_OVERWRITE_IF_EXISTS
332 | SHFL_CF_ACCESS_WRITE
);
335 params
.CreateFlags
|= SHFL_CF_ACT_OPEN_IF_EXISTS
;
339 params
.CreateFlags
|= SHFL_CF_ACT_FAIL_IF_NEW
;
340 if (file
->f_flags
& O_TRUNC
)
342 LogFunc(("O_TRUNC set\n"));
343 params
.CreateFlags
|= ( SHFL_CF_ACT_OVERWRITE_IF_EXISTS
344 | SHFL_CF_ACCESS_WRITE
);
348 if (!(params
.CreateFlags
& SHFL_CF_ACCESS_READWRITE
))
350 switch (file
->f_flags
& O_ACCMODE
)
353 params
.CreateFlags
|= SHFL_CF_ACCESS_READ
;
357 params
.CreateFlags
|= SHFL_CF_ACCESS_WRITE
;
361 params
.CreateFlags
|= SHFL_CF_ACCESS_READWRITE
;
369 if (file
->f_flags
& O_APPEND
)
371 LogFunc(("O_APPEND set\n"));
372 params
.CreateFlags
|= SHFL_CF_ACCESS_APPEND
;
375 params
.Info
.Attr
.fMode
= inode
->i_mode
;
376 LogFunc(("sf_reg_open: calling VbglR0SfCreate, file %s, flags=%#x, %#x\n",
377 sf_i
->path
->String
.utf8
, file
->f_flags
, params
.CreateFlags
));
378 rc
= VbglR0SfCreate(&client_handle
, &sf_g
->map
, sf_i
->path
, ¶ms
);
381 LogFunc(("VbglR0SfCreate failed flags=%d,%#x rc=%Rrc\n",
382 file
->f_flags
, params
.CreateFlags
, rc
));
384 return -RTErrConvertToErrno(rc
);
387 if (SHFL_HANDLE_NIL
== params
.Handle
)
389 switch (params
.Result
)
391 case SHFL_PATH_NOT_FOUND
:
392 case SHFL_FILE_NOT_FOUND
:
395 case SHFL_FILE_EXISTS
:
403 sf_i
->force_restat
= 1;
404 sf_r
->handle
= params
.Handle
;
406 file
->private_data
= sf_r
;
411 * Close a regular file.
413 * @param inode the inode
414 * @param file the file
415 * @returns 0 on success, Linux error code otherwise
417 static int sf_reg_release(struct inode
*inode
, struct file
*file
)
420 struct sf_reg_info
*sf_r
;
421 struct sf_glob_info
*sf_g
;
422 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
425 sf_g
= GET_GLOB_INFO(inode
->i_sb
);
426 sf_r
= file
->private_data
;
431 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
432 /* See the smbfs source (file.c). mmap in particular can cause data to be
433 * written to the file after it is closed, which we can't cope with. We
434 * copy and paste the body of filemap_write_and_wait() here as it was not
435 * defined before 2.6.6 and not exported until quite a bit later. */
436 /* filemap_write_and_wait(inode->i_mapping); */
437 if ( inode
->i_mapping
->nrpages
438 && filemap_fdatawrite(inode
->i_mapping
) != -EIO
)
439 filemap_fdatawait(inode
->i_mapping
);
441 rc
= VbglR0SfClose(&client_handle
, &sf_g
->map
, sf_r
->handle
);
443 LogFunc(("VbglR0SfClose failed rc=%Rrc\n", rc
));
447 sf_i
->handle
= SHFL_HANDLE_NIL
;
448 file
->private_data
= NULL
;
452 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
453 static int sf_reg_fault(struct vm_area_struct
*vma
, struct vm_fault
*vmf
)
454 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
455 static struct page
*sf_reg_nopage(struct vm_area_struct
*vma
, unsigned long vaddr
, int *type
)
456 # define SET_TYPE(t) *type = (t)
457 #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */
458 static struct page
*sf_reg_nopage(struct vm_area_struct
*vma
, unsigned long vaddr
, int unused
)
465 uint32_t nread
= PAGE_SIZE
;
467 struct file
*file
= vma
->vm_file
;
468 struct inode
*inode
= GET_F_DENTRY(file
)->d_inode
;
469 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
470 struct sf_reg_info
*sf_r
= file
->private_data
;
473 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
474 if (vmf
->pgoff
> vma
->vm_end
)
475 return VM_FAULT_SIGBUS
;
477 if (vaddr
> vma
->vm_end
)
479 SET_TYPE(VM_FAULT_SIGBUS
);
480 return NOPAGE_SIGBUS
;
484 /* Don't use GFP_HIGHUSER as long as sf_reg_read_aux() calls VbglR0SfRead()
485 * which works on virtual addresses. On Linux cannot reliably determine the
486 * physical address for high memory, see rtR0MemObjNativeLockKernel(). */
487 page
= alloc_page(GFP_USER
);
489 LogRelFunc(("failed to allocate page\n"));
490 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
493 SET_TYPE(VM_FAULT_OOM
);
499 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
500 off
= (vmf
->pgoff
<< PAGE_SHIFT
);
502 off
= (vaddr
- vma
->vm_start
) + (vma
->vm_pgoff
<< PAGE_SHIFT
);
504 err
= sf_reg_read_aux(__func__
, sf_g
, sf_r
, buf
, &nread
, off
);
509 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
510 return VM_FAULT_SIGBUS
;
512 SET_TYPE(VM_FAULT_SIGBUS
);
513 return NOPAGE_SIGBUS
;
517 BUG_ON (nread
> PAGE_SIZE
);
520 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
521 clear_user_page(page_address(page
), vmf
->pgoff
, page
);
522 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
523 clear_user_page(page_address(page
), vaddr
, page
);
525 clear_user_page(page_address(page
), vaddr
);
529 memset(buf
+ nread
, 0, PAGE_SIZE
- nread
);
531 flush_dcache_page(page
);
533 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
537 SET_TYPE(VM_FAULT_MAJOR
);
542 static struct vm_operations_struct sf_vma_ops
=
544 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
545 .fault
= sf_reg_fault
547 .nopage
= sf_reg_nopage
551 static int sf_reg_mmap(struct file
*file
, struct vm_area_struct
*vma
)
554 if (vma
->vm_flags
& VM_SHARED
)
556 LogFunc(("shared mmapping not available\n"));
560 vma
->vm_ops
= &sf_vma_ops
;
564 struct file_operations sf_reg_fops
=
568 .write
= sf_reg_write
,
569 .release
= sf_reg_release
,
571 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
572 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
573 .splice_read
= generic_file_splice_read
,
575 .sendfile
= generic_file_sendfile
,
577 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
578 .read_iter
= generic_file_read_iter
,
579 .write_iter
= generic_file_write_iter
,
581 .aio_read
= generic_file_aio_read
,
582 .aio_write
= generic_file_aio_write
,
584 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
587 .fsync
= simple_sync_file
,
589 .llseek
= generic_file_llseek
,
594 struct inode_operations sf_reg_iops
=
596 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
597 .revalidate
= sf_inode_revalidate
599 .getattr
= sf_getattr
,
600 .setattr
= sf_setattr
605 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
606 static int sf_readpage(struct file
*file
, struct page
*page
)
608 struct inode
*inode
= GET_F_DENTRY(file
)->d_inode
;
609 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
610 struct sf_reg_info
*sf_r
= file
->private_data
;
611 uint32_t nread
= PAGE_SIZE
;
613 loff_t off
= ((loff_t
)page
->index
) << PAGE_SHIFT
;
619 ret
= sf_reg_read_aux(__func__
, sf_g
, sf_r
, buf
, &nread
, off
);
623 if (PageLocked(page
))
627 BUG_ON(nread
> PAGE_SIZE
);
628 memset(&buf
[nread
], 0, PAGE_SIZE
- nread
);
629 flush_dcache_page(page
);
631 SetPageUptodate(page
);
637 sf_writepage(struct page
*page
, struct writeback_control
*wbc
)
639 struct address_space
*mapping
= page
->mapping
;
640 struct inode
*inode
= mapping
->host
;
641 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
642 struct sf_inode_info
*sf_i
= GET_INODE_INFO(inode
);
643 struct file
*file
= sf_i
->file
;
644 struct sf_reg_info
*sf_r
= file
->private_data
;
646 uint32_t nwritten
= PAGE_SIZE
;
647 int end_index
= inode
->i_size
>> PAGE_SHIFT
;
648 loff_t off
= ((loff_t
) page
->index
) << PAGE_SHIFT
;
653 if (page
->index
>= end_index
)
654 nwritten
= inode
->i_size
& (PAGE_SIZE
-1);
658 err
= sf_reg_write_aux(__func__
, sf_g
, sf_r
, buf
, &nwritten
, off
);
661 ClearPageUptodate(page
);
665 if (off
> inode
->i_size
)
669 ClearPageError(page
);
679 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
680 int sf_write_begin(struct file
*file
, struct address_space
*mapping
, loff_t pos
,
681 unsigned len
, unsigned flags
, struct page
**pagep
, void **fsdata
)
685 return simple_write_begin(file
, mapping
, pos
, len
, flags
, pagep
, fsdata
);
688 int sf_write_end(struct file
*file
, struct address_space
*mapping
, loff_t pos
,
689 unsigned len
, unsigned copied
, struct page
*page
, void *fsdata
)
691 struct inode
*inode
= mapping
->host
;
692 struct sf_glob_info
*sf_g
= GET_GLOB_INFO(inode
->i_sb
);
693 struct sf_reg_info
*sf_r
= file
->private_data
;
695 unsigned from
= pos
& (PAGE_SIZE
- 1);
696 uint32_t nwritten
= len
;
702 err
= sf_reg_write_aux(__func__
, sf_g
, sf_r
, buf
+from
, &nwritten
, pos
);
705 if (!PageUptodate(page
) && err
== PAGE_SIZE
)
706 SetPageUptodate(page
);
710 if (pos
> inode
->i_size
)
715 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
718 page_cache_release(page
);
724 # endif /* KERNEL_VERSION >= 2.6.24 */
726 struct address_space_operations sf_reg_aops
=
728 .readpage
= sf_readpage
,
729 .writepage
= sf_writepage
,
730 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
731 .write_begin
= sf_write_begin
,
732 .write_end
= sf_write_end
,
734 .prepare_write
= simple_prepare_write
,
735 .commit_write
= simple_commit_write
,