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; }
int main (int argc, char *argv[]) { glfs_t *fs = NULL; glfs_t *fs2 = NULL; glfs_t *fs_tmp = NULL; glfs_t *fs_tmp2 = NULL; int ret = 0, i; glfs_fd_t *fd = NULL; glfs_fd_t *fd2 = NULL; glfs_fd_t *fd_tmp = NULL; glfs_fd_t *fd_tmp2 = NULL; char readbuf[32]; char *filename = "file_tmp"; char *writebuf = NULL; char *vol_id = NULL; unsigned int cnt = 1; struct glfs_upcall *cbk = NULL; char *logfile = NULL; char *volname = NULL; char *hostname = NULL; if (argc != 4) { fprintf (stderr, "Invalid argument\n"); exit(1); } hostname = argv[1]; volname = argv[2]; logfile = argv[3]; fs = glfs_new (volname); if (!fs) { fprintf (stderr, "glfs_new: returned NULL\n"); return -1; } ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); LOG_ERR("glfs_set_volfile_server", ret); ret = glfs_set_logging (fs, logfile, 7); LOG_ERR("glfs_set_logging", ret); ret = glfs_init (fs); LOG_ERR("glfs_init", ret); /* This does not block, but enables caching of events. Real * applications like NFS-Ganesha run this in a thread before activity * on the fs (through this instance) happens. */ ret = glfs_h_poll_upcall(fs_tmp, &cbk); LOG_ERR ("glfs_h_poll_upcall", ret); fs2 = glfs_new (volname); if (!fs2) { fprintf (stderr, "glfs_new fs2: returned NULL\n"); return 1; } ret = glfs_set_volfile_server (fs2, "tcp", hostname, 24007); LOG_ERR("glfs_set_volfile_server-fs2", ret); ret = glfs_set_logging (fs2, logfile, 7); LOG_ERR("glfs_set_logging-fs2", ret); ret = glfs_init (fs2); LOG_ERR("glfs_init-fs2", ret); fd = glfs_creat(fs, filename, O_RDWR|O_SYNC, 0644); if (fd <= 0) { ret = -1; LOG_ERR ("glfs_creat", ret); } fprintf (stderr, "glfs-create fd - %d\n", fd); fd2 = glfs_open(fs2, filename, O_SYNC|O_RDWR|O_CREAT); if (fd2 <= 0) { ret = -1; LOG_ERR ("glfs_open-fs2", ret); } fprintf (stderr, "glfs-open fd2 - %d\n", fd2); do { if (cnt%2) { fd_tmp = fd; fs_tmp = fs; fd_tmp2 = fd2; fs_tmp2 = fs2; } else { fd_tmp = fd2; fs_tmp = fs2; fd_tmp2 = fd; fs_tmp2 = fs; } /* WRITE on fd_tmp */ writebuf = malloc(10); if (writebuf) { memcpy (writebuf, "abcd", 4); ret = glfs_write (fd_tmp, writebuf, 4, 0); if (ret <= 0) { ret = -1; LOG_ERR ("glfs_write", ret); } else { fprintf (stderr, "glfs_write suceeded\n"); } free(writebuf); } else { fprintf (stderr, "Could not allocate writebuf\n"); return -1; } /* READ on fd_tmp2 */ ret = glfs_lseek (fd_tmp2, 0, SEEK_SET); LOG_ERR ("glfs_lseek", ret); memset (readbuf, 0, sizeof(readbuf)); ret = glfs_pread (fd_tmp2, readbuf, 4, 0, 0, NULL); if (ret <= 0) { ret = -1; LOG_ERR ("glfs_pread", ret); } else { fprintf (stderr, "glfs_read: %s\n", readbuf); } /* Open() fops seem to be not performed on server side until * there are I/Os on that fd */ if (cnt > 2) { struct glfs_upcall_inode *in_arg = NULL; enum glfs_upcall_reason reason = 0; struct glfs_object *object = NULL; uint64_t flags = 0; uint64_t expire = 0; ret = glfs_h_poll_upcall(fs_tmp, &cbk); LOG_ERR ("glfs_h_poll_upcall", ret); reason = glfs_upcall_get_reason (cbk); /* Expect 'GLFS_INODE_INVALIDATE' upcall event. */ if (reason == GLFS_UPCALL_INODE_INVALIDATE) { in_arg = glfs_upcall_get_event (cbk); object = glfs_upcall_inode_get_object (in_arg); flags = glfs_upcall_inode_get_flags (in_arg); expire = glfs_upcall_inode_get_expire (in_arg); fprintf (stderr, " upcall event type - %d," " object(%p), flags(%d), " " expire_time_attr(%d)\n" , reason, object, flags, expire); } else { fprintf (stderr, "Didnt receive upcall notify event"); ret = -1; goto err; } glfs_free (cbk); } sleep(5); } while (++cnt < 5); err: glfs_close(fd); LOG_ERR ("glfs_close", ret); glfs_close(fd2); LOG_ERR ("glfs_close-fd2", ret); out: if (fs) { ret = glfs_fini(fs); fprintf (stderr, "glfs_fini(fs) returned %d \n", ret); } if (fs2) { ret = glfs_fini(fs2); fprintf (stderr, "glfs_fini(fs2) returned %d \n", ret); } if (ret) exit(1); exit(0); }
/* * Return scsi status or TCMU_NOT_HANDLED */ int tcmu_glfs_handle_cmd( struct tcmu_device *dev, struct tcmulib_cmd *tcmulib_cmd) { uint8_t *cdb = tcmulib_cmd->cdb; struct iovec *iovec = tcmulib_cmd->iovec; size_t iov_cnt = tcmulib_cmd->iov_cnt; uint8_t *sense = tcmulib_cmd->sense_buf; struct glfs_state *state = tcmu_get_dev_private(dev); uint8_t cmd; glfs_fd_t *gfd = state->gfd; int ret; uint32_t length; int result = SAM_STAT_GOOD; char *tmpbuf; uint64_t offset = state->block_size * tcmu_get_lba(cdb); uint32_t tl = state->block_size * tcmu_get_xfer_length(cdb); int do_verify = 0; uint32_t cmp_offset; ret = length = 0; cmd = cdb[0]; switch (cmd) { case INQUIRY: return tcmu_emulate_inquiry(dev, cdb, iovec, iov_cnt, sense); break; case TEST_UNIT_READY: return tcmu_emulate_test_unit_ready(cdb, iovec, iov_cnt, sense); break; case SERVICE_ACTION_IN_16: if (cdb[1] == READ_CAPACITY_16) { long long size; unsigned long long num_lbas; size = tcmu_get_device_size(dev); if (size == -1) { errp("Could not get device size\n"); return TCMU_NOT_HANDLED; } num_lbas = size / state->block_size; return tcmu_emulate_read_capacity_16(num_lbas, state->block_size, cdb, iovec, iov_cnt, sense); } else { return TCMU_NOT_HANDLED; } break; case MODE_SENSE: case MODE_SENSE_10: return tcmu_emulate_mode_sense(cdb, iovec, iov_cnt, sense); break; case MODE_SELECT: case MODE_SELECT_10: return tcmu_emulate_mode_select(cdb, iovec, iov_cnt, sense); break; case COMPARE_AND_WRITE: /* Blocks are transferred twice, first the set that * we compare to the existing data, and second the set * to write if the compare was successful. */ length = tl / 2; tmpbuf = malloc(length); if (!tmpbuf) { result = tcmu_set_sense_data(sense, HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, NULL); break; } ret = glfs_pread(gfd, tmpbuf, length, offset, SEEK_SET); if (ret != length) { result = set_medium_error(sense); free(tmpbuf); break; } cmp_offset = tcmu_compare_with_iovec(tmpbuf, iovec, length); if (cmp_offset != -1) { result = tcmu_set_sense_data(sense, MISCOMPARE, ASC_MISCOMPARE_DURING_VERIFY_OPERATION, &cmp_offset); free(tmpbuf); break; } free(tmpbuf); tcmu_seek_in_iovec(iovec, length); goto write; case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: if (cdb[1] & 0x2) result = tcmu_set_sense_data(sense, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB, NULL); else glfs_fdatasync(gfd); break; case WRITE_VERIFY: case WRITE_VERIFY_12: case WRITE_VERIFY_16: do_verify = 1; case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: length = tl; write: ret = glfs_pwritev(gfd, iovec, iov_cnt, offset, ALLOWED_BSOFLAGS); if (ret == length) { /* Sync if FUA */ if ((cmd != WRITE_6) && (cdb[1] & 0x8)) glfs_fdatasync(gfd); } else { errp("Error on write %x %x\n", ret, length); result = set_medium_error(sense); break; } if (!do_verify) break; tmpbuf = malloc(length); if (!tmpbuf) { result = tcmu_set_sense_data(sense, HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, NULL); break; } ret = glfs_pread(gfd, tmpbuf, length, offset, ALLOWED_BSOFLAGS); if (ret != length) { result = set_medium_error(sense); free(tmpbuf); break; } cmp_offset = tcmu_compare_with_iovec(tmpbuf, iovec, length); if (cmp_offset != -1) result = tcmu_set_sense_data(sense, MISCOMPARE, ASC_MISCOMPARE_DURING_VERIFY_OPERATION, &cmp_offset); free(tmpbuf); break; case WRITE_SAME: case WRITE_SAME_16: errp("WRITE_SAME called, but has vpd b2 been implemented?\n"); result = tcmu_set_sense_data(sense, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB, NULL); break; #if 0 /* WRITE_SAME used to punch hole in file */ if (cdb[1] & 0x08) { ret = glfs_discard(gfd, offset, tl); if (ret != 0) { result = tcmu_set_sense_data(sense, HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, NULL); } break; } while (tl > 0) { size_t blocksize = state->block_size; uint32_t val32; uint64_t val64; assert(iovec->iov_len >= 8); switch (cdb[1] & 0x06) { case 0x02: /* PBDATA==0 LBDATA==1 */ val32 = htobe32(offset); memcpy(iovec->iov_base, &val32, 4); break; case 0x04: /* PBDATA==1 LBDATA==0 */ /* physical sector format */ /* hey this is wrong val! But how to fix? */ val64 = htobe64(offset); memcpy(iovec->iov_base, &val64, 8); break; default: /* FIXME */ errp("PBDATA and LBDATA set!!!\n"); } ret = glfs_pwritev(gfd, iovec, blocksize, offset, ALLOWED_BSOFLAGS); if (ret != blocksize) result = set_medium_error(sense); offset += blocksize; tl -= blocksize; } break; #endif case READ_6: case READ_10: case READ_12: case READ_16: length = tcmu_iovec_length(iovec, iov_cnt); ret = glfs_preadv(gfd, iovec, iov_cnt, offset, SEEK_SET); if (ret != length) { errp("Error on read %x %x\n", ret, length); result = set_medium_error(sense); } break; case UNMAP: /* TODO: implement UNMAP */ result = tcmu_set_sense_data(sense, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB, NULL); break; default: result = TCMU_NOT_HANDLED; break; } dbgp("io done %p %x %d %u\n", cdb, cmd, result, length); if (result == TCMU_NOT_HANDLED) dbgp("io not handled %p %x %x %d %d %llu\n", cdb, result, cmd, ret, length, (unsigned long long)offset); else if (result != SAM_STAT_GOOD) { errp("io error %p %x %x %d %d %llu\n", cdb, result, cmd, ret, length, (unsigned long long)offset); } return result; }
int main (int argc, char *argv[]) { int ret = 0; glfs_t *fs = NULL; struct glfs_fd *fd = NULL; char *volname = NULL; char *log_file = NULL; char *hostname = NULL; char *buf = NULL; struct stat stat; if (argc != 4) { fprintf (stderr, "Expect following args %s <hostname> <Vol> <log file location>\n" , argv[0]); return -1; } hostname = argv[1]; volname = argv[2]; log_file = argv[3]; fs = setup_new_client (hostname, volname, log_file, 0); if (!fs) { fprintf (stderr, "\nsetup_new_client: returned NULL (%s)\n", strerror (errno)); goto error; } fd = glfs_opendir (fs, "/"); if (!fd) { fprintf (stderr, "/: %s\n", strerror (errno)); return -1; } glfs_readdirplus (fd, &stat); fd = glfs_open (fs, "/test", O_RDWR); if (fd == NULL) { fprintf (stderr, "glfs_open: returned NULL\n"); goto error; } buf = (char *) malloc (5); ret = glfs_pread (fd, buf, 5, 0, 0); if (ret < 0) { fprintf (stderr, "Read(%s): %d (%s)\n", "test", ret, strerror (errno)); return ret; } free (buf); glfs_close (fd); ret = glfs_fini (fs); if (ret < 0) { fprintf (stderr, "glfs_fini failed with ret: %d (%s)\n", ret, strerror (errno)); return -1; } return 0; error: return -1; }
bool GlusterBackend::get(const SyncEvent* _getEvent) { if(_getEvent == nullptr || _getEvent->fullPathBuffer.empty()) return false; //Try to find file /** * RETURN VALUES * NULL : Failure. @errno will be set with the type of failure. * Others : Pointer to the opened glfs_fd_t. */ glfs_fd_t *fd = glfs_open((glfs_t*)fs, _getEvent->fullPathBuffer.c_str(), O_RDONLY); if(!fd){ LOG(ERROR)<<"Error while openeing a handle to:"<<_getEvent->fullPathBuffer; return false; } FileNode* fileNode = FileSystem::getInstance().findAndOpenNode(_getEvent->fullPathBuffer); //If File exist then we won't download it! if(fileNode!=nullptr){ LOG(DEBUG)<<"File "<<fileNode->getFullPath()<<" already exist! no need to download."; //Close it! so it can be removed if needed uint64_t inodeNum = FileSystem::getInstance().assignINodeNum((intptr_t)fileNode); fileNode->close(inodeNum); glfs_close(fd); return false; } //Now create a file in FS //handle directories //FileSystem::getInstance().createHierarchy(_getEvent->fullPathBuffer,false); //FileNode *newFile = FileSystem::getInstance().mkFile(_getEvent->fullPathBuffer,false,true);//open string name = FileSystem::getInstance().getFileNameFromPath(_getEvent->fullPathBuffer); FileNode* newFile = new FileNode(name,_getEvent->fullPathBuffer, false,false); if(newFile == nullptr){ LOG(ERROR)<<"Failed to create a newNode:"<<_getEvent->fullPathBuffer; glfs_close(fd); return false; } //and write the content uint64_t bufSize = 64ll*1024ll*1024ll; char *buff = new char[bufSize];//64MB buffer size_t offset = 0; int64_t read = 0; do { //No need to download it anymore. if(newFile->mustBeDeleted()){ delete newFile; glfs_close(fd); return true; } read = glfs_pread(fd,buff,bufSize,offset,0); if(read < 0){ LOG(ERROR)<<"Error while reading: "<<_getEvent->fullPathBuffer; glfs_close(fd); return false; } if(read>0){ FileNode* afterMove = nullptr; long retCode = newFile->writeHandler(buff,offset,read,afterMove,true); while(retCode == -1)//-1 means moving retCode = newFile->writeHandler(buff,offset,read,afterMove,true); if(afterMove){ newFile = afterMove; FileSystem::getInstance().replaceAllInodesByNewNode((intptr_t)newFile,(intptr_t)afterMove); } //Check space availability if(retCode < 0) { LOG(ERROR)<<"Error in writing file:"<<newFile->getFullPath()<<", probably no diskspace, Code:"<<retCode; delete newFile; glfs_close(fd); delete []buff; return false; } } offset += read; }while(read); newFile->setNeedSync(false);//We have just created this file so it's upload flag false glfs_close(fd); delete []buff; //Add it to File system if(FileSystem::getInstance().createHierarchy(_getEvent->fullPathBuffer,false)==nullptr){ LOG(ERROR)<<"Error in creating hierarchy for newly downloaded file:"<<newFile->getFullPath(); delete newFile; return false; } if(!FileSystem::getInstance().addFile(newFile)){ LOG(ERROR)<<"Error in adding newly downloaded file:"<<newFile->getFullPath(); delete newFile; return false; } //Gone well return true; }
int main (int argc, char *argv[]) { glfs_t *fs = NULL; glfs_t *fs2 = NULL; glfs_t *fs_tmp = NULL; glfs_t *fs_tmp2 = NULL; int ret = 0, i; glfs_fd_t *fd = NULL; glfs_fd_t *fd2 = NULL; glfs_fd_t *fd_tmp = NULL; glfs_fd_t *fd_tmp2 = NULL; char readbuf[32]; char *filename = "file_tmp"; char *writebuf = NULL; char *vol_id = NULL; unsigned int cnt = 1; struct callback_arg cbk; char *logfile = NULL; char *volname = NULL; cbk.object = NULL; if (argc != 3) { fprintf (stderr, "Invalid argument\n"); exit(1); } volname = argv[1]; logfile = argv[2]; fs = glfs_new (volname); if (!fs) { fprintf (stderr, "glfs_new: returned NULL\n"); return -1; } ret = glfs_set_volfile_server (fs, "tcp", "localhost", 24007); LOG_ERR("glfs_set_volfile_server", ret); ret = glfs_set_logging (fs, logfile, 7); LOG_ERR("glfs_set_logging", ret); ret = glfs_init (fs); LOG_ERR("glfs_init", ret); fs2 = glfs_new (volname); if (!fs2) { fprintf (stderr, "glfs_new fs2: returned NULL\n"); return 1; } ret = glfs_set_volfile_server (fs2, "tcp", "localhost", 24007); LOG_ERR("glfs_set_volfile_server-fs2", ret); ret = glfs_set_logging (fs2, logfile, 7); LOG_ERR("glfs_set_logging-fs2", ret); ret = glfs_init (fs2); LOG_ERR("glfs_init-fs2", ret); fd = glfs_creat(fs, filename, O_RDWR|O_SYNC, 0644); if (fd <= 0) { ret = -1; LOG_ERR ("glfs_creat", ret); } fprintf (stderr, "glfs-create fd - %d\n", fd); fd2 = glfs_open(fs2, filename, O_SYNC|O_RDWR|O_CREAT); if (fd2 <= 0) { ret = -1; LOG_ERR ("glfs_open-fs2", ret); } fprintf (stderr, "glfs-open fd2 - %d\n", fd2); do { if (cnt%2) { fd_tmp = fd; fs_tmp = fs; fd_tmp2 = fd2; fs_tmp2 = fs2; } else { fd_tmp = fd2; fs_tmp = fs2; fd_tmp2 = fd; fs_tmp2 = fs; } /* WRITE on fd_tmp */ writebuf = malloc(10); if (writebuf) { memcpy (writebuf, "abcd", 4); ret = glfs_write (fd_tmp, writebuf, 4, 0); if (ret <= 0) { ret = -1; LOG_ERR ("glfs_write", ret); } else { fprintf (stderr, "glfs_write suceeded\n"); } free(writebuf); } else { fprintf (stderr, "Could not allocate writebuf\n"); return -1; } /* READ on fd_tmp2 */ ret = glfs_lseek (fd_tmp2, 0, SEEK_SET); LOG_ERR ("glfs_lseek", ret); ret = glfs_pread (fd_tmp2, readbuf, 4, 0, 0); if (ret <= 0) { ret = -1; LOG_ERR ("glfs_pread", ret); } else { fprintf (stderr, "glfs_read: %s\n", readbuf); } /* Open() fops seem to be not performed on server side until * there are I/Os on that fd */ if (cnt > 2) { ret = glfs_h_poll_upcall(fs_tmp, &cbk); LOG_ERR ("glfs_h_poll_upcall", ret); if (cbk.object) { fprintf (stderr, " upcall event type - %d," " flags - %d, expire_time_attr - %d\n" , cbk.reason, cbk.flags, cbk.expire_time_attr); } else { fprintf (stderr, "Dint receive upcall notify event"); ret = -1; goto err; } } sleep(5); } while (++cnt < 5); err: glfs_close(fd); LOG_ERR ("glfs_close", ret); glfs_close(fd2); LOG_ERR ("glfs_close-fd2", ret); out: if (fs) { ret = glfs_fini(fs); fprintf (stderr, "glfs_fini(fs) returned %d \n", ret); } if (fs2) { ret = glfs_fini(fs2); fprintf (stderr, "glfs_fini(fs2) returned %d \n", ret); } if (ret) exit(1); exit(0); }