1 | // SPDX-License-Identifier: MIT |
2 | /* |
3 | * VirtualBox Guest Shared Folders support: Regular file inode and file ops. |
4 | * |
5 | * Copyright (C) 2006-2018 Oracle Corporation |
6 | */ |
7 | |
8 | #include <linux/mm.h> |
9 | #include <linux/page-flags.h> |
10 | #include <linux/pagemap.h> |
11 | #include <linux/highmem.h> |
12 | #include <linux/sizes.h> |
13 | #include "vfsmod.h" |
14 | |
15 | struct vboxsf_handle { |
16 | u64 handle; |
17 | u32 root; |
18 | u32 access_flags; |
19 | struct kref refcount; |
20 | struct list_head head; |
21 | }; |
22 | |
23 | struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode, |
24 | u64 handle, u32 access_flags) |
25 | { |
26 | struct vboxsf_inode *sf_i = VBOXSF_I(inode); |
27 | struct vboxsf_handle *sf_handle; |
28 | |
29 | sf_handle = kmalloc(size: sizeof(*sf_handle), GFP_KERNEL); |
30 | if (!sf_handle) |
31 | return ERR_PTR(error: -ENOMEM); |
32 | |
33 | /* the host may have given us different attr then requested */ |
34 | sf_i->force_restat = 1; |
35 | |
36 | /* init our handle struct and add it to the inode's handles list */ |
37 | sf_handle->handle = handle; |
38 | sf_handle->root = VBOXSF_SBI(inode->i_sb)->root; |
39 | sf_handle->access_flags = access_flags; |
40 | kref_init(kref: &sf_handle->refcount); |
41 | |
42 | mutex_lock(&sf_i->handle_list_mutex); |
43 | list_add(new: &sf_handle->head, head: &sf_i->handle_list); |
44 | mutex_unlock(lock: &sf_i->handle_list_mutex); |
45 | |
46 | return sf_handle; |
47 | } |
48 | |
49 | static int vboxsf_file_open(struct inode *inode, struct file *file) |
50 | { |
51 | struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb); |
52 | struct shfl_createparms params = {}; |
53 | struct vboxsf_handle *sf_handle; |
54 | u32 access_flags = 0; |
55 | int err; |
56 | |
57 | /* |
58 | * We check the value of params.handle afterwards to find out if |
59 | * the call succeeded or failed, as the API does not seem to cleanly |
60 | * distinguish error and informational messages. |
61 | * |
62 | * Furthermore, we must set params.handle to SHFL_HANDLE_NIL to |
63 | * make the shared folders host service use our mode parameter. |
64 | */ |
65 | params.handle = SHFL_HANDLE_NIL; |
66 | if (file->f_flags & O_CREAT) { |
67 | params.create_flags |= SHFL_CF_ACT_CREATE_IF_NEW; |
68 | /* |
69 | * We ignore O_EXCL, as the Linux kernel seems to call create |
70 | * beforehand itself, so O_EXCL should always fail. |
71 | */ |
72 | if (file->f_flags & O_TRUNC) |
73 | params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS; |
74 | else |
75 | params.create_flags |= SHFL_CF_ACT_OPEN_IF_EXISTS; |
76 | } else { |
77 | params.create_flags |= SHFL_CF_ACT_FAIL_IF_NEW; |
78 | if (file->f_flags & O_TRUNC) |
79 | params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS; |
80 | } |
81 | |
82 | switch (file->f_flags & O_ACCMODE) { |
83 | case O_RDONLY: |
84 | access_flags |= SHFL_CF_ACCESS_READ; |
85 | break; |
86 | |
87 | case O_WRONLY: |
88 | access_flags |= SHFL_CF_ACCESS_WRITE; |
89 | break; |
90 | |
91 | case O_RDWR: |
92 | access_flags |= SHFL_CF_ACCESS_READWRITE; |
93 | break; |
94 | |
95 | default: |
96 | WARN_ON(1); |
97 | } |
98 | |
99 | if (file->f_flags & O_APPEND) |
100 | access_flags |= SHFL_CF_ACCESS_APPEND; |
101 | |
102 | params.create_flags |= access_flags; |
103 | params.info.attr.mode = inode->i_mode; |
104 | |
105 | err = vboxsf_create_at_dentry(dentry: file_dentry(file), params: ¶ms); |
106 | if (err == 0 && params.handle == SHFL_HANDLE_NIL) |
107 | err = (params.result == SHFL_FILE_EXISTS) ? -EEXIST : -ENOENT; |
108 | if (err) |
109 | return err; |
110 | |
111 | sf_handle = vboxsf_create_sf_handle(inode, handle: params.handle, access_flags); |
112 | if (IS_ERR(ptr: sf_handle)) { |
113 | vboxsf_close(root: sbi->root, handle: params.handle); |
114 | return PTR_ERR(ptr: sf_handle); |
115 | } |
116 | |
117 | file->private_data = sf_handle; |
118 | return 0; |
119 | } |
120 | |
121 | static void vboxsf_handle_release(struct kref *refcount) |
122 | { |
123 | struct vboxsf_handle *sf_handle = |
124 | container_of(refcount, struct vboxsf_handle, refcount); |
125 | |
126 | vboxsf_close(root: sf_handle->root, handle: sf_handle->handle); |
127 | kfree(objp: sf_handle); |
128 | } |
129 | |
130 | void vboxsf_release_sf_handle(struct inode *inode, struct vboxsf_handle *sf_handle) |
131 | { |
132 | struct vboxsf_inode *sf_i = VBOXSF_I(inode); |
133 | |
134 | mutex_lock(&sf_i->handle_list_mutex); |
135 | list_del(entry: &sf_handle->head); |
136 | mutex_unlock(lock: &sf_i->handle_list_mutex); |
137 | |
138 | kref_put(kref: &sf_handle->refcount, release: vboxsf_handle_release); |
139 | } |
140 | |
141 | static int vboxsf_file_release(struct inode *inode, struct file *file) |
142 | { |
143 | /* |
144 | * When a file is closed on our (the guest) side, we want any subsequent |
145 | * accesses done on the host side to see all changes done from our side. |
146 | */ |
147 | filemap_write_and_wait(mapping: inode->i_mapping); |
148 | |
149 | vboxsf_release_sf_handle(inode, sf_handle: file->private_data); |
150 | return 0; |
151 | } |
152 | |
153 | /* |
154 | * Write back dirty pages now, because there may not be any suitable |
155 | * open files later |
156 | */ |
157 | static void vboxsf_vma_close(struct vm_area_struct *vma) |
158 | { |
159 | filemap_write_and_wait(mapping: vma->vm_file->f_mapping); |
160 | } |
161 | |
162 | static const struct vm_operations_struct vboxsf_file_vm_ops = { |
163 | .close = vboxsf_vma_close, |
164 | .fault = filemap_fault, |
165 | .map_pages = filemap_map_pages, |
166 | }; |
167 | |
168 | static int vboxsf_file_mmap(struct file *file, struct vm_area_struct *vma) |
169 | { |
170 | int err; |
171 | |
172 | err = generic_file_mmap(file, vma); |
173 | if (!err) |
174 | vma->vm_ops = &vboxsf_file_vm_ops; |
175 | |
176 | return err; |
177 | } |
178 | |
179 | /* |
180 | * Note that since we are accessing files on the host's filesystem, files |
181 | * may always be changed underneath us by the host! |
182 | * |
183 | * The vboxsf API between the guest and the host does not offer any functions |
184 | * to deal with this. There is no inode-generation to check for changes, no |
185 | * events / callback on changes and no way to lock files. |
186 | * |
187 | * To avoid returning stale data when a file gets *opened* on our (the guest) |
188 | * side, we do a "stat" on the host side, then compare the mtime with the |
189 | * last known mtime and invalidate the page-cache if they differ. |
190 | * This is done from vboxsf_inode_revalidate(). |
191 | * |
192 | * When reads are done through the read_iter fop, it is possible to do |
193 | * further cache revalidation then, there are 3 options to deal with this: |
194 | * |
195 | * 1) Rely solely on the revalidation done at open time |
196 | * 2) Do another "stat" and compare mtime again. Unfortunately the vboxsf |
197 | * host API does not allow stat on handles, so we would need to use |
198 | * file->f_path.dentry and the stat will then fail if the file was unlinked |
199 | * or renamed (and there is no thing like NFS' silly-rename). So we get: |
200 | * 2a) "stat" and compare mtime, on stat failure invalidate the cache |
201 | * 2b) "stat" and compare mtime, on stat failure do nothing |
202 | * 3) Simply always call invalidate_inode_pages2_range on the range of the read |
203 | * |
204 | * Currently we are keeping things KISS and using option 1. this allows |
205 | * directly using generic_file_read_iter without wrapping it. |
206 | * |
207 | * This means that only data written on the host side before open() on |
208 | * the guest side is guaranteed to be seen by the guest. If necessary |
209 | * we may provide other read-cache strategies in the future and make this |
210 | * configurable through a mount option. |
211 | */ |
212 | const struct file_operations vboxsf_reg_fops = { |
213 | .llseek = generic_file_llseek, |
214 | .read_iter = generic_file_read_iter, |
215 | .write_iter = generic_file_write_iter, |
216 | .mmap = vboxsf_file_mmap, |
217 | .open = vboxsf_file_open, |
218 | .release = vboxsf_file_release, |
219 | .fsync = noop_fsync, |
220 | .splice_read = filemap_splice_read, |
221 | .setlease = simple_nosetlease, |
222 | }; |
223 | |
224 | const struct inode_operations vboxsf_reg_iops = { |
225 | .getattr = vboxsf_getattr, |
226 | .setattr = vboxsf_setattr |
227 | }; |
228 | |
229 | static int vboxsf_read_folio(struct file *file, struct folio *folio) |
230 | { |
231 | struct page *page = &folio->page; |
232 | struct vboxsf_handle *sf_handle = file->private_data; |
233 | loff_t off = page_offset(page); |
234 | u32 nread = PAGE_SIZE; |
235 | u8 *buf; |
236 | int err; |
237 | |
238 | buf = kmap(page); |
239 | |
240 | err = vboxsf_read(root: sf_handle->root, handle: sf_handle->handle, offset: off, buf_len: &nread, buf); |
241 | if (err == 0) { |
242 | memset(&buf[nread], 0, PAGE_SIZE - nread); |
243 | flush_dcache_page(page); |
244 | SetPageUptodate(page); |
245 | } else { |
246 | SetPageError(page); |
247 | } |
248 | |
249 | kunmap(page); |
250 | unlock_page(page); |
251 | return err; |
252 | } |
253 | |
254 | static struct vboxsf_handle *vboxsf_get_write_handle(struct vboxsf_inode *sf_i) |
255 | { |
256 | struct vboxsf_handle *h, *sf_handle = NULL; |
257 | |
258 | mutex_lock(&sf_i->handle_list_mutex); |
259 | list_for_each_entry(h, &sf_i->handle_list, head) { |
260 | if (h->access_flags == SHFL_CF_ACCESS_WRITE || |
261 | h->access_flags == SHFL_CF_ACCESS_READWRITE) { |
262 | kref_get(kref: &h->refcount); |
263 | sf_handle = h; |
264 | break; |
265 | } |
266 | } |
267 | mutex_unlock(lock: &sf_i->handle_list_mutex); |
268 | |
269 | return sf_handle; |
270 | } |
271 | |
272 | static int vboxsf_writepage(struct page *page, struct writeback_control *wbc) |
273 | { |
274 | struct inode *inode = page->mapping->host; |
275 | struct vboxsf_inode *sf_i = VBOXSF_I(inode); |
276 | struct vboxsf_handle *sf_handle; |
277 | loff_t off = page_offset(page); |
278 | loff_t size = i_size_read(inode); |
279 | u32 nwrite = PAGE_SIZE; |
280 | u8 *buf; |
281 | int err; |
282 | |
283 | if (off + PAGE_SIZE > size) |
284 | nwrite = size & ~PAGE_MASK; |
285 | |
286 | sf_handle = vboxsf_get_write_handle(sf_i); |
287 | if (!sf_handle) |
288 | return -EBADF; |
289 | |
290 | buf = kmap(page); |
291 | err = vboxsf_write(root: sf_handle->root, handle: sf_handle->handle, |
292 | offset: off, buf_len: &nwrite, buf); |
293 | kunmap(page); |
294 | |
295 | kref_put(kref: &sf_handle->refcount, release: vboxsf_handle_release); |
296 | |
297 | if (err == 0) { |
298 | ClearPageError(page); |
299 | /* mtime changed */ |
300 | sf_i->force_restat = 1; |
301 | } else { |
302 | ClearPageUptodate(page); |
303 | } |
304 | |
305 | unlock_page(page); |
306 | return err; |
307 | } |
308 | |
309 | static int vboxsf_write_end(struct file *file, struct address_space *mapping, |
310 | loff_t pos, unsigned int len, unsigned int copied, |
311 | struct page *page, void *fsdata) |
312 | { |
313 | struct inode *inode = mapping->host; |
314 | struct vboxsf_handle *sf_handle = file->private_data; |
315 | unsigned int from = pos & ~PAGE_MASK; |
316 | u32 nwritten = len; |
317 | u8 *buf; |
318 | int err; |
319 | |
320 | /* zero the stale part of the page if we did a short copy */ |
321 | if (!PageUptodate(page) && copied < len) |
322 | zero_user(page, start: from + copied, size: len - copied); |
323 | |
324 | buf = kmap(page); |
325 | err = vboxsf_write(root: sf_handle->root, handle: sf_handle->handle, |
326 | offset: pos, buf_len: &nwritten, buf: buf + from); |
327 | kunmap(page); |
328 | |
329 | if (err) { |
330 | nwritten = 0; |
331 | goto out; |
332 | } |
333 | |
334 | /* mtime changed */ |
335 | VBOXSF_I(inode)->force_restat = 1; |
336 | |
337 | if (!PageUptodate(page) && nwritten == PAGE_SIZE) |
338 | SetPageUptodate(page); |
339 | |
340 | pos += nwritten; |
341 | if (pos > inode->i_size) |
342 | i_size_write(inode, i_size: pos); |
343 | |
344 | out: |
345 | unlock_page(page); |
346 | put_page(page); |
347 | |
348 | return nwritten; |
349 | } |
350 | |
351 | /* |
352 | * Note simple_write_begin does not read the page from disk on partial writes |
353 | * this is ok since vboxsf_write_end only writes the written parts of the |
354 | * page and it does not call SetPageUptodate for partial writes. |
355 | */ |
356 | const struct address_space_operations vboxsf_reg_aops = { |
357 | .read_folio = vboxsf_read_folio, |
358 | .writepage = vboxsf_writepage, |
359 | .dirty_folio = filemap_dirty_folio, |
360 | .write_begin = simple_write_begin, |
361 | .write_end = vboxsf_write_end, |
362 | }; |
363 | |
364 | static const char *vboxsf_get_link(struct dentry *dentry, struct inode *inode, |
365 | struct delayed_call *done) |
366 | { |
367 | struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb); |
368 | struct shfl_string *path; |
369 | char *link; |
370 | int err; |
371 | |
372 | if (!dentry) |
373 | return ERR_PTR(error: -ECHILD); |
374 | |
375 | path = vboxsf_path_from_dentry(sbi, dentry); |
376 | if (IS_ERR(ptr: path)) |
377 | return ERR_CAST(ptr: path); |
378 | |
379 | link = kzalloc(PATH_MAX, GFP_KERNEL); |
380 | if (!link) { |
381 | __putname(path); |
382 | return ERR_PTR(error: -ENOMEM); |
383 | } |
384 | |
385 | err = vboxsf_readlink(root: sbi->root, parsed_path: path, PATH_MAX, buf: link); |
386 | __putname(path); |
387 | if (err) { |
388 | kfree(objp: link); |
389 | return ERR_PTR(error: err); |
390 | } |
391 | |
392 | set_delayed_call(call: done, fn: kfree_link, arg: link); |
393 | return link; |
394 | } |
395 | |
396 | const struct inode_operations vboxsf_lnk_iops = { |
397 | .get_link = vboxsf_get_link |
398 | }; |
399 | |