int default_write(uint64_t oid, const struct siocb *iocb) { int flags = get_open_flags(oid, false, iocb->flags), fd, ret = SD_RES_SUCCESS; char path[PATH_MAX]; ssize_t size; if (iocb->epoch < sys_epoch()) { sd_dprintf("%"PRIu32" sys %"PRIu32"\n", iocb->epoch, sys_epoch()); return SD_RES_OLD_NODE_VER; } get_obj_path(oid, path); if (uatomic_is_true(&sys->use_journal) && journal_file_write(oid, iocb->buf, iocb->length, iocb->offset, false) != SD_RES_SUCCESS) { sd_eprintf("turn off journaling\n"); uatomic_set_false(&sys->use_journal); flags |= O_DSYNC; sync(); } fd = open(path, flags, def_fmode); if (fd < 0) return err_to_sderr(oid, errno); size = xpwrite(fd, iocb->buf, iocb->length, iocb->offset); if (size != iocb->length) { sd_eprintf("failed to write object %"PRIx64", path=%s, offset=%" PRId64", size=%"PRId32", result=%zd, %m\n", oid, path, iocb->offset, iocb->length, size); ret = err_to_sderr(oid, errno); goto out; } out: close(fd); return ret; }
int default_create_and_write(uint64_t oid, const struct siocb *iocb) { char path[PATH_MAX], tmp_path[PATH_MAX]; int flags = get_open_flags(oid, true, iocb->flags); int ret, fd; uint32_t len = iocb->length; get_obj_path(oid, path); get_tmp_obj_path(oid, tmp_path); if (uatomic_is_true(&sys->use_journal) && journal_file_write(oid, iocb->buf, iocb->length, iocb->offset, true) != SD_RES_SUCCESS) { eprintf("turn off journaling\n"); uatomic_set_false(&sys->use_journal); flags |= O_DSYNC; sync(); } fd = open(tmp_path, flags, def_fmode); if (fd < 0) { if (errno == EEXIST) { /* This happens if node membership changes during object * creation; while gateway retries a CREATE request, * recovery process could also recover the object at the * same time. They should try to write the same date, * so it is okay to simply return success here. */ dprintf("%s exists\n", tmp_path); return SD_RES_SUCCESS; } eprintf("failed to open %s: %m\n", tmp_path); return err_to_sderr(oid, errno); } if (iocb->offset != 0 || iocb->length != get_objsize(oid)) { ret = prealloc(fd, get_objsize(oid)); if (ret < 0) { ret = err_to_sderr(oid, errno); goto out; } } ret = xpwrite(fd, iocb->buf, len, iocb->offset); if (ret != len) { eprintf("failed to write object. %m\n"); ret = err_to_sderr(oid, errno); goto out; } ret = rename(tmp_path, path); if (ret < 0) { eprintf("failed to rename %s to %s: %m\n", tmp_path, path); ret = err_to_sderr(oid, errno); goto out; } dprintf("%"PRIx64"\n", oid); ret = SD_RES_SUCCESS; out: if (ret != SD_RES_SUCCESS) unlink(tmp_path); close(fd); return ret; }