You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2060 lines
47 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
  1. /*
  2. FUSE: Filesystem in Userspace
  3. Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
  4. This program can be distributed under the terms of the GNU LGPLv2.
  5. See the file COPYING.LIB
  6. */
  7. #define _GNU_SOURCE
  8. #include "lfmp.h"
  9. #include "config.h"
  10. #include "debug.h"
  11. #include "fuse_i.h"
  12. #include "fuse_kernel.h"
  13. #include "fuse_opt.h"
  14. #include "fuse_misc.h"
  15. #include "fuse_pollhandle.h"
  16. #include "fuse_msgbuf.hpp"
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <stddef.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <limits.h>
  23. #include <errno.h>
  24. #include <assert.h>
  25. #include <sys/file.h>
  26. #ifndef F_LINUX_SPECIFIC_BASE
  27. #define F_LINUX_SPECIFIC_BASE 1024
  28. #endif
  29. #ifndef F_SETPIPE_SZ
  30. #define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
  31. #endif
  32. #define PARAM(inarg) (((char*)(inarg)) + sizeof(*(inarg)))
  33. #define OFFSET_MAX 0x7fffffffffffffffLL
  34. #define container_of(ptr, type, member) ({ \
  35. const typeof( ((type*)0)->member ) *__mptr = (ptr); \
  36. (type *)( (char*)__mptr - offsetof(type,member) );})
  37. static size_t pagesize;
  38. static lfmp_t g_FMP_fuse_req;
  39. static
  40. __attribute__((constructor))
  41. void
  42. fuse_ll_constructor(void)
  43. {
  44. pagesize = sysconf(_SC_PAGESIZE);
  45. lfmp_init(&g_FMP_fuse_req,sizeof(struct fuse_req),1);
  46. }
  47. static
  48. __attribute__((destructor))
  49. void
  50. fuse_ll_destructor(void)
  51. {
  52. lfmp_destroy(&g_FMP_fuse_req);
  53. }
  54. static
  55. void
  56. convert_stat(const struct stat *stbuf_,
  57. struct fuse_attr *attr_)
  58. {
  59. attr_->ino = stbuf_->st_ino;
  60. attr_->mode = stbuf_->st_mode;
  61. attr_->nlink = stbuf_->st_nlink;
  62. attr_->uid = stbuf_->st_uid;
  63. attr_->gid = stbuf_->st_gid;
  64. attr_->rdev = stbuf_->st_rdev;
  65. attr_->size = stbuf_->st_size;
  66. attr_->blksize = stbuf_->st_blksize;
  67. attr_->blocks = stbuf_->st_blocks;
  68. attr_->atime = stbuf_->st_atime;
  69. attr_->mtime = stbuf_->st_mtime;
  70. attr_->ctime = stbuf_->st_ctime;
  71. attr_->atimensec = ST_ATIM_NSEC(stbuf_);
  72. attr_->mtimensec = ST_MTIM_NSEC(stbuf_);
  73. attr_->ctimensec = ST_CTIM_NSEC(stbuf_);
  74. }
  75. static
  76. size_t
  77. iov_length(const struct iovec *iov,
  78. size_t count)
  79. {
  80. size_t seg;
  81. size_t ret = 0;
  82. for(seg = 0; seg < count; seg++)
  83. ret += iov[seg].iov_len;
  84. return ret;
  85. }
  86. static
  87. void
  88. destroy_req(fuse_req_t req)
  89. {
  90. lfmp_free(&g_FMP_fuse_req,req);
  91. }
  92. static
  93. struct fuse_req*
  94. fuse_ll_alloc_req(struct fuse_ll *f)
  95. {
  96. struct fuse_req *req;
  97. req = (struct fuse_req*)lfmp_calloc(&g_FMP_fuse_req);
  98. if(req == NULL)
  99. {
  100. fprintf(stderr, "fuse: failed to allocate request\n");
  101. }
  102. else
  103. {
  104. req->f = f;
  105. }
  106. return req;
  107. }
  108. static
  109. int
  110. fuse_send_msg(struct fuse_ll *f,
  111. struct fuse_chan *ch,
  112. struct iovec *iov,
  113. int count)
  114. {
  115. int rv;
  116. struct fuse_out_header *out = iov[0].iov_base;
  117. out->len = iov_length(iov, count);
  118. rv = writev(fuse_chan_fd(ch),iov,count);
  119. if(rv == -1)
  120. return -errno;
  121. return 0;
  122. }
  123. #define MAX_ERRNO 4095
  124. int
  125. fuse_send_reply_iov_nofree(fuse_req_t req,
  126. int error,
  127. struct iovec *iov,
  128. int count)
  129. {
  130. struct fuse_out_header out;
  131. if(error > 0)
  132. error = -error;
  133. if(error <= -MAX_ERRNO)
  134. {
  135. fprintf(stderr,"fuse: bad error value: %i\n",error);
  136. error = -ERANGE;
  137. }
  138. out.unique = req->unique;
  139. out.error = error;
  140. iov[0].iov_base = &out;
  141. iov[0].iov_len = sizeof(struct fuse_out_header);
  142. return fuse_send_msg(req->f, req->ch, iov, count);
  143. }
  144. static
  145. int
  146. send_reply_iov(fuse_req_t req,
  147. int error,
  148. struct iovec *iov,
  149. int count)
  150. {
  151. int res;
  152. res = fuse_send_reply_iov_nofree(req, error, iov, count);
  153. destroy_req(req);
  154. return res;
  155. }
  156. static
  157. int
  158. send_reply(fuse_req_t req,
  159. int error,
  160. const void *arg,
  161. size_t argsize)
  162. {
  163. struct iovec iov[2];
  164. int count = 1;
  165. if(argsize)
  166. {
  167. iov[1].iov_base = (void *) arg;
  168. iov[1].iov_len = argsize;
  169. count++;
  170. }
  171. return send_reply_iov(req, error, iov, count);
  172. }
  173. static
  174. void
  175. convert_statfs(const struct statvfs *stbuf,
  176. struct fuse_kstatfs *kstatfs)
  177. {
  178. kstatfs->bsize = stbuf->f_bsize;
  179. kstatfs->frsize = stbuf->f_frsize;
  180. kstatfs->blocks = stbuf->f_blocks;
  181. kstatfs->bfree = stbuf->f_bfree;
  182. kstatfs->bavail = stbuf->f_bavail;
  183. kstatfs->files = stbuf->f_files;
  184. kstatfs->ffree = stbuf->f_ffree;
  185. kstatfs->namelen = stbuf->f_namemax;
  186. }
  187. static
  188. int
  189. send_reply_ok(fuse_req_t req,
  190. const void *arg,
  191. size_t argsize)
  192. {
  193. return send_reply(req, 0, arg, argsize);
  194. }
  195. int
  196. fuse_reply_err(fuse_req_t req_,
  197. int err_)
  198. {
  199. return send_reply(req_,err_,NULL,0);
  200. }
  201. void
  202. fuse_reply_none(fuse_req_t req)
  203. {
  204. destroy_req(req);
  205. }
  206. static
  207. void
  208. fill_entry(struct fuse_entry_out *arg,
  209. const struct fuse_entry_param *e)
  210. {
  211. arg->nodeid = e->ino;
  212. arg->generation = e->generation;
  213. arg->entry_valid = e->timeout.entry;
  214. arg->entry_valid_nsec = 0;
  215. arg->attr_valid = e->timeout.attr;
  216. arg->attr_valid_nsec = 0;
  217. convert_stat(&e->attr,&arg->attr);
  218. }
  219. static
  220. void
  221. fill_open(struct fuse_open_out *arg_,
  222. const fuse_file_info_t *ffi_)
  223. {
  224. arg_->fh = ffi_->fh;
  225. if(ffi_->direct_io)
  226. arg_->open_flags |= FOPEN_DIRECT_IO;
  227. if(ffi_->keep_cache)
  228. arg_->open_flags |= FOPEN_KEEP_CACHE;
  229. if(ffi_->nonseekable)
  230. arg_->open_flags |= FOPEN_NONSEEKABLE;
  231. if(ffi_->cache_readdir)
  232. arg_->open_flags |= FOPEN_CACHE_DIR;
  233. if(ffi_->parallel_direct_writes)
  234. arg_->open_flags |= FOPEN_PARALLEL_DIRECT_WRITES;
  235. if(ffi_->noflush)
  236. arg_->open_flags |= FOPEN_NOFLUSH;
  237. if(ffi_->passthrough)
  238. {
  239. arg_->open_flags |= FOPEN_PASSTHROUGH;
  240. arg_->backing_id = ffi_->backing_id;
  241. }
  242. fprintf(stderr,
  243. "%d %d\n",
  244. !!(arg_->open_flags | FOPEN_KEEP_CACHE),
  245. !!(arg_->open_flags | FOPEN_PASSTHROUGH));
  246. }
  247. int
  248. fuse_reply_entry(fuse_req_t req,
  249. const struct fuse_entry_param *e)
  250. {
  251. struct fuse_entry_out arg = {0};
  252. size_t size = req->f->conn.proto_minor < 9 ?
  253. FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg);
  254. /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
  255. negative entry */
  256. if(!e->ino && req->f->conn.proto_minor < 4)
  257. return fuse_reply_err(req, ENOENT);
  258. fill_entry(&arg, e);
  259. #ifdef NDEBUG
  260. // TODO: Add checks for cases where a node could be marked bad by
  261. // the kernel.
  262. #endif
  263. return send_reply_ok(req, &arg, size);
  264. }
  265. struct fuse_create_out
  266. {
  267. struct fuse_entry_out e;
  268. struct fuse_open_out o;
  269. };
  270. int
  271. fuse_reply_create(fuse_req_t req,
  272. const struct fuse_entry_param *e,
  273. const fuse_file_info_t *f)
  274. {
  275. struct fuse_create_out buf = {0};
  276. size_t entrysize = req->f->conn.proto_minor < 9 ?
  277. FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(struct fuse_entry_out);
  278. struct fuse_entry_out *earg = (struct fuse_entry_out*)&buf.e;
  279. struct fuse_open_out *oarg = (struct fuse_open_out*)(((char*)&buf)+entrysize);
  280. fill_entry(earg, e);
  281. fill_open(oarg, f);
  282. return send_reply_ok(req, &buf, entrysize + sizeof(struct fuse_open_out));
  283. }
  284. int
  285. fuse_reply_attr(fuse_req_t req,
  286. const struct stat *attr,
  287. const uint64_t timeout)
  288. {
  289. struct fuse_attr_out arg = {0};
  290. size_t size = req->f->conn.proto_minor < 9 ?
  291. FUSE_COMPAT_ATTR_OUT_SIZE : sizeof(arg);
  292. arg.attr_valid = timeout;
  293. arg.attr_valid_nsec = 0;
  294. convert_stat(attr,&arg.attr);
  295. return send_reply_ok(req,&arg,size);
  296. }
  297. int
  298. fuse_reply_readlink(fuse_req_t req,
  299. const char *linkname)
  300. {
  301. return send_reply_ok(req, linkname, strlen(linkname));
  302. }
  303. int
  304. fuse_reply_open(fuse_req_t req,
  305. const fuse_file_info_t *f)
  306. {
  307. struct fuse_open_out arg = {0};
  308. fill_open(&arg, f);
  309. return send_reply_ok(req, &arg, sizeof(arg));
  310. }
  311. int
  312. fuse_reply_write(fuse_req_t req,
  313. size_t count)
  314. {
  315. struct fuse_write_out arg = {0};
  316. arg.size = count;
  317. return send_reply_ok(req, &arg, sizeof(arg));
  318. }
  319. int
  320. fuse_reply_buf(fuse_req_t req,
  321. const char *buf,
  322. size_t size)
  323. {
  324. return send_reply_ok(req, buf, size);
  325. }
  326. static
  327. int
  328. fuse_send_data_iov_fallback(struct fuse_ll *f,
  329. struct fuse_chan *ch,
  330. struct iovec *iov,
  331. int iov_count,
  332. struct fuse_bufvec *buf,
  333. size_t len)
  334. {
  335. int res;
  336. struct fuse_bufvec mem_buf = FUSE_BUFVEC_INIT(len);
  337. /* Optimize common case */
  338. if(buf->count == 1 && buf->idx == 0 && buf->off == 0 &&
  339. !(buf->buf[0].flags & FUSE_BUF_IS_FD))
  340. {
  341. /* FIXME: also avoid memory copy if there are multiple buffers
  342. but none of them contain an fd */
  343. iov[iov_count].iov_base = buf->buf[0].mem;
  344. iov[iov_count].iov_len = len;
  345. iov_count++;
  346. return fuse_send_msg(f, ch, iov, iov_count);
  347. }
  348. fuse_msgbuf_t *msgbuf;
  349. msgbuf = msgbuf_alloc();
  350. if(msgbuf == NULL)
  351. return -ENOMEM;
  352. mem_buf.buf[0].mem = msgbuf->mem;
  353. res = fuse_buf_copy(&mem_buf, buf, 0);
  354. if(res < 0)
  355. {
  356. msgbuf_free(msgbuf);
  357. return -res;
  358. }
  359. len = res;
  360. iov[iov_count].iov_base = msgbuf->mem;
  361. iov[iov_count].iov_len = len;
  362. iov_count++;
  363. res = fuse_send_msg(f, ch, iov, iov_count);
  364. msgbuf_free(msgbuf);
  365. return res;
  366. }
  367. struct fuse_ll_pipe
  368. {
  369. size_t size;
  370. int can_grow;
  371. int pipe[2];
  372. };
  373. static
  374. void
  375. fuse_ll_pipe_free(struct fuse_ll_pipe *llp)
  376. {
  377. close(llp->pipe[0]);
  378. close(llp->pipe[1]);
  379. free(llp);
  380. }
  381. static
  382. int
  383. fuse_send_data_iov(struct fuse_ll *f,
  384. struct fuse_chan *ch,
  385. struct iovec *iov,
  386. int iov_count,
  387. struct fuse_bufvec *buf,
  388. unsigned int flags)
  389. {
  390. size_t len = fuse_buf_size(buf);
  391. (void) flags;
  392. return fuse_send_data_iov_fallback(f, ch, iov, iov_count, buf, len);
  393. }
  394. int
  395. fuse_reply_data(fuse_req_t req,
  396. char *buf_,
  397. const size_t bufsize_)
  398. {
  399. int res;
  400. struct iovec iov[2];
  401. struct fuse_out_header out;
  402. iov[0].iov_base = &out;
  403. iov[0].iov_len = sizeof(struct fuse_out_header);
  404. iov[1].iov_base = buf_;
  405. iov[1].iov_len = bufsize_;
  406. out.unique = req->unique;
  407. out.error = 0;
  408. res = fuse_send_msg(req->f,req->ch,iov,2);
  409. if(res <= 0)
  410. {
  411. destroy_req(req);
  412. return res;
  413. }
  414. else
  415. {
  416. return fuse_reply_err(req, res);
  417. }
  418. }
  419. int
  420. fuse_reply_statfs(fuse_req_t req,
  421. const struct statvfs *stbuf)
  422. {
  423. struct fuse_statfs_out arg = {0};
  424. size_t size = req->f->conn.proto_minor < 4 ?
  425. FUSE_COMPAT_STATFS_SIZE : sizeof(arg);
  426. convert_statfs(stbuf, &arg.st);
  427. return send_reply_ok(req, &arg, size);
  428. }
  429. int
  430. fuse_reply_xattr(fuse_req_t req,
  431. size_t count)
  432. {
  433. struct fuse_getxattr_out arg = {0};
  434. arg.size = count;
  435. return send_reply_ok(req, &arg, sizeof(arg));
  436. }
  437. int
  438. fuse_reply_lock(fuse_req_t req,
  439. const struct flock *lock)
  440. {
  441. struct fuse_lk_out arg = {0};
  442. arg.lk.type = lock->l_type;
  443. if(lock->l_type != F_UNLCK)
  444. {
  445. arg.lk.start = lock->l_start;
  446. if(lock->l_len == 0)
  447. arg.lk.end = OFFSET_MAX;
  448. else
  449. arg.lk.end = lock->l_start + lock->l_len - 1;
  450. }
  451. arg.lk.pid = lock->l_pid;
  452. return send_reply_ok(req, &arg, sizeof(arg));
  453. }
  454. int
  455. fuse_reply_bmap(fuse_req_t req,
  456. uint64_t idx)
  457. {
  458. struct fuse_bmap_out arg = {0};
  459. arg.block = idx;
  460. return send_reply_ok(req, &arg, sizeof(arg));
  461. }
  462. static
  463. struct fuse_ioctl_iovec*
  464. fuse_ioctl_iovec_copy(const struct iovec *iov,
  465. size_t count)
  466. {
  467. struct fuse_ioctl_iovec *fiov;
  468. size_t i;
  469. fiov = malloc(sizeof(fiov[0]) * count);
  470. if(!fiov)
  471. return NULL;
  472. for (i = 0; i < count; i++)
  473. {
  474. fiov[i].base = (uintptr_t) iov[i].iov_base;
  475. fiov[i].len = iov[i].iov_len;
  476. }
  477. return fiov;
  478. }
  479. int
  480. fuse_reply_ioctl_retry(fuse_req_t req,
  481. const struct iovec *in_iov,
  482. size_t in_count,
  483. const struct iovec *out_iov,
  484. size_t out_count)
  485. {
  486. struct fuse_ioctl_out arg = {0};
  487. struct fuse_ioctl_iovec *in_fiov = NULL;
  488. struct fuse_ioctl_iovec *out_fiov = NULL;
  489. struct iovec iov[4];
  490. size_t count = 1;
  491. int res;
  492. arg.flags |= FUSE_IOCTL_RETRY;
  493. arg.in_iovs = in_count;
  494. arg.out_iovs = out_count;
  495. iov[count].iov_base = &arg;
  496. iov[count].iov_len = sizeof(arg);
  497. count++;
  498. if(req->f->conn.proto_minor < 16)
  499. {
  500. if(in_count)
  501. {
  502. iov[count].iov_base = (void *)in_iov;
  503. iov[count].iov_len = sizeof(in_iov[0]) * in_count;
  504. count++;
  505. }
  506. if(out_count)
  507. {
  508. iov[count].iov_base = (void *)out_iov;
  509. iov[count].iov_len = sizeof(out_iov[0]) * out_count;
  510. count++;
  511. }
  512. }
  513. else
  514. {
  515. /* Can't handle non-compat 64bit ioctls on 32bit */
  516. if((sizeof(void *) == 4) && (req->ioctl_64bit))
  517. {
  518. res = fuse_reply_err(req, EINVAL);
  519. goto out;
  520. }
  521. if(in_count)
  522. {
  523. in_fiov = fuse_ioctl_iovec_copy(in_iov, in_count);
  524. if(!in_fiov)
  525. goto enomem;
  526. iov[count].iov_base = (void *)in_fiov;
  527. iov[count].iov_len = sizeof(in_fiov[0]) * in_count;
  528. count++;
  529. }
  530. if(out_count)
  531. {
  532. out_fiov = fuse_ioctl_iovec_copy(out_iov, out_count);
  533. if(!out_fiov)
  534. goto enomem;
  535. iov[count].iov_base = (void *)out_fiov;
  536. iov[count].iov_len = sizeof(out_fiov[0]) * out_count;
  537. count++;
  538. }
  539. }
  540. res = send_reply_iov(req, 0, iov, count);
  541. out:
  542. free(in_fiov);
  543. free(out_fiov);
  544. return res;
  545. enomem:
  546. res = fuse_reply_err(req, ENOMEM);
  547. goto out;
  548. }
  549. int
  550. fuse_reply_ioctl(fuse_req_t req,
  551. int result,
  552. const void *buf,
  553. uint32_t size)
  554. {
  555. int count;
  556. struct iovec iov[3];
  557. struct fuse_ioctl_out arg;
  558. arg.result = result;
  559. arg.flags = 0;
  560. arg.in_iovs = 0;
  561. arg.out_iovs = 0;
  562. count = 1;
  563. iov[count].iov_base = &arg;
  564. iov[count].iov_len = sizeof(arg);
  565. count++;
  566. if(size)
  567. {
  568. iov[count].iov_base = (char*)buf;
  569. iov[count].iov_len = size;
  570. count++;
  571. }
  572. return send_reply_iov(req, 0, iov, count);
  573. }
  574. int
  575. fuse_reply_ioctl_iov(fuse_req_t req,
  576. int result,
  577. const struct iovec *iov,
  578. int count)
  579. {
  580. struct iovec *padded_iov;
  581. struct fuse_ioctl_out arg = {0};
  582. int res;
  583. padded_iov = malloc((count + 2) * sizeof(struct iovec));
  584. if(padded_iov == NULL)
  585. return fuse_reply_err(req, ENOMEM);
  586. arg.result = result;
  587. padded_iov[1].iov_base = &arg;
  588. padded_iov[1].iov_len = sizeof(arg);
  589. memcpy(&padded_iov[2], iov, count * sizeof(struct iovec));
  590. res = send_reply_iov(req, 0, padded_iov, count + 2);
  591. free(padded_iov);
  592. return res;
  593. }
  594. int
  595. fuse_reply_poll(fuse_req_t req,
  596. unsigned revents)
  597. {
  598. struct fuse_poll_out arg = {0};
  599. arg.revents = revents;
  600. return send_reply_ok(req, &arg, sizeof(arg));
  601. }
  602. static
  603. void
  604. do_lookup(fuse_req_t req,
  605. struct fuse_in_header *hdr_)
  606. {
  607. req->f->op.lookup(req,hdr_);
  608. }
  609. static
  610. void
  611. do_forget(fuse_req_t req,
  612. struct fuse_in_header *hdr_)
  613. {
  614. req->f->op.forget(req,hdr_);
  615. }
  616. static
  617. void
  618. do_batch_forget(fuse_req_t req,
  619. struct fuse_in_header *hdr_)
  620. {
  621. req->f->op.forget_multi(req,hdr_);
  622. }
  623. static
  624. void
  625. do_getattr(fuse_req_t req,
  626. struct fuse_in_header *hdr_)
  627. {
  628. req->f->op.getattr(req, hdr_);
  629. }
  630. static
  631. void
  632. do_setattr(fuse_req_t req_,
  633. struct fuse_in_header *hdr_)
  634. {
  635. req_->f->op.setattr(req_,hdr_);
  636. }
  637. static
  638. void
  639. do_access(fuse_req_t req,
  640. struct fuse_in_header *hdr_)
  641. {
  642. req->f->op.access(req,hdr_);
  643. }
  644. static
  645. void
  646. do_readlink(fuse_req_t req,
  647. struct fuse_in_header *hdr_)
  648. {
  649. req->f->op.readlink(req,hdr_);
  650. }
  651. static
  652. void
  653. do_mknod(fuse_req_t req,
  654. struct fuse_in_header *hdr_)
  655. {
  656. req->f->op.mknod(req,hdr_);
  657. }
  658. static
  659. void
  660. do_mkdir(fuse_req_t req,
  661. struct fuse_in_header *hdr_)
  662. {
  663. req->f->op.mkdir(req,hdr_);
  664. }
  665. static
  666. void
  667. do_unlink(fuse_req_t req,
  668. struct fuse_in_header *hdr_)
  669. {
  670. req->f->op.unlink(req,hdr_);
  671. }
  672. static
  673. void
  674. do_rmdir(fuse_req_t req,
  675. struct fuse_in_header *hdr_)
  676. {
  677. req->f->op.rmdir(req,hdr_);
  678. }
  679. static
  680. void
  681. do_symlink(fuse_req_t req,
  682. struct fuse_in_header *hdr_)
  683. {
  684. req->f->op.symlink(req,hdr_);
  685. }
  686. static
  687. void
  688. do_rename(fuse_req_t req,
  689. struct fuse_in_header *hdr_)
  690. {
  691. req->f->op.rename(req,hdr_);
  692. }
  693. static
  694. void
  695. do_link(fuse_req_t req,
  696. struct fuse_in_header *hdr_)
  697. {
  698. req->f->op.link(req,hdr_);
  699. }
  700. static
  701. void
  702. do_create(fuse_req_t req,
  703. struct fuse_in_header *hdr_)
  704. {
  705. req->f->op.create(req,hdr_);
  706. }
  707. static
  708. void
  709. do_open(fuse_req_t req,
  710. struct fuse_in_header *hdr_)
  711. {
  712. req->f->op.open(req,hdr_);
  713. }
  714. static
  715. void
  716. do_read(fuse_req_t req,
  717. struct fuse_in_header *hdr_)
  718. {
  719. req->f->op.read(req,hdr_);
  720. }
  721. static
  722. void
  723. do_write(fuse_req_t req,
  724. struct fuse_in_header *hdr_)
  725. {
  726. req->f->op.write(req,hdr_);
  727. }
  728. static
  729. void
  730. do_flush(fuse_req_t req,
  731. struct fuse_in_header *hdr_)
  732. {
  733. req->f->op.flush(req,hdr_);
  734. }
  735. static
  736. void
  737. do_release(fuse_req_t req,
  738. struct fuse_in_header *hdr_)
  739. {
  740. req->f->op.release(req,hdr_);
  741. }
  742. static
  743. void
  744. do_fsync(fuse_req_t req,
  745. struct fuse_in_header *hdr_)
  746. {
  747. req->f->op.fsync(req,hdr_);
  748. }
  749. static
  750. void
  751. do_opendir(fuse_req_t req,
  752. struct fuse_in_header *hdr_)
  753. {
  754. req->f->op.opendir(req,hdr_);
  755. }
  756. static
  757. void
  758. do_readdir(fuse_req_t req,
  759. struct fuse_in_header *hdr_)
  760. {
  761. req->f->op.readdir(req,hdr_);
  762. }
  763. static
  764. void
  765. do_readdir_plus(fuse_req_t req_,
  766. struct fuse_in_header *hdr_)
  767. {
  768. req_->f->op.readdir_plus(req_,hdr_);
  769. }
  770. static
  771. void
  772. do_releasedir(fuse_req_t req,
  773. struct fuse_in_header *hdr_)
  774. {
  775. req->f->op.releasedir(req,hdr_);
  776. }
  777. static
  778. void
  779. do_fsyncdir(fuse_req_t req,
  780. struct fuse_in_header *hdr_)
  781. {
  782. req->f->op.fsyncdir(req,hdr_);
  783. }
  784. static
  785. void
  786. do_statfs(fuse_req_t req,
  787. struct fuse_in_header *hdr_)
  788. {
  789. req->f->op.statfs(req,hdr_);
  790. }
  791. static
  792. void
  793. do_setxattr(fuse_req_t req,
  794. struct fuse_in_header *hdr_)
  795. {
  796. req->f->op.setxattr(req,hdr_);
  797. }
  798. static
  799. void
  800. do_getxattr(fuse_req_t req,
  801. struct fuse_in_header *hdr_)
  802. {
  803. req->f->op.getxattr(req,hdr_);
  804. }
  805. static
  806. void
  807. do_listxattr(fuse_req_t req,
  808. struct fuse_in_header *hdr_)
  809. {
  810. req->f->op.listxattr(req,hdr_);
  811. }
  812. static
  813. void
  814. do_removexattr(fuse_req_t req,
  815. struct fuse_in_header *hdr_)
  816. {
  817. req->f->op.removexattr(req,hdr_);
  818. }
  819. static
  820. void
  821. convert_fuse_file_lock(struct fuse_file_lock *fl,
  822. struct flock *flock)
  823. {
  824. memset(flock, 0, sizeof(struct flock));
  825. flock->l_type = fl->type;
  826. flock->l_whence = SEEK_SET;
  827. flock->l_start = fl->start;
  828. if(fl->end == OFFSET_MAX)
  829. flock->l_len = 0;
  830. else
  831. flock->l_len = fl->end - fl->start + 1;
  832. flock->l_pid = fl->pid;
  833. }
  834. static
  835. void
  836. do_getlk(fuse_req_t req,
  837. struct fuse_in_header *hdr_)
  838. {
  839. req->f->op.getlk(req,hdr_);
  840. }
  841. static
  842. void
  843. do_setlk_common(fuse_req_t req,
  844. uint64_t nodeid,
  845. const void *inarg,
  846. int sleep)
  847. {
  848. struct flock flock;
  849. fuse_file_info_t fi = {0};
  850. struct fuse_lk_in *arg = (struct fuse_lk_in*)inarg;
  851. fi.fh = arg->fh;
  852. fi.lock_owner = arg->owner;
  853. if(arg->lk_flags & FUSE_LK_FLOCK)
  854. {
  855. int op = 0;
  856. switch (arg->lk.type)
  857. {
  858. case F_RDLCK:
  859. op = LOCK_SH;
  860. break;
  861. case F_WRLCK:
  862. op = LOCK_EX;
  863. break;
  864. case F_UNLCK:
  865. op = LOCK_UN;
  866. break;
  867. }
  868. if(!sleep)
  869. op |= LOCK_NB;
  870. req->f->op.flock(req,nodeid,&fi,op);
  871. }
  872. else
  873. {
  874. convert_fuse_file_lock(&arg->lk, &flock);
  875. req->f->op.setlk(req,nodeid,&fi,&flock,sleep);
  876. }
  877. }
  878. static
  879. void
  880. do_setlk(fuse_req_t req,
  881. struct fuse_in_header *hdr_)
  882. {
  883. do_setlk_common(req, hdr_->nodeid, &hdr_[1], 0);
  884. }
  885. static
  886. void
  887. do_setlkw(fuse_req_t req,
  888. struct fuse_in_header *hdr_)
  889. {
  890. do_setlk_common(req, hdr_->nodeid, &hdr_[1], 1);
  891. }
  892. static
  893. void
  894. do_interrupt(fuse_req_t req,
  895. struct fuse_in_header *hdr_)
  896. {
  897. destroy_req(req);
  898. }
  899. static
  900. void
  901. do_bmap(fuse_req_t req,
  902. struct fuse_in_header *hdr_)
  903. {
  904. req->f->op.bmap(req,hdr_);
  905. }
  906. static
  907. void
  908. do_ioctl(fuse_req_t req,
  909. struct fuse_in_header *hdr_)
  910. {
  911. req->f->op.ioctl(req, hdr_);
  912. }
  913. void
  914. fuse_pollhandle_destroy(fuse_pollhandle_t *ph)
  915. {
  916. free(ph);
  917. }
  918. static
  919. void
  920. do_poll(fuse_req_t req,
  921. struct fuse_in_header *hdr_)
  922. {
  923. req->f->op.poll(req,hdr_);
  924. }
  925. static
  926. void
  927. do_fallocate(fuse_req_t req,
  928. struct fuse_in_header *hdr_)
  929. {
  930. req->f->op.fallocate(req,hdr_);
  931. }
  932. static
  933. void
  934. do_init(fuse_req_t req,
  935. struct fuse_in_header *hdr_)
  936. {
  937. struct fuse_init_out outarg = {0};
  938. struct fuse_init_in *arg = (struct fuse_init_in *) &hdr_[1];
  939. struct fuse_ll *f = req->f;
  940. size_t bufsize = fuse_chan_bufsize(req->ch);
  941. uint64_t inargflags;
  942. uint64_t outargflags;
  943. inargflags = 0;
  944. outargflags = 0;
  945. if(f->debug)
  946. debug_fuse_init_in(arg);
  947. f->conn.proto_major = arg->major;
  948. f->conn.proto_minor = arg->minor;
  949. f->conn.capable = 0;
  950. f->conn.want = 0;
  951. outarg.major = FUSE_KERNEL_VERSION;
  952. outarg.minor = FUSE_KERNEL_MINOR_VERSION;
  953. outarg.max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
  954. if(arg->major < 7)
  955. {
  956. fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n",
  957. arg->major, arg->minor);
  958. fuse_reply_err(req, EPROTO);
  959. return;
  960. }
  961. if(arg->major > 7)
  962. {
  963. /* Wait for a second INIT request with a 7.X version */
  964. send_reply_ok(req, &outarg, sizeof(outarg));
  965. return;
  966. }
  967. if(arg->minor >= 6)
  968. {
  969. inargflags = arg->flags;
  970. if(inargflags & FUSE_INIT_EXT)
  971. inargflags |= (((uint64_t)arg->flags2) << 32);
  972. if(arg->max_readahead < f->conn.max_readahead)
  973. f->conn.max_readahead = arg->max_readahead;
  974. if(inargflags & FUSE_ASYNC_READ)
  975. f->conn.capable |= FUSE_CAP_ASYNC_READ;
  976. if(inargflags & FUSE_POSIX_LOCKS)
  977. f->conn.capable |= FUSE_CAP_POSIX_LOCKS;
  978. if(inargflags & FUSE_ATOMIC_O_TRUNC)
  979. f->conn.capable |= FUSE_CAP_ATOMIC_O_TRUNC;
  980. if(inargflags & FUSE_EXPORT_SUPPORT)
  981. f->conn.capable |= FUSE_CAP_EXPORT_SUPPORT;
  982. if(inargflags & FUSE_BIG_WRITES)
  983. f->conn.capable |= FUSE_CAP_BIG_WRITES;
  984. if(inargflags & FUSE_DONT_MASK)
  985. f->conn.capable |= FUSE_CAP_DONT_MASK;
  986. if(inargflags & FUSE_FLOCK_LOCKS)
  987. f->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
  988. if(inargflags & FUSE_POSIX_ACL)
  989. f->conn.capable |= FUSE_CAP_POSIX_ACL;
  990. if(inargflags & FUSE_CACHE_SYMLINKS)
  991. f->conn.capable |= FUSE_CAP_CACHE_SYMLINKS;
  992. if(inargflags & FUSE_ASYNC_DIO)
  993. f->conn.capable |= FUSE_CAP_ASYNC_DIO;
  994. if(inargflags & FUSE_PARALLEL_DIROPS)
  995. f->conn.capable |= FUSE_CAP_PARALLEL_DIROPS;
  996. if(inargflags & FUSE_MAX_PAGES)
  997. f->conn.capable |= FUSE_CAP_MAX_PAGES;
  998. if(inargflags & FUSE_WRITEBACK_CACHE)
  999. f->conn.capable |= FUSE_CAP_WRITEBACK_CACHE;
  1000. if(inargflags & FUSE_DO_READDIRPLUS)
  1001. f->conn.capable |= FUSE_CAP_READDIR_PLUS;
  1002. if(inargflags & FUSE_READDIRPLUS_AUTO)
  1003. f->conn.capable |= FUSE_CAP_READDIR_PLUS_AUTO;
  1004. if(inargflags & FUSE_SETXATTR_EXT)
  1005. f->conn.capable |= FUSE_CAP_SETXATTR_EXT;
  1006. if(inargflags & FUSE_DIRECT_IO_ALLOW_MMAP)
  1007. f->conn.capable |= FUSE_CAP_DIRECT_IO_ALLOW_MMAP;
  1008. if(inargflags & FUSE_CREATE_SUPP_GROUP)
  1009. f->conn.capable |= FUSE_CAP_CREATE_SUPP_GROUP;
  1010. if(inargflags & FUSE_PASSTHROUGH)
  1011. f->conn.capable |= FUSE_CAP_PASSTHROUGH;
  1012. if(inargflags & FUSE_HANDLE_KILLPRIV)
  1013. f->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
  1014. if(inargflags & FUSE_HANDLE_KILLPRIV_V2)
  1015. f->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV_V2;
  1016. }
  1017. else
  1018. {
  1019. f->conn.want &= ~FUSE_CAP_ASYNC_READ;
  1020. f->conn.max_readahead = 0;
  1021. }
  1022. if(req->f->conn.proto_minor >= 18)
  1023. f->conn.capable |= FUSE_CAP_IOCTL_DIR;
  1024. if(f->op.getlk && f->op.setlk && !f->no_remote_posix_lock)
  1025. f->conn.want |= FUSE_CAP_POSIX_LOCKS;
  1026. if(f->op.flock && !f->no_remote_flock)
  1027. f->conn.want |= FUSE_CAP_FLOCK_LOCKS;
  1028. if(bufsize < FUSE_MIN_READ_BUFFER)
  1029. {
  1030. fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
  1031. bufsize);
  1032. bufsize = FUSE_MIN_READ_BUFFER;
  1033. }
  1034. bufsize -= pagesize;
  1035. if(bufsize < f->conn.max_write)
  1036. f->conn.max_write = bufsize;
  1037. f->got_init = 1;
  1038. if(f->op.init)
  1039. f->op.init(f->userdata, &f->conn);
  1040. outargflags = outarg.flags;
  1041. if((inargflags & FUSE_MAX_PAGES) && (f->conn.want & FUSE_CAP_MAX_PAGES))
  1042. {
  1043. outargflags |= FUSE_MAX_PAGES;
  1044. outarg.max_pages = f->conn.max_pages;
  1045. msgbuf_set_bufsize(outarg.max_pages + 1);
  1046. }
  1047. if(f->conn.want & FUSE_CAP_ASYNC_READ)
  1048. outargflags |= FUSE_ASYNC_READ;
  1049. if(f->conn.want & FUSE_CAP_POSIX_LOCKS)
  1050. outargflags |= FUSE_POSIX_LOCKS;
  1051. if(f->conn.want & FUSE_CAP_ATOMIC_O_TRUNC)
  1052. outargflags |= FUSE_ATOMIC_O_TRUNC;
  1053. if(f->conn.want & FUSE_CAP_EXPORT_SUPPORT)
  1054. outargflags |= FUSE_EXPORT_SUPPORT;
  1055. if(f->conn.want & FUSE_CAP_BIG_WRITES)
  1056. outargflags |= FUSE_BIG_WRITES;
  1057. if(f->conn.want & FUSE_CAP_DONT_MASK)
  1058. outargflags |= FUSE_DONT_MASK;
  1059. if(f->conn.want & FUSE_CAP_FLOCK_LOCKS)
  1060. outargflags |= FUSE_FLOCK_LOCKS;
  1061. if(f->conn.want & FUSE_CAP_POSIX_ACL)
  1062. outargflags |= FUSE_POSIX_ACL;
  1063. if(f->conn.want & FUSE_CAP_CACHE_SYMLINKS)
  1064. outargflags |= FUSE_CACHE_SYMLINKS;
  1065. if(f->conn.want & FUSE_CAP_ASYNC_DIO)
  1066. outargflags |= FUSE_ASYNC_DIO;
  1067. if(f->conn.want & FUSE_CAP_PARALLEL_DIROPS)
  1068. outargflags |= FUSE_PARALLEL_DIROPS;
  1069. if(f->conn.want & FUSE_CAP_WRITEBACK_CACHE)
  1070. outargflags |= FUSE_WRITEBACK_CACHE;
  1071. if(f->conn.want & FUSE_CAP_READDIR_PLUS)
  1072. outargflags |= FUSE_DO_READDIRPLUS;
  1073. if(f->conn.want & FUSE_CAP_READDIR_PLUS_AUTO)
  1074. outargflags |= FUSE_READDIRPLUS_AUTO;
  1075. if(f->conn.want & FUSE_CAP_SETXATTR_EXT)
  1076. outargflags |= FUSE_SETXATTR_EXT;
  1077. if(f->conn.want & FUSE_CAP_CREATE_SUPP_GROUP)
  1078. outargflags |= FUSE_CREATE_SUPP_GROUP;
  1079. if(f->conn.want & FUSE_CAP_DIRECT_IO_ALLOW_MMAP)
  1080. outargflags |= FUSE_DIRECT_IO_ALLOW_MMAP;
  1081. if(f->conn.want & FUSE_CAP_HANDLE_KILLPRIV)
  1082. outargflags |= FUSE_HANDLE_KILLPRIV;
  1083. if(f->conn.want & FUSE_CAP_HANDLE_KILLPRIV_V2)
  1084. outargflags |= FUSE_HANDLE_KILLPRIV_V2;
  1085. if(f->conn.want & FUSE_CAP_PASSTHROUGH)
  1086. {
  1087. outargflags |= FUSE_PASSTHROUGH;
  1088. outarg.max_stack_depth = 1;
  1089. }
  1090. if(inargflags & FUSE_INIT_EXT)
  1091. {
  1092. outargflags |= FUSE_INIT_EXT;
  1093. outarg.flags2 = (outargflags >> 32);
  1094. }
  1095. outarg.flags = outargflags;
  1096. outarg.max_readahead = f->conn.max_readahead;
  1097. outarg.max_write = f->conn.max_write;
  1098. if(f->conn.proto_minor >= 13)
  1099. {
  1100. if(f->conn.max_background >= (1 << 16))
  1101. f->conn.max_background = (1 << 16) - 1;
  1102. if(f->conn.congestion_threshold > f->conn.max_background)
  1103. f->conn.congestion_threshold = f->conn.max_background;
  1104. if(!f->conn.congestion_threshold)
  1105. {
  1106. f->conn.congestion_threshold = f->conn.max_background * 3 / 4;
  1107. }
  1108. outarg.max_background = f->conn.max_background;
  1109. outarg.congestion_threshold = f->conn.congestion_threshold;
  1110. }
  1111. if(f->conn.proto_minor >= 23)
  1112. outarg.time_gran = 1;
  1113. size_t outargsize;
  1114. if(arg->minor < 5)
  1115. outargsize = FUSE_COMPAT_INIT_OUT_SIZE;
  1116. else if(arg->minor < 23)
  1117. outargsize = FUSE_COMPAT_22_INIT_OUT_SIZE;
  1118. else
  1119. outargsize = sizeof(outarg);
  1120. if(f->debug)
  1121. debug_fuse_init_out(req->unique,&outarg,outargsize);
  1122. send_reply_ok(req, &outarg, outargsize);
  1123. }
  1124. static
  1125. void
  1126. do_destroy(fuse_req_t req,
  1127. struct fuse_in_header *hdr_)
  1128. {
  1129. struct fuse_ll *f = req->f;
  1130. f->got_destroy = 1;
  1131. f->op.destroy(f->userdata);
  1132. send_reply_ok(req,NULL,0);
  1133. }
  1134. static
  1135. void
  1136. list_del_nreq(struct fuse_notify_req *nreq)
  1137. {
  1138. struct fuse_notify_req *prev = nreq->prev;
  1139. struct fuse_notify_req *next = nreq->next;
  1140. prev->next = next;
  1141. next->prev = prev;
  1142. }
  1143. static
  1144. void
  1145. list_add_nreq(struct fuse_notify_req *nreq,
  1146. struct fuse_notify_req *next)
  1147. {
  1148. struct fuse_notify_req *prev = next->prev;
  1149. nreq->next = next;
  1150. nreq->prev = prev;
  1151. prev->next = nreq;
  1152. next->prev = nreq;
  1153. }
  1154. static
  1155. void
  1156. list_init_nreq(struct fuse_notify_req *nreq)
  1157. {
  1158. nreq->next = nreq;
  1159. nreq->prev = nreq;
  1160. }
  1161. static
  1162. void
  1163. do_notify_reply(fuse_req_t req,
  1164. struct fuse_in_header *hdr_)
  1165. {
  1166. struct fuse_ll *f = req->f;
  1167. struct fuse_notify_req *nreq;
  1168. struct fuse_notify_req *head;
  1169. pthread_mutex_lock(&f->lock);
  1170. head = &f->notify_list;
  1171. for(nreq = head->next; nreq != head; nreq = nreq->next)
  1172. {
  1173. if(nreq->unique == req->unique)
  1174. {
  1175. list_del_nreq(nreq);
  1176. break;
  1177. }
  1178. }
  1179. pthread_mutex_unlock(&f->lock);
  1180. if(nreq != head)
  1181. nreq->reply(nreq, req, hdr_->nodeid, &hdr_[1]);
  1182. }
  1183. static
  1184. void
  1185. do_copy_file_range(fuse_req_t req_,
  1186. struct fuse_in_header *hdr_)
  1187. {
  1188. req_->f->op.copy_file_range(req_,hdr_);
  1189. }
  1190. static
  1191. void
  1192. do_setupmapping(fuse_req_t req_,
  1193. struct fuse_in_header *hdr_)
  1194. {
  1195. printf("setupmapping\n");
  1196. req_->f->op.setupmapping(req_,hdr_);
  1197. }
  1198. static
  1199. void
  1200. do_removemapping(fuse_req_t req_,
  1201. struct fuse_in_header *hdr_)
  1202. {
  1203. printf("removemapping\n");
  1204. req_->f->op.removemapping(req_,hdr_);
  1205. }
  1206. static
  1207. void
  1208. do_syncfs(fuse_req_t req_,
  1209. struct fuse_in_header *hdr_)
  1210. {
  1211. printf("syncfs\n");
  1212. req_->f->op.syncfs(req_,hdr_);
  1213. }
  1214. static
  1215. void
  1216. do_tmpfile(fuse_req_t req_,
  1217. struct fuse_in_header *hdr_)
  1218. {
  1219. printf("tmpfile\n");
  1220. req_->f->op.tmpfile(req_,hdr_);
  1221. }
  1222. static
  1223. int
  1224. send_notify_iov(struct fuse_ll *f,
  1225. struct fuse_chan *ch,
  1226. int notify_code,
  1227. struct iovec *iov,
  1228. int count)
  1229. {
  1230. struct fuse_out_header out;
  1231. if(!f->got_init)
  1232. return -ENOTCONN;
  1233. out.unique = 0;
  1234. out.error = notify_code;
  1235. iov[0].iov_base = &out;
  1236. iov[0].iov_len = sizeof(struct fuse_out_header);
  1237. return fuse_send_msg(f, ch, iov, count);
  1238. }
  1239. int
  1240. fuse_lowlevel_notify_poll(fuse_pollhandle_t *ph)
  1241. {
  1242. if(ph != NULL)
  1243. {
  1244. struct fuse_notify_poll_wakeup_out outarg;
  1245. struct iovec iov[2];
  1246. outarg.kh = ph->kh;
  1247. iov[1].iov_base = &outarg;
  1248. iov[1].iov_len = sizeof(outarg);
  1249. return send_notify_iov(ph->f, ph->ch, FUSE_NOTIFY_POLL, iov, 2);
  1250. }
  1251. else
  1252. {
  1253. return 0;
  1254. }
  1255. }
  1256. int
  1257. fuse_lowlevel_notify_inval_inode(struct fuse_chan *ch,
  1258. uint64_t ino,
  1259. off_t off,
  1260. off_t len)
  1261. {
  1262. struct fuse_notify_inval_inode_out outarg;
  1263. struct fuse_ll *f;
  1264. struct iovec iov[2];
  1265. if(!ch)
  1266. return -EINVAL;
  1267. f = (struct fuse_ll*)fuse_session_data(fuse_chan_session(ch));
  1268. if(!f)
  1269. return -ENODEV;
  1270. outarg.ino = ino;
  1271. outarg.off = off;
  1272. outarg.len = len;
  1273. iov[1].iov_base = &outarg;
  1274. iov[1].iov_len = sizeof(outarg);
  1275. return send_notify_iov(f, ch, FUSE_NOTIFY_INVAL_INODE, iov, 2);
  1276. }
  1277. int
  1278. fuse_lowlevel_notify_inval_entry(struct fuse_chan *ch,
  1279. uint64_t parent,
  1280. const char *name,
  1281. size_t namelen)
  1282. {
  1283. struct fuse_notify_inval_entry_out outarg;
  1284. struct fuse_ll *f;
  1285. struct iovec iov[3];
  1286. if(!ch)
  1287. return -EINVAL;
  1288. f = (struct fuse_ll*)fuse_session_data(fuse_chan_session(ch));
  1289. if(!f)
  1290. return -ENODEV;
  1291. outarg.parent = parent;
  1292. outarg.namelen = namelen;
  1293. // TODO: Add ability to set `flags`
  1294. outarg.flags = 0;
  1295. iov[1].iov_base = &outarg;
  1296. iov[1].iov_len = sizeof(outarg);
  1297. iov[2].iov_base = (void *)name;
  1298. iov[2].iov_len = namelen + 1;
  1299. return send_notify_iov(f, ch, FUSE_NOTIFY_INVAL_ENTRY, iov, 3);
  1300. }
  1301. int
  1302. fuse_lowlevel_notify_delete(struct fuse_chan *ch,
  1303. uint64_t parent,
  1304. uint64_t child,
  1305. const char *name,
  1306. size_t namelen)
  1307. {
  1308. struct fuse_notify_delete_out outarg;
  1309. struct fuse_ll *f;
  1310. struct iovec iov[3];
  1311. if(!ch)
  1312. return -EINVAL;
  1313. f = (struct fuse_ll*)fuse_session_data(fuse_chan_session(ch));
  1314. if(!f)
  1315. return -ENODEV;
  1316. if(f->conn.proto_minor < 18)
  1317. return -ENOSYS;
  1318. outarg.parent = parent;
  1319. outarg.child = child;
  1320. outarg.namelen = namelen;
  1321. outarg.padding = 0;
  1322. iov[1].iov_base = &outarg;
  1323. iov[1].iov_len = sizeof(outarg);
  1324. iov[2].iov_base = (void *)name;
  1325. iov[2].iov_len = namelen + 1;
  1326. return send_notify_iov(f, ch, FUSE_NOTIFY_DELETE, iov, 3);
  1327. }
  1328. int
  1329. fuse_lowlevel_notify_store(struct fuse_chan *ch,
  1330. uint64_t ino,
  1331. off_t offset,
  1332. struct fuse_bufvec *bufv,
  1333. enum fuse_buf_copy_flags flags)
  1334. {
  1335. struct fuse_out_header out;
  1336. struct fuse_notify_store_out outarg;
  1337. struct fuse_ll *f;
  1338. struct iovec iov[3];
  1339. size_t size = fuse_buf_size(bufv);
  1340. int res;
  1341. if(!ch)
  1342. return -EINVAL;
  1343. f = (struct fuse_ll*)fuse_session_data(fuse_chan_session(ch));
  1344. if(!f)
  1345. return -ENODEV;
  1346. if(f->conn.proto_minor < 15)
  1347. return -ENOSYS;
  1348. out.unique = 0;
  1349. out.error = FUSE_NOTIFY_STORE;
  1350. outarg.nodeid = ino;
  1351. outarg.offset = offset;
  1352. outarg.size = size;
  1353. outarg.padding = 0;
  1354. iov[0].iov_base = &out;
  1355. iov[0].iov_len = sizeof(out);
  1356. iov[1].iov_base = &outarg;
  1357. iov[1].iov_len = sizeof(outarg);
  1358. res = fuse_send_data_iov(f, ch, iov, 2, bufv, flags);
  1359. if(res > 0)
  1360. res = -res;
  1361. return res;
  1362. }
  1363. struct fuse_retrieve_req
  1364. {
  1365. struct fuse_notify_req nreq;
  1366. void *cookie;
  1367. };
  1368. static
  1369. void
  1370. fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
  1371. fuse_req_t req,
  1372. uint64_t ino,
  1373. const void *inarg)
  1374. {
  1375. struct fuse_retrieve_req *rreq =
  1376. container_of(nreq, struct fuse_retrieve_req, nreq);
  1377. fuse_reply_none(req);
  1378. free(rreq);
  1379. }
  1380. int
  1381. fuse_lowlevel_notify_retrieve(struct fuse_chan *ch,
  1382. uint64_t ino,
  1383. size_t size,
  1384. off_t offset,
  1385. void *cookie)
  1386. {
  1387. struct fuse_notify_retrieve_out outarg;
  1388. struct fuse_ll *f;
  1389. struct iovec iov[2];
  1390. struct fuse_retrieve_req *rreq;
  1391. int err;
  1392. if(!ch)
  1393. return -EINVAL;
  1394. f = (struct fuse_ll*)fuse_session_data(fuse_chan_session(ch));
  1395. if(!f)
  1396. return -ENODEV;
  1397. if(f->conn.proto_minor < 15)
  1398. return -ENOSYS;
  1399. rreq = malloc(sizeof(*rreq));
  1400. if(rreq == NULL)
  1401. return -ENOMEM;
  1402. pthread_mutex_lock(&f->lock);
  1403. rreq->cookie = cookie;
  1404. rreq->nreq.unique = f->notify_ctr++;
  1405. rreq->nreq.reply = fuse_ll_retrieve_reply;
  1406. list_add_nreq(&rreq->nreq, &f->notify_list);
  1407. pthread_mutex_unlock(&f->lock);
  1408. outarg.notify_unique = rreq->nreq.unique;
  1409. outarg.nodeid = ino;
  1410. outarg.offset = offset;
  1411. outarg.size = size;
  1412. iov[1].iov_base = &outarg;
  1413. iov[1].iov_len = sizeof(outarg);
  1414. err = send_notify_iov(f, ch, FUSE_NOTIFY_RETRIEVE, iov, 2);
  1415. if(err)
  1416. {
  1417. pthread_mutex_lock(&f->lock);
  1418. list_del_nreq(&rreq->nreq);
  1419. pthread_mutex_unlock(&f->lock);
  1420. free(rreq);
  1421. }
  1422. return err;
  1423. }
  1424. void *
  1425. fuse_req_userdata(fuse_req_t req)
  1426. {
  1427. return req->f->userdata;
  1428. }
  1429. const
  1430. struct fuse_ctx *
  1431. fuse_req_ctx(fuse_req_t req)
  1432. {
  1433. return &req->ctx;
  1434. }
  1435. static struct {
  1436. void (*func)(fuse_req_t, struct fuse_in_header *);
  1437. const char *name;
  1438. } fuse_ll_ops[] =
  1439. {
  1440. [FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
  1441. [FUSE_FORGET] = { do_forget, "FORGET" },
  1442. [FUSE_GETATTR] = { do_getattr, "GETATTR" },
  1443. [FUSE_SETATTR] = { do_setattr, "SETATTR" },
  1444. [FUSE_READLINK] = { do_readlink, "READLINK" },
  1445. [FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
  1446. [FUSE_MKNOD] = { do_mknod, "MKNOD" },
  1447. [FUSE_MKDIR] = { do_mkdir, "MKDIR" },
  1448. [FUSE_UNLINK] = { do_unlink, "UNLINK" },
  1449. [FUSE_RMDIR] = { do_rmdir, "RMDIR" },
  1450. [FUSE_RENAME] = { do_rename, "RENAME" },
  1451. [FUSE_LINK] = { do_link, "LINK" },
  1452. [FUSE_OPEN] = { do_open, "OPEN" },
  1453. [FUSE_READ] = { do_read, "READ" },
  1454. [FUSE_WRITE] = { do_write, "WRITE" },
  1455. [FUSE_STATFS] = { do_statfs, "STATFS" },
  1456. [FUSE_RELEASE] = { do_release, "RELEASE" },
  1457. [FUSE_FSYNC] = { do_fsync, "FSYNC" },
  1458. [FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
  1459. [FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
  1460. [FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
  1461. [FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
  1462. [FUSE_FLUSH] = { do_flush, "FLUSH" },
  1463. [FUSE_INIT] = { do_init, "INIT" },
  1464. [FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
  1465. [FUSE_READDIR] = { do_readdir, "READDIR" },
  1466. [FUSE_READDIRPLUS] = { do_readdir_plus, "READDIR_PLUS" },
  1467. [FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
  1468. [FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
  1469. [FUSE_GETLK] = { do_getlk, "GETLK" },
  1470. [FUSE_SETLK] = { do_setlk, "SETLK" },
  1471. [FUSE_SETLKW] = { do_setlkw, "SETLKW" },
  1472. [FUSE_ACCESS] = { do_access, "ACCESS" },
  1473. [FUSE_CREATE] = { do_create, "CREATE" },
  1474. [FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
  1475. [FUSE_BMAP] = { do_bmap, "BMAP" },
  1476. [FUSE_IOCTL] = { do_ioctl, "IOCTL" },
  1477. [FUSE_POLL] = { do_poll, "POLL" },
  1478. [FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" },
  1479. [FUSE_DESTROY] = { do_destroy, "DESTROY" },
  1480. [FUSE_NOTIFY_REPLY] = { do_notify_reply, "NOTIFY_REPLY" },
  1481. [FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
  1482. [FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" },
  1483. [FUSE_SETUPMAPPING] = { do_setupmapping, "SETUPMAPPING" },
  1484. [FUSE_REMOVEMAPPING] = { do_removemapping, "REMOVEMAPPING" },
  1485. [FUSE_SYNCFS] = { do_syncfs, "SYNCFS" },
  1486. [FUSE_TMPFILE] = { do_tmpfile, "TMPFILE" }
  1487. };
  1488. #define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
  1489. enum {
  1490. KEY_HELP,
  1491. KEY_VERSION,
  1492. };
  1493. static const struct fuse_opt fuse_ll_opts[] =
  1494. {
  1495. { "debug", offsetof(struct fuse_ll, debug), 1 },
  1496. { "-d", offsetof(struct fuse_ll, debug), 1 },
  1497. { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 },
  1498. { "max_background=%u", offsetof(struct fuse_ll, conn.max_background), 0 },
  1499. { "congestion_threshold=%u",
  1500. offsetof(struct fuse_ll, conn.congestion_threshold), 0 },
  1501. { "no_remote_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1},
  1502. { "no_remote_lock", offsetof(struct fuse_ll, no_remote_flock), 1},
  1503. { "no_remote_flock", offsetof(struct fuse_ll, no_remote_flock), 1},
  1504. { "no_remote_posix_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1},
  1505. FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
  1506. FUSE_OPT_KEY("-h", KEY_HELP),
  1507. FUSE_OPT_KEY("--help", KEY_HELP),
  1508. FUSE_OPT_KEY("-V", KEY_VERSION),
  1509. FUSE_OPT_KEY("--version", KEY_VERSION),
  1510. FUSE_OPT_END
  1511. };
  1512. static
  1513. void
  1514. fuse_ll_version(void)
  1515. {
  1516. fprintf(stderr, "using FUSE kernel interface version %i.%i\n",
  1517. FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
  1518. }
  1519. static
  1520. void
  1521. fuse_ll_help(void)
  1522. {
  1523. fprintf(stderr,
  1524. " -o max_readahead=N set maximum readahead\n"
  1525. " -o max_background=N set number of maximum background requests\n"
  1526. " -o congestion_threshold=N set kernel's congestion threshold\n"
  1527. " -o no_remote_lock disable remote file locking\n"
  1528. " -o no_remote_flock disable remote file locking (BSD)\n"
  1529. " -o no_remote_posix_lock disable remove file locking (POSIX)\n"
  1530. );
  1531. }
  1532. static
  1533. int
  1534. fuse_ll_opt_proc(void *data,
  1535. const char *arg,
  1536. int key,
  1537. struct fuse_args *outargs)
  1538. {
  1539. (void) data; (void) outargs;
  1540. switch (key)
  1541. {
  1542. case KEY_HELP:
  1543. fuse_ll_help();
  1544. break;
  1545. case KEY_VERSION:
  1546. fuse_ll_version();
  1547. break;
  1548. default:
  1549. fprintf(stderr, "fuse: unknown option `%s'\n", arg);
  1550. }
  1551. return -1;
  1552. }
  1553. int
  1554. fuse_lowlevel_is_lib_option(const char *opt)
  1555. {
  1556. return fuse_opt_match(fuse_ll_opts, opt);
  1557. }
  1558. static
  1559. void
  1560. fuse_ll_destroy(void *data)
  1561. {
  1562. struct fuse_ll *f = (struct fuse_ll *)data;
  1563. struct fuse_ll_pipe *llp;
  1564. if(f->got_init && !f->got_destroy)
  1565. {
  1566. if(f->op.destroy)
  1567. f->op.destroy(f->userdata);
  1568. }
  1569. llp = pthread_getspecific(f->pipe_key);
  1570. if(llp != NULL)
  1571. fuse_ll_pipe_free(llp);
  1572. pthread_key_delete(f->pipe_key);
  1573. pthread_mutex_destroy(&f->lock);
  1574. free(f);
  1575. lfmp_clear(&g_FMP_fuse_req);
  1576. }
  1577. static
  1578. void
  1579. fuse_ll_pipe_destructor(void *data)
  1580. {
  1581. struct fuse_ll_pipe *llp = data;
  1582. fuse_ll_pipe_free(llp);
  1583. }
  1584. static
  1585. void
  1586. fuse_send_errno(struct fuse_ll *f_,
  1587. struct fuse_chan *ch_,
  1588. const int errno_,
  1589. const uint64_t unique_id_)
  1590. {
  1591. struct fuse_out_header out = {0};
  1592. struct iovec iov = {0};
  1593. out.unique = unique_id_;
  1594. out.error = -errno_;
  1595. iov.iov_base = &out;
  1596. iov.iov_len = sizeof(struct fuse_out_header);
  1597. fuse_send_msg(f_,ch_,&iov,1);
  1598. }
  1599. static
  1600. void
  1601. fuse_send_enomem(struct fuse_ll *f_,
  1602. struct fuse_chan *ch_,
  1603. const uint64_t unique_id_)
  1604. {
  1605. fuse_send_errno(f_,ch_,ENOMEM,unique_id_);
  1606. }
  1607. static
  1608. int
  1609. fuse_ll_buf_receive_read(struct fuse_session *se_,
  1610. fuse_msgbuf_t *msgbuf_)
  1611. {
  1612. int rv;
  1613. rv = read(fuse_chan_fd(se_->ch),msgbuf_->mem,msgbuf_->size);
  1614. if(rv == -1)
  1615. return -errno;
  1616. if(rv < sizeof(struct fuse_in_header))
  1617. {
  1618. fprintf(stderr, "short read from fuse device\n");
  1619. return -EIO;
  1620. }
  1621. return rv;
  1622. }
  1623. static
  1624. void
  1625. fuse_ll_buf_process_read(struct fuse_session *se_,
  1626. const fuse_msgbuf_t *msgbuf_)
  1627. {
  1628. int err;
  1629. struct fuse_req *req;
  1630. struct fuse_in_header *in;
  1631. in = (struct fuse_in_header*)msgbuf_->mem;
  1632. // printf("%d\n",in->opcode);
  1633. req = fuse_ll_alloc_req(se_->f);
  1634. if(req == NULL)
  1635. return fuse_send_enomem(se_->f,se_->ch,in->unique);
  1636. req->unique = in->unique;
  1637. req->ctx.uid = in->uid;
  1638. req->ctx.gid = in->gid;
  1639. req->ctx.pid = in->pid;
  1640. req->ch = se_->ch;
  1641. err = ENOSYS;
  1642. if(in->opcode >= FUSE_MAXOP)
  1643. goto reply_err;
  1644. if(fuse_ll_ops[in->opcode].func == NULL)
  1645. goto reply_err;
  1646. fuse_ll_ops[in->opcode].func(req, in);
  1647. return;
  1648. reply_err:
  1649. fuse_reply_err(req, err);
  1650. return;
  1651. }
  1652. static
  1653. void
  1654. fuse_ll_buf_process_read_init(struct fuse_session *se_,
  1655. const fuse_msgbuf_t *msgbuf_)
  1656. {
  1657. int err;
  1658. struct fuse_req *req;
  1659. struct fuse_in_header *in;
  1660. in = (struct fuse_in_header*)msgbuf_->mem;
  1661. req = fuse_ll_alloc_req(se_->f);
  1662. if(req == NULL)
  1663. return fuse_send_enomem(se_->f,se_->ch,in->unique);
  1664. req->unique = in->unique;
  1665. req->ctx.uid = in->uid;
  1666. req->ctx.gid = in->gid;
  1667. req->ctx.pid = in->pid;
  1668. req->ch = se_->ch;
  1669. err = EIO;
  1670. if(in->opcode != FUSE_INIT)
  1671. goto reply_err;
  1672. if(fuse_ll_ops[in->opcode].func == NULL)
  1673. goto reply_err;
  1674. se_->process_buf = fuse_ll_buf_process_read;
  1675. fuse_ll_ops[in->opcode].func(req, in);
  1676. return;
  1677. reply_err:
  1678. fuse_reply_err(req, err);
  1679. return;
  1680. }
  1681. /*
  1682. * always call fuse_lowlevel_new_common() internally, to work around a
  1683. * misfeature in the FreeBSD runtime linker, which links the old
  1684. * version of a symbol to internal references.
  1685. */
  1686. struct fuse_session *
  1687. fuse_lowlevel_new_common(struct fuse_args *args,
  1688. const struct fuse_lowlevel_ops *op,
  1689. size_t op_size,
  1690. void *userdata)
  1691. {
  1692. int err;
  1693. struct fuse_ll *f;
  1694. struct fuse_session *se;
  1695. if(sizeof(struct fuse_lowlevel_ops) < op_size)
  1696. {
  1697. fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
  1698. op_size = sizeof(struct fuse_lowlevel_ops);
  1699. }
  1700. f = (struct fuse_ll *) calloc(1, sizeof(struct fuse_ll));
  1701. if(f == NULL)
  1702. {
  1703. fprintf(stderr, "fuse: failed to allocate fuse object\n");
  1704. goto out;
  1705. }
  1706. f->conn.max_write = UINT_MAX;
  1707. f->conn.max_readahead = UINT_MAX;
  1708. list_init_nreq(&f->notify_list);
  1709. f->notify_ctr = 1;
  1710. fuse_mutex_init(&f->lock);
  1711. err = pthread_key_create(&f->pipe_key, fuse_ll_pipe_destructor);
  1712. if(err)
  1713. {
  1714. fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
  1715. strerror(err));
  1716. goto out_free;
  1717. }
  1718. if(fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
  1719. goto out_key_destroy;
  1720. memcpy(&f->op, op, op_size);
  1721. f->owner = getuid();
  1722. f->userdata = userdata;
  1723. se = fuse_session_new(f,
  1724. fuse_ll_buf_receive_read,
  1725. fuse_ll_buf_process_read_init,
  1726. fuse_ll_destroy);
  1727. if(!se)
  1728. goto out_key_destroy;
  1729. return se;
  1730. out_key_destroy:
  1731. pthread_key_delete(f->pipe_key);
  1732. out_free:
  1733. pthread_mutex_destroy(&f->lock);
  1734. free(f);
  1735. out:
  1736. return NULL;
  1737. }
  1738. struct fuse_session*
  1739. fuse_lowlevel_new(struct fuse_args *args,
  1740. const struct fuse_lowlevel_ops *op,
  1741. size_t op_size,
  1742. void *userdata)
  1743. {
  1744. return fuse_lowlevel_new_common(args, op, op_size, userdata);
  1745. }