1 // SPDX-License-Identifier: MIT
3 * VirtualBox Guest Shared Folders support: Utility functions.
4 * Mainly conversion from/to VirtualBox/Linux data structures.
6 * Copyright (C) 2006-2018 Oracle Corporation
9 #include <linux/namei.h>
10 #include <linux/nls.h>
11 #include <linux/sizes.h>
12 #include <linux/vfs.h>
15 struct inode
*vboxsf_new_inode(struct super_block
*sb
)
17 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(sb
);
23 inode
= new_inode(sb
);
25 return ERR_PTR(-ENOMEM
);
27 idr_preload(GFP_KERNEL
);
28 spin_lock_irqsave(&sbi
->ino_idr_lock
, flags
);
29 cursor
= idr_get_cursor(&sbi
->ino_idr
);
30 ret
= idr_alloc_cyclic(&sbi
->ino_idr
, inode
, 1, 0, GFP_ATOMIC
);
31 if (ret
>= 0 && ret
< cursor
)
32 sbi
->next_generation
++;
33 gen
= sbi
->next_generation
;
34 spin_unlock_irqrestore(&sbi
->ino_idr_lock
, flags
);
43 inode
->i_generation
= gen
;
47 /* set [inode] attributes based on [info], uid/gid based on [sbi] */
48 int vboxsf_init_inode(struct vboxsf_sbi
*sbi
, struct inode
*inode
,
49 const struct shfl_fsobjinfo
*info
, bool reinit
)
51 const struct shfl_fsobjattr
*attr
;
57 #define mode_set(r) ((attr->mode & (SHFL_UNIX_##r)) ? (S_##r) : 0)
59 mode
= mode_set(IRUSR
);
60 mode
|= mode_set(IWUSR
);
61 mode
|= mode_set(IXUSR
);
63 mode
|= mode_set(IRGRP
);
64 mode
|= mode_set(IWGRP
);
65 mode
|= mode_set(IXGRP
);
67 mode
|= mode_set(IROTH
);
68 mode
|= mode_set(IWOTH
);
69 mode
|= mode_set(IXOTH
);
73 /* We use the host-side values for these */
74 inode
->i_flags
|= S_NOATIME
| S_NOCMTIME
;
75 inode
->i_mapping
->a_ops
= &vboxsf_reg_aops
;
77 if (SHFL_IS_DIRECTORY(attr
->mode
)) {
80 mode
&= ~sbi
->o
.dmask
;
83 inode
->i_op
= &vboxsf_dir_iops
;
84 inode
->i_fop
= &vboxsf_dir_fops
;
86 * XXX: this probably should be set to the number of entries
87 * in the directory plus two (. ..)
90 } else if (!S_ISDIR(inode
->i_mode
))
93 } else if (SHFL_IS_SYMLINK(attr
->mode
)) {
96 mode
&= ~sbi
->o
.fmask
;
99 inode
->i_op
= &vboxsf_lnk_iops
;
101 } else if (!S_ISLNK(inode
->i_mode
))
103 inode
->i_mode
= mode
;
105 if (sbi
->o
.fmode_set
)
107 mode
&= ~sbi
->o
.fmask
;
110 inode
->i_op
= &vboxsf_reg_iops
;
111 inode
->i_fop
= &vboxsf_reg_fops
;
113 } else if (!S_ISREG(inode
->i_mode
))
115 inode
->i_mode
= mode
;
118 inode
->i_uid
= sbi
->o
.uid
;
119 inode
->i_gid
= sbi
->o
.gid
;
121 inode
->i_size
= info
->size
;
122 inode
->i_blkbits
= 12;
123 /* i_blocks always in units of 512 bytes! */
124 allocated
= info
->allocated
+ 511;
125 do_div(allocated
, 512);
126 inode
->i_blocks
= allocated
;
128 inode
->i_atime
= ns_to_timespec64(
129 info
->access_time
.ns_relative_to_unix_epoch
);
130 inode
->i_ctime
= ns_to_timespec64(
131 info
->change_time
.ns_relative_to_unix_epoch
);
132 inode
->i_mtime
= ns_to_timespec64(
133 info
->modification_time
.ns_relative_to_unix_epoch
);
137 int vboxsf_create_at_dentry(struct dentry
*dentry
,
138 struct shfl_createparms
*params
)
140 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
141 struct shfl_string
*path
;
144 path
= vboxsf_path_from_dentry(sbi
, dentry
);
146 return PTR_ERR(path
);
148 err
= vboxsf_create(sbi
->root
, path
, params
);
154 int vboxsf_stat(struct vboxsf_sbi
*sbi
, struct shfl_string
*path
,
155 struct shfl_fsobjinfo
*info
)
157 struct shfl_createparms params
= {};
160 params
.handle
= SHFL_HANDLE_NIL
;
161 params
.create_flags
= SHFL_CF_LOOKUP
| SHFL_CF_ACT_FAIL_IF_NEW
;
163 err
= vboxsf_create(sbi
->root
, path
, ¶ms
);
167 if (params
.result
!= SHFL_FILE_EXISTS
)
176 int vboxsf_stat_dentry(struct dentry
*dentry
, struct shfl_fsobjinfo
*info
)
178 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
179 struct shfl_string
*path
;
182 path
= vboxsf_path_from_dentry(sbi
, dentry
);
184 return PTR_ERR(path
);
186 err
= vboxsf_stat(sbi
, path
, info
);
191 int vboxsf_inode_revalidate(struct dentry
*dentry
)
193 struct vboxsf_sbi
*sbi
;
194 struct vboxsf_inode
*sf_i
;
195 struct shfl_fsobjinfo info
;
196 struct timespec64 prev_mtime
;
200 if (!dentry
|| !d_really_is_positive(dentry
))
203 inode
= d_inode(dentry
);
204 prev_mtime
= inode
->i_mtime
;
205 sf_i
= VBOXSF_I(inode
);
206 sbi
= VBOXSF_SBI(dentry
->d_sb
);
207 if (!sf_i
->force_restat
) {
208 if (time_before(jiffies
, dentry
->d_time
+ sbi
->o
.ttl
))
212 err
= vboxsf_stat_dentry(dentry
, &info
);
216 dentry
->d_time
= jiffies
;
217 sf_i
->force_restat
= 0;
218 err
= vboxsf_init_inode(sbi
, inode
, &info
, true);
223 * If the file was changed on the host side we need to invalidate the
224 * page-cache for it. Note this also gets triggered by our own writes,
225 * this is unavoidable.
227 if (timespec64_compare(&inode
->i_mtime
, &prev_mtime
) > 0)
228 invalidate_inode_pages2(inode
->i_mapping
);
233 int vboxsf_getattr(struct user_namespace
*mnt_userns
, const struct path
*path
,
234 struct kstat
*kstat
, u32 request_mask
, unsigned int flags
)
237 struct dentry
*dentry
= path
->dentry
;
238 struct inode
*inode
= d_inode(dentry
);
239 struct vboxsf_inode
*sf_i
= VBOXSF_I(inode
);
241 switch (flags
& AT_STATX_SYNC_TYPE
) {
242 case AT_STATX_DONT_SYNC
:
245 case AT_STATX_FORCE_SYNC
:
246 sf_i
->force_restat
= 1;
249 err
= vboxsf_inode_revalidate(dentry
);
254 generic_fillattr(&init_user_ns
, d_inode(dentry
), kstat
);
258 int vboxsf_setattr(struct user_namespace
*mnt_userns
, struct dentry
*dentry
,
261 struct vboxsf_inode
*sf_i
= VBOXSF_I(d_inode(dentry
));
262 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
263 struct shfl_createparms params
= {};
264 struct shfl_fsobjinfo info
= {};
268 params
.handle
= SHFL_HANDLE_NIL
;
269 params
.create_flags
= SHFL_CF_ACT_OPEN_IF_EXISTS
|
270 SHFL_CF_ACT_FAIL_IF_NEW
|
271 SHFL_CF_ACCESS_ATTR_WRITE
;
273 /* this is at least required for Posix hosts */
274 if (iattr
->ia_valid
& ATTR_SIZE
)
275 params
.create_flags
|= SHFL_CF_ACCESS_WRITE
;
277 err
= vboxsf_create_at_dentry(dentry
, ¶ms
);
278 if (err
|| params
.result
!= SHFL_FILE_EXISTS
)
279 return err
? err
: -ENOENT
;
281 #define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0)
284 * Setting the file size and setting the other attributes has to
285 * be handled separately.
287 if (iattr
->ia_valid
& (ATTR_MODE
| ATTR_ATIME
| ATTR_MTIME
)) {
288 if (iattr
->ia_valid
& ATTR_MODE
) {
289 info
.attr
.mode
= mode_set(IRUSR
);
290 info
.attr
.mode
|= mode_set(IWUSR
);
291 info
.attr
.mode
|= mode_set(IXUSR
);
292 info
.attr
.mode
|= mode_set(IRGRP
);
293 info
.attr
.mode
|= mode_set(IWGRP
);
294 info
.attr
.mode
|= mode_set(IXGRP
);
295 info
.attr
.mode
|= mode_set(IROTH
);
296 info
.attr
.mode
|= mode_set(IWOTH
);
297 info
.attr
.mode
|= mode_set(IXOTH
);
299 if (iattr
->ia_mode
& S_IFDIR
)
300 info
.attr
.mode
|= SHFL_TYPE_DIRECTORY
;
302 info
.attr
.mode
|= SHFL_TYPE_FILE
;
305 if (iattr
->ia_valid
& ATTR_ATIME
)
306 info
.access_time
.ns_relative_to_unix_epoch
=
307 timespec64_to_ns(&iattr
->ia_atime
);
309 if (iattr
->ia_valid
& ATTR_MTIME
)
310 info
.modification_time
.ns_relative_to_unix_epoch
=
311 timespec64_to_ns(&iattr
->ia_mtime
);
314 * Ignore ctime (inode change time) as it can't be set
315 * from userland anyway.
318 buf_len
= sizeof(info
);
319 err
= vboxsf_fsinfo(sbi
->root
, params
.handle
,
320 SHFL_INFO_SET
| SHFL_INFO_FILE
, &buf_len
,
323 vboxsf_close(sbi
->root
, params
.handle
);
327 /* the host may have given us different attr then requested */
328 sf_i
->force_restat
= 1;
333 if (iattr
->ia_valid
& ATTR_SIZE
) {
334 memset(&info
, 0, sizeof(info
));
335 info
.size
= iattr
->ia_size
;
336 buf_len
= sizeof(info
);
337 err
= vboxsf_fsinfo(sbi
->root
, params
.handle
,
338 SHFL_INFO_SET
| SHFL_INFO_SIZE
, &buf_len
,
341 vboxsf_close(sbi
->root
, params
.handle
);
345 /* the host may have given us different attr then requested */
346 sf_i
->force_restat
= 1;
349 vboxsf_close(sbi
->root
, params
.handle
);
351 /* Update the inode with what the host has actually given us. */
352 if (sf_i
->force_restat
)
353 vboxsf_inode_revalidate(dentry
);
359 * [dentry] contains string encoded in coding system that corresponds
360 * to [sbi]->nls, we must convert it to UTF8 here.
361 * Returns a shfl_string allocated through __getname (must be freed using
362 * __putname), or an ERR_PTR on error.
364 struct shfl_string
*vboxsf_path_from_dentry(struct vboxsf_sbi
*sbi
,
365 struct dentry
*dentry
)
367 struct shfl_string
*shfl_path
;
368 int path_len
, out_len
, nb
;
375 return ERR_PTR(-ENOMEM
);
377 path
= dentry_path_raw(dentry
, buf
, PATH_MAX
);
380 return ERR_CAST(path
);
382 path_len
= strlen(path
);
385 shfl_path
= __getname();
388 return ERR_PTR(-ENOMEM
);
391 out
= shfl_path
->string
.utf8
;
392 out_len
= PATH_MAX
- SHFLSTRING_HEADER_SIZE
- 1;
395 nb
= sbi
->nls
->char2uni(path
, path_len
, &uni
);
397 __putname(shfl_path
);
399 return ERR_PTR(-EINVAL
);
404 nb
= utf32_to_utf8(uni
, out
, out_len
);
406 __putname(shfl_path
);
408 return ERR_PTR(-ENAMETOOLONG
);
414 shfl_path
->length
= out
- shfl_path
->string
.utf8
;
415 shfl_path
->size
= shfl_path
->length
+ 1;
418 if ((SHFLSTRING_HEADER_SIZE
+ path_len
+ 1) > PATH_MAX
) {
420 return ERR_PTR(-ENAMETOOLONG
);
423 * dentry_path stores the name at the end of buf, but the
424 * shfl_string string we return must be properly aligned.
426 shfl_path
= (struct shfl_string
*)buf
;
427 memmove(shfl_path
->string
.utf8
, path
, path_len
);
428 shfl_path
->string
.utf8
[path_len
] = 0;
429 shfl_path
->length
= path_len
;
430 shfl_path
->size
= path_len
+ 1;
436 int vboxsf_nlscpy(struct vboxsf_sbi
*sbi
, char *name
, size_t name_bound_len
,
437 const unsigned char *utf8_name
, size_t utf8_len
)
442 size_t out_bound_len
;
446 in_bound_len
= utf8_len
;
450 /* Reserve space for terminating 0 */
451 out_bound_len
= name_bound_len
- 1;
453 while (in_bound_len
) {
457 nb
= utf8_to_utf32(in
, in_bound_len
, &uni
);
464 nb
= sbi
->nls
->uni2char(uni
, out
, out_bound_len
);
478 static struct vboxsf_dir_buf
*vboxsf_dir_buf_alloc(struct list_head
*list
)
480 struct vboxsf_dir_buf
*b
;
482 b
= kmalloc(sizeof(*b
), GFP_KERNEL
);
486 b
->buf
= kmalloc(DIR_BUFFER_SIZE
, GFP_KERNEL
);
494 b
->free
= DIR_BUFFER_SIZE
;
495 list_add(&b
->head
, list
);
500 static void vboxsf_dir_buf_free(struct vboxsf_dir_buf
*b
)
507 struct vboxsf_dir_info
*vboxsf_dir_info_alloc(void)
509 struct vboxsf_dir_info
*p
;
511 p
= kmalloc(sizeof(*p
), GFP_KERNEL
);
515 INIT_LIST_HEAD(&p
->info_list
);
519 void vboxsf_dir_info_free(struct vboxsf_dir_info
*p
)
521 struct list_head
*list
, *pos
, *tmp
;
523 list
= &p
->info_list
;
524 list_for_each_safe(pos
, tmp
, list
) {
525 struct vboxsf_dir_buf
*b
;
527 b
= list_entry(pos
, struct vboxsf_dir_buf
, head
);
528 vboxsf_dir_buf_free(b
);
533 int vboxsf_dir_read_all(struct vboxsf_sbi
*sbi
, struct vboxsf_dir_info
*sf_d
,
536 struct vboxsf_dir_buf
*b
;
541 /* vboxsf_dirinfo returns 1 on end of dir */
543 b
= vboxsf_dir_buf_alloc(&sf_d
->info_list
);
552 err
= vboxsf_dirinfo(sbi
->root
, handle
, NULL
, 0, 0,
553 &size
, buf
, &entries
);
557 b
->entries
+= entries
;
562 if (b
&& b
->used
== 0)
563 vboxsf_dir_buf_free(b
);
565 /* -EILSEQ means the host could not translate a filename, ignore */
566 if (err
> 0 || err
== -EILSEQ
)