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 void vboxsf_init_inode(struct vboxsf_sbi
*sbi
, struct inode
*inode
,
49 const struct shfl_fsobjinfo
*info
)
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
)) {
78 inode
->i_mode
= sbi
->o
.dmode_set
? sbi
->o
.dmode
: mode
;
79 inode
->i_mode
&= ~sbi
->o
.dmask
;
80 inode
->i_mode
|= S_IFDIR
;
81 inode
->i_op
= &vboxsf_dir_iops
;
82 inode
->i_fop
= &vboxsf_dir_fops
;
84 * XXX: this probably should be set to the number of entries
85 * in the directory plus two (. ..)
88 } else if (SHFL_IS_SYMLINK(attr
->mode
)) {
89 inode
->i_mode
= sbi
->o
.fmode_set
? sbi
->o
.fmode
: mode
;
90 inode
->i_mode
&= ~sbi
->o
.fmask
;
91 inode
->i_mode
|= S_IFLNK
;
92 inode
->i_op
= &vboxsf_lnk_iops
;
95 inode
->i_mode
= sbi
->o
.fmode_set
? sbi
->o
.fmode
: mode
;
96 inode
->i_mode
&= ~sbi
->o
.fmask
;
97 inode
->i_mode
|= S_IFREG
;
98 inode
->i_op
= &vboxsf_reg_iops
;
99 inode
->i_fop
= &vboxsf_reg_fops
;
103 inode
->i_uid
= sbi
->o
.uid
;
104 inode
->i_gid
= sbi
->o
.gid
;
106 inode
->i_size
= info
->size
;
107 inode
->i_blkbits
= 12;
108 /* i_blocks always in units of 512 bytes! */
109 allocated
= info
->allocated
+ 511;
110 do_div(allocated
, 512);
111 inode
->i_blocks
= allocated
;
113 inode
->i_atime
= ns_to_timespec64(
114 info
->access_time
.ns_relative_to_unix_epoch
);
115 inode
->i_ctime
= ns_to_timespec64(
116 info
->change_time
.ns_relative_to_unix_epoch
);
117 inode
->i_mtime
= ns_to_timespec64(
118 info
->modification_time
.ns_relative_to_unix_epoch
);
121 int vboxsf_create_at_dentry(struct dentry
*dentry
,
122 struct shfl_createparms
*params
)
124 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
125 struct shfl_string
*path
;
128 path
= vboxsf_path_from_dentry(sbi
, dentry
);
130 return PTR_ERR(path
);
132 err
= vboxsf_create(sbi
->root
, path
, params
);
138 int vboxsf_stat(struct vboxsf_sbi
*sbi
, struct shfl_string
*path
,
139 struct shfl_fsobjinfo
*info
)
141 struct shfl_createparms params
= {};
144 params
.handle
= SHFL_HANDLE_NIL
;
145 params
.create_flags
= SHFL_CF_LOOKUP
| SHFL_CF_ACT_FAIL_IF_NEW
;
147 err
= vboxsf_create(sbi
->root
, path
, ¶ms
);
151 if (params
.result
!= SHFL_FILE_EXISTS
)
160 int vboxsf_stat_dentry(struct dentry
*dentry
, struct shfl_fsobjinfo
*info
)
162 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
163 struct shfl_string
*path
;
166 path
= vboxsf_path_from_dentry(sbi
, dentry
);
168 return PTR_ERR(path
);
170 err
= vboxsf_stat(sbi
, path
, info
);
175 int vboxsf_inode_revalidate(struct dentry
*dentry
)
177 struct vboxsf_sbi
*sbi
;
178 struct vboxsf_inode
*sf_i
;
179 struct shfl_fsobjinfo info
;
180 struct timespec64 prev_mtime
;
184 if (!dentry
|| !d_really_is_positive(dentry
))
187 inode
= d_inode(dentry
);
188 prev_mtime
= inode
->i_mtime
;
189 sf_i
= VBOXSF_I(inode
);
190 sbi
= VBOXSF_SBI(dentry
->d_sb
);
191 if (!sf_i
->force_restat
) {
192 if (time_before(jiffies
, dentry
->d_time
+ sbi
->o
.ttl
))
196 err
= vboxsf_stat_dentry(dentry
, &info
);
200 dentry
->d_time
= jiffies
;
201 sf_i
->force_restat
= 0;
202 vboxsf_init_inode(sbi
, inode
, &info
);
205 * If the file was changed on the host side we need to invalidate the
206 * page-cache for it. Note this also gets triggered by our own writes,
207 * this is unavoidable.
209 if (timespec64_compare(&inode
->i_mtime
, &prev_mtime
) > 0)
210 invalidate_inode_pages2(inode
->i_mapping
);
215 int vboxsf_getattr(const struct path
*path
, struct kstat
*kstat
,
216 u32 request_mask
, unsigned int flags
)
219 struct dentry
*dentry
= path
->dentry
;
220 struct inode
*inode
= d_inode(dentry
);
221 struct vboxsf_inode
*sf_i
= VBOXSF_I(inode
);
223 switch (flags
& AT_STATX_SYNC_TYPE
) {
224 case AT_STATX_DONT_SYNC
:
227 case AT_STATX_FORCE_SYNC
:
228 sf_i
->force_restat
= 1;
231 err
= vboxsf_inode_revalidate(dentry
);
236 generic_fillattr(d_inode(dentry
), kstat
);
240 int vboxsf_setattr(struct dentry
*dentry
, struct iattr
*iattr
)
242 struct vboxsf_inode
*sf_i
= VBOXSF_I(d_inode(dentry
));
243 struct vboxsf_sbi
*sbi
= VBOXSF_SBI(dentry
->d_sb
);
244 struct shfl_createparms params
= {};
245 struct shfl_fsobjinfo info
= {};
249 params
.handle
= SHFL_HANDLE_NIL
;
250 params
.create_flags
= SHFL_CF_ACT_OPEN_IF_EXISTS
|
251 SHFL_CF_ACT_FAIL_IF_NEW
|
252 SHFL_CF_ACCESS_ATTR_WRITE
;
254 /* this is at least required for Posix hosts */
255 if (iattr
->ia_valid
& ATTR_SIZE
)
256 params
.create_flags
|= SHFL_CF_ACCESS_WRITE
;
258 err
= vboxsf_create_at_dentry(dentry
, ¶ms
);
259 if (err
|| params
.result
!= SHFL_FILE_EXISTS
)
260 return err
? err
: -ENOENT
;
262 #define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0)
265 * Setting the file size and setting the other attributes has to
266 * be handled separately.
268 if (iattr
->ia_valid
& (ATTR_MODE
| ATTR_ATIME
| ATTR_MTIME
)) {
269 if (iattr
->ia_valid
& ATTR_MODE
) {
270 info
.attr
.mode
= mode_set(IRUSR
);
271 info
.attr
.mode
|= mode_set(IWUSR
);
272 info
.attr
.mode
|= mode_set(IXUSR
);
273 info
.attr
.mode
|= mode_set(IRGRP
);
274 info
.attr
.mode
|= mode_set(IWGRP
);
275 info
.attr
.mode
|= mode_set(IXGRP
);
276 info
.attr
.mode
|= mode_set(IROTH
);
277 info
.attr
.mode
|= mode_set(IWOTH
);
278 info
.attr
.mode
|= mode_set(IXOTH
);
280 if (iattr
->ia_mode
& S_IFDIR
)
281 info
.attr
.mode
|= SHFL_TYPE_DIRECTORY
;
283 info
.attr
.mode
|= SHFL_TYPE_FILE
;
286 if (iattr
->ia_valid
& ATTR_ATIME
)
287 info
.access_time
.ns_relative_to_unix_epoch
=
288 timespec64_to_ns(&iattr
->ia_atime
);
290 if (iattr
->ia_valid
& ATTR_MTIME
)
291 info
.modification_time
.ns_relative_to_unix_epoch
=
292 timespec64_to_ns(&iattr
->ia_mtime
);
295 * Ignore ctime (inode change time) as it can't be set
296 * from userland anyway.
299 buf_len
= sizeof(info
);
300 err
= vboxsf_fsinfo(sbi
->root
, params
.handle
,
301 SHFL_INFO_SET
| SHFL_INFO_FILE
, &buf_len
,
304 vboxsf_close(sbi
->root
, params
.handle
);
308 /* the host may have given us different attr then requested */
309 sf_i
->force_restat
= 1;
314 if (iattr
->ia_valid
& ATTR_SIZE
) {
315 memset(&info
, 0, sizeof(info
));
316 info
.size
= iattr
->ia_size
;
317 buf_len
= sizeof(info
);
318 err
= vboxsf_fsinfo(sbi
->root
, params
.handle
,
319 SHFL_INFO_SET
| SHFL_INFO_SIZE
, &buf_len
,
322 vboxsf_close(sbi
->root
, params
.handle
);
326 /* the host may have given us different attr then requested */
327 sf_i
->force_restat
= 1;
330 vboxsf_close(sbi
->root
, params
.handle
);
332 /* Update the inode with what the host has actually given us. */
333 if (sf_i
->force_restat
)
334 vboxsf_inode_revalidate(dentry
);
340 * [dentry] contains string encoded in coding system that corresponds
341 * to [sbi]->nls, we must convert it to UTF8 here.
342 * Returns a shfl_string allocated through __getname (must be freed using
343 * __putname), or an ERR_PTR on error.
345 struct shfl_string
*vboxsf_path_from_dentry(struct vboxsf_sbi
*sbi
,
346 struct dentry
*dentry
)
348 struct shfl_string
*shfl_path
;
349 int path_len
, out_len
, nb
;
356 return ERR_PTR(-ENOMEM
);
358 path
= dentry_path_raw(dentry
, buf
, PATH_MAX
);
361 return ERR_CAST(path
);
363 path_len
= strlen(path
);
366 shfl_path
= __getname();
369 return ERR_PTR(-ENOMEM
);
372 out
= shfl_path
->string
.utf8
;
373 out_len
= PATH_MAX
- SHFLSTRING_HEADER_SIZE
- 1;
376 nb
= sbi
->nls
->char2uni(path
, path_len
, &uni
);
378 __putname(shfl_path
);
380 return ERR_PTR(-EINVAL
);
385 nb
= utf32_to_utf8(uni
, out
, out_len
);
387 __putname(shfl_path
);
389 return ERR_PTR(-ENAMETOOLONG
);
395 shfl_path
->length
= out
- shfl_path
->string
.utf8
;
396 shfl_path
->size
= shfl_path
->length
+ 1;
399 if ((SHFLSTRING_HEADER_SIZE
+ path_len
+ 1) > PATH_MAX
) {
401 return ERR_PTR(-ENAMETOOLONG
);
404 * dentry_path stores the name at the end of buf, but the
405 * shfl_string string we return must be properly aligned.
407 shfl_path
= (struct shfl_string
*)buf
;
408 memmove(shfl_path
->string
.utf8
, path
, path_len
);
409 shfl_path
->string
.utf8
[path_len
] = 0;
410 shfl_path
->length
= path_len
;
411 shfl_path
->size
= path_len
+ 1;
417 int vboxsf_nlscpy(struct vboxsf_sbi
*sbi
, char *name
, size_t name_bound_len
,
418 const unsigned char *utf8_name
, size_t utf8_len
)
423 size_t out_bound_len
;
427 in_bound_len
= utf8_len
;
431 /* Reserve space for terminating 0 */
432 out_bound_len
= name_bound_len
- 1;
434 while (in_bound_len
) {
438 nb
= utf8_to_utf32(in
, in_bound_len
, &uni
);
445 nb
= sbi
->nls
->uni2char(uni
, out
, out_bound_len
);
459 static struct vboxsf_dir_buf
*vboxsf_dir_buf_alloc(struct list_head
*list
)
461 struct vboxsf_dir_buf
*b
;
463 b
= kmalloc(sizeof(*b
), GFP_KERNEL
);
467 b
->buf
= kmalloc(DIR_BUFFER_SIZE
, GFP_KERNEL
);
475 b
->free
= DIR_BUFFER_SIZE
;
476 list_add(&b
->head
, list
);
481 static void vboxsf_dir_buf_free(struct vboxsf_dir_buf
*b
)
488 struct vboxsf_dir_info
*vboxsf_dir_info_alloc(void)
490 struct vboxsf_dir_info
*p
;
492 p
= kmalloc(sizeof(*p
), GFP_KERNEL
);
496 INIT_LIST_HEAD(&p
->info_list
);
500 void vboxsf_dir_info_free(struct vboxsf_dir_info
*p
)
502 struct list_head
*list
, *pos
, *tmp
;
504 list
= &p
->info_list
;
505 list_for_each_safe(pos
, tmp
, list
) {
506 struct vboxsf_dir_buf
*b
;
508 b
= list_entry(pos
, struct vboxsf_dir_buf
, head
);
509 vboxsf_dir_buf_free(b
);
514 int vboxsf_dir_read_all(struct vboxsf_sbi
*sbi
, struct vboxsf_dir_info
*sf_d
,
517 struct vboxsf_dir_buf
*b
;
522 /* vboxsf_dirinfo returns 1 on end of dir */
524 b
= vboxsf_dir_buf_alloc(&sf_d
->info_list
);
533 err
= vboxsf_dirinfo(sbi
->root
, handle
, NULL
, 0, 0,
534 &size
, buf
, &entries
);
538 b
->entries
+= entries
;
543 if (b
&& b
->used
== 0)
544 vboxsf_dir_buf_free(b
);
546 /* -EILSEQ means the host could not translate a filename, ignore */
547 if (err
> 0 || err
== -EILSEQ
)