/** * return index if found, * negative value on error. */ static int xattr_name_to_id(libzfswrap_vfs_t *p_vfs, creden_t *pcred, inogen_t object, char *name) { unsigned int i; char names[MAXPATHLEN], *ptr; size_t namesize; int retval = 0; /* get xattrs */ retval = libzfswrap_listxattr(p_vfs, pcred, object, (char **)&name, &namesize); if (retval) return -posix2fsal_error(retval); if (namesize == 0) return -ERR_FSAL_NOENT; for (ptr = names, i = 0; ptr < names + namesize; i++, ptr += strlen(ptr) + 1) { if (!strcmp(name, ptr)) return i + XATTR_COUNT; } return -ERR_FSAL_NOENT; }
/** * return index if found, * negative value on error. */ static int xattr_name_to_id(libzfswrap_vfs_t *p_vfs, zfsfsal_op_context_t *p_context, zfsfsal_handle_t *p_objecthandle, const char *psz_name, unsigned int *p_id) { unsigned int i; char *psz_buffer, *ptr; size_t i_size; creden_t cred; cred.uid = p_context->credential.user; cred.gid = p_context->credential.group; /* get xattrs */ TakeTokenFSCall(); int rc = libzfswrap_listxattr(p_vfs, &cred, p_objecthandle->data.zfs_handle, &psz_buffer, &i_size); ReleaseTokenFSCall(); if(rc) return posix2fsal_error(rc); for(ptr = psz_buffer, i = 0; ptr < psz_buffer + i_size; i++, ptr += strlen(ptr) + 1) { if(!strcmp(psz_name, ptr)) { *p_id = i + XATTR_COUNT; free(psz_buffer); return ERR_FSAL_NO_ERROR; } } free(psz_buffer); return ERR_FSAL_NOENT; }
static int xattr_id_to_name(libzfswrap_vfs_t *p_vfs, zfsfsal_op_context_t *p_context, zfsfsal_handle_t *p_objecthandle, unsigned int xattr_id, char *psz_name) { unsigned int index; unsigned int curr_idx; char *psz_buffer, *ptr; size_t i_size; size_t len; int rc; creden_t cred; if(xattr_id < XATTR_COUNT) return ERR_FSAL_INVAL; index = xattr_id - XATTR_COUNT; cred.uid = p_context->credential.user; cred.gid = p_context->credential.group; /* get xattrs */ TakeTokenFSCall(); rc = libzfswrap_listxattr(p_vfs, &cred, p_objecthandle->data.zfs_handle, &psz_buffer, &i_size); ReleaseTokenFSCall(); if(rc) return posix2fsal_error(rc); for(ptr = psz_buffer, curr_idx = 0; ptr < psz_buffer + i_size; curr_idx++, ptr += len + 1) { len = strlen(ptr); if(curr_idx == index) { strcpy(psz_name, ptr); free(psz_buffer); return ERR_FSAL_NO_ERROR; } } free(psz_buffer); return ERR_FSAL_NOENT; }
static int xattr_id_to_name(libzfswrap_vfs_t *p_vfs, creden_t *pcred, inogen_t object, unsigned int xattr_id, char *name) { unsigned int index; unsigned int curr_idx; char names[MAXPATHLEN], *ptr; size_t namesize; size_t len = 0; int retval = 0; if (xattr_id < XATTR_COUNT) return ERR_FSAL_INVAL; index = xattr_id - XATTR_COUNT; /* get xattrs */ retval = libzfswrap_listxattr(p_vfs, pcred, object, (char **)&names, &namesize); if (retval) return posix2fsal_error(retval); if (namesize == 0) return ERR_FSAL_NOENT; errno = 0; for (ptr = names, curr_idx = 0; ptr < names + namesize; curr_idx++, ptr += len + 1) { len = strlen(ptr); if (curr_idx == index) { strcpy(name, ptr); return ERR_FSAL_NO_ERROR; } } return ERR_FSAL_NOENT; }
fsal_status_t tank_list_ext_attrs(struct fsal_obj_handle *obj_hdl, unsigned int argcookie, fsal_xattrent_t *xattrs_tab, unsigned int xattrs_tabsize, unsigned int *p_nb_returned, int *end_of_list) { unsigned int index; unsigned int out_index; unsigned int cookie = argcookie; struct zfs_fsal_obj_handle *obj_handle = NULL; char names[MAXPATHLEN], *ptr; size_t namesize; int xattr_idx; int retval; creden_t cred; /* sanity checks */ if (!obj_hdl || !xattrs_tab || !p_nb_returned || !end_of_list) return fsalstat(ERR_FSAL_FAULT, 0); obj_handle = container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle); cred.uid = op_ctx->creds->caller_uid; cred.gid = op_ctx->creds->caller_gid; /* Deal with special cookie */ if (cookie == XATTR_RW_COOKIE) cookie = XATTR_COUNT; for (index = cookie, out_index = 0; index < XATTR_COUNT && out_index < xattrs_tabsize; index++) { if (do_match_type(xattr_list[index].flags, obj_hdl->attributes.type)) { /* fills an xattr entry */ xattrs_tab[out_index].xattr_id = index; strncpy(xattr_list[index].xattr_name, xattrs_tab[out_index].xattr_name, MAXNAMLEN); xattr_list[index].xattr_name[MAXNAMLEN] = '\0'; xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes (all supported) */ xattrs_tab[out_index].attributes.mask = obj_hdl->attributes.mask; if (file_attributes_to_xattr_attrs(&obj_hdl->attributes, &xattrs_tab [out_index] .attributes, index)) { /* set error flag */ xattrs_tab[out_index].attributes.mask = ATTR_RDATTR_ERR; } /* next output slot */ out_index++; } } /* save a call if output array is full */ if (out_index == xattrs_tabsize) { *end_of_list = false; *p_nb_returned = out_index; return fsalstat(ERR_FSAL_NO_ERROR, 0); } /* get the path of the file in Lustre */ /* get xattrs */ retval = libzfswrap_listxattr(ZFSFSAL_GetVFS(obj_handle->handle), &cred, obj_handle->handle->zfs_handle, (char **)&names, &namesize); if (retval) return fsalstat(posix2fsal_error(retval), retval); if (namesize > 0) { size_t len = 0; errno = 0; for (ptr = names, xattr_idx = 0; (ptr < names + namesize) && (out_index < xattrs_tabsize); xattr_idx++, ptr += len + 1) { len = strlen(ptr); index = XATTR_COUNT + xattr_idx; /* skip if index is before cookie */ if (index < cookie) continue; /* fills an xattr entry */ xattrs_tab[out_index].xattr_id = index; strncpy(xattrs_tab[out_index].xattr_name, ptr, len + 1); xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes (all supported) */ xattrs_tab[out_index].attributes.mask = obj_hdl->attributes.mask; if (file_attributes_to_xattr_attrs (&obj_hdl->attributes, &xattrs_tab[out_index].attributes, index)) { /* set error flag */ xattrs_tab[out_index].attributes.mask = ATTR_RDATTR_ERR; } /* next output slot */ out_index++; } /* all xattrs are in the output array */ if (ptr >= names + namesize) *end_of_list = true; else *end_of_list = false; } else /* no xattrs */ *end_of_list = true; *p_nb_returned = out_index; return fsalstat(ERR_FSAL_NO_ERROR, 0); }
/** * Retrieves the list of extended attributes for an object in the filesystem. * * \param p_objecthandle Handle of the object we want to get extended attributes. * \param cookie index of the next entry to be returned. * \param p_context pointer to the current security context. * \param xattrs_tab a table for storing extended attributes list to. * \param xattrs_tabsize the maximum number of xattr entries that xattrs_tab * can contain. * \param p_nb_returned the number of xattr entries actually stored in xattrs_tab. * \param end_of_list this boolean indicates that the end of xattrs list has been reached. */ fsal_status_t ZFSFSAL_ListXAttrs(fsal_handle_t * obj_handle, /* IN */ unsigned int argcookie, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_xattrent_t * xattrs_tab, /* IN/OUT */ unsigned int xattrs_tabsize, /* IN */ unsigned int *p_nb_returned, /* OUT */ int *end_of_list /* OUT */ ) { unsigned int index; unsigned int out_index; fsal_status_t st; fsal_attrib_list_t file_attrs; int rc; creden_t cred; zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle; unsigned int cookie = argcookie ; /* sanity checks */ if(!p_objecthandle || !p_context || !xattrs_tab || !p_nb_returned || !end_of_list) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_ListXAttrs); /* Deal with special cookie */ if( argcookie == FSAL_XATTR_RW_COOKIE ) cookie = XATTR_COUNT ; /* object attributes we want to retrieve from parent */ file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_TYPE | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID; /* don't retrieve unsuipported attributes */ file_attrs.asked_attributes &= global_fs_info.supported_attrs; st = ZFSFSAL_getattrs(obj_handle, p_context, &file_attrs); if(FSAL_IS_ERROR(st)) Return(st.major, st.minor, INDEX_FSAL_ListXAttrs); /* Get the right VFS */ ZFSFSAL_VFS_RDLock(); libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle); if(!p_vfs) { ZFSFSAL_VFS_Unlock(); Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_ListXAttrs); } for(index = cookie, out_index = 0; index < XATTR_COUNT && out_index < xattrs_tabsize; index++) { if(do_match_type(xattr_list[index].flags, p_objecthandle->data.type)) { /* fills an xattr entry */ xattrs_tab[out_index].xattr_id = index; FSAL_str2name(xattr_list[index].xattr_name, FSAL_MAX_NAME_LEN, &xattrs_tab[out_index].xattr_name); xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes (all supported) */ xattrs_tab[out_index].attributes.asked_attributes = global_fs_info.supported_attrs; if(file_attributes_to_xattr_attrs (&file_attrs, &xattrs_tab[out_index].attributes, index)) { /* set error flag */ xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; } /* next output slot */ out_index++; } } /* Save a call if the output array is full */ if(out_index == xattrs_tabsize) { *end_of_list = FALSE; *p_nb_returned = out_index; ZFSFSAL_VFS_Unlock(); Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); } /* List the extended attributes */ char *psz_buffer; size_t i_size; cred.uid = p_context->credential.user; cred.gid = p_context->credential.group; TakeTokenFSCall(); rc = libzfswrap_listxattr(p_vfs, &cred, p_objecthandle->data.zfs_handle, &psz_buffer, &i_size); ReleaseTokenFSCall(); ZFSFSAL_VFS_Unlock(); if(rc) Return(posix2fsal_error(rc), 0, INDEX_FSAL_ListXAttrs); if(i_size > 0) { size_t len = 0; char *ptr; int xattr_idx; for(ptr = psz_buffer, xattr_idx = 0; (ptr < psz_buffer + i_size) && (out_index < xattrs_tabsize); xattr_idx++, ptr += len + 1) { len = strlen(ptr); index = XATTR_COUNT + xattr_idx; /* Skip if the index is before the cookie */ if(index < cookie) continue; xattrs_tab[out_index].xattr_id = index; FSAL_str2name(ptr, len + 1, &xattrs_tab[out_index].xattr_name); xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes (all supported) */ xattrs_tab[out_index].attributes.asked_attributes = global_fs_info.supported_attrs; if(file_attributes_to_xattr_attrs(&file_attrs, &xattrs_tab[out_index].attributes, index)) { /* set error flag */ xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; } /* next output slot */ out_index++; } /* Every xattrs are in the output array */ if(ptr >= psz_buffer + i_size) *end_of_list = TRUE; else *end_of_list = FALSE; } else *end_of_list = TRUE; free(psz_buffer); *p_nb_returned = out_index; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); }