[Libguestfs] [PATCH libnbd] copy: Refactor ‘struct rw’.

Eric Blake eblake at redhat.com
Mon Feb 22 18:04:52 UTC 2021


On 2/22/21 9:42 AM, Richard W.M. Jones wrote:
> Make this a (fairly) abstract structure.  At least hide the subtype
> fields from the main program.  This change is pure refactoring and
> doesn’t change the semantics.
> ---
>  copy/file-ops.c             | 164 +++++++++++++++++--
>  copy/main.c                 | 315 ++++++++----------------------------
>  copy/multi-thread-copying.c | 104 ++++++------
>  copy/nbd-ops.c              | 248 +++++++++++++++++++++++++---
>  copy/nbdcopy.h              |  53 +++---
>  copy/null-ops.c             |  50 +++++-
>  copy/pipe-ops.c             |  64 +++++++-
>  copy/synch-copying.c        |  30 ++--
>  8 files changed, 649 insertions(+), 379 deletions(-)

Adds more than it removes, but I agree that the new layout looks easier
to maintain.

> +++ b/copy/nbdcopy.h
> @@ -36,8 +36,6 @@
>   */
>  #define THREAD_WORK_SIZE (128 * 1024 * 1024)
>  
> -DEFINE_VECTOR_TYPE (handles, struct nbd_handle *)
> -
>  /* Abstracts the input (src) and output (dst) parameters on the
>   * command line.
>   */
> @@ -45,21 +43,20 @@ struct rw {
>    struct rw_ops *ops;           /* Operations. */
>    const char *name;             /* Printable name, for error messages etc. */
>    int64_t size;                 /* May be -1 for streams. */
> -  union {
> -    struct {                    /* For files and pipes. */
> -      int fd;
> -      struct stat stat;
> -      bool seek_hole_supported;
> -      int sector_size;
> -    } local;
> -    struct {
> -      handles handles;          /* For NBD, one handle per connection. */
> -      bool can_trim, can_zero;  /* Cached nbd_can_trim, nbd_can_zero. */
> -    } nbd;
> -  } u;
> +  /* Followed by private data for the particular subtype. */
>  };
>  
> -extern struct rw src, dst;
> +extern struct rw *src, *dst;
> +
> +/* Create subtypes. */
> +extern struct rw *file_create (const char *name,
> +                               const struct stat *stat, int fd);
> +extern struct rw *nbd_rw_create_uri (const char *name,
> +                                     const char *uri, bool writing);
> +extern struct rw *nbd_rw_create_subprocess (const char **argv, size_t argc,
> +                                            bool writing);
> +extern struct rw *null_create (const char *name);
> +extern struct rw *pipe_create (const char *name, int fd);
>  
>  /* Underlying data buffers. */
>  struct buffer {
> @@ -117,6 +114,28 @@ struct rw_ops {
>    /* Close the connection and free up associated resources. */
>    void (*close) (struct rw *rw);
>  
> +  /* Return true if this is a read-only connection. */
> +  bool (*is_read_only) (struct rw *rw);
> +
> +  /* For source only, does it support reading extents? */
> +  bool (*can_extents) (struct rw *rw);
> +
> +  /* Return true if the connection can do multi-conn.  This is true
> +   * for files, false for streams, and passed through for NBD.
> +   */
> +  bool (*can_multi_conn) (struct rw *rw);
> +
> +  /* For multi-conn capable backends, before copying we must call this
> +   * to begin multi-conn.  For NBD this means opening the additional
> +   * connections.
> +   */
> +  void (*start_multi_conn) (struct rw *rw);
> +
> +  /* Truncate, only called on output files.  This callback can be NULL
> +   * for types that don't support this.
> +   */
> +  void (*truncate) (struct rw *rw, int64_t size);
> +
>    /* Flush pending writes to permanent storage. */
>    void (*flush) (struct rw *rw);

Looks nice, beyond what Nir already pointed out.


-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




More information about the Libguestfs mailing list