static int default_read_from_path(uint64_t oid, const char *path, const struct siocb *iocb) { int flags = prepare_iocb(oid, iocb, false), fd, ret = SD_RES_SUCCESS; ssize_t size; /* * Make sure oid is in the right place because oid might be misplaced * in a wrong place, due to 'shutdown/restart with less disks' or any * bugs. We need call err_to_sderr() to return EIO if disk is broken. * * For stale path, get_store_stale_path already does default_exist job. */ if (!is_stale_path(path) && !default_exist(oid, iocb->ec_index)) return err_to_sderr(path, oid, ENOENT); fd = open(path, flags); if (fd < 0) return err_to_sderr(path, oid, errno); size = xpread(fd, iocb->buf, iocb->length, iocb->offset); if (unlikely(size != iocb->length)) { sd_err("failed to read object %"PRIx64", path=%s, offset=%" PRId32", size=%"PRId32", result=%zd, %m", oid, path, iocb->offset, iocb->length, size); ret = err_to_sderr(path, oid, errno); } close(fd); return ret; }
int default_write(uint64_t oid, const struct siocb *iocb) { int flags = prepare_iocb(oid, iocb, false), fd, ret = SD_RES_SUCCESS; char path[PATH_MAX]; ssize_t size; uint32_t len = iocb->length; uint64_t offset = iocb->offset; static bool trim_is_supported = true; if (iocb->epoch < sys_epoch()) { sd_debug("%"PRIu32" sys %"PRIu32, iocb->epoch, sys_epoch()); return SD_RES_OLD_NODE_VER; } if (uatomic_is_true(&sys->use_journal) && unlikely(journal_write_store(oid, iocb->buf, iocb->length, iocb->offset, false)) != SD_RES_SUCCESS) { sd_err("turn off journaling"); uatomic_set_false(&sys->use_journal); flags |= O_DSYNC; sync(); } get_store_path(oid, iocb->ec_index, path); /* * Make sure oid is in the right place because oid might be misplaced * in a wrong place, due to 'shutdown/restart with less/more disks' or * any bugs. We need call err_to_sderr() to return EIO if disk is broken */ if (!default_exist(oid, iocb->ec_index)) return err_to_sderr(path, oid, ENOENT); fd = open(path, flags, sd_def_fmode); if (unlikely(fd < 0)) return err_to_sderr(path, oid, errno); if (trim_is_supported && is_sparse_object(oid)) { if (default_trim(fd, oid, iocb, &offset, &len) < 0) { trim_is_supported = false; offset = iocb->offset; len = iocb->length; } } size = xpwrite(fd, iocb->buf, len, offset); if (unlikely(size != len)) { sd_err("failed to write object %"PRIx64", path=%s, offset=%" PRId32", size=%"PRId32", result=%zd, %m", oid, path, iocb->offset, iocb->length, size); ret = err_to_sderr(path, oid, errno); goto out; } out: close(fd); return ret; }
static int get_object_path(uint64_t oid, uint32_t epoch, char *path) { if (default_exist(oid)) { get_obj_path(oid, path); } else { get_stale_obj_path(oid, epoch, path); if (access(path, F_OK) < 0) { if (errno == ENOENT) return SD_RES_NO_OBJ; return SD_RES_EIO; } } return SD_RES_SUCCESS; }
static int get_object_path(uint64_t oid, uint32_t epoch, char *path, size_t size) { if (default_exist(oid, 0)) { snprintf(path, PATH_MAX, "%s/%016"PRIx64, md_get_object_dir(oid), oid); } else { get_store_stale_path(oid, epoch, 0, path); if (access(path, F_OK) < 0) { if (errno == ENOENT) return SD_RES_NO_OBJ; return SD_RES_EIO; } } return SD_RES_SUCCESS; }
int default_write(uint64_t oid, const struct siocb *iocb) { int flags = prepare_iocb(oid, iocb, false), fd, ret = SD_RES_SUCCESS; char path[PATH_MAX]; ssize_t size; if (iocb->epoch < sys_epoch()) { sd_debug("%"PRIu32" sys %"PRIu32, iocb->epoch, sys_epoch()); return SD_RES_OLD_NODE_VER; } get_store_path(oid, iocb->ec_index, path); /* * Make sure oid is in the right place because oid might be misplaced * in a wrong place, due to 'shutdown/restart with less/more disks' or * any bugs. We need call err_to_sderr() to return EIO if disk is broken */ if (!default_exist(oid, iocb->ec_index)) return err_to_sderr(path, oid, errno); fd = open(path, flags, sd_def_fmode); if (unlikely(fd < 0)) return err_to_sderr(path, oid, errno); size = xpwrite(fd, iocb->buf, iocb->length, iocb->offset); if (unlikely(size != iocb->length)) { sd_err("failed to write object %"PRIx64", path=%s, offset=%" PRId32", size=%"PRId32", result=%zd, %m", oid, path, iocb->offset, iocb->length, size); ret = err_to_sderr(path, oid, errno); goto out; } out: close(fd); return ret; }