From 00946f2ca4a02621bb48801124a8c731691e4007 Mon Sep 17 00:00:00 2001 From: Susant Kumar Palai Date: Tue, 6 Aug 2013 14:45:06 -0700 Subject: [PATCH 1/3] VFS plugin was sending the actual size of the volume instead of the total number of block units because of which windows was getting the wrong volume capacity. Signed-off-by: Susant Kumar Palai Reviewed-by: Jeremy Allison Reviewed-by: Christopher R. Hertel --- source3/modules/vfs_glusterfs.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index 1323e0e..af8d5b7 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -301,7 +301,6 @@ static uint64_t vfs_gluster_disk_free(struct vfs_handle_struct *handle, uint64_t *dsize_p) { struct statvfs statvfs = { 0, }; - uint64_t dfree = 0; int ret; ret = glfs_statvfs(handle->data, path, &statvfs); @@ -309,19 +308,17 @@ static uint64_t vfs_gluster_disk_free(struct vfs_handle_struct *handle, return -1; } - dfree = statvfs.f_bsize * statvfs.f_bavail; - if (bsize_p != NULL) { - *bsize_p = statvfs.f_bsize; + *bsize_p = (uint64_t)statvfs.f_bsize; /* Block size */ } if (dfree_p != NULL) { - *dfree_p = dfree; + *dfree_p = (uint64_t)statvfs.f_bavail; /* Available Block units */ } if (dsize_p != NULL) { - *dsize_p = statvfs.f_bsize * statvfs.f_blocks; + *dsize_p = (uint64_t)statvfs.f_blocks; /* Total Block units */ } - return dfree; + return (uint64_t)statvfs.f_bavail; } static int vfs_gluster_get_quota(struct vfs_handle_struct *handle, -- 1.8.3.1 From 57fb56c40a4103b4ec047900d7a76a5db8896718 Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Sun, 11 Aug 2013 15:59:29 -0400 Subject: [PATCH 2/3] vfs_glusterfs: Implement proper mashalling/unmarshalling of ACLs Use the primitives available in Samba byteorder.h for implementing proper (un)marshalling of ACL xattrs. - Incorporated Raghavendra Talur's comments on v3 Signed-off-by: Anand Avati Signed-off-by: Raghavendra Talur Reviewed-by: Jeremy Allison Reviewed-by: Christopher R. Hertel Tested-by: Jose A. Rivera Autobuild-User(master): Simo Sorce Autobuild-Date(master): Fri Aug 16 20:34:51 CEST 2013 on sn-devel-104 --- source3/modules/vfs_glusterfs.c | 153 +++++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 42 deletions(-) diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index af8d5b7..eac1b24 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -992,13 +992,36 @@ static int vfs_gluster_set_offline(struct vfs_handle_struct *handle, return -1; } -/* Posix ACL Operations */ +/* + Gluster ACL Format: + + Size = 4 (header) + N * 8 (entry) + + Offset Size Field (Little Endian) + ------------------------------------- + 0-3 4-byte Version + + 4-5 2-byte Entry-1 tag + 6-7 2-byte Entry-1 perm + 8-11 4-byte Entry-1 id + + 12-13 2-byte Entry-2 tag + 14-15 2-byte Entry-2 perm + 16-19 4-byte Entry-2 id + ... + + */ + +/* header version */ #define GLUSTER_ACL_VERSION 2 + +/* perm bits */ #define GLUSTER_ACL_READ 0x04 #define GLUSTER_ACL_WRITE 0x02 #define GLUSTER_ACL_EXECUTE 0x01 +/* tag values */ #define GLUSTER_ACL_UNDEFINED_TAG 0x00 #define GLUSTER_ACL_USER_OBJ 0x01 #define GLUSTER_ACL_USER 0x02 @@ -1009,58 +1032,49 @@ static int vfs_gluster_set_offline(struct vfs_handle_struct *handle, #define GLUSTER_ACL_UNDEFINED_ID (-1) -struct gluster_ace { - uint16_t tag; - uint16_t perm; - uint32_t id; -}; - -struct gluster_acl_header { - uint32_t version; - struct gluster_ace entries[]; -}; +#define GLUSTER_ACL_HEADER_SIZE 4 +#define GLUSTER_ACL_ENTRY_SIZE 8 static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size, TALLOC_CTX *mem_ctx) { int count; size_t size; - struct gluster_ace *ace; struct smb_acl_entry *smb_ace; - struct gluster_acl_header *hdr; struct smb_acl_t *result; int i; + int offset; uint16_t tag; uint16_t perm; uint32_t id; size = xattr_size; - if (size < sizeof(*hdr)) { - /* ACL should be at least as big as the header */ + if (size < GLUSTER_ACL_HEADER_SIZE) { + /* ACL should be at least as big as the header (4 bytes) */ errno = EINVAL; return NULL; } - size -= sizeof(*hdr); + size -= GLUSTER_ACL_HEADER_SIZE; /* size of header = 4 bytes */ - if (size % sizeof(*ace)) { + if (size % GLUSTER_ACL_ENTRY_SIZE) { /* Size of entries must strictly be a multiple of - size of an ACE + size of an ACE (8 bytes) */ errno = EINVAL; return NULL; } - count = size / sizeof(*ace); + count = size / GLUSTER_ACL_ENTRY_SIZE; - hdr = (void *)buf; - - if (ntohl(hdr->version) != GLUSTER_ACL_VERSION) { + /* Version is the first 4 bytes of the ACL */ + if (IVAL(buf, 0) != GLUSTER_ACL_VERSION) { DEBUG(0, ("Unknown gluster ACL version: %d\n", - ntohl(hdr->version))); + IVAL(buf, 0))); return NULL; } + offset = GLUSTER_ACL_HEADER_SIZE; result = sys_acl_init(mem_ctx); if (!result) { @@ -1078,10 +1092,19 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size, result->count = count; smb_ace = result->acl; - ace = hdr->entries; for (i = 0; i < count; i++) { - tag = ntohs(ace->tag); + /* TAG is the first 2 bytes of an entry */ + tag = SVAL(buf, offset); + offset += 2; + + /* PERM is the next 2 bytes of an entry */ + perm = SVAL(buf, offset); + offset += 2; + + /* ID is the last 4 bytes of an entry */ + id = IVAL(buf, offset); + offset += 4; switch(tag) { case GLUSTER_ACL_USER: @@ -1107,7 +1130,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size, return NULL; } - id = ntohl(ace->id); switch(smb_ace->a_type) { case SMB_ACL_USER: @@ -1120,8 +1142,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size, break; } - perm = ntohs(ace->perm); - smb_ace->a_perm = 0; smb_ace->a_perm |= ((perm & GLUSTER_ACL_READ) ? SMB_ACL_READ : 0); @@ -1130,7 +1150,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size, smb_ace->a_perm |= ((perm & GLUSTER_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0); - ace++; smb_ace++; } @@ -1138,21 +1157,54 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size, } +static int gluster_ace_cmp(const void *left, const void *right) +{ + int ret = 0; + uint16_t tag_left, tag_right; + uint32_t id_left, id_right; + + /* + Sorting precedence: + + - Smaller TAG values must be earlier. + + - Within same TAG, smaller identifiers must be earlier, E.g: + UID 0 entry must be earlier than UID 200 + GID 17 entry must be earlier than GID 19 + */ + + /* TAG is the first element in the entry */ + tag_left = SVAL(left, 0); + tag_right = SVAL(right, 0); + + ret = (tag_left - tag_right); + if (!ret) { + /* ID is the third element in the entry, after two short + integers (tag and perm), i.e at offset 4. + */ + id_left = IVAL(left, 4); + id_right = IVAL(right, 4); + ret = id_left - id_right; + } + + return ret; +} + + static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) { ssize_t size; - struct gluster_ace *ace; struct smb_acl_entry *smb_ace; - struct gluster_acl_header *hdr; int i; int count; uint16_t tag; uint16_t perm; uint32_t id; + int offset; count = theacl->count; - size = sizeof(*hdr) + (count * sizeof(*ace)); + size = GLUSTER_ACL_HEADER_SIZE + (count * GLUSTER_ACL_ENTRY_SIZE); if (!buf) { return size; } @@ -1162,13 +1214,14 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) return -1; } - hdr = (void *)buf; - ace = hdr->entries; smb_ace = theacl->acl; - hdr->version = htonl(GLUSTER_ACL_VERSION); + /* Version is the first 4 bytes of the ACL */ + SIVAL(buf, 0, GLUSTER_ACL_VERSION); + offset = GLUSTER_ACL_HEADER_SIZE; for (i = 0; i < count; i++) { + /* Calculate tag */ switch(smb_ace->a_type) { case SMB_ACL_USER: tag = GLUSTER_ACL_USER; @@ -1195,8 +1248,8 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) return -1; } - ace->tag = ntohs(tag); + /* Calculate id */ switch(smb_ace->a_type) { case SMB_ACL_USER: id = smb_ace->info.user.uid; @@ -1209,20 +1262,36 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) break; } - ace->id = ntohl(id); + /* Calculate perm */ + perm = 0; - ace->perm = 0; - ace->perm |= + perm |= ((smb_ace->a_perm & SMB_ACL_READ) ? GLUSTER_ACL_READ : 0); - ace->perm |= + perm |= ((smb_ace->a_perm & SMB_ACL_WRITE) ? GLUSTER_ACL_WRITE : 0); - ace->perm |= + perm |= ((smb_ace->a_perm & SMB_ACL_EXECUTE) ? GLUSTER_ACL_EXECUTE : 0); - ace++; + + /* TAG is the first 2 bytes of an entry */ + SSVAL(buf, offset, tag); + offset += 2; + + /* PERM is the next 2 bytes of an entry */ + SSVAL(buf, offset, perm); + offset += 2; + + /* ID is the last 4 bytes of an entry */ + SIVAL(buf, offset, id); + offset += 4; + smb_ace++; } + /* Skip the header, sort @count number of 8-byte entries */ + qsort(buf+GLUSTER_ACL_HEADER_SIZE, count, GLUSTER_ACL_ENTRY_SIZE, + gluster_ace_cmp); + return size; } -- 1.8.3.1 From bd409aa03db3c654b3cf5e32c0679a97e5796e97 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Thu, 29 Aug 2013 16:58:16 -0500 Subject: [PATCH 3/3] vfs_glusterfs: Fix excessive debug output from vfs_gluster_open(). The vfs_gluster_open() function generates a debug message (at level 0) for every failed attempt to open a pathname. This includes cases in which attempts are made to open a directory as a file (those attempts are retried calling vfs_gluster_opendir()). The result is that the log file fills with messages about failed attempts to open directories, just because they are directories. This latest version, of the patch completely removes logging from the vfs_gluster_open() function. The error code returned is handled in upper layers, and the open function in the default VFS module does not log any errors. Signed-off-by: Christopher R. Hertel Reviewed-by: susant palai Reviewed-by: raghavendra talur Reviewed-by: Jose A. Rivera Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Aug 30 02:43:48 CEST 2013 on sn-devel-104 --- source3/modules/vfs_glusterfs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index eac1b24..237236a 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -481,11 +481,8 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, } if (glfd == NULL) { - DEBUG(0, ("glfs_{open[dir],creat}(%s) failed: %s\n", - smb_fname->base_name, strerror(errno))); return -1; } - return glfd_fd_store(glfd); } -- 1.8.3.1