Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libperfuse Add support for extended attributes



details:   https://anonhg.NetBSD.org/src/rev/57b22d658c56
branches:  trunk
changeset: 766602:57b22d658c56
user:      manu <manu%NetBSD.org@localhost>
date:      Tue Jun 28 16:19:16 2011 +0000

description:
Add support for extended attributes

diffstat:

 lib/libperfuse/Makefile       |    6 +-
 lib/libperfuse/fuse.h         |    7 +-
 lib/libperfuse/ops.c          |  213 +++++++++++++++++++++++++++++++++++++++++-
 lib/libperfuse/perfuse.c      |    9 +-
 lib/libperfuse/perfuse_priv.h |   14 ++-
 lib/libperfuse/subr.c         |   60 +++++++++++-
 6 files changed, 299 insertions(+), 10 deletions(-)

diffs (truncated from 420 to 300 lines):

diff -r 0903bc97c413 -r 57b22d658c56 lib/libperfuse/Makefile
--- a/lib/libperfuse/Makefile   Tue Jun 28 14:58:33 2011 +0000
+++ b/lib/libperfuse/Makefile   Tue Jun 28 16:19:16 2011 +0000
@@ -1,11 +1,9 @@
-# $NetBSD: Makefile,v 1.4 2011/05/26 12:56:30 joerg Exp $
+# $NetBSD: Makefile,v 1.5 2011/06/28 16:19:16 manu Exp $
 
 LIB=            perfuse
-LIBDPLIBS+=     puffs  ${.CURDIR}/../libpuffs
+LIBDPLIBS+=     puffs  /usr/src/lib/libpuffs
 
-.ifdef DEBUG
 PERFUSE_OPT_DEBUG_FLAGS=   -g -DPERFUSE_DEBUG
-.endif
 
 CWARNFLAGS.clang+=     -Wno-format-security
 
diff -r 0903bc97c413 -r 57b22d658c56 lib/libperfuse/fuse.h
--- a/lib/libperfuse/fuse.h     Tue Jun 28 14:58:33 2011 +0000
+++ b/lib/libperfuse/fuse.h     Tue Jun 28 16:19:16 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: fuse.h,v 1.3 2011/05/11 14:52:48 jakllsch Exp $ */
+/*  $NetBSD: fuse.h,v 1.4 2011/06/28 16:19:16 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -39,6 +39,11 @@
 #define FUSE_BUFSIZE MAX(FUSE_PREF_BUFSIZE /* CONSTCOND */, FUSE_MIN_BUFSIZE)
 #endif /* FUSE_BUFSIZE */
 
+/* From <linux/limits.h> */
+#define LINUX_XATTR_NAME_MAX   255 
+#define LINUX_XATTR_SIZE_MAX 65536
+#define LINUX_XATTR_LIST_MAX 65536 
+
 struct fuse_attr {
        uint64_t        ino;
        uint64_t        size;
diff -r 0903bc97c413 -r 57b22d658c56 lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c      Tue Jun 28 14:58:33 2011 +0000
+++ b/lib/libperfuse/ops.c      Tue Jun 28 16:19:16 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: ops.c,v 1.30 2011/06/01 15:54:10 manu Exp $ */
+/*  $NetBSD: ops.c,v 1.31 2011/06/28 16:19:16 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -36,6 +36,7 @@
 #include <puffs.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
+#include <sys/extattr.h>
 #include <machine/vmparam.h>
 
 #include "perfuse_priv.h"
@@ -2924,3 +2925,213 @@
        return;
 }
 
+/* ARGSUSED4 */
+int
+perfuse_node_getextattr(pu, opc, attrns, attrname, attrsize, attr, resid, pcr)
+       struct puffs_usermount *pu;
+       puffs_cookie_t opc;
+       int attrns;
+       const char *attrname;
+       size_t *attrsize;
+       uint8_t *attr;
+       size_t *resid;
+       const struct puffs_cred *pcr;
+{
+       struct perfuse_state *ps;
+       char fuse_attrname[LINUX_XATTR_NAME_MAX + 1];
+       perfuse_msg_t *pm;
+       struct fuse_getxattr_in *fgi;
+       struct fuse_getxattr_out *fgo;
+       struct fuse_out_header *foh;
+       size_t attrnamelen;
+       size_t len;
+       char *np;
+       int error;
+
+       ps = puffs_getspecific(pu);
+       attrname = perfuse_native_ns(attrns, attrname, fuse_attrname);
+       attrnamelen = strlen(attrname) + 1;
+       len = sizeof(*fgi) + attrnamelen;
+
+       pm = ps->ps_new_msg(pu, opc, FUSE_GETXATTR, len, pcr);
+       fgi = GET_INPAYLOAD(ps, pm, fuse_getxattr_in);
+       fgi->size = (resid != NULL) ? *resid : 0;
+       np = (char *)(void *)(fgi + 1);
+       (void)strlcpy(np, attrname, attrnamelen);
+       
+       if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0)
+               goto out;
+
+       /*
+        * We just get fuse_getattr_out with list size if we requested
+        * a null size.
+        */
+       if (resid == NULL) {
+               fgo = GET_OUTPAYLOAD(ps, pm, fuse_getxattr_out);
+
+               if (attrsize != NULL)
+                       *attrsize = fgo->size;
+
+               goto out;
+       }
+
+       /*
+        * And with a non null requested size, we get the list just 
+        * after the header
+        */
+       foh = GET_OUTHDR(ps, pm);
+       np = (char *)(void *)(foh + 1);
+
+       if (resid != NULL) {
+               len = MAX(foh->len - sizeof(*foh), *resid);
+               (void)memcpy(attr, np, len);
+               *resid -= len;
+       }
+       
+out: 
+       ps->ps_destroy_msg(pm);
+
+       return error;
+}
+
+int
+perfuse_node_setextattr(pu, opc, attrns, attrname, attr, resid, pcr)
+       struct puffs_usermount *pu;
+       puffs_cookie_t opc;
+       int attrns;
+       const char *attrname;
+       uint8_t *attr;
+       size_t *resid;
+       const struct puffs_cred *pcr;
+{
+       struct perfuse_state *ps;
+       char fuse_attrname[LINUX_XATTR_NAME_MAX + 1];
+       perfuse_msg_t *pm;
+       struct fuse_setxattr_in *fsi;
+       size_t attrnamelen;
+       size_t len;
+       char *np;
+       int error;
+       
+       ps = puffs_getspecific(pu);
+       attrname = perfuse_native_ns(attrns, attrname, fuse_attrname);
+       attrnamelen = strlen(attrname) + 1;
+       len = sizeof(*fsi) + attrnamelen + *resid;
+
+       pm = ps->ps_new_msg(pu, opc, FUSE_SETXATTR, len, pcr);
+       fsi = GET_INPAYLOAD(ps, pm, fuse_setxattr_in);
+       fsi->size = *resid;
+       fsi->flags = 0;
+       np = (char *)(void *)(fsi + 1);
+       (void)strlcpy(np, attrname, attrnamelen);
+       np += attrnamelen;
+       (void)memcpy(np, (char *)attr, *resid);
+
+       if ((error = xchg_msg(pu, opc, pm, 
+                             NO_PAYLOAD_REPLY_LEN, wait_reply)) != 0)
+               goto out;
+
+       *resid = 0;
+out: 
+       ps->ps_destroy_msg(pm);
+
+       return error;
+}
+
+/* ARGSUSED2 */
+int
+perfuse_node_listextattr(pu, opc, attrns, attrsize, attrs, resid, pcr)
+       struct puffs_usermount *pu;
+       puffs_cookie_t opc;
+       int attrns;
+       size_t *attrsize;
+       uint8_t *attrs;
+       size_t *resid;
+       const struct puffs_cred *pcr;
+{
+       struct perfuse_state *ps;
+       perfuse_msg_t *pm;
+       struct fuse_getxattr_in *fgi;
+       struct fuse_getxattr_out *fgo;
+       struct fuse_out_header *foh;
+       char *np;
+       size_t len, puffs_len;
+       int error;
+       
+       ps = puffs_getspecific(pu);
+       len = sizeof(*fgi);
+
+       pm = ps->ps_new_msg(pu, opc, FUSE_LISTXATTR, len, pcr);
+       fgi = GET_INPAYLOAD(ps, pm, fuse_getxattr_in);
+       if (resid != NULL)
+               fgi->size = *resid;
+       else
+               fgi->size = 0;
+       
+       if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0)
+               goto out;
+
+       /*
+        * We just get fuse_getattr_out with list size if we requested
+        * a null size.
+        */
+       if (resid == NULL) {
+               fgo = GET_OUTPAYLOAD(ps, pm, fuse_getxattr_out);
+
+               if (attrsize != NULL)
+                       *attrsize = fgo->size;
+
+               goto out;
+       }
+
+       /*
+        * And with a non null requested size, we get the list just 
+        * after the header
+        */
+       foh = GET_OUTHDR(ps, pm);
+       np = (char *)(void *)(foh + 1);
+       puffs_len = foh->len - sizeof(*foh);
+
+       if (attrs != NULL) {
+               (void)memcpy(attrs, np, puffs_len);
+               *resid -= puffs_len;
+       }
+
+       if (attrsize != NULL) 
+               *attrsize = puffs_len;
+
+out: 
+       ps->ps_destroy_msg(pm);
+
+       return error;
+}
+
+int
+perfuse_node_deleteextattr(pu, opc, attrns, attrname, pcr)
+       struct puffs_usermount *pu;
+       puffs_cookie_t opc;
+       int attrns;
+       const char *attrname;
+       const struct puffs_cred *pcr;
+{
+       struct perfuse_state *ps;
+       char fuse_attrname[LINUX_XATTR_NAME_MAX + 1];
+       perfuse_msg_t *pm;
+       size_t attrnamelen;
+       char *np;
+       int error;
+       
+       ps = puffs_getspecific(pu);
+       attrname = perfuse_native_ns(attrns, attrname, fuse_attrname);
+       attrnamelen = strlen(attrname) + 1;
+
+       pm = ps->ps_new_msg(pu, opc, FUSE_REMOVEXATTR, attrnamelen, pcr);
+       np = _GET_INPAYLOAD(ps, pm, char *);
+       (void)strlcpy(np, attrname, attrnamelen);
+       
+       error = xchg_msg(pu, opc, pm, NO_PAYLOAD_REPLY_LEN, wait_reply);
+       
+       ps->ps_destroy_msg(pm);
+
+       return error;
+}
diff -r 0903bc97c413 -r 57b22d658c56 lib/libperfuse/perfuse.c
--- a/lib/libperfuse/perfuse.c  Tue Jun 28 14:58:33 2011 +0000
+++ b/lib/libperfuse/perfuse.c  Tue Jun 28 16:19:16 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse.c,v 1.15 2011/05/30 14:50:08 manu Exp $ */
+/*  $NetBSD: perfuse.c,v 1.16 2011/06/28 16:19:16 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -34,6 +34,7 @@
 #include <puffs.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/extattr.h>
 #include <sys/un.h>
 #include <machine/vmparam.h>
 
@@ -476,6 +477,12 @@
        PUFFSOP_SET(pops, perfuse, node, advlock);
        PUFFSOP_SET(pops, perfuse, node, read);
        PUFFSOP_SET(pops, perfuse, node, write);
+#ifdef PUFFS_EXTNAMELEN
+       PUFFSOP_SET(pops, perfuse, node, getextattr);
+       PUFFSOP_SET(pops, perfuse, node, setextattr);
+       PUFFSOP_SET(pops, perfuse, node, listextattr);
+       PUFFSOP_SET(pops, perfuse, node, deleteextattr);
+#endif /* PUFFS_EXTNAMELEN */
 
        puffs_flags = PUFFS_KFLAG_WTCACHE;
 
diff -r 0903bc97c413 -r 57b22d658c56 lib/libperfuse/perfuse_priv.h



Home | Main Index | Thread Index | Old Index