Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

EA -> listxattr support added

  • Loading branch information...
commit 9c1229a842738fed765936c784ead7ae4e6f552a 1 parent 8686f69
Rohan Puri authored
Showing with 161 additions and 101 deletions.
  1. +2 −1  module/lzfs_vnops.c
  2. +118 −53 module/lzfs_xattr.c
  3. +41 −47 module/lzfs_xattr_user.c
3  module/lzfs_vnops.c
View
@@ -28,6 +28,7 @@
#include <linux/writeback.h>
#include <sys/lzfs_snap.h>
#include <linux/xattr.h>
+#include <sys/lzfs_xattr.h>
#ifdef DEBUG_SUBSYSTEM
#undef DEBUG_SUBSYSTEM
@@ -1080,7 +1081,7 @@ const struct inode_operations zfs_inode_operations = {
.permission = lzfs_vnop_permission,
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
- // .listxattr = ext2_listxattr,
+ .listxattr = lzfs_listxattr,
.removexattr = generic_removexattr,
};
171 module/lzfs_xattr.c
View
@@ -5,86 +5,152 @@
#include <sys/types.h>
#include <sys/lzfs_inode.h>
#include <sys/lzfs_xattr.h>
+#include <linux/xattr.h>
int
lzfs_xattr_get(struct inode *inode, const char *name,
void *buffer, size_t size)
{
-/* char *tmp = "hello world";
- int error = 0;
- printk("name=%s, buffer=%p, buffer_size=%ld",
- name, buffer, (long)size);
- if(buffer) {
- memcpy(buffer, (void *)tmp, 12);
- error = 12;
- }
- return error;
-*/
struct inode *xinode = NULL;
vnode_t *vp;
- vnode_t *dvp;
- vnode_t *xvp;
- //vattr_t *vap;
- int err = 0;
- const struct cred *cred = get_current_cred();
- struct iovec iov;
+ vnode_t *dvp;
+ vnode_t *xvp;
+ int err = 0;
+ const struct cred *cred = get_current_cred();
+ struct iovec iov;
uio_t uio;
- printk("size of size:%ld\n", (long)size);
- /* uio_t uio = {
- .uio_iov = &iov,
- .uio_resid = size,
- .uio_iovcnt = 1,
- .uio_loffset = (offset_t)0,
- .uio_limit = MAXOFFSET_T,
- .uio_segflg = UIO_SYSSPACE,
- };
-*/
- //down_write(inode->xattr_sem);
- printk(" \nread file attr name is : %s\n", name);
- dvp = LZFS_ITOV(inode);
+
+ dvp = LZFS_ITOV(inode);
err = zfs_lookup(dvp, NULL, &vp, NULL, LOOKUP_XATTR, NULL,
- (struct cred *) cred, NULL, NULL, NULL);
-// put_cred(cred);
- if(err) {
- // up_write(inode->xattr_sem);
- return -err;
+ (struct cred *) cred, NULL, NULL, NULL);
+ if(err) {
+ return -err;
}
ASSERT(vp != NULL);
+
err = zfs_lookup(vp, (char *) name, &xvp, NULL, 0, NULL,
- (struct cred *) cred, NULL, NULL, NULL);
-// put_cred(cred);
- if(err) {
- // up_write(inode->xattr_sem);
- return -err;
- }
+ (struct cred *) cred, NULL, NULL, NULL);
+ if(err) {
+ return -err;
+ }
xinode = LZFS_VTOI(xvp);
- if(!size)
+ if(!size) {
return ((int) xinode->i_size);
- iov.iov_base = buffer;
- // iov.iov_len = xinode->i_size,
+ }
+ iov.iov_base = buffer;
iov.iov_len = size;
uio.uio_iov = &iov;
uio.uio_resid = size;
uio.uio_iovcnt = 1;
uio.uio_loffset = (offset_t)0;
-// uio.uio_limit = MAXOFFSET_T,
uio.uio_segflg = UIO_SYSSPACE;
- printk("size of read is :%ld\n", (long) xinode->i_size);
err = zfs_read(xvp, &uio, 0, (cred_t *)cred, NULL);
- put_cred(cred);
- if(err) {
- // up_write(inode->xattr_sem);
- return -err;
- }
+ put_cred(cred);
+ if(err) {
+ return -err;
+ }
- printk("read file buffer arg is : %s\n", (char *)buffer);
-// up_write(inode->xattr_sem);
return size - uio.uio_resid;
}
+#define for_each_xattr_handler(handlers, handler) \
+ for ((handler) = *(handlers)++; \
+ (handler) != NULL; \
+ (handler) = *(handlers)++)
+
+
+static inline struct xattr_handler *
+find_xattr_handler_prefix(struct xattr_handler **handlers,
+ const char *name)
+{
+ struct xattr_handler *ea_handler;
+
+ if (!handlers) {
+ return NULL;
+ }
+ for_each_xattr_handler(handlers, ea_handler) {
+ if (strncmp(ea_handler->prefix, name,
+ strlen(ea_handler->prefix)) == 0)
+ break;
+ }
+ return ea_handler;
+}
+
+
+
+struct listxattr_buf {
+ size_t size;
+ size_t pos;
+ char *buf;
+ struct inode *inode;
+};
+static int listxattr_filler(void *buf, const char *name, int namelen,
+ loff_t offset, u64 ino, unsigned int d_type)
+{
+
+ struct listxattr_buf *b = (struct listxattr_buf *)buf;
+ size_t size = 0;
+
+ if (name[0] != '.' ||
+ (namelen != 1 && (name[1] != '.' || namelen != 2))) {
+ struct xattr_handler *handler;
+ handler = find_xattr_handler_prefix(
+ b->inode->i_sb->s_xattr,
+ "user.");
+ if (!handler)
+ return 0;
+ if (b->buf) {
+ size = handler->list(b->inode, b->buf + b->pos,
+ b->size, name, namelen);
+ if (size > b->size)
+ return -ERANGE;
+ } else {
+ size = handler->list(b->inode, NULL,
+ 0, name, namelen);
+ }
+ }
+ b->pos += size;
+ return 0;
+}
+
+
+ssize_t
+lzfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+ vnode_t *dvp;
+ vnode_t *vp; /* xattr dir vnode pointer */
+ int err = 0, eof;
+ const struct cred *cred = get_current_cred();
+ loff_t pos = 0;
+
+ struct listxattr_buf buf = {
+ .inode = dentry->d_inode,
+ .buf = buffer,
+ .size = buffer ? size : 0,
+ };
+
+ dvp = LZFS_ITOV(dentry->d_inode);
+ err = zfs_lookup(dvp, NULL, &vp, NULL, LOOKUP_XATTR, NULL,
+ (struct cred *) cred, NULL, NULL, NULL);
+ if(err) {
+ return -err;
+ }
+ ASSERT(vp != NULL);
+
+ if(!size)
+ return (LZFS_VTOI(vp))->i_size;
+ err = zfs_readdir(vp, (void *)&buf, NULL, &eof, NULL, 0,
+ listxattr_filler, &pos);
+ if(err)
+ return -err;
+ else
+ err = buf.pos;
+ return err;
+}
+
struct xattr_handler *lzfs_xattr_handlers[] = {
&lzfs_xattr_user_handler,
// &lzfs_xattr_trusted_handler,
@@ -98,4 +164,3 @@ struct xattr_handler *lzfs_xattr_handlers[] = {
NULL
};
-
88 module/lzfs_xattr_user.c
View
@@ -23,83 +23,77 @@ lzfs_xattr_user_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
-// return -EOPNOTSUPP;
vnode_t *vp;
- vnode_t *dvp;
+ vnode_t *dvp;
vnode_t *xvp;
- vattr_t *vap;
- int err = 0;
- const struct cred *cred = get_current_cred();
+ vattr_t *vap;
+ int err = 0;
+ const struct cred *cred = get_current_cred();
struct iovec iov = {
- .iov_base = (void *) value,
- .iov_len = size,
- };
+ .iov_base = (void *) value,
+ .iov_len = size,
+ };
uio_t uio = {
- .uio_iov = &iov,
- .uio_resid = size,
- .uio_iovcnt = 1,
- .uio_loffset = (offset_t)0,
- .uio_limit = MAXOFFSET_T,
- .uio_segflg = UIO_SYSSPACE,
- };
+ .uio_iov = &iov,
+ .uio_resid = size,
+ .uio_iovcnt = 1,
+ .uio_loffset = (offset_t)0,
+ .uio_limit = MAXOFFSET_T,
+ .uio_segflg = UIO_SYSSPACE,
+ };
- //err = checkname((char *)dentry->d_name.name);
- printk("name is : %s, value is : %s, size is :%ld", name, ( char *) value, (long)size);
- //if(err)
- // return ((void * )-ENAMETOOLONG);
-// down_write(inode->xattr_sem);
dvp = LZFS_ITOV(inode);
- err = zfs_lookup(dvp, NULL, &vp, NULL, LOOKUP_XATTR | CREATE_XATTR_DIR, NULL,
- (struct cred *) cred, NULL, NULL, NULL);
- // put_cred(cred);
- printk("\n\n zfs_lookup complete \n\n");
+ err = zfs_lookup(dvp, NULL, &vp, NULL, LOOKUP_XATTR | CREATE_XATTR_DIR,
+ NULL, (struct cred *) cred, NULL, NULL, NULL);
if(err) {
-// up_write(inode->xattr_sem);
return -err;
}
vap = kmalloc(sizeof(vattr_t), GFP_KERNEL);
- ASSERT(vap != NULL);
+ ASSERT(vap != NULL);
- memset(vap, 0, sizeof(vap));
+ memset(vap, 0, sizeof(vap));
- vap->va_type = VREG;
- vap->va_mode = 0644;
- vap->va_mask = AT_TYPE|AT_MODE;
- vap->va_uid = current_fsuid();
- vap->va_gid = current_fsgid();
+ vap->va_type = VREG;
+ vap->va_mode = 0644;
+ vap->va_mask = AT_TYPE|AT_MODE;
+ vap->va_uid = current_fsuid();
+ vap->va_gid = current_fsgid();
err = zfs_create(vp, (char *)name, vap, 0, 0644,
- &xvp, (struct cred *)cred, 0, NULL, NULL);
- //put_cred(cred);
- kfree(vap);
+ &xvp, (struct cred *)cred, 0, NULL, NULL);
+ kfree(vap);
if(err) {
-// up_write(inode->xattr_sem);
return -err;
}
err = zfs_write(xvp, &uio, 0, (cred_t *)cred, NULL);
- put_cred(cred);
+ put_cred(cred);
if(err) {
-// up_write(inode->xattr_sem);
return -err;
}
-// up_write(inode->xattr_sem);
return err;
-
}
static size_t
lzfs_xattr_user_list(struct inode *inode, char *list, size_t list_size,
- const char *name, size_t name_len)
-{
- return 0;
+ const char *name, size_t name_len)
+{
+ const size_t prefix_len = XATTR_USER_PREFIX_LEN;
+ const size_t total_len = prefix_len + name_len + 1;
+
+ if (list && total_len <= list_size) {
+ memcpy(list, XATTR_USER_PREFIX, prefix_len);
+ memcpy(list+prefix_len, name, name_len);
+ list[prefix_len + name_len] = '\0';
+ }
+ return total_len;
}
struct xattr_handler lzfs_xattr_user_handler = {
- .prefix = XATTR_USER_PREFIX,
- .list = lzfs_xattr_user_list,
- .get = lzfs_xattr_user_get,
- .set = lzfs_xattr_user_set,
+ .prefix = XATTR_USER_PREFIX,
+ .list = lzfs_xattr_user_list,
+ .get = lzfs_xattr_user_get,
+ .set = lzfs_xattr_user_set,
};
Please sign in to comment.
Something went wrong with that request. Please try again.