PERFORCE change 194386 for review
Ilya Putsikau
ilya at FreeBSD.org
Tue Jun 7 10:58:26 UTC 2011
http://p4web.freebsd.org/@@194386?ac=10
Change 194386 by ilya at ilya_triton2011 on 2011/06/07 10:58:20
Start macfuse merge
Affected files ...
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_device.c#4 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.h#2 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#5 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#7 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#3 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.c#3 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.h#5 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#3 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#10 edit
Differences ...
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_device.c#4 (text+ko) ====
@@ -291,7 +291,7 @@
DEBUG2G("reader is to be sacked\n");
if (tick) {
DEBUG2G("weird -- \"kick\" is set tho there is message\n");
- fuse_ticket_drop_notowned(tick);
+ fuse_ticket_drop_invalid(tick);
}
return (ENODEV); /* This should make the daemon get off of us */
}
@@ -343,7 +343,7 @@
* (used when the one who inserted the message thinks the daemon
* won't aswer)
*/
- fuse_ticket_drop_notowned(tick);
+ fuse_ticket_drop_invalid(tick);
return (err);
}
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.h#2 (text+ko) ====
@@ -1,26 +1,92 @@
/*
- * Fuse filehandle, for in-kernel bookkeping of daemon's filehandles
- * (which are presented to us as an opque 64 bit id, see the fh_id
- * member of the struct).
- * It serves as private data for in-kernel file structures, but can
- * as well occur standalone.
+ * Copyright (C) 2006 Google. All Rights Reserved.
+ * Amit Singh <singh@>
*/
+#ifndef _FUSE_FILE_H_
+#define _FUSE_FILE_H_
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/vnode.h>
+
+typedef enum fufh_type {
+ FUFH_INVALID = -1,
+ FUFH_RDONLY = 0,
+ FUFH_WRONLY = 1,
+ FUFH_RDWR = 2,
+ FUFH_MAXTYPE = 3,
+} fufh_type_t;
+
+#define FUFH_VALID 0x00000001
+#define FUFH_MAPPED 0x00000002
+#define FUFH_STRATEGY 0x00000004
+
struct fuse_filehandle {
- struct vnode *fh_vp;
- uint64_t fh_id;
- int mode;
- struct ucred *cred;
- pid_t pid;
- int useco;
- LIST_ENTRY(fuse_filehandle) fh_link;
- struct file *fp;
- int flags;
- enum fuse_opcode op;
+ uint64_t fh_id;
+ fufh_type_t type;
+ int fufh_flags;
+ int open_count;
+ int open_flags;
+ int fuse_open_flags;
};
+typedef struct fuse_filehandle * fuse_filehandle_t;
+
+static __inline__ fufh_type_t
+fuse_filehandle_xlate_from_mmap(int fflags)
+{
+ if (fflags & (PROT_READ | PROT_WRITE)) {
+ return FUFH_RDWR;
+ } else if (fflags & (PROT_WRITE)) {
+ return FUFH_WRONLY;
+ } else if ((fflags & PROT_READ) || (fflags & PROT_EXEC)) {
+ return FUFH_RDONLY;
+ } else {
+ return FUFH_INVALID;
+ }
+}
+
+static __inline__ fufh_type_t
+fuse_filehandle_xlate_from_fflags(int fflags)
+{
+ if ((fflags & FREAD) && (fflags & FWRITE)) {
+ return FUFH_RDWR;
+ } else if (fflags & (FWRITE)) {
+ return FUFH_WRONLY;
+ } else if (fflags & (FREAD)) {
+ return FUFH_RDONLY;
+ } else {
+ panic("What kind of a flag is this?");
+ }
+}
-#define FTOFH(fp) ((struct fuse_filehandle *)(fp)->f_data)
+static __inline__ int
+fuse_filehandle_xlate_to_oflags(fufh_type_t type)
+{
+ int oflags = -1;
+
+ switch (type) {
+ case FUFH_RDONLY:
+ oflags = O_RDONLY;
+ break;
+ case FUFH_WRONLY:
+ oflags = O_WRONLY;
+ break;
+ case FUFH_RDWR:
+ oflags = O_RDWR;
+ break;
+ default:
+ break;
+ }
+
+ return oflags;
+}
-#define ASSERT_VOP_ELOCKED__FH(vp) ASSERT_VOP_ELOCKED((vp), "unsafe filehandle access")
-#define ASSERT_VOP_LOCKED__FH(vp) ASSERT_VOP_LOCKED((vp), "unsafe filehandle access")
+int fuse_filehandle_get(struct vnode *vp, struct thread *td, struct ucred *cred,
+ fufh_type_t fufh_type);
+int fuse_filehandle_put(struct vnode *vp, struct thread *td, struct ucred *cred,
+ fufh_type_t fufh_type, int foregrounded);
+#endif /* _FUSE_FILE_H_ */
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#5 (text+ko) ====
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 2006 Google. All Rights Reserved.
+ * Amit Singh <singh@>
+ */
+
#include "config.h"
#include <sys/types.h>
@@ -29,9 +34,14 @@
#include <sys/priv.h>
#include "fuse.h"
+#include "fuse_file.h"
+#include "fuse_internal.h"
+#include "fuse_ipc.h"
#include "fuse_node.h"
-#include "fuse_ipc.h"
-#include "fuse_internal.h"
+#include "fuse_file.h"
+// #include "fuse_nodehash.h"
+#include "fuse_param.h"
+// #include "fuse_sysctl.h"
/* access */
@@ -213,62 +223,106 @@
fuse_check_spyable(struct fuse_dispatcher *fdip, struct mount *mp,
struct thread *td, struct ucred *cred)
{
- struct fuse_data *data = fusefs_get_data(mp);
- struct fuse_secondary_data *x_fsdat;
- int denied;
+ return (0);
+}
+
+/* fsync */
+
+int
+fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio)
+{
+ fuse_trace_printf_func();
+
+ if (tick->tk_aw_ohead.error == ENOSYS) {
+ tick->tk_data->dataflag |= (fticket_opcode(tick) == FUSE_FSYNC) ?
+ FSESS_NOFSYNC : FSESS_NOFSYNCDIR;
+ }
+
+ fuse_ticket_drop(tick);
+
+ return 0;
+}
- if (data->dataflag & FSESS_DAEMON_CAN_SPY)
- return (0);
+int
+fuse_internal_fsync(struct vnode *vp,
+ struct thread *td,
+ struct ucred *cred,
+ struct fuse_filehandle *fufh,
+ void *param)
+{
+ int op = FUSE_FSYNC;
+ struct fuse_fsync_in *ffsi;
+ struct fuse_dispatcher *fdip = param;
- /*
- * The policy is to forbid a user from using the filesystem,
- * unless she has it mounted.
- *
- * This is primarily to
- * protect her from the daemon spying on her I/O
- * operations. Although this is not a concern if the user
- * is more privileged than the daemon, we consistently
- * demand the per-user mount, in order to be compatible
- * with the Linux implementation.
- *
- * Secondary mounts let arbitrary number of users mount and
- * use the filesystem. However, the primary mounter must explicitly
- * allow secondary mounts. This is again for providing Linux like
- * defaults.
- */
+ fuse_trace_printf_func();
- denied = fuse_match_cred(mp->mnt_cred, cred);
- if (! denied)
- goto allow;
+ fdip->iosize = sizeof(*ffsi);
+ fdip->tick = NULL;
+ if (vnode_vtype(vp) == VDIR) {
+ op = FUSE_FSYNCDIR;
+ }
+
+ fdisp_make_vp(fdip, op, vp, td, cred);
+ ffsi = fdip->indata;
+ ffsi->fh = fufh->fh_id;
- LIST_FOREACH(x_fsdat, &data->slaves_head, slaves_link) {
- denied = fuse_match_cred(x_fsdat->mp->mnt_cred, cred);
- if (! denied)
- goto allow;
- }
+ ffsi->fsync_flags = 1;
+
+ fuse_insert_callback(fdip->tick, fuse_internal_fsync_callback);
+ fuse_insert_message(fdip->tick);
- return (EACCES);
+ return 0;
-allow:
- return (0);
}
-/* fsync */
+/* readdir */
int
-fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio)
+fuse_internal_readdir(struct vnode *vp,
+ struct uio *uio,
+ struct thread *td,
+ struct ucred *cred,
+ struct fuse_filehandle *fufh,
+ struct fuse_iov *cookediov)
{
- if (tick->tk_aw_ohead.error == ENOSYS)
- tick->tk_data->dataflag |=
- fticket_opcode(tick) == FUSE_FSYNC ?
- FSESS_NOFSYNC : FSESS_NOFSYNCDIR;
+ int err = 0;
+ struct fuse_dispatcher fdi;
+ struct fuse_read_in *fri;
+
+ if (uio_resid(uio) == 0) {
+ return (0);
+ }
+
+ fdisp_init(&fdi, 0);
+
+ /* Note that we DO NOT have a UIO_SYSSPACE here (so no need for p2p I/O). */
+
+ while (uio_resid(uio) > 0) {
+
+ fdi.iosize = sizeof(*fri);
+ fdisp_make_vp(&fdi, FUSE_READDIR, vp, td, cred);
+
+ fri = fdi.indata;
+ fri->fh = fufh->fh_id;
+ fri->offset = uio_offset(uio);
+ fri->size = min(uio_resid(uio), FUSE_DEFAULT_IOSIZE); // mp->max_read
+
+ if ((err = fdisp_wait_answ(&fdi))) {
+ goto out;
+ }
+
+ if ((err = fuse_internal_readdir_processdata(uio, fri->size, fdi.answ,
+ fdi.iosize, cookediov))) {
+ break;
+ }
+ }
+
+ fuse_ticket_drop(fdi.tick);
- fuse_ticket_drop(tick);
- return (0);
+out:
+ return ((err == -1) ? 0 : err);
}
-/* readdir */
-
int
fuse_internal_readdir_processdata(struct uio *uio,
size_t reqsize,
@@ -276,28 +330,6 @@
size_t bufsize,
void *param)
{
- /*
- * The daemon presents us with a virtual geometry when reading dirents.
- * This info is stored in the "off" field of fuse_dirent (which is the
- * struct we can read from her). "off" shows the absolut position of
- * the next entry (by definition). So I might pull 40 actual bytes from
- * the daemon, that might count as 60 by her virtual geometry, and when
- * I translate fuse_dirents to POSIX dirents, I have 20 bytes to pass
- * to the userspace reader.
- *
- * How to keep these in sync? We don't want to make the general read
- * routine complex (to which here we serve a background, and which
- * naively treats reading by a liner logic). So we artifically inflate
- * dirents: we pad them with as much zeros as we need them to get to
- * next offset (as the deamon declared), and we pass it to the reader
- * thusly (this will work as fuse dirents are bigger than std ones). So
- * we do more IO with the reader than absolutely necessary, but it's
- * hardly a problem as the expensive thing is reading from the daemon,
- * not sending data to the reader.
- *
- * There is no use to change this simple geometry translation scheme
- * 'till we do page caching. [We do now, but it's still fine as is.]
- */
int err = 0;
int cou = 0;
int bytesavail;
@@ -307,33 +339,10 @@
struct fuse_dirent *fudge;
struct fuse_iov *cookediov = param;
- KASSERT(bufsize <= reqsize, ("read more than asked for?"));
-
- DEBUG2G("starting\n");
-
- /*
- * Sanity check: if this fails, we would overrun the allocated space
- * upon entering the loop below, so we'd better leave right now.
- * If so, we return -1 to terminate reading.
- */
if (bufsize < FUSE_NAME_OFFSET) {
return (-1);
}
- DEBUG2G("entering loop with bufsize %d\n", (int)bufsize);
-
- /*
- * Can we avoid infite loops? An infinite loop could occur only if we
- * leave this function with 0 return value, because otherwise we wont't
- * be called again. But both 0 exit points imply that some data has
- * been consumed... because
- * 1) if a turn is not aborted, it consumes positive amount of data
- * 2) the 0 jump-out from within the loop can't occur in the first
- * turn
- * 3) if we exit 0 after the loop is over, then at least one turn
- * was completed, otherwise we hed exited above with -1.
- */
-
for (;;) {
if (bufsize < FUSE_NAME_OFFSET) {
@@ -346,15 +355,6 @@
fudge = (struct fuse_dirent *)buf;
freclen = FUSE_DIRENT_SIZE(fudge);
- DEBUG("bufsize %d, freclen %d\n", (int)bufsize, (int)freclen);
-
- /*
- * Here is an exit condition: we terminate the whole reading
- * process if a fresh chunk of buffer is already too short to
- * cut out an entry.
- * (It it was not the first turn in the loop, nevermind,
- * return with asking for more)
- */
if (bufsize < freclen) {
err = ((cou == 1) ? -1 : 0);
break;
@@ -367,25 +367,14 @@
}
#endif
- /* Sanity checks */
-
if (!fudge->namelen || fudge->namelen > MAXNAMLEN) {
- DEBUG2G("bogus namelen %d at turn %d\n",
- fudge->namelen, cou);
err = EINVAL;
break;
}
bytesavail = GENERIC_DIRSIZ((struct pseudo_dirent *)&fudge->namelen);
- /*
- * Exit condition 2: if the pretended amount of input is more
- * than that the userspace wants, then it's time to stop
- * reading.
- */
- if (bytesavail > uio->uio_resid) {
- DEBUG2G("leaving at %d-th item as we have %d bytes but only %d is asked for\n",
- cou, bytesavail, uio->uio_resid);
+ if (bytesavail > uio_resid(uio)) {
err = -1;
break;
}
@@ -402,10 +391,6 @@
(char *)buf + FUSE_NAME_OFFSET, fudge->namelen);
((char *)cookediov->base)[bytesavail] = '\0';
- DEBUG("bytesavail %d, fudge->off %llu, fudge->namelen %d, uio->uio_offset %d, name %s\n",
- bytesavail, (unsigned long long)fudge->off, fudge->namelen, (int)uio->uio_offset,
- (char *)cookediov->base + sizeof(struct dirent) - MAXNAMLEN - 1);
-
err = uiomove(cookediov->base, cookediov->len, uio);
if (err) {
break;
@@ -413,7 +398,7 @@
buf = (char *)buf + freclen;
bufsize -= freclen;
- uio->uio_offset = fudge->off;
+ uio_setoffset(uio, fudge->off);
}
return (err);
@@ -421,6 +406,26 @@
/* remove */
+#ifdef XXXIP
+static int
+fuse_unlink_callback(struct vnode *vp, void *cargs)
+{
+ struct vattr *vap;
+ uint64_t target_nlink;
+
+ vap = VTOVA(vp);
+
+ target_nlink = *(uint64_t *)cargs;
+
+ if ((vap->va_nlink == target_nlink) && (vnode_vtype(vp) == VREG)) {
+ fuse_invalidate_attr(vp);
+ }
+
+ return 0;
+}
+#endif
+
+#define INVALIDATE_CACHED_VATTRS_UPON_UNLINK 1
int
fuse_internal_remove(struct vnode *dvp,
struct vnode *vp,
@@ -428,9 +433,14 @@
enum fuse_opcode op)
{
struct fuse_dispatcher fdi;
+ struct vattr *vap = VTOVA(vp);
+#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
+ int need_invalidate = 0;
+ uint64_t target_nlink = 0;
+#endif
int err = 0;
- debug_printf("dvp=%p, cnp=%p, op=%d, context=%p\n", vp, cnp, op, context);
+ debug_printf("dvp=%p, cnp=%p, op=%d\n", vp, cnp, op);
fdisp_init(&fdi, cnp->cn_namelen + 1);
fdisp_make_vp(&fdi, op, dvp, curthread, NULL);
@@ -438,6 +448,13 @@
memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen);
((char *)fdi.indata)[cnp->cn_namelen] = '\0';
+#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
+ if (vap->va_nlink > 1) {
+ need_invalidate = 1;
+ target_nlink = vap->va_nlink;
+ }
+#endif
+
if (!(err = fdisp_wait_answ(&fdi))) {
fuse_ticket_drop(fdi.tick);
}
@@ -445,6 +462,15 @@
fuse_invalidate_attr(dvp);
fuse_invalidate_attr(vp);
+#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
+#ifdef XXXIP
+ if (need_invalidate && !err) {
+ vnode_iterate(vnode_mount(vp), 0, fuse_unlink_callback,
+ (void *)&target_nlink);
+ }
+#endif
+#endif
+
return (err);
}
@@ -511,6 +537,8 @@
memcpy((char *)fdip->indata + bufsize, cnp->cn_nameptr, cnp->cn_namelen);
((char *)fdip->indata)[bufsize + cnp->cn_namelen] = '\0';
+
+ fdip->iosize = bufsize + cnp->cn_namelen + 1;
}
int
@@ -521,13 +549,10 @@
{
int err = 0;
struct fuse_entry_out *feo;
- struct mount *mp = dvp->v_mount;
+ struct mount *mp = vnode_mount(dvp);
debug_printf("fdip=%p\n", fdip);
- KASSERT(! (mp->mnt_flag & MNT_RDONLY),
- ("request for new entry in a read-only mount"));
-
if ((err = fdisp_wait_answ(fdip))) {
return (err);
}
@@ -538,24 +563,13 @@
goto out;
}
- /*
- * The Linux code doesn't seem to make a fuss about
- * getting a nodeid for a new entry which is already
- * in use. Therefore we used to do the same.
- * This is not possible with our implementation of
- * atomic create+open; so, even if we could ignore this
- * fuzz here, we don't do, for the sake of consistency.
- */
err = fuse_vget_i(mp, curthread, feo->nodeid, vtyp, vpp,
VG_FORCENEW, VTOI(dvp));
-
if (err) {
- DEBUG2G("failed to fetch vnode for nodeid\n");
fuse_internal_forget_send(mp, curthread, NULL, feo->nodeid, 1, fdip);
return err;
}
- VTOFUD(*vpp)->nlookup++;
cache_attrs(*vpp, feo);
out:
@@ -577,7 +591,7 @@
struct fuse_dispatcher fdi;
fdisp_init(&fdi, 0);
- fuse_internal_newentry_makerequest(dvp->v_mount, VTOI(dvp), cnp,
+ fuse_internal_newentry_makerequest(vnode_mount(dvp), VTOI(dvp), cnp,
op, buf, bufsize, &fdi);
err = fuse_internal_newentry_core(dvp, vpp, vtyp, &fdi);
fuse_invalidate_attr(dvp);
@@ -587,51 +601,19 @@
/* entity destruction */
-static void
-fuse_internal_forget_send_pid(struct mount *mp,
- pid_t pid,
- struct ucred *cred,
- uint64_t nodeid,
- uint64_t nlookup,
- struct fuse_dispatcher *fdip)
-{
- struct fuse_forget_in *ffi;
-
- KASSERT(nlookup > 0, ("zero-times forget for vp #%llu",
- (long long unsigned) nodeid));
-
- DEBUG("sending FORGET with %llu lookups\n", (unsigned long long)nlookup);
-
- fdisp_init(fdip, sizeof(*ffi));
- fdisp_make_pid(fdip, mp, FUSE_FORGET, nodeid, pid, cred);
-
- ffi = fdip->indata;
- ffi->nlookup = nlookup;
-
- fticket_disown(fdip->tick);
- fuse_insert_message(fdip->tick);
-}
-
int
-fuse_internal_forget_callback(struct fuse_ticket *tick,
- struct uio *uio)
+fuse_internal_forget_callback(struct fuse_ticket *tick, struct uio *uio)
{
struct fuse_dispatcher fdi;
- struct fuse_pidcred *pidcred;
- /*
- * XXX I think I'm right to send a forget regardless of possible
- * errors, but...
- */
+ debug_printf("tick=%p, uio=%p\n", tick, uio);
fdi.tick = tick;
- pidcred = tick->tk_aw_handler_parm.base;
+ fuse_internal_forget_send(tick->tk_data->mp, curthread, NULL,
+ ((struct fuse_in_header *)tick->tk_ms_fiov.base)->nodeid,
+ 1, &fdi);
- fuse_internal_forget_send_pid(tick->tk_data->mp, pidcred->pid, &pidcred->cred,
- ((struct fuse_in_header *)tick->tk_ms_fiov.base)->nodeid,
- 1, &fdi);
-
- return (0);
+ return 0;
}
void
@@ -642,9 +624,24 @@
uint64_t nlookup,
struct fuse_dispatcher *fdip)
{
- RECTIFY_TDCR(td, cred);
- return (fuse_internal_forget_send_pid(mp, td->td_proc->p_pid, cred, nodeid,
- nlookup, fdip));
+ struct fuse_forget_in *ffi;
+
+ debug_printf("mp=%p, nodeid=%llx, nlookup=%lld, fdip=%p\n",
+ mp, nodeid, nlookup, fdip);
+
+ /*
+ * KASSERT(nlookup > 0, ("zero-times forget for vp #%llu",
+ * (long long unsigned) nodeid));
+ */
+
+ fdisp_init(fdip, sizeof(*ffi));
+ fdisp_make(fdip, mp, FUSE_FORGET, nodeid, td, cred);
+
+ ffi = fdip->indata;
+ ffi->nlookup = nlookup;
+
+ fticket_invalidate(fdip->tick);
+ fuse_insert_message(fdip->tick);
}
/* fuse start/stop */
@@ -654,11 +651,7 @@
{
int err = 0;
struct fuse_data *data = tick->tk_data;
-#if FUSE_KERNELABI_GEQ(7, 5)
struct fuse_init_out *fiio;
-#else
- struct fuse_init_in_out *fiio;
-#endif
if ((err = tick->tk_aw_ohead.error)) {
goto out;
@@ -670,9 +663,9 @@
fiio = fticket_resp(tick)->base;
- /* XXX is the following check adequate? */
+ /* XXX: Do we want to check anything further besides this? */
if (fiio->major < 7) {
- DEBUG2G("userpace version too low\n");
+ debug_printf("userpace version too low\n");
err = EPROTONOSUPPORT;
goto out;
}
@@ -680,14 +673,12 @@
data->fuse_libabi_major = fiio->major;
data->fuse_libabi_minor = fiio->minor;
- if (FUSE_KERNELABI_GEQ(7, 5) && fuse_libabi_geq(data, 7, 5)) {
-#if FUSE_KERNELABI_GEQ(7, 5)
+ if (fuse_libabi_geq(data, 7, 5)) {
if (fticket_resp(tick)->len == sizeof(struct fuse_init_out)) {
data->max_write = fiio->max_write;
} else {
err = EINVAL;
}
-#endif
} else {
/* Old fix values */
data->max_write = 4096;
@@ -711,11 +702,7 @@
void
fuse_internal_send_init(struct fuse_data *data, struct thread *td)
{
-#if FUSE_KERNELABI_GEQ(7, 5)
struct fuse_init_in *fiii;
-#else
- struct fuse_init_in_out *fiii;
-#endif
struct fuse_dispatcher fdi;
fdisp_init(&fdi, sizeof(*fiii));
@@ -723,6 +710,8 @@
fiii = fdi.indata;
fiii->major = FUSE_KERNEL_VERSION;
fiii->minor = FUSE_KERNEL_MINOR_VERSION;
+ fiii->max_readahead = FUSE_DEFAULT_IOSIZE * 16;
+ fiii->flags = 0;
fuse_insert_callback(fdi.tick, fuse_internal_init_callback);
fuse_insert_message(fdi.tick);
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#7 (text+ko) ====
@@ -51,26 +51,26 @@
}
/* XXX */
+void cluster_push(struct vnode *vp, int a);
+
struct fuse_pidcred {
- pid_t pid;
- struct ucred cred;
+ pid_t pid;
+ struct ucred cred;
};
/* access */
-#define FACCESS_VA_VALID 0x01 /* flag to sign to reuse cached attributes
- regardless of cache timeout */
-#define FACCESS_DO_ACCESS 0x02 /* flag showing if we are to do access check */
-#define FACCESS_STICKY 0x04 /* do sticky dir permission check */
-#define FACCESS_CHOWN 0x08 /* do permission check for owner changing */
-#define FACCESS_NOCHECKSPY 0x10 /* don't check if daemon is allowed to spy on
- user */
-#define FACCESS_SETGID 0x12 /* do permission check for setting setgid flag */
+#define FVP_ACCESS_NOOP 0x01
+
+#define FACCESS_VA_VALID 0x01
+#define FACCESS_DO_ACCESS 0x02
+#define FACCESS_STICKY 0x04
+#define FACCESS_CHOWN 0x08
+#define FACCESS_NOCHECKSPY 0x10
+#define FACCESS_SETGID 0x12
#define FACCESS_XQUERIES FACCESS_STICKY | FACCESS_CHOWN | FACCESS_SETGID
-#define FVP_ACCESS_NOOP 0x01 /* vnode based control flag for doing access check */
-
struct fuse_access_param {
uid_t xuid;
gid_t xgid;
@@ -142,12 +142,19 @@
\
timespecadd(&VTOFUD(vp)->cached_attrs_valid, &uptsp_ ## __func__); \
\
- fuse_internal_attr_fat2vat((vp)->v_mount, &(fuse_out)->attr, VTOVA(vp)); \
+ fuse_internal_attr_fat2vat(vnode_mount(vp), &(fuse_out)->attr, VTOVA(vp)); \
} while (0)
/* fsync */
int
+fuse_internal_fsync(struct vnode *vp,
+ struct thread *td,
+ struct ucred *cred,
+ struct fuse_filehandle *fufh,
+ void *param);
+
+int
fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
/* readdir */
@@ -157,6 +164,14 @@
};
int
+fuse_internal_readdir(struct vnode *vp,
+ struct uio *uio,
+ struct thread *td,
+ struct ucred *cred,
+ struct fuse_filehandle *fufh,
+ struct fuse_iov *cookediov);
+
+int
fuse_internal_readdir_processdata(struct uio *uio,
size_t reqsize,
void *buf,
@@ -252,4 +267,27 @@
int fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio);
void fuse_internal_send_init(struct fuse_data *data, struct thread *td);
+/* miscellaneous */
+
+#define fuse_isdeadfs_nop(vp) 0
+
+static __inline__
+int
+fuse_isdeadfs(struct vnode *vp)
+{
+ struct mount *mp = vnode_mount(vp);
+ struct fuse_data *data = fusefs_get_data(mp);
+
+ return (data->dataflag & FSESS_KICK);
+}
+
+static __inline__
+int
+fuse_isdeadfs_mp(struct mount *mp)
+{
+ struct fuse_data *data = fusefs_get_data(mp);
+
+ return (data->dataflag & FSESS_KICK);
+}
+
#endif /* _FUSE_INTERNAL_H_ */
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#3 (text+ko) ====
@@ -41,8 +41,7 @@
fp->f_vnode->v_type == VBAD ||
fp->f_vnode->v_op == &dead_vnodeops ||
fp->f_vnode->v_data == NULL ||
- fp->f_data == NULL ||
- FTOFH(fp)->fh_vp->v_type == VBAD);
+ fp->f_data == NULL);
}
/*
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.c#3 (text+ko) ====
@@ -3,10 +3,6 @@
* Amit Singh <singh@>
*/
-/*
- * Messaging related routines.
- */
-
#include "config.h"
#include <sys/types.h>
@@ -30,26 +26,27 @@
#include "fuse.h"
#include "fuse_node.h"
#include "fuse_ipc.h"
+#include "fuse_internal.h"
static struct fuse_ticket *fticket_alloc(struct fuse_data *data);
static void fticket_refresh(struct fuse_ticket *tick);
static void fticket_destroy(struct fuse_ticket *tick);
static int fticket_wait_answer(struct fuse_ticket *tick);
-static __inline int fticket_aw_pull_uio(struct fuse_ticket *tick,
- struct uio *uio);
-static __inline void fuse_push_freeticks(struct fuse_ticket *tick);
-static __inline
-struct fuse_ticket *fuse_pop_freeticks(struct fuse_data *data);
-static __inline void fuse_push_allticks(struct fuse_ticket *tick);
-static __inline void fuse_remove_allticks(struct fuse_ticket *tick);
+static __inline__ int fticket_aw_pull_uio(struct fuse_ticket *tick, struct uio *uio);
+static __inline__ void fuse_push_freeticks(struct fuse_ticket *tick);
+
+static __inline__ struct fuse_ticket *
+fuse_pop_freeticks(struct fuse_data *data);
+
+static __inline__ void fuse_push_allticks(struct fuse_ticket *tick);
+static __inline__ void fuse_remove_allticks(struct fuse_ticket *tick);
static struct fuse_ticket *fuse_pop_allticks(struct fuse_data *data);
-static int fuse_body_audit(struct fuse_ticket *tick, size_t blen);
-static __inline void fuse_setup_ihead(struct fuse_in_header *ihead,
- struct fuse_ticket *tick, uint64_t nid,
- enum fuse_opcode op, size_t blen,
- pid_t pid, struct ucred *cred);
-
+static int fuse_body_audit(struct fuse_ticket *tick, size_t blen);
+static __inline__ void fuse_setup_ihead(struct fuse_in_header *ihead,
+ struct fuse_ticket *tick, uint64_t nid,
+ enum fuse_opcode op, size_t blen,
+ pid_t pid, struct ucred *cred);
static fuse_handler_t fuse_standard_handler;
SYSCTL_NODE(_vfs, OID_AUTO, fuse, CTLFLAG_RW, 0, "FUSE tunables");
@@ -73,14 +70,6 @@
MALLOC_DEFINE(M_FUSEMSG, "fuse_messaging",
"buffer for fuse messaging related things");
-/***************************************
- *
- * >>> Interface ("methods") of messaging related objects
- *
- ***************************************/
-
-/* fuse_iov methods ==> */
-
void
fiov_init(struct fuse_iov *fiov, size_t size)
{
@@ -112,6 +101,9 @@
fiov->base = realloc(fiov->base, FU_AT_LEAST(size), M_FUSEMSG,
M_WAITOK | M_ZERO);
+ if (!fiov->base) {
+ panic("FUSE: realloc failed");
+ }
fiov->allocated_size = FU_AT_LEAST(size);
fiov->credit = fuse_iov_credit;
@@ -168,6 +160,7 @@
tick = malloc(sizeof(*tick), M_FUSEMSG, M_WAITOK | M_ZERO);
+ tick->tk_unique = data->ticketer++;
tick->tk_data = data;
fiov_init(&tick->tk_ms_fiov, sizeof(struct fuse_in_header));
@@ -175,7 +168,6 @@
mtx_init(&tick->tk_aw_mtx, "fuse answer delivery mutex", NULL, MTX_DEF);
fiov_init(&tick->tk_aw_fiov, 0);
- fiov_init(&tick->tk_aw_handler_parm, 0);
tick->tk_aw_type = FT_A_FIOV;
return (tick);
@@ -192,8 +184,8 @@
tick->tk_ms_type = FT_M_FIOV;
bzero(&tick->tk_aw_ohead, sizeof(struct fuse_out_header));
+
fiov_refresh(&tick->tk_aw_fiov);
- fiov_adjust(&tick->tk_aw_handler_parm, 0);
tick->tk_aw_errno = 0;
tick->tk_aw_bufdata = NULL;
tick->tk_aw_bufsize = 0;
@@ -212,7 +204,6 @@
mtx_destroy(&tick->tk_aw_mtx);
fiov_teardown(&tick->tk_aw_fiov);
- fiov_teardown(&tick->tk_aw_handler_parm);
free(tick, M_FUSEMSG);
}
@@ -241,14 +232,6 @@
mtx_unlock(&tick->tk_aw_mtx);
if (!(err || fticket_answered(tick))) {
- /*
- * Some deadlocky scenarios can get us here, like SIGKILLing
- * the fusexmp daemon after a fuse dir has been null mounted
- * over its original copy in the "normal" fs
- *
- * (I guess there is no need of kicking the daemon at this
- * point...)
- */
debug_printf("fuse requester was woken up but still no answer");
err = ENXIO;
}
@@ -260,11 +243,10 @@
fticket_aw_pull_uio(struct fuse_ticket *tick, struct uio *uio)
{
int err = 0;
- size_t len = uio->uio_resid;
+ size_t len = uio_resid(uio);
debug_printf("tick=%p, uio=%p\n", tick, uio);
-
if (len) {
switch (tick->tk_aw_type) {
case FT_A_FIOV:
@@ -304,7 +286,7 @@
return (0);
}
- err = fuse_body_audit(tick, uio->uio_resid);
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list