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/pagemap.h>
13 #include <linux/vfs.h>
16 struct inode
*vboxsf_new_inode(struct super_block
*sb
)
18 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(sb
);
24 inode
= new_inode(sb
);
26 return ERR_PTR(-ENOMEM
);
28 idr_preload(GFP_KERNEL
);
29 spin_lock_irqsave(&sbi
->ino_idr_lock
, flags
);
30 cursor
= idr_get_cursor(&sbi
->ino_idr
);
31 ret
= idr_alloc_cyclic(&sbi
->ino_idr
, inode
, 1, 0, GFP_ATOMIC
);
32 if (ret
>= 0 && ret
< cursor
)
33 sbi
->next_generation
++;
34 gen
= sbi
->next_generation
;
35 spin_unlock_irqrestore(&sbi
->ino_idr_lock
, flags
);
44 inode
->i_generation
= gen
;
48 /* set [inode] attributes based on [info], uid/gid based on [sbi] */
49 int vboxsf_init_inode(struct vboxsf_sbi
*sbi
, struct inode
*inode
,
50 const struct shfl_fsobjinfo
*info
, bool reinit
)
52 const struct shfl_fsobjattr
*attr
;
58 #define mode_set(r) ((attr->mode & (SHFL_UNIX_##r)) ? (S_##r) : 0)
60 mode
= mode_set(IRUSR
);
61 mode
|= mode_set(IWUSR
);
62 mode
|= mode_set(IXUSR
);
64 mode
|= mode_set(IRGRP
);
65 mode
|= mode_set(IWGRP
);
66 mode
|= mode_set(IXGRP
);
68 mode
|= mode_set(IROTH
);
69 mode
|= mode_set(IWOTH
);
70 mode
|= mode_set(IXOTH
);
74 /* We use the host-side values for these */
75 inode
->i_flags
|= S_NOATIME
| S_NOCMTIME
;
76 inode
->i_mapping
->a_ops
= &vboxsf_reg_aops
;
78 if (SHFL_IS_DIRECTORY(attr
->mode
)) {
81 mode
&= ~sbi
->o
.dmask
;
84 inode
->i_op
= &vboxsf_dir_iops
;
85 inode
->i_fop
= &vboxsf_dir_fops
;
87 * XXX: this probably should be set to the number of entries
88 * in the directory plus two (. ..)
91 } else if (!S_ISDIR(inode
->i_mode
))
94 } else if (SHFL_IS_SYMLINK(attr
->mode
)) {
97 mode
&= ~sbi
->o
.fmask
;
100 inode
->i_op
= &vboxsf_lnk_iops
;
102 } else if (!S_ISLNK(inode
->i_mode
))
104 inode
->i_mode
= mode
;
106 if (sbi
->o
.fmode_set
)
108 mode
&= ~sbi
->o
.fmask
;
111 inode
->i_op
= &vboxsf_reg_iops
;
112 inode
->i_fop
= &vboxsf_reg_fops
;
114 } else if (!S_ISREG(inode
->i_mode
))
116 inode
->i_mode
= mode
;
119 inode
->i_uid
= sbi
->o
.uid
;
120 inode
->i_gid
= sbi
->o
.gid
;
122 inode
->i_size
= info
->size
;
123 inode
->i_blkbits
= 12;
124 /* i_blocks always in units of 512 bytes! */
125 allocated
= info
->allocated
+ 511;
126 do_div(allocated
, 512);
127 inode
->i_blocks
= allocated
;
129 inode_set_atime_to_ts(inode
,
130 ns_to_timespec64(info
->access_time
.ns_relative_to_unix_epoch
));
131 inode_set_ctime_to_ts(inode
,
132 ns_to_timespec64(info
->change_time
.ns_relative_to_unix_epoch
));
133 inode_set_mtime_to_ts(inode
,
134 ns_to_timespec64(info
->modification_time
.ns_relative_to_unix_epoch
));
138 int vboxsf_create_at_dentry(struct dentry
*dentry
,
139 struct shfl_createparms
*params
)
141 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
142 struct shfl_string
*path
;
145 path
= vboxsf_path_from_dentry(sbi
, dentry
);
147 return PTR_ERR(path
);
149 err
= vboxsf_create(sbi
->root
, path
, params
);
155 int vboxsf_stat(struct vboxsf_sbi
*sbi
, struct shfl_string
*path
,
156 struct shfl_fsobjinfo
*info
)
158 struct shfl_createparms params
= {};
161 params
.handle
= SHFL_HANDLE_NIL
;
162 params
.create_flags
= SHFL_CF_LOOKUP
| SHFL_CF_ACT_FAIL_IF_NEW
;
164 err
= vboxsf_create(sbi
->root
, path
, ¶ms
);
168 if (params
.result
!= SHFL_FILE_EXISTS
)
177 int vboxsf_stat_dentry(struct dentry
*dentry
, struct shfl_fsobjinfo
*info
)
179 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
180 struct shfl_string
*path
;
183 path
= vboxsf_path_from_dentry(sbi
, dentry
);
185 return PTR_ERR(path
);
187 err
= vboxsf_stat(sbi
, path
, info
);
192 int vboxsf_inode_revalidate(struct dentry
*dentry
)
194 struct vboxsf_sbi
*sbi
;
195 struct vboxsf_inode
*sf_i
;
196 struct shfl_fsobjinfo info
;
197 struct timespec64 mtime
, prev_mtime
;
201 if (!dentry
|| !d_really_is_positive(dentry
))
204 inode
= d_inode(dentry
);
205 prev_mtime
= inode_get_mtime(inode
);
206 sf_i
= VBOXSF_I(inode
);
207 sbi
= VBOXSF_SBI(dentry
->d_sb
);
208 if (!sf_i
->force_restat
) {
209 if (time_before(jiffies
, dentry
->d_time
+ sbi
->o
.ttl
))
213 err
= vboxsf_stat_dentry(dentry
, &info
);
217 dentry
->d_time
= jiffies
;
218 sf_i
->force_restat
= 0;
219 err
= vboxsf_init_inode(sbi
, inode
, &info
, true);
224 * If the file was changed on the host side we need to invalidate the
225 * page-cache for it. Note this also gets triggered by our own writes,
226 * this is unavoidable.
228 mtime
= inode_get_mtime(inode
);
229 if (timespec64_compare(&mtime
, &prev_mtime
) > 0)
230 invalidate_inode_pages2(inode
->i_mapping
);
235 int vboxsf_getattr(struct mnt_idmap
*idmap
, const struct path
*path
,
236 struct kstat
*kstat
, u32 request_mask
, unsigned int flags
)
239 struct dentry
*dentry
= path
->dentry
;
240 struct inode
*inode
= d_inode(dentry
);
241 struct vboxsf_inode
*sf_i
= VBOXSF_I(inode
);
243 switch (flags
& AT_STATX_SYNC_TYPE
) {
244 case AT_STATX_DONT_SYNC
:
247 case AT_STATX_FORCE_SYNC
:
248 sf_i
->force_restat
= 1;
251 err
= vboxsf_inode_revalidate(dentry
);
256 generic_fillattr(&nop_mnt_idmap
, request_mask
, d_inode(dentry
), kstat
);
260 int vboxsf_setattr(struct mnt_idmap
*idmap
, struct dentry
*dentry
,
263 struct vboxsf_inode
*sf_i
= VBOXSF_I(d_inode(dentry
));
264 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
265 struct shfl_createparms params
= {};
266 struct shfl_fsobjinfo info
= {};
270 params
.handle
= SHFL_HANDLE_NIL
;
271 params
.create_flags
= SHFL_CF_ACT_OPEN_IF_EXISTS
|
272 SHFL_CF_ACT_FAIL_IF_NEW
|
273 SHFL_CF_ACCESS_ATTR_WRITE
;
275 /* this is at least required for Posix hosts */
276 if (iattr
->ia_valid
& ATTR_SIZE
)
277 params
.create_flags
|= SHFL_CF_ACCESS_WRITE
;
279 err
= vboxsf_create_at_dentry(dentry
, ¶ms
);
280 if (err
|| params
.result
!= SHFL_FILE_EXISTS
)
281 return err
? err
: -ENOENT
;
283 #define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0)
286 * Setting the file size and setting the other attributes has to
287 * be handled separately.
289 if (iattr
->ia_valid
& (ATTR_MODE
| ATTR_ATIME
| ATTR_MTIME
)) {
290 if (iattr
->ia_valid
& ATTR_MODE
) {
291 info
.attr
.mode
= mode_set(IRUSR
);
292 info
.attr
.mode
|= mode_set(IWUSR
);
293 info
.attr
.mode
|= mode_set(IXUSR
);
294 info
.attr
.mode
|= mode_set(IRGRP
);
295 info
.attr
.mode
|= mode_set(IWGRP
);
296 info
.attr
.mode
|= mode_set(IXGRP
);
297 info
.attr
.mode
|= mode_set(IROTH
);
298 info
.attr
.mode
|= mode_set(IWOTH
);
299 info
.attr
.mode
|= mode_set(IXOTH
);
301 if (iattr
->ia_mode
& S_IFDIR
)
302 info
.attr
.mode
|= SHFL_TYPE_DIRECTORY
;
304 info
.attr
.mode
|= SHFL_TYPE_FILE
;
307 if (iattr
->ia_valid
& ATTR_ATIME
)
308 info
.access_time
.ns_relative_to_unix_epoch
=
309 timespec64_to_ns(&iattr
->ia_atime
);
311 if (iattr
->ia_valid
& ATTR_MTIME
)
312 info
.modification_time
.ns_relative_to_unix_epoch
=
313 timespec64_to_ns(&iattr
->ia_mtime
);
316 * Ignore ctime (inode change time) as it can't be set
317 * from userland anyway.
320 buf_len
= sizeof(info
);
321 err
= vboxsf_fsinfo(sbi
->root
, params
.handle
,
322 SHFL_INFO_SET
| SHFL_INFO_FILE
, &buf_len
,
325 vboxsf_close(sbi
->root
, params
.handle
);
329 /* the host may have given us different attr then requested */
330 sf_i
->force_restat
= 1;
335 if (iattr
->ia_valid
& ATTR_SIZE
) {
336 memset(&info
, 0, sizeof(info
));
337 info
.size
= iattr
->ia_size
;
338 buf_len
= sizeof(info
);
339 err
= vboxsf_fsinfo(sbi
->root
, params
.handle
,
340 SHFL_INFO_SET
| SHFL_INFO_SIZE
, &buf_len
,
343 vboxsf_close(sbi
->root
, params
.handle
);
347 /* the host may have given us different attr then requested */
348 sf_i
->force_restat
= 1;
351 vboxsf_close(sbi
->root
, params
.handle
);
353 /* Update the inode with what the host has actually given us. */
354 if (sf_i
->force_restat
)
355 vboxsf_inode_revalidate(dentry
);
361 * [dentry] contains string encoded in coding system that corresponds
362 * to [sbi]->nls, we must convert it to UTF8 here.
363 * Returns a shfl_string allocated through __getname (must be freed using
364 * __putname), or an ERR_PTR on error.
366 struct shfl_string
*vboxsf_path_from_dentry(struct vboxsf_sbi
*sbi
,
367 struct dentry
*dentry
)
369 struct shfl_string
*shfl_path
;
370 int path_len
, out_len
, nb
;
377 return ERR_PTR(-ENOMEM
);
379 path
= dentry_path_raw(dentry
, buf
, PATH_MAX
);
382 return ERR_CAST(path
);
384 path_len
= strlen(path
);
387 shfl_path
= __getname();
390 return ERR_PTR(-ENOMEM
);
393 out
= shfl_path
->string
.utf8
;
394 out_len
= PATH_MAX
- SHFLSTRING_HEADER_SIZE
- 1;
397 nb
= sbi
->nls
->char2uni(path
, path_len
, &uni
);
399 __putname(shfl_path
);
401 return ERR_PTR(-EINVAL
);
406 nb
= utf32_to_utf8(uni
, out
, out_len
);
408 __putname(shfl_path
);
410 return ERR_PTR(-ENAMETOOLONG
);
416 shfl_path
->length
= out
- shfl_path
->string
.utf8
;
417 shfl_path
->size
= shfl_path
->length
+ 1;
420 if ((SHFLSTRING_HEADER_SIZE
+ path_len
+ 1) > PATH_MAX
) {
422 return ERR_PTR(-ENAMETOOLONG
);
425 * dentry_path stores the name at the end of buf, but the
426 * shfl_string string we return must be properly aligned.
428 shfl_path
= (struct shfl_string
*)buf
;
429 memmove(shfl_path
->string
.utf8
, path
, path_len
);
430 shfl_path
->string
.utf8
[path_len
] = 0;
431 shfl_path
->length
= path_len
;
432 shfl_path
->size
= path_len
+ 1;
438 int vboxsf_nlscpy(struct vboxsf_sbi
*sbi
, char *name
, size_t name_bound_len
,
439 const unsigned char *utf8_name
, size_t utf8_len
)
443 size_t out_bound_len
;
447 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
);
477 static struct vboxsf_dir_buf
*vboxsf_dir_buf_alloc(struct list_head
*list
)
479 struct vboxsf_dir_buf
*b
;
481 b
= kmalloc(sizeof(*b
), GFP_KERNEL
);
485 b
->buf
= kmalloc(DIR_BUFFER_SIZE
, GFP_KERNEL
);
493 b
->free
= DIR_BUFFER_SIZE
;
494 list_add(&b
->head
, list
);
499 static void vboxsf_dir_buf_free(struct vboxsf_dir_buf
*b
)
506 struct vboxsf_dir_info
*vboxsf_dir_info_alloc(void)
508 struct vboxsf_dir_info
*p
;
510 p
= kmalloc(sizeof(*p
), GFP_KERNEL
);
514 INIT_LIST_HEAD(&p
->info_list
);
518 void vboxsf_dir_info_free(struct vboxsf_dir_info
*p
)
520 struct list_head
*list
, *pos
, *tmp
;
522 list
= &p
->info_list
;
523 list_for_each_safe(pos
, tmp
, list
) {
524 struct vboxsf_dir_buf
*b
;
526 b
= list_entry(pos
, struct vboxsf_dir_buf
, head
);
527 vboxsf_dir_buf_free(b
);
532 int vboxsf_dir_read_all(struct vboxsf_sbi
*sbi
, struct vboxsf_dir_info
*sf_d
,
535 struct vboxsf_dir_buf
*b
;
540 /* vboxsf_dirinfo returns 1 on end of dir */
542 b
= vboxsf_dir_buf_alloc(&sf_d
->info_list
);
551 err
= vboxsf_dirinfo(sbi
->root
, handle
, NULL
, 0, 0,
552 &size
, buf
, &entries
);
556 b
->entries
+= entries
;
561 if (b
&& b
->used
== 0)
562 vboxsf_dir_buf_free(b
);
564 /* -EILSEQ means the host could not translate a filename, ignore */
565 if (err
> 0 || err
== -EILSEQ
)