Lines Matching +full:libfuse +full:- +full:dev
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
5 Implementation of (most of) the low-level FUSE API. The session loop
43 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
44 (type *)( (char *)__mptr - offsetof(type,member) );})
60 attr->ino = stbuf->st_ino; in convert_stat()
61 attr->mode = stbuf->st_mode; in convert_stat()
62 attr->nlink = stbuf->st_nlink; in convert_stat()
63 attr->uid = stbuf->st_uid; in convert_stat()
64 attr->gid = stbuf->st_gid; in convert_stat()
65 attr->rdev = stbuf->st_rdev; in convert_stat()
66 attr->size = stbuf->st_size; in convert_stat()
67 attr->blksize = stbuf->st_blksize; in convert_stat()
68 attr->blocks = stbuf->st_blocks; in convert_stat()
69 attr->atime = stbuf->st_atime; in convert_stat()
70 attr->mtime = stbuf->st_mtime; in convert_stat()
71 attr->ctime = stbuf->st_ctime; in convert_stat()
72 attr->atimensec = ST_ATIM_NSEC(stbuf); in convert_stat()
73 attr->mtimensec = ST_MTIM_NSEC(stbuf); in convert_stat()
74 attr->ctimensec = ST_CTIM_NSEC(stbuf); in convert_stat()
79 stbuf->st_mode = attr->mode; in convert_attr()
80 stbuf->st_uid = attr->uid; in convert_attr()
81 stbuf->st_gid = attr->gid; in convert_attr()
82 stbuf->st_size = attr->size; in convert_attr()
83 stbuf->st_atime = attr->atime; in convert_attr()
84 stbuf->st_mtime = attr->mtime; in convert_attr()
85 stbuf->st_ctime = attr->ctime; in convert_attr()
86 ST_ATIM_NSEC_SET(stbuf, attr->atimensec); in convert_attr()
87 ST_MTIM_NSEC_SET(stbuf, attr->mtimensec); in convert_attr()
88 ST_CTIM_NSEC_SET(stbuf, attr->ctimensec); in convert_attr()
103 req->next = req; in list_init_req()
104 req->prev = req; in list_init_req()
109 struct fuse_req *prev = req->prev; in list_del_req()
110 struct fuse_req *next = req->next; in list_del_req()
111 prev->next = next; in list_del_req()
112 next->prev = prev; in list_del_req()
117 struct fuse_req *prev = next->prev; in list_add_req()
118 req->next = next; in list_add_req()
119 req->prev = prev; in list_add_req()
120 prev->next = req; in list_add_req()
121 next->prev = req; in list_add_req()
126 assert(req->ch == NULL); in destroy_req()
127 pthread_mutex_destroy(&req->lock); in destroy_req()
134 struct fuse_session *se = req->se; in fuse_free_req()
136 pthread_mutex_lock(&se->lock); in fuse_free_req()
137 req->u.ni.func = NULL; in fuse_free_req()
138 req->u.ni.data = NULL; in fuse_free_req()
140 ctr = --req->ctr; in fuse_free_req()
141 fuse_chan_put(req->ch); in fuse_free_req()
142 req->ch = NULL; in fuse_free_req()
143 pthread_mutex_unlock(&se->lock); in fuse_free_req()
156 req->se = se; in fuse_ll_alloc_req()
157 req->ctr = 1; in fuse_ll_alloc_req()
159 pthread_mutex_init(&req->lock, NULL); in fuse_ll_alloc_req()
172 out->len = iov_length(iov, count); in fuse_send_msg()
173 if (se->debug) { in fuse_send_msg()
174 if (out->unique == 0) { in fuse_send_msg()
176 out->error, out->len); in fuse_send_msg()
177 } else if (out->error) { in fuse_send_msg()
180 (unsigned long long) out->unique, out->error, in fuse_send_msg()
181 strerror(-out->error), out->len); in fuse_send_msg()
185 (unsigned long long) out->unique, out->len); in fuse_send_msg()
190 if (se->io != NULL) in fuse_send_msg()
191 /* se->io->writev is never NULL if se->io is not NULL as in fuse_send_msg()
193 res = se->io->writev(ch ? ch->fd : se->fd, iov, count, in fuse_send_msg()
194 se->userdata); in fuse_send_msg()
196 res = writev(ch ? ch->fd : se->fd, iov, count); in fuse_send_msg()
200 if (res == -1) { in fuse_send_msg()
204 return -err; in fuse_send_msg()
217 const char *str = strerrordesc_np(error * -1);
220 if (error <= -1000 || error > 0) {
223 error = -ERANGE;
226 out.unique = req->unique;
232 return fuse_send_msg(req->se, req->ch, iov, count);
296 dirent->ino = stbuf->st_ino;
297 dirent->off = off;
298 dirent->namelen = namelen;
299 dirent->type = (stbuf->st_mode & S_IFMT) >> 12;
300 memcpy(dirent->name, name, namelen);
301 memset(dirent->name + namelen, 0, entlen_padded - entlen);
309 kstatfs->bsize = stbuf->f_bsize;
310 kstatfs->frsize = stbuf->f_frsize;
311 kstatfs->blocks = stbuf->f_blocks;
312 kstatfs->bfree = stbuf->f_bfree;
313 kstatfs->bavail = stbuf->f_bavail;
314 kstatfs->files = stbuf->f_files;
315 kstatfs->ffree = stbuf->f_ffree;
316 kstatfs->namelen = stbuf->f_namemax;
326 return send_reply(req, -err, NULL, 0);
346 double f = t - (double) calc_timeout_sec(t);
358 arg->nodeid = e->ino;
359 arg->generation = e->generation;
360 arg->entry_valid = calc_timeout_sec(e->entry_timeout);
361 arg->entry_valid_nsec = calc_timeout_nsec(e->entry_timeout);
362 arg->attr_valid = calc_timeout_sec(e->attr_timeout);
363 arg->attr_valid_nsec = calc_timeout_nsec(e->attr_timeout);
364 convert_stat(&e->attr, &arg->attr);
385 memset(&dp->entry_out, 0, sizeof(dp->entry_out));
386 fill_entry(&dp->entry_out, e);
388 struct fuse_dirent *dirent = &dp->dirent;
389 dirent->ino = e->attr.st_ino;
390 dirent->off = off;
391 dirent->namelen = namelen;
392 dirent->type = (e->attr.st_mode & S_IFMT) >> 12;
393 memcpy(dirent->name, name, namelen);
394 memset(dirent->name + namelen, 0, entlen_padded - entlen);
402 arg->fh = f->fh;
403 if (f->direct_io)
404 arg->open_flags |= FOPEN_DIRECT_IO;
405 if (f->keep_cache)
406 arg->open_flags |= FOPEN_KEEP_CACHE;
407 if (f->cache_readdir)
408 arg->open_flags |= FOPEN_CACHE_DIR;
409 if (f->nonseekable)
410 arg->open_flags |= FOPEN_NONSEEKABLE;
411 if (f->noflush)
412 arg->open_flags |= FOPEN_NOFLUSH;
413 if (f->parallel_direct_writes)
414 arg->open_flags |= FOPEN_PARALLEL_DIRECT_WRITES;
420 size_t size = req->se->conn.proto_minor < 9 ?
423 /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
425 if (!e->ino && req->se->conn.proto_minor < 4)
437 size_t entrysize = req->se->conn.proto_minor < 9 ?
453 size_t size = req->se->conn.proto_minor < 9 ?
504 if (buf->count == 1 && buf->idx == 0 && buf->off == 0 &&
505 !(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
509 iov[iov_count].iov_base = buf->buf[0].mem;
523 return -res;
544 close(llp->pipe[0]);
545 close(llp->pipe[1]);
555 if (rv == -1)
558 if (fcntl(fds[0], F_SETFL, O_NONBLOCK) == -1 ||
559 fcntl(fds[1], F_SETFL, O_NONBLOCK) == -1 ||
560 fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 ||
561 fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) {
564 rv = -1;
577 struct fuse_ll_pipe *llp = pthread_getspecific(se->pipe_key);
585 res = fuse_pipe(llp->pipe);
586 if (res == -1) {
594 llp->size = pagesize * 16;
595 llp->can_grow = 1;
597 pthread_setspecific(se->pipe_key, llp);
606 struct fuse_ll_pipe *llp = pthread_getspecific(se->pipe_key);
608 pthread_setspecific(se->pipe_key, NULL);
619 if (res == -1) {
621 return -EIO;
625 return -EIO;
637 maxfd = open("/proc/sys/fs/pipe-max-size", O_RDONLY);
639 return -errno;
641 res = read(maxfd, buf, sizeof(buf) - 1);
647 return -saved_errno;
655 return -errno;
674 if (se->broken_splice_nonblock)
681 for (idx = buf->idx; idx < buf->count; idx++) {
682 total_buf_size += buf->buf[idx].size;
683 if (idx == buf->idx)
684 total_buf_size -= buf->off;
689 if (se->conn.proto_minor < 14 ||
690 !(se->conn.want & FUSE_CAP_SPLICE_WRITE))
700 out->len = headerlen + len;
706 pipesize = pagesize * (iov_count + buf->count + 1) + out->len;
708 if (llp->size < pipesize) {
709 if (llp->can_grow) {
710 res = fcntl(llp->pipe[0], F_SETPIPE_SZ, pipesize);
711 if (res == -1) {
712 res = grow_pipe_to_max(llp->pipe[0]);
714 llp->size = res;
715 llp->can_grow = 0;
718 llp->size = res;
720 if (llp->size < pipesize)
725 res = vmsplice(llp->pipe[1], iov, iov_count, SPLICE_F_NONBLOCK);
726 if (res == -1)
730 res = -EIO;
737 pipe_buf.buf[0].fd = llp->pipe[1];
742 if (res == -EAGAIN || res == -EINVAL) {
753 if (res == -EAGAIN)
754 se->broken_splice_nonblock = 1;
756 pthread_setspecific(se->pipe_key, NULL);
760 res = -res;
798 res = read_back(llp->pipe[0], tmpbuf, headerlen);
804 res = read_back(llp->pipe[0], mbuf, now_len);
821 out->len = headerlen + len;
823 if (se->debug) {
826 (unsigned long long) out->unique, out->len);
831 (se->conn.want & FUSE_CAP_SPLICE_MOVE))
834 if (se->io != NULL && se->io->splice_send != NULL) {
835 res = se->io->splice_send(llp->pipe[0], NULL,
836 ch ? ch->fd : se->fd, NULL, out->len,
837 splice_flags, se->userdata);
839 res = splice(llp->pipe[0], NULL, ch ? ch->fd : se->fd, NULL,
840 out->len, splice_flags);
842 if (res == -1) {
843 res = -errno;
847 if (res != out->len) {
848 res = -EIO;
850 res, out->len);
884 out.unique = req->unique;
887 res = fuse_send_data_iov(req->se, req->ch, iov, 1, bufv, flags);
899 size_t size = req->se->conn.proto_minor < 4 ?
923 arg.lk.type = lock->l_type;
924 if (lock->l_type != F_UNLCK) {
925 arg.lk.start = lock->l_start;
926 if (lock->l_len == 0)
929 arg.lk.end = lock->l_start + lock->l_len - 1;
931 arg.lk.pid = lock->l_pid;
982 if (req->se->conn.proto_minor < 16) {
995 /* Can't handle non-compat 64bit ioctls on 32bit */
996 if (sizeof(void *) == 4 && req->ioctl_64bit) {
1102 if (req->se->op.lookup)
1103 req->se->op.lookup(req, nodeid, name);
1112 if (req->se->op.forget)
1113 req->se->op.forget(req, nodeid, arg->nlookup);
1127 if (req->se->op.forget_multi) {
1128 req->se->op.forget_multi(req, arg->count,
1130 } else if (req->se->op.forget) {
1131 for (i = 0; i < arg->count; i++) {
1135 dummy_req = fuse_ll_alloc_req(req->se);
1139 dummy_req->unique = req->unique;
1140 dummy_req->ctx = req->ctx;
1141 dummy_req->ch = NULL;
1143 req->se->op.forget(dummy_req, forget->nodeid,
1144 forget->nlookup);
1157 if (req->se->conn.proto_minor >= 9) {
1160 if (arg->getattr_flags & FUSE_GETATTR_FH) {
1162 fi.fh = arg->fh;
1167 if (req->se->op.getattr)
1168 req->se->op.getattr(req, nodeid, fip);
1177 if (req->se->op.setattr) {
1183 if (arg->valid & FATTR_FH) {
1184 arg->valid &= ~FATTR_FH;
1187 fi->fh = arg->fh;
1189 arg->valid &=
1202 req->se->op.setattr(req, nodeid, &stbuf, arg->valid, fi);
1211 if (req->se->op.access)
1212 req->se->op.access(req, nodeid, arg->mask);
1221 if (req->se->op.readlink)
1222 req->se->op.readlink(req, nodeid);
1232 if (req->se->conn.proto_minor >= 12)
1233 req->ctx.umask = arg->umask;
1237 if (req->se->op.mknod)
1238 req->se->op.mknod(req, nodeid, name, arg->mode, arg->rdev);
1247 if (req->se->conn.proto_minor >= 12)
1248 req->ctx.umask = arg->umask;
1250 if (req->se->op.mkdir)
1251 req->se->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
1260 if (req->se->op.unlink)
1261 req->se->op.unlink(req, nodeid, name);
1270 if (req->se->op.rmdir)
1271 req->se->op.rmdir(req, nodeid, name);
1281 if (req->se->op.symlink)
1282 req->se->op.symlink(req, linkname, nodeid, name);
1293 if (req->se->op.rename)
1294 req->se->op.rename(req, nodeid, oldname, arg->newdir, newname,
1306 if (req->se->op.rename)
1307 req->se->op.rename(req, nodeid, oldname, arg->newdir, newname,
1308 arg->flags);
1317 if (req->se->op.link)
1318 req->se->op.link(req, arg->oldnodeid, nodeid, PARAM(arg));
1327 if (req->se->op.create) {
1332 fi.flags = arg->flags;
1334 if (req->se->conn.proto_minor >= 12)
1335 req->ctx.umask = arg->umask;
1339 req->se->op.create(req, nodeid, name, arg->mode, &fi);
1350 fi.flags = arg->flags;
1352 if (req->se->op.open)
1353 req->se->op.open(req, nodeid, &fi);
1362 if (req->se->op.read) {
1366 fi.fh = arg->fh;
1367 if (req->se->conn.proto_minor >= 9) {
1368 fi.lock_owner = arg->lock_owner;
1369 fi.flags = arg->flags;
1371 req->se->op.read(req, nodeid, arg->size, arg->offset, &fi);
1383 fi.fh = arg->fh;
1384 fi.writepage = (arg->write_flags & FUSE_WRITE_CACHE) != 0;
1386 if (req->se->conn.proto_minor < 9) {
1389 fi.lock_owner = arg->lock_owner;
1390 fi.flags = arg->flags;
1394 if (req->se->op.write)
1395 req->se->op.write(req, nodeid, param, arg->size,
1396 arg->offset, &fi);
1404 struct fuse_session *se = req->se;
1413 fi.fh = arg->fh;
1414 fi.writepage = arg->write_flags & FUSE_WRITE_CACHE;
1416 if (se->conn.proto_minor < 9) {
1418 bufv.buf[0].size -= sizeof(struct fuse_in_header) +
1422 fi.lock_owner = arg->lock_owner;
1423 fi.flags = arg->flags;
1427 bufv.buf[0].size -= sizeof(struct fuse_in_header) +
1430 if (bufv.buf[0].size < arg->size) {
1435 bufv.buf[0].size = arg->size;
1437 se->op.write_buf(req, nodeid, &bufv, arg->offset, &fi);
1440 /* Need to reset the pipe if ->write_buf() didn't consume all data */
1441 if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count)
1451 fi.fh = arg->fh;
1453 if (req->se->conn.proto_minor >= 7)
1454 fi.lock_owner = arg->lock_owner;
1456 if (req->se->op.flush)
1457 req->se->op.flush(req, nodeid, &fi);
1468 fi.flags = arg->flags;
1469 fi.fh = arg->fh;
1470 if (req->se->conn.proto_minor >= 8) {
1471 fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0;
1472 fi.lock_owner = arg->lock_owner;
1474 if (arg->release_flags & FUSE_RELEASE_FLOCK_UNLOCK) {
1476 fi.lock_owner = arg->lock_owner;
1479 if (req->se->op.release)
1480 req->se->op.release(req, nodeid, &fi);
1489 int datasync = arg->fsync_flags & 1;
1492 fi.fh = arg->fh;
1494 if (req->se->op.fsync)
1495 req->se->op.fsync(req, nodeid, datasync, &fi);
1506 fi.flags = arg->flags;
1508 if (req->se->op.opendir)
1509 req->se->op.opendir(req, nodeid, &fi);
1520 fi.fh = arg->fh;
1522 if (req->se->op.readdir)
1523 req->se->op.readdir(req, nodeid, arg->size, arg->offset, &fi);
1534 fi.fh = arg->fh;
1536 if (req->se->op.readdirplus)
1537 req->se->op.readdirplus(req, nodeid, arg->size, arg->offset, &fi);
1548 fi.flags = arg->flags;
1549 fi.fh = arg->fh;
1551 if (req->se->op.releasedir)
1552 req->se->op.releasedir(req, nodeid, &fi);
1561 int datasync = arg->fsync_flags & 1;
1564 fi.fh = arg->fh;
1566 if (req->se->op.fsyncdir)
1567 req->se->op.fsyncdir(req, nodeid, datasync, &fi);
1577 if (req->se->op.statfs)
1578 req->se->op.statfs(req, nodeid);
1590 struct fuse_session *se = req->se;
1591 unsigned int xattr_ext = !!(se->conn.want & FUSE_CAP_SETXATTR_EXT);
1598 if (req->se->op.setxattr)
1599 req->se->op.setxattr(req, nodeid, name, value, arg->size,
1600 arg->flags);
1609 if (req->se->op.getxattr)
1610 req->se->op.getxattr(req, nodeid, PARAM(arg), arg->size);
1619 if (req->se->op.listxattr)
1620 req->se->op.listxattr(req, nodeid, arg->size);
1629 if (req->se->op.removexattr)
1630 req->se->op.removexattr(req, nodeid, name);
1639 flock->l_type = fl->type;
1640 flock->l_whence = SEEK_SET;
1641 flock->l_start = fl->start;
1642 if (fl->end == OFFSET_MAX)
1643 flock->l_len = 0;
1645 flock->l_len = fl->end - fl->start + 1;
1646 flock->l_pid = fl->pid;
1656 fi.fh = arg->fh;
1657 fi.lock_owner = arg->owner;
1659 convert_fuse_file_lock(&arg->lk, &flock);
1660 if (req->se->op.getlk)
1661 req->se->op.getlk(req, nodeid, &fi, &flock);
1674 fi.fh = arg->fh;
1675 fi.lock_owner = arg->owner;
1677 if (arg->lk_flags & FUSE_LK_FLOCK) {
1680 switch (arg->lk.type) {
1694 if (req->se->op.flock)
1695 req->se->op.flock(req, nodeid, &fi, op);
1699 convert_fuse_file_lock(&arg->lk, &flock);
1700 if (req->se->op.setlk)
1701 req->se->op.setlk(req, nodeid, &fi, &flock, sleep);
1721 for (curr = se->list.next; curr != &se->list; curr = curr->next) {
1722 if (curr->unique == req->u.i.unique) {
1726 curr->ctr++;
1727 pthread_mutex_unlock(&se->lock);
1730 pthread_mutex_lock(&curr->lock);
1731 pthread_mutex_lock(&se->lock);
1732 curr->interrupted = 1;
1733 func = curr->u.ni.func;
1734 data = curr->u.ni.data;
1735 pthread_mutex_unlock(&se->lock);
1738 pthread_mutex_unlock(&curr->lock);
1740 pthread_mutex_lock(&se->lock);
1741 curr->ctr--;
1742 if (!curr->ctr) {
1743 fuse_chan_put(req->ch);
1744 req->ch = NULL;
1751 for (curr = se->interrupts.next; curr != &se->interrupts;
1752 curr = curr->next) {
1753 if (curr->u.i.unique == req->u.i.unique)
1762 struct fuse_session *se = req->se;
1765 if (se->debug)
1767 (unsigned long long) arg->unique);
1769 req->u.i.unique = arg->unique;
1771 pthread_mutex_lock(&se->lock);
1773 fuse_chan_put(req->ch);
1774 req->ch = NULL;
1777 list_add_req(req, &se->interrupts);
1778 pthread_mutex_unlock(&se->lock);
1786 for (curr = se->interrupts.next; curr != &se->interrupts;
1787 curr = curr->next) {
1788 if (curr->u.i.unique == req->unique) {
1789 req->interrupted = 1;
1791 fuse_chan_put(curr->ch);
1792 curr->ch = NULL;
1797 curr = se->interrupts.next;
1798 if (curr != &se->interrupts) {
1810 if (req->se->op.bmap)
1811 req->se->op.bmap(req, nodeid, arg->blocksize, arg->block);
1819 unsigned int flags = arg->flags;
1820 void *in_buf = arg->in_size ? PARAM(arg) : NULL;
1824 !(req->se->conn.want & FUSE_CAP_IOCTL_DIR)) {
1830 fi.fh = arg->fh;
1832 if (sizeof(void *) == 4 && req->se->conn.proto_minor >= 16 &&
1834 req->ioctl_64bit = 1;
1837 if (req->se->op.ioctl)
1838 req->se->op.ioctl(req, nodeid, arg->cmd,
1839 (void *)(uintptr_t)arg->arg, &fi, flags,
1840 in_buf, arg->in_size, arg->out_size);
1856 fi.fh = arg->fh;
1857 fi.poll_events = arg->events;
1859 if (req->se->op.poll) {
1862 if (arg->flags & FUSE_POLL_SCHEDULE_NOTIFY) {
1868 ph->kh = arg->kh;
1869 ph->se = req->se;
1872 req->se->op.poll(req, nodeid, &fi, ph);
1884 fi.fh = arg->fh;
1886 if (req->se->op.fallocate)
1887 req->se->op.fallocate(req, nodeid, arg->mode, arg->offset, arg->length, &fi);
1898 fi_in.fh = arg->fh_in;
1901 fi_out.fh = arg->fh_out;
1904 if (req->se->op.copy_file_range)
1905 req->se->op.copy_file_range(req, nodeid_in, arg->off_in,
1906 &fi_in, arg->nodeid_out,
1907 arg->off_out, &fi_out, arg->len,
1908 arg->flags);
1919 fi.fh = arg->fh;
1921 if (req->se->op.lseek)
1922 req->se->op.lseek(req, nodeid, arg->offset, arg->whence, &fi);
1928 * multi-threading becomes relevant */
1934 struct fuse_session *se = req->se;
1935 size_t bufsize = se->bufsize;
1940 if (se->debug) {
1941 fuse_log(FUSE_LOG_DEBUG, "INIT: %u.%u\n", arg->major, arg->minor);
1942 if (arg->major == 7 && arg->minor >= 6) {
1943 fuse_log(FUSE_LOG_DEBUG, "flags=0x%08x\n", arg->flags);
1945 arg->max_readahead);
1948 se->conn.proto_major = arg->major;
1949 se->conn.proto_minor = arg->minor;
1950 se->conn.capable = 0;
1951 se->conn.want = 0;
1957 if (arg->major < 7) {
1959 arg->major, arg->minor);
1964 if (arg->major > 7) {
1970 if (arg->minor >= 6) {
1971 if (arg->max_readahead < se->conn.max_readahead)
1972 se->conn.max_readahead = arg->max_readahead;
1973 inargflags = arg->flags;
1975 inargflags = inargflags | (uint64_t) arg->flags2 << 32;
1977 se->conn.capable |= FUSE_CAP_ASYNC_READ;
1979 se->conn.capable |= FUSE_CAP_POSIX_LOCKS;
1981 se->conn.capable |= FUSE_CAP_ATOMIC_O_TRUNC;
1983 se->conn.capable |= FUSE_CAP_EXPORT_SUPPORT;
1985 se->conn.capable |= FUSE_CAP_DONT_MASK;
1987 se->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
1989 se->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA;
1991 se->conn.capable |= FUSE_CAP_READDIRPLUS;
1993 se->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO;
1995 se->conn.capable |= FUSE_CAP_ASYNC_DIO;
1997 se->conn.capable |= FUSE_CAP_WRITEBACK_CACHE;
1999 se->conn.capable |= FUSE_CAP_NO_OPEN_SUPPORT;
2001 se->conn.capable |= FUSE_CAP_PARALLEL_DIROPS;
2003 se->conn.capable |= FUSE_CAP_POSIX_ACL;
2005 se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
2007 se->conn.capable |= FUSE_CAP_CACHE_SYMLINKS;
2009 se->conn.capable |= FUSE_CAP_NO_OPENDIR_SUPPORT;
2011 se->conn.capable |= FUSE_CAP_EXPLICIT_INVAL_DATA;
2013 se->conn.capable |= FUSE_CAP_SETXATTR_EXT;
2022 if (arg->minor >= 38)
2023 se->conn.capable |= FUSE_CAP_EXPIRE_ONLY;
2025 se->conn.max_readahead = 0;
2028 if (se->conn.proto_minor >= 14) {
2031 if ((se->io == NULL) || (se->io->splice_send != NULL)) {
2032 se->conn.capable |= FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE;
2035 if ((se->io == NULL) || (se->io->splice_receive != NULL)) {
2036 se->conn.capable |= FUSE_CAP_SPLICE_READ;
2040 if (se->conn.proto_minor >= 18)
2041 se->conn.capable |= FUSE_CAP_IOCTL_DIR;
2051 if ((cond) && (se->conn.capable & (cap))) \
2052 se->conn.want |= (cap)
2060 LL_SET_DEFAULT(se->op.write_buf, FUSE_CAP_SPLICE_READ);
2061 LL_SET_DEFAULT(se->op.getlk && se->op.setlk,
2063 LL_SET_DEFAULT(se->op.flock, FUSE_CAP_FLOCK_LOCKS);
2064 LL_SET_DEFAULT(se->op.readdirplus, FUSE_CAP_READDIRPLUS);
2065 LL_SET_DEFAULT(se->op.readdirplus && se->op.readdir,
2068 /* This could safely become default, but libfuse needs an API extension
2073 se->conn.time_gran = 1;
2080 se->bufsize = bufsize;
2082 if (se->conn.max_write > bufsize - FUSE_BUFFER_HEADER_SIZE)
2083 se->conn.max_write = bufsize - FUSE_BUFFER_HEADER_SIZE;
2085 se->got_init = 1;
2086 if (se->op.init)
2087 se->op.init(se->userdata, &se->conn);
2089 if (se->conn.want & (~se->conn.capable)) {
2092 se->conn.want & (~se->conn.capable));
2094 se->error = -EPROTO;
2099 unsigned max_read_mo = get_max_read(se->mo);
2100 if (se->conn.max_read != max_read_mo) {
2103 se->conn.max_read, max_read_mo);
2105 se->error = -EPROTO;
2110 if (se->conn.max_write < bufsize - FUSE_BUFFER_HEADER_SIZE) {
2111 se->bufsize = se->conn.max_write + FUSE_BUFFER_HEADER_SIZE;
2113 if (arg->flags & FUSE_MAX_PAGES) {
2115 outarg.max_pages = (se->conn.max_write - 1) / getpagesize() + 1;
2122 if (se->conn.want & FUSE_CAP_ASYNC_READ)
2124 if (se->conn.want & FUSE_CAP_POSIX_LOCKS)
2126 if (se->conn.want & FUSE_CAP_ATOMIC_O_TRUNC)
2128 if (se->conn.want & FUSE_CAP_EXPORT_SUPPORT)
2130 if (se->conn.want & FUSE_CAP_DONT_MASK)
2132 if (se->conn.want & FUSE_CAP_FLOCK_LOCKS)
2134 if (se->conn.want & FUSE_CAP_AUTO_INVAL_DATA)
2136 if (se->conn.want & FUSE_CAP_READDIRPLUS)
2138 if (se->conn.want & FUSE_CAP_READDIRPLUS_AUTO)
2140 if (se->conn.want & FUSE_CAP_ASYNC_DIO)
2142 if (se->conn.want & FUSE_CAP_WRITEBACK_CACHE)
2144 if (se->conn.want & FUSE_CAP_POSIX_ACL)
2146 if (se->conn.want & FUSE_CAP_CACHE_SYMLINKS)
2148 if (se->conn.want & FUSE_CAP_EXPLICIT_INVAL_DATA)
2150 if (se->conn.want & FUSE_CAP_SETXATTR_EXT)
2160 outarg.max_readahead = se->conn.max_readahead;
2161 outarg.max_write = se->conn.max_write;
2162 if (se->conn.proto_minor >= 13) {
2163 if (se->conn.max_background >= (1 << 16))
2164 se->conn.max_background = (1 << 16) - 1;
2165 if (se->conn.congestion_threshold > se->conn.max_background)
2166 se->conn.congestion_threshold = se->conn.max_background;
2167 if (!se->conn.congestion_threshold) {
2168 se->conn.congestion_threshold =
2169 se->conn.max_background * 3 / 4;
2172 outarg.max_background = se->conn.max_background;
2173 outarg.congestion_threshold = se->conn.congestion_threshold;
2175 if (se->conn.proto_minor >= 23)
2176 outarg.time_gran = se->conn.time_gran;
2178 if (se->debug) {
2191 if (arg->minor < 5)
2193 else if (arg->minor < 23)
2201 struct fuse_session *se = req->se;
2206 se->got_destroy = 1;
2207 if (se->op.destroy)
2208 se->op.destroy(se->userdata);
2215 struct fuse_notify_req *prev = nreq->prev;
2216 struct fuse_notify_req *next = nreq->next;
2217 prev->next = next;
2218 next->prev = prev;
2224 struct fuse_notify_req *prev = next->prev;
2225 nreq->next = next;
2226 nreq->prev = prev;
2227 prev->next = nreq;
2228 next->prev = nreq;
2233 nreq->next = nreq;
2234 nreq->prev = nreq;
2240 struct fuse_session *se = req->se;
2244 pthread_mutex_lock(&se->lock);
2245 head = &se->notify_list;
2246 for (nreq = head->next; nreq != head; nreq = nreq->next) {
2247 if (nreq->unique == req->unique) {
2252 pthread_mutex_unlock(&se->lock);
2255 nreq->reply(nreq, req, nodeid, inarg, buf);
2263 if (!se->got_init)
2264 return -ENOTCONN;
2280 outarg.kh = ph->kh;
2285 return send_notify_iov(ph->se, FUSE_NOTIFY_POLL, iov, 2);
2298 return -EINVAL;
2300 if (se->conn.proto_minor < 12)
2301 return -ENOSYS;
2330 * @return zero for success, -errno for failure
2340 return -EINVAL;
2342 if (se->conn.proto_minor < 12)
2343 return -ENOSYS;
2369 return -EINVAL;
2371 if (!(se->conn.capable & FUSE_CAP_EXPIRE_ONLY))
2372 return -ENOSYS;
2386 return -EINVAL;
2388 if (se->conn.proto_minor < 18)
2389 return -ENOSYS;
2415 return -EINVAL;
2417 if (se->conn.proto_minor < 15)
2418 return -ENOSYS;
2435 res = -res;
2450 struct fuse_session *se = req->se;
2462 bufv.buf[0].size -= sizeof(struct fuse_in_header) +
2465 if (bufv.buf[0].size < arg->size) {
2470 bufv.buf[0].size = arg->size;
2472 if (se->op.retrieve_reply) {
2473 se->op.retrieve_reply(req, rreq->cookie, ino,
2474 arg->offset, &bufv);
2480 if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count)
2493 return -EINVAL;
2495 if (se->conn.proto_minor < 15)
2496 return -ENOSYS;
2500 return -ENOMEM;
2502 pthread_mutex_lock(&se->lock);
2503 rreq->cookie = cookie;
2504 rreq->nreq.unique = se->notify_ctr++;
2505 rreq->nreq.reply = fuse_ll_retrieve_reply;
2506 list_add_nreq(&rreq->nreq, &se->notify_list);
2507 pthread_mutex_unlock(&se->lock);
2509 outarg.notify_unique = rreq->nreq.unique;
2520 pthread_mutex_lock(&se->lock);
2521 list_del_nreq(&rreq->nreq);
2522 pthread_mutex_unlock(&se->lock);
2531 return req->se->userdata;
2536 return &req->ctx;
2542 pthread_mutex_lock(&req->lock);
2543 pthread_mutex_lock(&req->se->lock);
2544 req->u.ni.func = func;
2545 req->u.ni.data = data;
2546 pthread_mutex_unlock(&req->se->lock);
2547 if (req->interrupted && func)
2549 pthread_mutex_unlock(&req->lock);
2556 pthread_mutex_lock(&req->se->lock);
2557 interrupted = req->interrupted;
2558 pthread_mutex_unlock(&req->se->lock);
2630 fuse_log(FUSE_LOG_ERR, "fuse: copy from pipe: %s\n", strerror(-res));
2635 return -1;
2660 if (buf->flags & FUSE_BUF_IS_FD) {
2661 if (buf->size < tmpbuf.buf[0].size)
2662 tmpbuf.buf[0].size = buf->size;
2677 in = buf->mem;
2680 if (se->debug) {
2683 (unsigned long long) in->unique,
2684 opname((enum fuse_opcode) in->opcode), in->opcode,
2685 (unsigned long long) in->nodeid, buf->size, in->pid);
2691 .unique = in->unique,
2692 .error = -ENOMEM,
2703 req->unique = in->unique;
2704 req->ctx.uid = in->uid;
2705 req->ctx.gid = in->gid;
2706 req->ctx.pid = in->pid;
2707 req->ch = ch ? fuse_chan_get(ch) : NULL;
2710 if (!se->got_init) {
2713 expected = se->cuse_data ? CUSE_INIT : FUSE_INIT;
2714 if (in->opcode != expected)
2716 } else if (in->opcode == FUSE_INIT || in->opcode == CUSE_INIT)
2720 /* Implement -o allow_root */
2721 if (se->deny_others && in->uid != se->owner && in->uid != 0 &&
2722 in->opcode != FUSE_INIT && in->opcode != FUSE_READ &&
2723 in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC &&
2724 in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
2725 in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR &&
2726 in->opcode != FUSE_NOTIFY_REPLY &&
2727 in->opcode != FUSE_READDIRPLUS)
2731 if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
2733 if (in->opcode != FUSE_INTERRUPT) {
2735 pthread_mutex_lock(&se->lock);
2737 list_add_req(req, &se->list);
2738 pthread_mutex_unlock(&se->lock);
2743 if ((buf->flags & FUSE_BUF_IS_FD) && write_header_size < buf->size &&
2744 (in->opcode != FUSE_WRITE || !se->op.write_buf) &&
2745 in->opcode != FUSE_NOTIFY_REPLY) {
2749 newmbuf = realloc(mbuf, buf->size);
2754 tmpbuf = FUSE_BUFVEC_INIT(buf->size - write_header_size);
2758 err = -res;
2766 if (in->opcode == FUSE_WRITE && se->op.write_buf)
2767 do_write_buf(req, in->nodeid, inarg, buf);
2768 else if (in->opcode == FUSE_NOTIFY_REPLY)
2769 do_notify_reply(req, in->nodeid, inarg, buf);
2771 fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);
2780 if (buf->flags & FUSE_BUF_IS_FD)
2790 LL_OPTION("-d", debug, 1),
2791 LL_OPTION("--debug", debug, 1),
2806 potentially of interest to an end-user */
2808 " -o allow_other allow access by all users\n"
2809 " -o allow_root allow access by root\n"
2810 " -o auto_unmount auto unmount on process termination\n");
2817 if (se->got_init && !se->got_destroy) {
2818 if (se->op.destroy)
2819 se->op.destroy(se->userdata);
2821 llp = pthread_getspecific(se->pipe_key);
2824 pthread_key_delete(se->pipe_key);
2825 pthread_mutex_destroy(&se->lock);
2826 free(se->cuse_data);
2827 if (se->fd != -1)
2828 close(se->fd);
2829 if (se->io != NULL)
2830 free(se->io);
2831 destroy_mount_opts(se->mo);
2853 size_t bufsize = se->bufsize;
2857 if (se->conn.proto_minor < 14 || !(se->conn.want & FUSE_CAP_SPLICE_READ))
2864 if (llp->size < bufsize) {
2865 if (llp->can_grow) {
2866 res = fcntl(llp->pipe[0], F_SETPIPE_SZ, bufsize);
2867 if (res == -1) {
2868 llp->can_grow = 0;
2869 res = grow_pipe_to_max(llp->pipe[0]);
2871 llp->size = res;
2874 llp->size = res;
2876 if (llp->size < bufsize)
2880 if (se->io != NULL && se->io->splice_receive != NULL) {
2881 res = se->io->splice_receive(ch ? ch->fd : se->fd, NULL,
2882 llp->pipe[1], NULL, bufsize, 0,
2883 se->userdata);
2885 res = splice(ch ? ch->fd : se->fd, NULL, llp->pipe[1], NULL,
2893 if (res == -1) {
2902 return -err;
2907 return -EIO;
2913 .fd = llp->pipe[0],
2926 if (!buf->mem) {
2927 buf->mem = malloc(se->bufsize);
2928 if (!buf->mem) {
2931 return -ENOMEM;
2934 buf->size = se->bufsize;
2935 buf->flags = 0;
2941 strerror(-res));
2948 return -EIO;
2953 /* Don't overwrite buf->mem, as that would cause a leak */
2954 buf->fd = tmpbuf.fd;
2955 buf->flags = tmpbuf.flags;
2957 buf->size = tmpbuf.size;
2963 if (!buf->mem) {
2964 buf->mem = malloc(se->bufsize);
2965 if (!buf->mem) {
2968 return -ENOMEM;
2973 if (se->io != NULL) {
2974 /* se->io->read is never NULL if se->io is not NULL as
2976 res = se->io->read(ch ? ch->fd : se->fd, buf->mem, se->bufsize,
2977 se->userdata);
2979 res = read(ch ? ch->fd : se->fd, buf->mem, se->bufsize);
2985 if (res == -1) {
3002 return -err;
3006 return -EIO;
3009 buf->size = res;
3027 if (args->argc == 0) {
3037 se->fd = -1;
3038 se->conn.max_write = UINT_MAX;
3039 se->conn.max_readahead = UINT_MAX;
3042 if(fuse_opt_parse(args, se, fuse_ll_opts, NULL) == -1)
3044 if(se->deny_others) {
3047 * access to root and mountpoint owner in libfuse.
3051 if(fuse_opt_add_arg(args, "-oallow_other") == -1)
3058 if(args->argc == 1 &&
3059 args->argv[0][0] == '-') {
3062 } else if (args->argc != 1) {
3065 for(i = 1; i < args->argc-1; i++)
3066 fuse_log(FUSE_LOG_ERR, "%s ", args->argv[i]);
3067 fuse_log(FUSE_LOG_ERR, "%s'\n", args->argv[i]);
3071 if (se->debug)
3074 se->bufsize = FUSE_MAX_MAX_PAGES * getpagesize() +
3077 list_init_req(&se->list);
3078 list_init_req(&se->interrupts);
3079 list_init_nreq(&se->notify_list);
3080 se->notify_ctr = 1;
3081 pthread_mutex_init(&se->lock, NULL);
3083 err = pthread_key_create(&se->pipe_key, fuse_ll_pipe_destructor);
3090 memcpy(&se->op, op, op_size);
3091 se->owner = getuid();
3092 se->userdata = userdata;
3094 se->mo = mo;
3098 pthread_mutex_destroy(&se->lock);
3116 return -EBADF;
3121 return -EINVAL;
3122 } else if (io->read == NULL || io->writev == NULL) {
3125 in libfuse will function properly. Therefore, we enforce the
3128 "implement both io->read() and io->writev\n");
3129 return -EINVAL;
3132 se->io = malloc(sizeof(struct fuse_custom_io));
3133 if (se->io == NULL) {
3136 return -errno;
3139 se->fd = fd;
3140 *se->io = *io;
3153 fd = open("/dev/null", O_RDWR);
3160 * /dev/fuse before launching the file system and pass on the file
3161 * descriptor by specifying /dev/fd/N as the mount point. Note that the
3165 if (fd != -1) {
3166 if (fcntl(fd, F_GETFD) == -1) {
3168 "fuse: Invalid file descriptor /dev/fd/%u\n",
3170 return -1;
3172 se->fd = fd;
3177 fd = fuse_kern_mount(mountpoint, se->mo);
3178 if (fd == -1)
3179 return -1;
3180 se->fd = fd;
3183 se->mountpoint = strdup(mountpoint);
3184 if (se->mountpoint == NULL)
3191 return -1;
3196 return se->fd;
3201 if (se->mountpoint != NULL) {
3202 fuse_kern_unmount(se->mountpoint, se->fd);
3203 se->fd = -1;
3204 free(se->mountpoint);
3205 se->mountpoint = NULL;
3217 unsigned long pid = req->ctx.pid;
3225 return -ENOMEM;
3227 ret = -EIO;
3229 if (fd == -1)
3235 ret = -EIO;
3245 ret = -EIO;
3275 return -ENOSYS;
3279 /* Prevent spurious data race warning - we don't care
3284 se->exited = 1;
3290 se->exited = 0;
3291 se->error = 0;
3297 return se->exited;