utils.c 12 KB

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