static fsal_status_t lookup(struct fsal_obj_handle *parent, const struct req_op_context *opctx, const char *path, struct fsal_obj_handle **handle) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; struct glfs_object *glhandle = NULL; unsigned char globjhdl[GLAPI_HANDLE_LENGTH]; struct glusterfs_handle *objhandle = NULL; struct glusterfs_export *glfs_export = container_of(parent->export, struct glusterfs_export, export); struct glusterfs_handle *parenthandle = container_of(parent, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif glhandle = glfs_h_lookupat(glfs_export->gl_fs, parenthandle->glhandle, path, &sb); if (glhandle == NULL) { status = gluster2fsal_error(errno); goto out; } rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } rc = construct_handle(glfs_export, &sb, glhandle, globjhdl, GLAPI_HANDLE_LENGTH, &objhandle); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } *handle = &objhandle->handle; out: if (status.major != ERR_FSAL_NO_ERROR) { gluster_cleanup_vars(glhandle); } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_lookup); #endif return status; }
static fsal_status_t renamefile(struct fsal_obj_handle *olddir_hdl, const struct req_op_context *opctx, const char *old_name, struct fsal_obj_handle *newdir_hdl, const char *new_name) { int rc = 0, credrc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_export *glfs_export = container_of(olddir_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *srcparenthandle = container_of(olddir_hdl, struct glusterfs_handle, handle); struct glusterfs_handle *dstparenthandle = container_of(newdir_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif credrc = setglustercreds(glfs_export, &opctx->creds->caller_uid, &opctx->creds->caller_gid, opctx->creds->caller_glen, opctx->creds->caller_garray); if (credrc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } rc = glfs_h_rename(glfs_export->gl_fs, srcparenthandle->glhandle, old_name, dstparenthandle->glhandle, new_name); credrc = setglustercreds(glfs_export, NULL, NULL, 0, NULL); if (credrc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } if (rc != 0) { status = gluster2fsal_error(errno); goto out; } out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_renamefile); #endif return status; }
static fsal_status_t file_close(struct fsal_obj_handle *obj_hdl) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif rc = glfs_close(objhandle->glfd); if (rc != 0) { status = gluster2fsal_error(errno); goto out; } objhandle->glfd = NULL; objhandle->openflags = FSAL_O_CLOSED; out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_file_close); #endif return status; }
static fsal_status_t file_write(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, uint64_t seek_descriptor, size_t buffer_size, void *buffer, size_t * write_amount, bool * fsal_stable) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif rc = glfs_pwrite(objhandle->glfd, buffer, buffer_size, seek_descriptor, ((*fsal_stable) ? O_SYNC : 0)); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } *write_amount = rc; if (objhandle->openflags & FSAL_O_SYNC) *fsal_stable = true; out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_file_write); #endif return status; }
static fsal_status_t readsymlink(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, struct gsh_buffdesc *link_content, bool refresh) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_export *glfs_export = container_of(obj_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif link_content->len = 1024; // bad bad!!! need to determine size link_content->addr = gsh_malloc(link_content->len); if (link_content->addr == NULL) { status = gluster2fsal_error(rc); goto out; } rc = glfs_h_readlink(glfs_export->gl_fs, objhandle->glhandle, link_content->addr, link_content->len); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } /* Check if return buffer overflowed, it is still '\0' terminated */ link_content->len = (strlen(link_content->addr) + 1); out: if (status.major != ERR_FSAL_NO_ERROR) { gsh_free(link_content->addr); link_content->addr = NULL; link_content->len = 0; } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_readsymlink); #endif return status; }
static fsal_status_t handle_release(struct fsal_obj_handle *obj_hdl) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif rc = fsal_obj_handle_uninit(&objhandle->handle); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } if (objhandle->glfd) { rc = glfs_close(objhandle->glfd); if (rc) { status = gluster2fsal_error(errno); /* cleanup as much as possible */ } } if (objhandle->glhandle) { rc = glfs_h_close(objhandle->glhandle); if (rc) { status = gluster2fsal_error(errno); goto out; } } gsh_free(objhandle); out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_handle_release); #endif return status; }
static fsal_status_t getattrs(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; struct glusterfs_export *glfs_export = container_of(obj_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif /* FIXME: Should we hold the fd so that any async op does * not close it */ if (objhandle->openflags != FSAL_O_CLOSED) { rc = glfs_fstat(objhandle->glfd, &sb); } else { rc = glfs_h_stat(glfs_export->gl_fs, objhandle->glhandle, &sb); } if (rc != 0) { if (errno == ENOENT) status = gluster2fsal_error(ESTALE); else status = gluster2fsal_error(errno); goto out; } stat2fsal_attributes(&sb, &objhandle->handle.attributes); out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_getattrs); #endif return status; }
static fsal_status_t file_open(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, fsal_openflags_t openflags) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glfs_fd *glfd = NULL; int p_flags = 0; struct glusterfs_export *glfs_export = container_of(obj_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif if (objhandle->openflags != FSAL_O_CLOSED) { return fsalstat(ERR_FSAL_SERVERFAULT, 0); } rc = fsal2posix_openflags(openflags, &p_flags); if (rc != 0) { status.major = rc; goto out; } glfd = glfs_h_open(glfs_export->gl_fs, objhandle->glhandle, p_flags); if (glfd == NULL) { status = gluster2fsal_error(errno); goto out; } objhandle->openflags = openflags; objhandle->glfd = glfd; out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_file_open); #endif return status; }
static fsal_status_t file_read(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, uint64_t seek_descriptor, size_t buffer_size, void *buffer, size_t * read_amount, bool * end_of_file) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif rc = glfs_pread(objhandle->glfd, buffer, buffer_size, seek_descriptor, 0 /*TODO: flags is unused, so pass in something */ ); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } if (rc < buffer_size) { *end_of_file = true; } *read_amount = rc; out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_file_read); #endif return status; }
static fsal_status_t commit(struct fsal_obj_handle *obj_hdl, /* sync */ off_t offset, size_t len) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif /* TODO: Everybody pretty much ignores the range sent */ rc = glfs_fsync(objhandle->glfd); if (rc < 0) { status = gluster2fsal_error(errno); } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_commit); #endif return status; }
static fsal_status_t setattrs(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, struct attrlist *attrs) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; int mask = 0; struct glusterfs_export *glfs_export = container_of(obj_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif memset(&sb, 0, sizeof(struct stat)); if (FSAL_TEST_MASK(attrs->mask, ATTR_SIZE)) { rc = glfs_h_truncate(glfs_export->gl_fs, objhandle->glhandle, attrs->filesize); if (rc != 0) { status = gluster2fsal_error(errno); goto out; } } if (FSAL_TEST_MASK(attrs->mask, ATTR_MODE)) { mask |= GLAPI_SET_ATTR_MODE; sb.st_mode = fsal2unix_mode(attrs->mode); } if (FSAL_TEST_MASK(attrs->mask, ATTR_OWNER)) { mask |= GLAPI_SET_ATTR_UID; sb.st_uid = attrs->owner; } if (FSAL_TEST_MASK(attrs->mask, ATTR_GROUP)) { mask |= GLAPI_SET_ATTR_GID; sb.st_gid = attrs->group; } if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME)) { mask |= GLAPI_SET_ATTR_ATIME; sb.st_atim = attrs->atime; } if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME_SERVER)) { mask |= GLAPI_SET_ATTR_ATIME; struct timespec timestamp; rc = clock_gettime(CLOCK_REALTIME, ×tamp); if (rc != 0) { status = gluster2fsal_error(errno); goto out; } sb.st_atim = timestamp; } if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME)) { mask |= GLAPI_SET_ATTR_MTIME; sb.st_mtim = attrs->mtime; } if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME_SERVER)) { mask |= GLAPI_SET_ATTR_MTIME; struct timespec timestamp; rc = clock_gettime(CLOCK_REALTIME, ×tamp); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } sb.st_mtim = timestamp; } rc = glfs_h_setattrs(glfs_export->gl_fs, objhandle->glhandle, &sb, mask); if (rc != 0) { status = gluster2fsal_error(errno); goto out; } out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_setattrs); #endif return status; }
static fsal_status_t makesymlink(struct fsal_obj_handle *dir_hdl, const struct req_op_context *opctx, const char *name, const char *link_path, struct attrlist *attrib, struct fsal_obj_handle **handle) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; struct glfs_object *glhandle = NULL; unsigned char globjhdl[GLAPI_HANDLE_LENGTH]; struct glusterfs_handle *objhandle = NULL; struct glusterfs_export *glfs_export = container_of(dir_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *parenthandle = container_of(dir_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif rc = setglustercreds(glfs_export, &opctx->creds->caller_uid, &opctx->creds->caller_gid, opctx->creds->caller_glen, opctx->creds->caller_garray); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } /* FIXME: what else from attrib should we use? */ glhandle = glfs_h_symlink(glfs_export->gl_fs, parenthandle->glhandle, name, link_path, &sb); rc = setglustercreds(glfs_export, NULL, NULL, 0, NULL); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } if (glhandle == NULL) { status = gluster2fsal_error(errno); goto out; } rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } rc = construct_handle(glfs_export, &sb, glhandle, globjhdl, GLAPI_HANDLE_LENGTH, &objhandle); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } *handle = &objhandle->handle; *attrib = objhandle->handle.attributes; out: if (status.major != ERR_FSAL_NO_ERROR) { gluster_cleanup_vars(glhandle); } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_makesymlink); #endif return status; }
static fsal_status_t makenode(struct fsal_obj_handle *dir_hdl, const struct req_op_context *opctx, const char *name, object_file_type_t nodetype, fsal_dev_t * dev, struct attrlist *attrib, struct fsal_obj_handle **handle) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; struct glfs_object *glhandle = NULL; unsigned char globjhdl[GLAPI_HANDLE_LENGTH]; struct glusterfs_handle *objhandle = NULL; dev_t ndev = { 0, }; struct glusterfs_export *glfs_export = container_of(dir_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *parenthandle = container_of(dir_hdl, struct glusterfs_handle, handle); mode_t create_mode; #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif switch (nodetype) { case BLOCK_FILE: if (!dev) return fsalstat(ERR_FSAL_INVAL, 0); /* FIXME: This needs a feature flag test? */ ndev = makedev(dev->major, dev->minor); create_mode = S_IFBLK; break; case CHARACTER_FILE: if (!dev) return fsalstat(ERR_FSAL_INVAL, 0); ndev = makedev(dev->major, dev->minor); create_mode = S_IFCHR; break; case FIFO_FILE: create_mode = S_IFIFO; break; case SOCKET_FILE: create_mode = S_IFSOCK; break; default: LogMajor(COMPONENT_FSAL, "Invalid node type in FSAL_mknode: %d", nodetype); return fsalstat(ERR_FSAL_INVAL, 0); } rc = setglustercreds(glfs_export, &opctx->creds->caller_uid, &opctx->creds->caller_gid, opctx->creds->caller_glen, opctx->creds->caller_garray); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } /* FIXME: what else from attrib should we use? */ glhandle = glfs_h_mknod(glfs_export->gl_fs, parenthandle->glhandle, name, create_mode | fsal2unix_mode(attrib->mode), ndev, &sb); rc = setglustercreds(glfs_export, NULL, NULL, 0, NULL); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } if (glhandle == NULL) { status = gluster2fsal_error(errno); goto out; } rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } rc = construct_handle(glfs_export, &sb, glhandle, globjhdl, GLAPI_HANDLE_LENGTH, &objhandle); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } *handle = &objhandle->handle; *attrib = objhandle->handle.attributes; out: if (status.major != ERR_FSAL_NO_ERROR) { gluster_cleanup_vars(glhandle); } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_makenode); #endif return status; }
static fsal_status_t read_dirents(struct fsal_obj_handle *dir_hdl, const struct req_op_context *opctx, fsal_cookie_t * whence, void *dir_state, fsal_readdir_cb cb, bool * eof) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glfs_fd *glfd = NULL; long offset = 0; struct dirent *pde = NULL; struct glusterfs_export *glfs_export = container_of(dir_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(dir_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif glfd = glfs_h_opendir(glfs_export->gl_fs, objhandle->glhandle); if (glfd == NULL) { return gluster2fsal_error(errno); } if (whence != NULL) { offset = *whence; } glfs_seekdir(glfd, offset); while (!(*eof)) { struct dirent de; rc = glfs_readdir_r(glfd, &de, &pde); if (rc == 0 && pde != NULL) { /* skip . and .. */ if ((strcmp(de.d_name, ".") == 0) || (strcmp(de.d_name, "..") == 0)) { continue; } if (!cb (opctx, de.d_name, dir_state, glfs_telldir(glfd))) { goto out; } } else if (rc == 0 && pde == NULL) { *eof = true; } else if (rc != 0) { status = gluster2fsal_error(errno); goto out; } else { /* Can't happen */ abort(); } } out: rc = glfs_closedir(glfd); if (rc < 0) { status = gluster2fsal_error(errno); } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_read_dirents); #endif return status; }
static fsal_status_t lock_op(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, void * p_owner, fsal_lock_op_t lock_op, fsal_lock_param_t *request_lock, fsal_lock_param_t *conflicting_lock) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); struct flock flock; int cmd; int saverrno = 0; #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif if (objhandle->openflags == FSAL_O_CLOSED) { LogDebug(COMPONENT_FSAL, "ERROR: Attempting to lock with no file descriptor open"); status.major = ERR_FSAL_FAULT; goto out; } if (lock_op == FSAL_OP_LOCKT) { cmd = F_GETLK; } else if (lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_UNLOCK) { cmd = F_SETLK; } else { LogDebug(COMPONENT_FSAL, "ERROR: Unsupported lock operation %d\n", lock_op); status.major = ERR_FSAL_NOTSUPP; goto out; } if (request_lock->lock_type == FSAL_LOCK_R) { flock.l_type = F_RDLCK; } else if (request_lock->lock_type == FSAL_LOCK_W) { flock.l_type = F_WRLCK; } else { LogDebug(COMPONENT_FSAL, "ERROR: The requested lock type was not read or write."); status.major = ERR_FSAL_NOTSUPP; goto out; } /* TODO: Override R/W and just provide U? */ if (lock_op == FSAL_OP_UNLOCK) flock.l_type = F_UNLCK; flock.l_len = request_lock->lock_length; flock.l_start = request_lock->lock_start; flock.l_whence = SEEK_SET; rc = glfs_posix_lock (objhandle->glfd, cmd, &flock); if (rc != 0 && lock_op == FSAL_OP_LOCK && conflicting_lock && (errno == EACCES || errno == EAGAIN)) { /* process conflicting lock */ saverrno = errno; cmd = F_GETLK; rc = glfs_posix_lock (objhandle->glfd, cmd, &flock); if (rc) { LogCrit(COMPONENT_FSAL, "Failed to get conflicting lock post lock" " failure"); status = gluster2fsal_error(errno); goto out; } conflicting_lock->lock_length = flock.l_len; conflicting_lock->lock_start = flock.l_start; conflicting_lock->lock_type = flock.l_type; status = gluster2fsal_error(saverrno); goto out; } else if (rc != 0) { status = gluster2fsal_error(errno); goto out; } if (conflicting_lock != NULL) { if (lock_op == FSAL_OP_LOCKT && flock.l_type != F_UNLCK) { conflicting_lock->lock_length = flock.l_len; conflicting_lock->lock_start = flock.l_start; conflicting_lock->lock_type = flock.l_type; } else { conflicting_lock->lock_length = 0; conflicting_lock->lock_start = 0; conflicting_lock->lock_type = FSAL_NO_LOCK; } } out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_lock_op); #endif return status; }
/* * Read the ACL in GlusterFS format and convert it into fsal ACL before * storing it in fsalattr */ fsal_status_t glusterfs_get_acl(struct glusterfs_export *glfs_export, struct glfs_object *glhandle, glusterfs_fsal_xstat_t *buffxstat, struct attrlist *fsalattr) { fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; fsal_acl_data_t acldata; fsal_acl_status_t aclstatus; fsal_ace_t *pace = NULL; int e_count = 0, i_count = 0, new_count = 0, new_i_count = 0; if (fsalattr->acl != NULL) { /* We should never be passed attributes that have an * ACL attached, but just in case some future code * path changes that assumption, let's release the * old ACL properly. */ int acl_status; acl_status = nfs4_acl_release_entry(fsalattr->acl); if (acl_status != NFS_V4_ACL_SUCCESS) LogCrit(COMPONENT_FSAL, "Failed to release old acl, status=%d", acl_status); fsalattr->acl = NULL; } if (NFSv4_ACL_SUPPORT) { buffxstat->e_acl = glfs_h_acl_get(glfs_export->gl_fs->fs, glhandle, ACL_TYPE_ACCESS); if (!buffxstat->e_acl) { status = gluster2fsal_error(errno); return status; } e_count = ace_count(buffxstat->e_acl); if (buffxstat->is_dir) { buffxstat->i_acl = glfs_h_acl_get(glfs_export->gl_fs->fs, glhandle, ACL_TYPE_DEFAULT); i_count = ace_count(buffxstat->i_acl); } /* Allocating memory for both ALLOW and DENY entries */ acldata.naces = 2 * (e_count + i_count); LogDebug(COMPONENT_FSAL, "No of aces present in fsal_acl_t = %d" , acldata.naces); if (!acldata.naces) return status; FSAL_SET_MASK(buffxstat->attr_valid, XATTR_ACL); acldata.aces = (fsal_ace_t *) nfs4_ace_alloc(acldata.naces); pace = acldata.aces; new_count = posix_acl_2_fsal_acl(buffxstat->e_acl, buffxstat->is_dir, false, &pace); if (new_count < 0) return fsalstat(ERR_FSAL_NO_ACE, -1); if (i_count > 0) { new_i_count = posix_acl_2_fsal_acl(buffxstat->i_acl, true, true, &pace); if (new_i_count > 0) new_count += new_i_count; else LogDebug(COMPONENT_FSAL, "Inherit acl is not set for this directory"); } /* Reallocating acldata into the required size */ acldata.aces = (fsal_ace_t *) gsh_realloc(acldata.aces, new_count*sizeof(fsal_ace_t)); acldata.naces = new_count; fsalattr->acl = nfs4_acl_new_entry(&acldata, &aclstatus); LogDebug(COMPONENT_FSAL, "fsal acl = %p, fsal_acl_status = %u", fsalattr->acl, aclstatus); if (fsalattr->acl == NULL) { LogCrit(COMPONENT_FSAL, "failed to create a new acl entry"); return fsalstat(ERR_FSAL_NOMEM, -1); } fsalattr->valid_mask |= ATTR_ACL; } else { /* We were asked for ACL but do not support. */ status = fsalstat(ERR_FSAL_NOTSUPP, 0); } return status; }