/** * GPFSFSAL_getattrs: * Get attributes for the object specified by its filehandle. * * \param filehandle (input): * The handle of the object to get parameters. * \param cred (input): * Authentication context for the operation (user,...). * \param object_attributes (mandatory input/output): * The retrieved attributes for the object. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - Another error code if an error occured. */ fsal_status_t GPFSFSAL_getattrs(fsal_handle_t * p_filehandle, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_attrib_list_t * p_object_attributes /* IN/OUT */ ) { fsal_status_t st; gpfsfsal_xstat_t buffxstat; #ifdef _USE_NFS4_ACL fsal_accessflags_t access_mask = 0; #endif /* sanity checks. * note : object_attributes is mandatory in GPFSFSAL_getattrs. */ if(!p_filehandle || !p_context || !p_object_attributes) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs); TakeTokenFSCall(); st = fsal_get_xstat_by_handle(p_context, p_filehandle, &buffxstat); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(st)) ReturnStatus(st, INDEX_FSAL_getattrs); /* convert attributes */ st = gpfsfsal_xstat_2_fsal_attributes(&buffxstat, p_object_attributes); if(FSAL_IS_ERROR(st)) { FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); ReturnStatus(st, INDEX_FSAL_getattrs); } #ifdef _USE_NFS4_ACL if(p_object_attributes->acl) { /* Check permission to get attributes and ACL. */ access_mask = FSAL_MODE_MASK_SET(0) | /* Dummy */ FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_READ_ATTR | FSAL_ACE_PERM_READ_ACL); st = fsal_internal_testAccess(p_context, access_mask, NULL, p_object_attributes); if(FSAL_IS_ERROR(st)) ReturnStatus(st, INDEX_FSAL_getattrs); } #endif Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getattrs); }
int main() { fsal_path_t path; int rc,fd,status, i, memsz, mempos, memval; fsal_op_context_t op_context; struct statfs stat_buf; gpfsfsal_export_context_t *p_export_context = calloc(0, sizeof(gpfsfsal_export_context_t)); fsal_handle_t object_handle; fsal_handle_t object_handle_garbled; gpfsfsal_xstat_t buffstat; fsal_name_t file_name; unsigned char *handle_ptr; char *TESTDIR = "/ibm/gpfs0"; char *TESTFILE = "invalid_getattrs_example"; char *TESTFILE_PATH = "/ibm/gpfs0/invalid_getattrs_example"; char *CREATETESTFILE = "mknod /ibm/gpfs0/invalid_getattrs_example u 1 1"; char *REMOVETESTFILE = "ssh int001st001 rm -rf /ibm/gpfs0/invalid_getattrs_example"; printf("Creating test file: %s\n", TESTFILE); system(CREATETESTFILE); strcpy(path.path, TESTDIR); path.len = strlen(TESTDIR); strcpy(file_name.name, TESTFILE); file_name.len = strlen(TESTFILE); fd = open(path.path, O_RDONLY | O_DIRECTORY); if(fd < 0) { printf("Couldn't open directory.\n"); return 0; } p_export_context->mount_root_fd = fd; rc = statfs(path.path, &stat_buf); if(rc) { printf ("statfs call failed on file %s: %d", path.path, rc); return 0; } p_export_context->fsid[0] = stat_buf.f_fsid.__val[0]; p_export_context->fsid[1] = stat_buf.f_fsid.__val[1]; /* Get file handle to root of GPFS share */ op_context.export_context = p_export_context; status = fsal_internal_get_handle(&op_context, &path, (fsal_handle_t *)(&(p_export_context->mount_root_handle))); if (status) printf("fsal_internal_get_handle() failed\n"); /* Now show the error for when we use a nonsense file handle. */ /* printf("USING AN UNINITIALIZED FILE HANDLE FOR GETATTR ...\n"); fsal_get_xstat_by_handle(&op_context, &object_handle, &buffstat); printf("\n"); */ /* Get handle of file */ fsal_internal_get_handle_at(fd, &file_name, &object_handle); /* Getattrs of file */ printf("USING A CORRECT FILE HANDLE FOR GETATTR ...\n"); handle_ptr = ((gpfsfsal_handle_t *)&object_handle)->data.handle.f_handle; printf("handle: "); for(i=0; i < OPENHANDLE_HANDLE_LEN; i++) printf("%02x", (unsigned char)handle_ptr[i]); printf("\n"); fsal_get_xstat_by_handle(&op_context, &object_handle, &buffstat); /* print attrs */ print_attrs(&buffstat); printf("\n"); /* Getattrs of file */ /* printf("USING A FILE HANDLE THAT HAS BEEN MEMSET at 4th BYTE FOR GETATTR ...\n"); memcpy(&object_handle_garbled, &object_handle, sizeof(fsal_handle_t)); handle_ptr = ((gpfsfsal_handle_t *)&object_handle_garbled)->data.handle.f_handle; memset(handle_ptr+3, 4, 1); printf("handle: "); for(i=0; i < OPENHANDLE_HANDLE_LEN; i++) printf("%02x", (unsigned char)handle_ptr[i]); printf("\n"); fsal_get_xstat_by_handle(&op_context, &object_handle_garbled, &buffstat); printf("\n"); */ /* Getattrs of file */ /* printf("USING A FILE HANDLE THAT HAS BEEN MEMSET at 2nd BYTE FOR GETATTR ...\n"); memcpy(&object_handle_garbled, &object_handle, sizeof(fsal_handle_t)); handle_ptr = ((gpfsfsal_handle_t *)&object_handle_garbled)->data.handle.f_handle; memset(handle_ptr+1, 4, 1); printf("handle: "); for(i=0; i < OPENHANDLE_HANDLE_LEN; i++) printf("%02x", (unsigned char)handle_ptr[i]); printf("\n"); fsal_get_xstat_by_handle(&op_context, &object_handle_garbled, &buffstat); printf("\n"); */ /* Getattrs of file */ /* printf("USING FILE HANDLEs THAT HAVE BEEN MEMSET\n"); for(memsz=0; memsz <= OPENHANDLE_HANDLE_LEN; memsz++) { for(mempos=0; mempos <= OPENHANDLE_HANDLE_LEN-memsz; mempos++) { for(memval=0; memval <= 255; memval++) { memcpy(&object_handle_garbled, &object_handle, sizeof(fsal_handle_t)); handle_ptr = ((gpfsfsal_handle_t *)&object_handle_garbled)->data.handle.f_handle; memset(handle_ptr+mempos, memval, memsz); printf("handle: "); for(i=0; i < OPENHANDLE_HANDLE_LEN; i++) printf("%02x", (unsigned char)handle_ptr[i]); printf("\n"); fsal_get_xstat_by_handle(&op_context, &object_handle_garbled, &buffstat); } } } */ /* delete file */ printf("Removing test file: %s\n", TESTFILE); system(REMOVETESTFILE); /* Now show the INTERRUPT error. */ printf("USING A FILE HANDLE FROM A DELETED FILE FOR GETATTR ...\n"); fsal_get_xstat_by_handle(&op_context, &object_handle, &buffstat); printf("\n"); close(fd); return 0; }
/** * @param exp_hdl Handle * @param path Path * @param handle Reference to handle * * modelled on old api except we don't stuff attributes. * @return Status of operation */ fsal_status_t gpfs_lookup_path(struct fsal_export *exp_hdl, const char *path, struct fsal_obj_handle **handle, struct attrlist *attrs_out) { fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; fsal_status_t fsal_status; int retval = 0; int dir_fd; struct fsal_filesystem *fs; struct gpfs_fsal_obj_handle *hdl; struct attrlist attributes; gpfsfsal_xstat_t buffxstat; struct gpfs_file_handle *fh = alloca(sizeof(struct gpfs_file_handle)); struct fsal_fsid__ fsid; struct gpfs_fsal_export *gpfs_export; memset(fh, 0, sizeof(struct gpfs_file_handle)); fh->handle_size = GPFS_MAX_FH_SIZE; *handle = NULL; /* poison it */ dir_fd = open_dir_by_path_walk(-1, path, &buffxstat.buffstat); fsal_prepare_attrs(&attributes, ATTR_GPFS_ALLOC_HANDLE); if (attrs_out != NULL) attributes.mask |= attrs_out->mask; if (dir_fd < 0) { LogCrit(COMPONENT_FSAL, "Could not open directory for path %s", path); retval = -dir_fd; goto errout; } fsal_status = fsal_internal_fd2handle(dir_fd, fh); if (FSAL_IS_ERROR(fsal_status)) goto fileerr; gpfs_export = container_of(exp_hdl, struct gpfs_fsal_export, export); fsal_status = fsal_get_xstat_by_handle(dir_fd, fh, &buffxstat, NULL, false, (attributes.mask & ATTR_ACL) != 0); if (FSAL_IS_ERROR(fsal_status)) goto fileerr; fsal_status = gpfsfsal_xstat_2_fsal_attributes(&buffxstat, &attributes, gpfs_export->use_acl); LogFullDebug(COMPONENT_FSAL, "fsid=0x%016"PRIx64".0x%016"PRIx64, attributes.fsid.major, attributes.fsid.minor); if (FSAL_IS_ERROR(fsal_status)) goto fileerr; close(dir_fd); gpfs_extract_fsid(fh, &fsid); fs = lookup_fsid(&fsid, GPFS_FSID_TYPE); if (fs == NULL) { LogInfo(COMPONENT_FSAL, "Could not find file system for path %s", path); retval = ENOENT; goto errout; } if (fs->fsal != exp_hdl->fsal) { LogInfo(COMPONENT_FSAL, "File system for path %s did not belong to FSAL %s", path, exp_hdl->fsal->name); retval = EACCES; goto errout; } LogDebug(COMPONENT_FSAL, "filesystem %s for path %s", fs->path, path); /* Make sure ATTR_RDATTR_ERR is cleared on success. */ attributes.mask &= ~ATTR_RDATTR_ERR; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, fs, &attributes, NULL, exp_hdl); if (attrs_out != NULL) { /* Copy the attributes to caller, passing ACL ref. */ fsal_copy_attrs(attrs_out, &attributes, true); } else { /* Done with the attrs */ fsal_release_attrs(&attributes); } *handle = &hdl->obj_handle; return fsalstat(ERR_FSAL_NO_ERROR, 0); fileerr: retval = errno; close(dir_fd); errout: /* Done with attributes */ fsal_release_attrs(&attributes); fsal_error = posix2fsal_error(retval); return fsalstat(fsal_error, retval); }