utils.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * VirtualBox Guest Shared Folders support: Utility functions.
  4. * Mainly conversion from/to VirtualBox/Linux data structures.
  5. *
  6. * Copyright (C) 2006-2018 Oracle Corporation
  7. */
  8. #include <linux/namei.h>
  9. #include <linux/nls.h>
  10. #include <linux/sizes.h>
  11. #include <linux/pagemap.h>
  12. #include <linux/vfs.h>
  13. #include "vfsmod.h"
  14. struct inode *vboxsf_new_inode(struct super_block *sb)
  15. {
  16. struct vboxsf_sbi *sbi = VBOXSF_SBI(sb);
  17. struct inode *inode;
  18. unsigned long flags;
  19. int cursor, ret;
  20. u32 gen;
  21. inode = new_inode(sb);
  22. if (!inode)
  23. return ERR_PTR(-ENOMEM);
  24. idr_preload(GFP_KERNEL);
  25. spin_lock_irqsave(&sbi->ino_idr_lock, flags);
  26. cursor = idr_get_cursor(&sbi->ino_idr);
  27. ret = idr_alloc_cyclic(&sbi->ino_idr, inode, 1, 0, GFP_ATOMIC);
  28. if (ret >= 0 && ret < cursor)
  29. sbi->next_generation++;
  30. gen = sbi->next_generation;
  31. spin_unlock_irqrestore(&sbi->ino_idr_lock, flags);
  32. idr_preload_end();
  33. if (ret < 0) {
  34. iput(inode);
  35. return ERR_PTR(ret);
  36. }
  37. inode->i_ino = ret;
  38. inode->i_generation = gen;
  39. return inode;
  40. }
  41. /* set [inode] attributes based on [info], uid/gid based on [sbi] */
  42. int vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
  43. const struct shfl_fsobjinfo *info, bool reinit)
  44. {
  45. const struct shfl_fsobjattr *attr;
  46. s64 allocated;
  47. umode_t mode;
  48. attr = &info->attr;
  49. #define mode_set(r) ((attr->mode & (SHFL_UNIX_##r)) ? (S_##r) : 0)
  50. mode = mode_set(IRUSR);
  51. mode |= mode_set(IWUSR);
  52. mode |= mode_set(IXUSR);
  53. mode |= mode_set(IRGRP);
  54. mode |= mode_set(IWGRP);
  55. mode |= mode_set(IXGRP);
  56. mode |= mode_set(IROTH);
  57. mode |= mode_set(IWOTH);
  58. mode |= mode_set(IXOTH);
  59. #undef mode_set
  60. /* We use the host-side values for these */
  61. inode->i_flags |= S_NOATIME | S_NOCMTIME;
  62. inode->i_mapping->a_ops = &vboxsf_reg_aops;
  63. if (SHFL_IS_DIRECTORY(attr->mode)) {
  64. if (sbi->o.dmode_set)
  65. mode = sbi->o.dmode;
  66. mode &= ~sbi->o.dmask;
  67. mode |= S_IFDIR;
  68. if (!reinit) {
  69. inode->i_op = &vboxsf_dir_iops;
  70. inode->i_fop = &vboxsf_dir_fops;
  71. /*
  72. * XXX: this probably should be set to the number of entries
  73. * in the directory plus two (. ..)
  74. */
  75. set_nlink(inode, 1);
  76. } else if (!S_ISDIR(inode->i_mode))
  77. return -ESTALE;
  78. inode->i_mode = mode;
  79. } else if (SHFL_IS_SYMLINK(attr->mode)) {
  80. if (sbi->o.fmode_set)
  81. mode = sbi->o.fmode;
  82. mode &= ~sbi->o.fmask;
  83. mode |= S_IFLNK;
  84. if (!reinit) {
  85. inode->i_op = &vboxsf_lnk_iops;
  86. set_nlink(inode, 1);
  87. } else if (!S_ISLNK(inode->i_mode))
  88. return -ESTALE;
  89. inode->i_mode = mode;
  90. } else {
  91. if (sbi->o.fmode_set)
  92. mode = sbi->o.fmode;
  93. mode &= ~sbi->o.fmask;
  94. mode |= S_IFREG;
  95. if (!reinit) {
  96. inode->i_op = &vboxsf_reg_iops;
  97. inode->i_fop = &vboxsf_reg_fops;
  98. set_nlink(inode, 1);
  99. } else if (!S_ISREG(inode->i_mode))
  100. return -ESTALE;
  101. inode->i_mode = mode;
  102. }
  103. inode->i_uid = sbi->o.uid;
  104. inode->i_gid = sbi->o.gid;
  105. inode->i_size = info->size;
  106. inode->i_blkbits = 12;
  107. /* i_blocks always in units of 512 bytes! */
  108. allocated = info->allocated + 511;
  109. do_div(allocated, 512);
  110. inode->i_blocks = allocated;
  111. inode_set_atime_to_ts(inode,
  112. ns_to_timespec64(info->access_time.ns_relative_to_unix_epoch));
  113. inode_set_ctime_to_ts(inode,
  114. ns_to_timespec64(info->change_time.ns_relative_to_unix_epoch));
  115. inode_set_mtime_to_ts(inode,
  116. ns_to_timespec64(info->modification_time.ns_relative_to_unix_epoch));
  117. return 0;
  118. }
  119. int vboxsf_create_at_dentry(struct dentry *dentry,
  120. struct shfl_createparms *params)
  121. {
  122. struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
  123. struct shfl_string *path;
  124. int err;
  125. path = vboxsf_path_from_dentry(sbi, dentry);
  126. if (IS_ERR(path))
  127. return PTR_ERR(path);
  128. err = vboxsf_create(sbi->root, path, params);
  129. __putname(path);
  130. return err;
  131. }
  132. int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path,
  133. struct shfl_fsobjinfo *info)
  134. {
  135. struct shfl_createparms params = {};
  136. int err;
  137. params.handle = SHFL_HANDLE_NIL;
  138. params.create_flags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
  139. err = vboxsf_create(sbi->root, path, &params);
  140. if (err)
  141. return err;
  142. if (params.result != SHFL_FILE_EXISTS)
  143. return -ENOENT;
  144. if (info)
  145. *info = params.info;
  146. return 0;
  147. }
  148. int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info)
  149. {
  150. struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
  151. struct shfl_string *path;
  152. int err;
  153. path = vboxsf_path_from_dentry(sbi, dentry);
  154. if (IS_ERR(path))
  155. return PTR_ERR(path);
  156. err = vboxsf_stat(sbi, path, info);
  157. __putname(path);
  158. return err;
  159. }
  160. int vboxsf_inode_revalidate(struct dentry *dentry)
  161. {
  162. struct vboxsf_sbi *sbi;
  163. struct vboxsf_inode *sf_i;
  164. struct shfl_fsobjinfo info;
  165. struct timespec64 mtime, prev_mtime;
  166. struct inode *inode;
  167. int err;
  168. if (!dentry || !d_really_is_positive(dentry))
  169. return -EINVAL;
  170. inode = d_inode(dentry);
  171. prev_mtime = inode_get_mtime(inode);
  172. sf_i = VBOXSF_I(inode);
  173. sbi = VBOXSF_SBI(dentry->d_sb);
  174. if (!sf_i->force_restat) {
  175. if (time_before(jiffies, dentry->d_time + sbi->o.ttl))
  176. return 0;
  177. }
  178. err = vboxsf_stat_dentry(dentry, &info);
  179. if (err)
  180. return err;
  181. dentry->d_time = jiffies;
  182. sf_i->force_restat = 0;
  183. err = vboxsf_init_inode(sbi, inode, &info, true);
  184. if (err)
  185. return err;
  186. /*
  187. * If the file was changed on the host side we need to invalidate the
  188. * page-cache for it. Note this also gets triggered by our own writes,
  189. * this is unavoidable.
  190. */
  191. mtime = inode_get_mtime(inode);
  192. if (timespec64_compare(&mtime, &prev_mtime) > 0)
  193. invalidate_inode_pages2(inode->i_mapping);
  194. return 0;
  195. }
  196. int vboxsf_getattr(struct mnt_idmap *idmap, const struct path *path,
  197. struct kstat *kstat, u32 request_mask, unsigned int flags)
  198. {
  199. int err;
  200. struct dentry *dentry = path->dentry;
  201. struct inode *inode = d_inode(dentry);
  202. struct vboxsf_inode *sf_i = VBOXSF_I(inode);
  203. switch (flags & AT_STATX_SYNC_TYPE) {
  204. case AT_STATX_DONT_SYNC:
  205. err = 0;
  206. break;
  207. case AT_STATX_FORCE_SYNC:
  208. sf_i->force_restat = 1;
  209. fallthrough;
  210. default:
  211. err = vboxsf_inode_revalidate(dentry);
  212. }
  213. if (err)
  214. return err;
  215. generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(dentry), kstat);
  216. return 0;
  217. }
  218. int vboxsf_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
  219. struct iattr *iattr)
  220. {
  221. struct vboxsf_inode *sf_i = VBOXSF_I(d_inode(dentry));
  222. struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
  223. struct shfl_createparms params = {};
  224. struct shfl_fsobjinfo info = {};
  225. u32 buf_len;
  226. int err;
  227. params.handle = SHFL_HANDLE_NIL;
  228. params.create_flags = SHFL_CF_ACT_OPEN_IF_EXISTS |
  229. SHFL_CF_ACT_FAIL_IF_NEW |
  230. SHFL_CF_ACCESS_ATTR_WRITE;
  231. /* this is at least required for Posix hosts */
  232. if (iattr->ia_valid & ATTR_SIZE)
  233. params.create_flags |= SHFL_CF_ACCESS_WRITE;
  234. err = vboxsf_create_at_dentry(dentry, &params);
  235. if (err || params.result != SHFL_FILE_EXISTS)
  236. return err ? err : -ENOENT;
  237. #define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0)
  238. /*
  239. * Setting the file size and setting the other attributes has to
  240. * be handled separately.
  241. */
  242. if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) {
  243. if (iattr->ia_valid & ATTR_MODE) {
  244. info.attr.mode = mode_set(IRUSR);
  245. info.attr.mode |= mode_set(IWUSR);
  246. info.attr.mode |= mode_set(IXUSR);
  247. info.attr.mode |= mode_set(IRGRP);
  248. info.attr.mode |= mode_set(IWGRP);
  249. info.attr.mode |= mode_set(IXGRP);
  250. info.attr.mode |= mode_set(IROTH);
  251. info.attr.mode |= mode_set(IWOTH);
  252. info.attr.mode |= mode_set(IXOTH);
  253. if (iattr->ia_mode & S_IFDIR)
  254. info.attr.mode |= SHFL_TYPE_DIRECTORY;
  255. else
  256. info.attr.mode |= SHFL_TYPE_FILE;
  257. }
  258. if (iattr->ia_valid & ATTR_ATIME)
  259. info.access_time.ns_relative_to_unix_epoch =
  260. timespec64_to_ns(&iattr->ia_atime);
  261. if (iattr->ia_valid & ATTR_MTIME)
  262. info.modification_time.ns_relative_to_unix_epoch =
  263. timespec64_to_ns(&iattr->ia_mtime);
  264. /*
  265. * Ignore ctime (inode change time) as it can't be set
  266. * from userland anyway.
  267. */
  268. buf_len = sizeof(info);
  269. err = vboxsf_fsinfo(sbi->root, params.handle,
  270. SHFL_INFO_SET | SHFL_INFO_FILE, &buf_len,
  271. &info);
  272. if (err) {
  273. vboxsf_close(sbi->root, params.handle);
  274. return err;
  275. }
  276. /* the host may have given us different attr then requested */
  277. sf_i->force_restat = 1;
  278. }
  279. #undef mode_set
  280. if (iattr->ia_valid & ATTR_SIZE) {
  281. memset(&info, 0, sizeof(info));
  282. info.size = iattr->ia_size;
  283. buf_len = sizeof(info);
  284. err = vboxsf_fsinfo(sbi->root, params.handle,
  285. SHFL_INFO_SET | SHFL_INFO_SIZE, &buf_len,
  286. &info);
  287. if (err) {
  288. vboxsf_close(sbi->root, params.handle);
  289. return err;
  290. }
  291. /* the host may have given us different attr then requested */
  292. sf_i->force_restat = 1;
  293. }
  294. vboxsf_close(sbi->root, params.handle);
  295. /* Update the inode with what the host has actually given us. */
  296. if (sf_i->force_restat)
  297. vboxsf_inode_revalidate(dentry);
  298. return 0;
  299. }
  300. /*
  301. * [dentry] contains string encoded in coding system that corresponds
  302. * to [sbi]->nls, we must convert it to UTF8 here.
  303. * Returns a shfl_string allocated through __getname (must be freed using
  304. * __putname), or an ERR_PTR on error.
  305. */
  306. struct shfl_string *vboxsf_path_from_dentry(struct vboxsf_sbi *sbi,
  307. struct dentry *dentry)
  308. {
  309. struct shfl_string *shfl_path;
  310. int path_len, out_len, nb;
  311. char *buf, *path;
  312. wchar_t uni;
  313. u8 *out;
  314. buf = __getname();
  315. if (!buf)
  316. return ERR_PTR(-ENOMEM);
  317. path = dentry_path_raw(dentry, buf, PATH_MAX);
  318. if (IS_ERR(path)) {
  319. __putname(buf);
  320. return ERR_CAST(path);
  321. }
  322. path_len = strlen(path);
  323. if (sbi->nls) {
  324. shfl_path = __getname();
  325. if (!shfl_path) {
  326. __putname(buf);
  327. return ERR_PTR(-ENOMEM);
  328. }
  329. out = shfl_path->string.utf8;
  330. out_len = PATH_MAX - SHFLSTRING_HEADER_SIZE - 1;
  331. while (path_len) {
  332. nb = sbi->nls->char2uni(path, path_len, &uni);
  333. if (nb < 0) {
  334. __putname(shfl_path);
  335. __putname(buf);
  336. return ERR_PTR(-EINVAL);
  337. }
  338. path += nb;
  339. path_len -= nb;
  340. nb = utf32_to_utf8(uni, out, out_len);
  341. if (nb < 0) {
  342. __putname(shfl_path);
  343. __putname(buf);
  344. return ERR_PTR(-ENAMETOOLONG);
  345. }
  346. out += nb;
  347. out_len -= nb;
  348. }
  349. *out = 0;
  350. shfl_path->length = out - shfl_path->string.utf8;
  351. shfl_path->size = shfl_path->length + 1;
  352. __putname(buf);
  353. } else {
  354. if ((SHFLSTRING_HEADER_SIZE + path_len + 1) > PATH_MAX) {
  355. __putname(buf);
  356. return ERR_PTR(-ENAMETOOLONG);
  357. }
  358. /*
  359. * dentry_path stores the name at the end of buf, but the
  360. * shfl_string string we return must be properly aligned.
  361. */
  362. shfl_path = (struct shfl_string *)buf;
  363. memmove(shfl_path->string.utf8, path, path_len);
  364. shfl_path->string.utf8[path_len] = 0;
  365. shfl_path->length = path_len;
  366. shfl_path->size = path_len + 1;
  367. }
  368. return shfl_path;
  369. }
  370. int vboxsf_nlscpy(struct vboxsf_sbi *sbi, char *name, size_t name_bound_len,
  371. const unsigned char *utf8_name, size_t utf8_len)
  372. {
  373. const char *in;
  374. char *out;
  375. size_t out_bound_len;
  376. size_t in_bound_len;
  377. in = utf8_name;
  378. in_bound_len = utf8_len;
  379. out = name;
  380. /* Reserve space for terminating 0 */
  381. out_bound_len = name_bound_len - 1;
  382. while (in_bound_len) {
  383. int nb;
  384. unicode_t uni;
  385. nb = utf8_to_utf32(in, in_bound_len, &uni);
  386. if (nb < 0)
  387. return -EINVAL;
  388. in += nb;
  389. in_bound_len -= nb;
  390. nb = sbi->nls->uni2char(uni, out, out_bound_len);
  391. if (nb < 0)
  392. return nb;
  393. out += nb;
  394. out_bound_len -= nb;
  395. }
  396. *out = 0;
  397. return 0;
  398. }
  399. static struct vboxsf_dir_buf *vboxsf_dir_buf_alloc(struct list_head *list)
  400. {
  401. struct vboxsf_dir_buf *b;
  402. b = kmalloc(sizeof(*b), GFP_KERNEL);
  403. if (!b)
  404. return NULL;
  405. b->buf = kmalloc(DIR_BUFFER_SIZE, GFP_KERNEL);
  406. if (!b->buf) {
  407. kfree(b);
  408. return NULL;
  409. }
  410. b->entries = 0;
  411. b->used = 0;
  412. b->free = DIR_BUFFER_SIZE;
  413. list_add(&b->head, list);
  414. return b;
  415. }
  416. static void vboxsf_dir_buf_free(struct vboxsf_dir_buf *b)
  417. {
  418. list_del(&b->head);
  419. kfree(b->buf);
  420. kfree(b);
  421. }
  422. struct vboxsf_dir_info *vboxsf_dir_info_alloc(void)
  423. {
  424. struct vboxsf_dir_info *p;
  425. p = kmalloc(sizeof(*p), GFP_KERNEL);
  426. if (!p)
  427. return NULL;
  428. INIT_LIST_HEAD(&p->info_list);
  429. return p;
  430. }
  431. void vboxsf_dir_info_free(struct vboxsf_dir_info *p)
  432. {
  433. struct list_head *list, *pos, *tmp;
  434. list = &p->info_list;
  435. list_for_each_safe(pos, tmp, list) {
  436. struct vboxsf_dir_buf *b;
  437. b = list_entry(pos, struct vboxsf_dir_buf, head);
  438. vboxsf_dir_buf_free(b);
  439. }
  440. kfree(p);
  441. }
  442. int vboxsf_dir_read_all(struct vboxsf_sbi *sbi, struct vboxsf_dir_info *sf_d,
  443. u64 handle)
  444. {
  445. struct vboxsf_dir_buf *b;
  446. u32 entries, size;
  447. int err = 0;
  448. void *buf;
  449. /* vboxsf_dirinfo returns 1 on end of dir */
  450. while (err == 0) {
  451. b = vboxsf_dir_buf_alloc(&sf_d->info_list);
  452. if (!b) {
  453. err = -ENOMEM;
  454. break;
  455. }
  456. buf = b->buf;
  457. size = b->free;
  458. err = vboxsf_dirinfo(sbi->root, handle, NULL, 0, 0,
  459. &size, buf, &entries);
  460. if (err < 0)
  461. break;
  462. b->entries += entries;
  463. b->free -= size;
  464. b->used += size;
  465. }
  466. if (b && b->used == 0)
  467. vboxsf_dir_buf_free(b);
  468. /* -EILSEQ means the host could not translate a filename, ignore */
  469. if (err > 0 || err == -EILSEQ)
  470. err = 0;
  471. return err;
  472. }