Lines Matching +full:next +full:- +full:level +full:- +full:cache

7  * See the COPYING file in the top-level directory.
14 #include "block/block-io.h"
20 #include "qemu/error-report.h"
45 #define GLUSTER_LOGFILE_DEFAULT "-" /* handled in libgfapi as /dev/stderr */
47 * Several versions of GlusterFS (3.12? -> 6.0.1) fail when the transfer size
90 .name = "qemu-gluster-create-opts",
113 .help = "Gluster log level, valid range is 0-9",
136 .help = "Gluster log level, valid range is 0-9",
164 .help = "Gluster log level, valid range is 0-9",
245 entry->saved.volume = g_strdup(volume); in glfs_set_preopened()
247 entry->saved.fs = fs; in glfs_set_preopened()
248 entry->saved.ref = 1; in glfs_set_preopened()
258 if (strcmp(entry->saved.volume, volume) == 0) { in glfs_find_preopened()
259 entry->saved.ref++; in glfs_find_preopened()
260 return entry->saved.fs; in glfs_find_preopened()
270 ListElement *next; in glfs_clear_preopened() local
276 QLIST_FOREACH_SAFE(entry, &glfs_list, list, next) { in glfs_clear_preopened()
277 if (entry->saved.fs == fs) { in glfs_clear_preopened()
278 if (--entry->saved.ref) { in glfs_clear_preopened()
284 glfs_fini(entry->saved.fs); in glfs_clear_preopened()
285 g_free(entry->saved.volume); in glfs_clear_preopened()
296 return -EINVAL; in parse_volume_options()
303 return -EINVAL; in parse_volume_options()
305 gconf->volume = g_strndup(q, p - q); in parse_volume_options()
310 return -EINVAL; in parse_volume_options()
312 gconf->path = g_strdup(p); in parse_volume_options()
359 return -EINVAL; in qemu_gluster_parse_uri()
363 QAPI_LIST_PREPEND(gconf->server, gsconf); in qemu_gluster_parse_uri()
368 gsconf->type = SOCKET_ADDRESS_TYPE_INET; in qemu_gluster_parse_uri()
370 gsconf->type = SOCKET_ADDRESS_TYPE_INET; in qemu_gluster_parse_uri()
372 gsconf->type = SOCKET_ADDRESS_TYPE_UNIX; in qemu_gluster_parse_uri()
375 return -EINVAL; in qemu_gluster_parse_uri()
385 qp = g_uri_parse_params(uri_query, -1, "&", G_URI_PARAMS_NONE, NULL); in qemu_gluster_parse_uri()
387 return -EINVAL; in qemu_gluster_parse_uri()
391 return -EINVAL; in qemu_gluster_parse_uri()
400 if (uri_server || uri_port != -1 || !uri_socket) { in qemu_gluster_parse_uri()
401 return -EINVAL; in qemu_gluster_parse_uri()
403 gsconf->u.q_unix.path = g_strdup(uri_socket); in qemu_gluster_parse_uri()
405 gsconf->u.inet.host = g_strdup(uri_server ? uri_server : "localhost"); in qemu_gluster_parse_uri()
407 gsconf->u.inet.port = g_strdup_printf("%d", uri_port); in qemu_gluster_parse_uri()
409 gsconf->u.inet.port = g_strdup_printf("%d", GLUSTER_DEFAULT_PORT); in qemu_gluster_parse_uri()
425 glfs = glfs_find_preopened(gconf->volume); in qemu_gluster_glfs_init()
430 glfs = glfs_new(gconf->volume); in qemu_gluster_glfs_init()
435 glfs_set_preopened(gconf->volume, glfs); in qemu_gluster_glfs_init()
437 for (server = gconf->server; server; server = server->next) { in qemu_gluster_glfs_init()
438 switch (server->value->type) { in qemu_gluster_glfs_init()
441 server->value->u.q_unix.path, 0); in qemu_gluster_glfs_init()
444 if (parse_uint_full(server->value->u.inet.port, 10, &port) < 0 || in qemu_gluster_glfs_init()
447 server->value->u.inet.port); in qemu_gluster_glfs_init()
452 server->value->u.inet.host, in qemu_gluster_glfs_init()
466 ret = glfs_set_logging(glfs, gconf->logfile, gconf->debug); in qemu_gluster_glfs_init()
474 " to connect", gconf->volume, gconf->path); in qemu_gluster_glfs_init()
475 for (server = gconf->server; server; server = server->next) { in qemu_gluster_glfs_init()
476 if (server->value->type == SOCKET_ADDRESS_TYPE_UNIX) { in qemu_gluster_glfs_init()
478 server->value->u.q_unix.path); in qemu_gluster_glfs_init()
481 server->value->u.inet.host, in qemu_gluster_glfs_init()
482 server->value->u.inet.port); in qemu_gluster_glfs_init()
537 gconf->volume = g_strdup(ptr); in qemu_gluster_parse_json()
544 gconf->path = g_strdup(ptr); in qemu_gluster_parse_json()
546 tail = &gconf->server; in qemu_gluster_parse_json()
570 type = qapi_enum_parse(&SocketAddressType_lookup, ptr, -1, NULL); in qemu_gluster_parse_json()
579 gsconf->type = type; in qemu_gluster_parse_json()
582 if (gsconf->type == SOCKET_ADDRESS_TYPE_INET) { in qemu_gluster_parse_json()
596 gsconf->u.inet.host = g_strdup(ptr); in qemu_gluster_parse_json()
604 gsconf->u.inet.port = g_strdup(ptr); in qemu_gluster_parse_json()
611 gsconf->u.inet.has_to = true; in qemu_gluster_parse_json()
615 gsconf->u.inet.has_ipv4 = true; in qemu_gluster_parse_json()
619 gsconf->u.inet.has_ipv6 = true; in qemu_gluster_parse_json()
621 if (gsconf->u.inet.has_to) { in qemu_gluster_parse_json()
625 if (gsconf->u.inet.has_ipv4 || gsconf->u.inet.has_ipv6) { in qemu_gluster_parse_json()
652 gsconf->u.q_unix.path = g_strdup(ptr); in qemu_gluster_parse_json()
671 return -errno; in qemu_gluster_parse_json()
695 "-drive driver=qcow2,file.driver=gluster," in qemu_gluster_parse()
720 errno = -ret; in qemu_gluster_init()
738 if (!ret || ret == acb->size) { in gluster_finish_aiocb()
739 acb->ret = 0; /* Success */ in gluster_finish_aiocb()
741 acb->ret = -errno; /* Read/Write failed */ in gluster_finish_aiocb()
743 acb->ret = -EIO; /* Partial read/write - fail it */ in gluster_finish_aiocb()
746 aio_co_schedule(acb->aio_context, acb->coroutine); in gluster_finish_aiocb()
769 * - Corrected versions return -1 and set errno to EINVAL.
770 * - Versions that support SEEK_DATA/HOLE correctly, will return -1 and set
796 BDRVGlusterState *s = bs->opaque; in qemu_gluster_open()
805 ret = -EINVAL; in qemu_gluster_open()
813 s->debug = qemu_opt_get_number(opts, GLUSTER_OPT_DEBUG, in qemu_gluster_open()
815 if (s->debug < 0) { in qemu_gluster_open()
816 s->debug = 0; in qemu_gluster_open()
817 } else if (s->debug > GLUSTER_DEBUG_MAX) { in qemu_gluster_open()
818 s->debug = GLUSTER_DEBUG_MAX; in qemu_gluster_open()
822 gconf->debug = s->debug; in qemu_gluster_open()
823 gconf->has_debug = true; in qemu_gluster_open()
826 s->logfile = g_strdup(logfile ? logfile : GLUSTER_LOGFILE_DEFAULT); in qemu_gluster_open()
828 gconf->logfile = g_strdup(s->logfile); in qemu_gluster_open()
830 s->glfs = qemu_gluster_init(gconf, filename, options, errp); in qemu_gluster_open()
831 if (!s->glfs) { in qemu_gluster_open()
832 ret = -errno; in qemu_gluster_open()
838 * ENOSPC), gluster will dump its cache, preventing retries. This means in qemu_gluster_open()
840 * 'resync-failed-syncs-after-fsync' key value, but there is no way to in qemu_gluster_open()
843 ret = glfs_set_xlator_option(s->glfs, "*-write-behind", in qemu_gluster_open()
844 "resync-failed-syncs-after-fsync", in qemu_gluster_open()
848 ret = -errno; in qemu_gluster_open()
855 s->fd = glfs_open(s->glfs, gconf->path, open_flags); in qemu_gluster_open()
856 ret = s->fd ? 0 : -errno; in qemu_gluster_open()
858 if (ret == -EACCES || ret == -EROFS) { in qemu_gluster_open()
859 /* Try to degrade to read-only, but if it doesn't work, still use the in qemu_gluster_open()
864 s->fd = glfs_open(s->glfs, gconf->path, open_flags); in qemu_gluster_open()
865 ret = s->fd ? 0 : -errno; in qemu_gluster_open()
870 s->supports_seek_data = qemu_gluster_test_seek(s->fd); in qemu_gluster_open()
878 g_free(s->logfile); in qemu_gluster_open()
879 if (s->fd) { in qemu_gluster_open()
880 glfs_close(s->fd); in qemu_gluster_open()
883 glfs_clear_preopened(s->glfs); in qemu_gluster_open()
890 bs->bl.max_transfer = GLUSTER_MAX_TRANSFER; in qemu_gluster_refresh_limits()
891 bs->bl.max_pdiscard = MIN(SIZE_MAX, INT64_MAX); in qemu_gluster_refresh_limits()
904 assert(state->bs != NULL); in qemu_gluster_reopen_prepare()
906 s = state->bs->opaque; in qemu_gluster_reopen_prepare()
908 state->opaque = g_new0(BDRVGlusterReopenState, 1); in qemu_gluster_reopen_prepare()
909 reop_s = state->opaque; in qemu_gluster_reopen_prepare()
911 qemu_gluster_parse_flags(state->flags, &open_flags); in qemu_gluster_reopen_prepare()
914 gconf->debug = s->debug; in qemu_gluster_reopen_prepare()
915 gconf->has_debug = true; in qemu_gluster_reopen_prepare()
916 gconf->logfile = g_strdup(s->logfile); in qemu_gluster_reopen_prepare()
919 * If 'state->bs->exact_filename' is empty, 'state->options' should contain in qemu_gluster_reopen_prepare()
922 if (state->bs->exact_filename[0] != '\0') { in qemu_gluster_reopen_prepare()
923 reop_s->glfs = qemu_gluster_init(gconf, state->bs->exact_filename, NULL, in qemu_gluster_reopen_prepare()
926 reop_s->glfs = qemu_gluster_init(gconf, NULL, state->options, errp); in qemu_gluster_reopen_prepare()
928 if (reop_s->glfs == NULL) { in qemu_gluster_reopen_prepare()
929 ret = -errno; in qemu_gluster_reopen_prepare()
934 ret = glfs_set_xlator_option(reop_s->glfs, "*-write-behind", in qemu_gluster_reopen_prepare()
935 "resync-failed-syncs-after-fsync", "on"); in qemu_gluster_reopen_prepare()
938 ret = -errno; in qemu_gluster_reopen_prepare()
943 reop_s->fd = glfs_open(reop_s->glfs, gconf->path, open_flags); in qemu_gluster_reopen_prepare()
944 if (reop_s->fd == NULL) { in qemu_gluster_reopen_prepare()
945 /* reops->glfs will be cleaned up in _abort */ in qemu_gluster_reopen_prepare()
946 ret = -errno; in qemu_gluster_reopen_prepare()
951 /* state->opaque will be freed in either the _abort or _commit */ in qemu_gluster_reopen_prepare()
958 BDRVGlusterReopenState *reop_s = state->opaque; in qemu_gluster_reopen_commit()
959 BDRVGlusterState *s = state->bs->opaque; in qemu_gluster_reopen_commit()
963 if (s->fd) { in qemu_gluster_reopen_commit()
964 glfs_close(s->fd); in qemu_gluster_reopen_commit()
967 glfs_clear_preopened(s->glfs); in qemu_gluster_reopen_commit()
970 s->fd = reop_s->fd; in qemu_gluster_reopen_commit()
971 s->glfs = reop_s->glfs; in qemu_gluster_reopen_commit()
973 g_free(state->opaque); in qemu_gluster_reopen_commit()
974 state->opaque = NULL; in qemu_gluster_reopen_commit()
980 BDRVGlusterReopenState *reop_s = state->opaque; in qemu_gluster_reopen_abort()
986 if (reop_s->fd) { in qemu_gluster_reopen_abort()
987 glfs_close(reop_s->fd); in qemu_gluster_reopen_abort()
990 glfs_clear_preopened(reop_s->glfs); in qemu_gluster_reopen_abort()
992 g_free(state->opaque); in qemu_gluster_reopen_abort()
993 state->opaque = NULL; in qemu_gluster_reopen_abort()
1004 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_pwrite_zeroes()
1011 ret = glfs_zerofill_async(s->fd, offset, bytes, gluster_finish_aiocb, &acb); in qemu_gluster_co_pwrite_zeroes()
1013 return -errno; in qemu_gluster_co_pwrite_zeroes()
1029 return -errno; in qemu_gluster_do_truncate()
1034 return -ENOTSUP; in qemu_gluster_do_truncate()
1044 if (glfs_fallocate(fd, 0, current_length, offset - current_length)) { in qemu_gluster_do_truncate()
1046 return -errno; in qemu_gluster_do_truncate()
1054 return -errno; in qemu_gluster_do_truncate()
1056 if (glfs_zerofill(fd, current_length, offset - current_length)) { in qemu_gluster_do_truncate()
1058 return -errno; in qemu_gluster_do_truncate()
1065 return -errno; in qemu_gluster_do_truncate()
1071 return -EINVAL; in qemu_gluster_do_truncate()
1080 BlockdevCreateOptionsGluster *opts = &options->u.gluster; in qemu_gluster_co_create()
1085 assert(options->driver == BLOCKDEV_DRIVER_GLUSTER); in qemu_gluster_co_create()
1087 glfs = qemu_gluster_glfs_init(opts->location, errp); in qemu_gluster_co_create()
1089 ret = -errno; in qemu_gluster_co_create()
1093 fd = glfs_creat(glfs, opts->location->path, in qemu_gluster_co_create()
1096 ret = -errno; in qemu_gluster_co_create()
1100 ret = qemu_gluster_do_truncate(fd, opts->size, opts->preallocation, errp); in qemu_gluster_co_create()
1105 ret = -errno; in qemu_gluster_co_create()
1125 options->driver = BLOCKDEV_DRIVER_GLUSTER; in qemu_gluster_co_create_opts()
1126 gopts = &options->u.gluster; in qemu_gluster_co_create_opts()
1129 gopts->location = gconf; in qemu_gluster_co_create_opts()
1131 gopts->size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), in qemu_gluster_co_create_opts()
1135 gopts->preallocation = qapi_enum_parse(&PreallocMode_lookup, tmp, in qemu_gluster_co_create_opts()
1140 ret = -EINVAL; in qemu_gluster_co_create_opts()
1144 gconf->debug = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG, in qemu_gluster_co_create_opts()
1146 if (gconf->debug < 0) { in qemu_gluster_co_create_opts()
1147 gconf->debug = 0; in qemu_gluster_co_create_opts()
1148 } else if (gconf->debug > GLUSTER_DEBUG_MAX) { in qemu_gluster_co_create_opts()
1149 gconf->debug = GLUSTER_DEBUG_MAX; in qemu_gluster_co_create_opts()
1151 gconf->has_debug = true; in qemu_gluster_co_create_opts()
1153 gconf->logfile = qemu_opt_get_del(opts, GLUSTER_OPT_LOGFILE); in qemu_gluster_co_create_opts()
1154 if (!gconf->logfile) { in qemu_gluster_co_create_opts()
1155 gconf->logfile = g_strdup(GLUSTER_LOGFILE_DEFAULT); in qemu_gluster_co_create_opts()
1180 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_rw()
1190 ret = glfs_pwritev_async(s->fd, qiov->iov, qiov->niov, offset, 0, in qemu_gluster_co_rw()
1193 ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0, in qemu_gluster_co_rw()
1198 return -errno; in qemu_gluster_co_rw()
1212 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_truncate()
1213 return qemu_gluster_do_truncate(s->fd, offset, prealloc, errp); in qemu_gluster_co_truncate()
1235 BDRVGlusterState *s = bs->opaque; in qemu_gluster_close()
1237 g_free(s->logfile); in qemu_gluster_close()
1238 if (s->fd) { in qemu_gluster_close()
1239 glfs_close(s->fd); in qemu_gluster_close()
1240 s->fd = NULL; in qemu_gluster_close()
1242 glfs_clear_preopened(s->glfs); in qemu_gluster_close()
1249 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_flush_to_disk()
1256 ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb); in qemu_gluster_co_flush_to_disk()
1258 ret = -errno; in qemu_gluster_co_flush_to_disk()
1271 /* Some versions of Gluster (3.5.6 -> 3.5.8?) will not retain its cache in qemu_gluster_co_flush_to_disk()
1273 * continue. Gluster versions prior to 3.5.6 don't retain the cache in qemu_gluster_co_flush_to_disk()
1277 * The 'resync-failed-syncs-after-fsync' xlator option for the in qemu_gluster_co_flush_to_disk()
1278 * write-behind cache will cause later gluster versions to retain its in qemu_gluster_co_flush_to_disk()
1279 * cache after error, so long as the fd remains open. However, we in qemu_gluster_co_flush_to_disk()
1285 bs->drv = NULL; in qemu_gluster_co_flush_to_disk()
1295 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_pdiscard()
1304 ret = glfs_discard_async(s->fd, offset, bytes, gluster_finish_aiocb, &acb); in qemu_gluster_co_pdiscard()
1306 return -errno; in qemu_gluster_co_pdiscard()
1316 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_getlength()
1319 ret = glfs_lseek(s->fd, 0, SEEK_END); in qemu_gluster_co_getlength()
1321 return -errno; in qemu_gluster_co_getlength()
1330 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_get_allocated_file_size()
1334 ret = glfs_fstat(s->fd, &st); in qemu_gluster_co_get_allocated_file_size()
1336 return -errno; in qemu_gluster_co_get_allocated_file_size()
1346 * beginning of the next hole in @hole, and return 0.
1347 * If @start is in a non-trailing hole, store @start in @hole and the
1348 * beginning of the next non-hole in @data, and return 0.
1349 * If @start is in a trailing hole or beyond EOF, return -ENXIO.
1350 * If we can't find out, return a negative errno other than -ENXIO.
1352 * (Shamefully copied from file-posix.c, only minuscule adaptions.)
1357 BDRVGlusterState *s = bs->opaque; in find_allocation()
1359 if (!s->supports_seek_data) { in find_allocation()
1369 * D2. offs > start: start is in a hole, next data at offs in find_allocation()
1377 offs = glfs_lseek(s->fd, start, SEEK_DATA); in find_allocation()
1379 return -errno; /* D3 or D4 */ in find_allocation()
1384 * -EIO in this case, and we'll treat it like D4. Unfortunately some in find_allocation()
1387 return -EIO; in find_allocation()
1391 /* D2: in hole, next data at offs */ in find_allocation()
1404 * H2. offs > start: either start is in data, next hole at offs, in find_allocation()
1416 offs = glfs_lseek(s->fd, start, SEEK_HOLE); in find_allocation()
1418 return -errno; /* D1 and (H3 or H4) */ in find_allocation()
1423 * -EIO in this case, and we'll treat it like H4. Unfortunately some in find_allocation()
1426 return -EIO; in find_allocation()
1431 * D1 and H2: either in data, next hole at offs, or it was in in find_allocation()
1442 return -EBUSY; in find_allocation()
1446 return -ENOTSUP; in find_allocation()
1461 * (Based on raw_co_block_status() from file-posix.c.)
1471 BDRVGlusterState *s = bs->opaque; in qemu_gluster_co_block_status()
1473 int ret = -EINVAL; in qemu_gluster_co_block_status()
1475 assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment)); in qemu_gluster_co_block_status()
1477 if (!s->fd) { in qemu_gluster_co_block_status()
1489 if (ret == -ENXIO) { in qemu_gluster_co_block_status()
1500 *pnum = hole - offset; in qemu_gluster_co_block_status()
1506 if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) { in qemu_gluster_co_block_status()
1512 *pnum = ROUND_UP(*pnum, bs->bl.request_alignment); in qemu_gluster_co_block_status()
1517 /* On a hole, compute bytes to the beginning of the next extent. */ in qemu_gluster_co_block_status()
1519 *pnum = data - offset; in qemu_gluster_co_block_status()