Staging: unisys: visorchipset: Remove filexfer.c
There is not any code using the functionality in filexfer.c so I removed it and filexfer.h. Signed-off-by: Ken Cox <jkc@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
e40d1c8ad9
Коммит
2079c4aaf6
|
@ -4,7 +4,7 @@
|
|||
|
||||
obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset.o
|
||||
|
||||
visorchipset-y := visorchipset_main.o controlvm_direct.o file.o filexfer.o \
|
||||
visorchipset-y := visorchipset_main.o controlvm_direct.o file.o \
|
||||
parser.o
|
||||
|
||||
ccflags-y += -Idrivers/staging/unisys/include
|
||||
|
|
|
@ -1,506 +0,0 @@
|
|||
/* filexfer.c
|
||||
*
|
||||
* Copyright © 2013 - 2013 UNISYS CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/* Code here-in is the "glue" that connects controlvm messages with the
|
||||
* sparfilexfer driver, which is used to transfer file contents as payload
|
||||
* across the controlvm channel.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
#include "controlvm.h"
|
||||
#include "visorchipset.h"
|
||||
#include "filexfer.h"
|
||||
|
||||
#ifdef ENABLE_SPARFILEXFER /* sparfilexfer kernel module enabled in build */
|
||||
#include "sparfilexfer.h"
|
||||
|
||||
/* Driver-global memory */
|
||||
static LIST_HEAD(Request_list); /* list of struct any_request *, via
|
||||
* req_list memb */
|
||||
|
||||
/* lock for above pool for allocation of any_request structs, and pool
|
||||
* name; note that kmem_cache_create requires that we keep the storage
|
||||
* for the pool name for the life of the pool
|
||||
*/
|
||||
static DEFINE_SPINLOCK(Request_list_lock);
|
||||
|
||||
static struct kmem_cache *Request_memory_pool;
|
||||
static const char Request_memory_pool_name[] = "filexfer_request_pool";
|
||||
size_t Caller_req_context_bytes = 0; /* passed to filexfer_constructor() */
|
||||
|
||||
/* This structure defines a single controlvm GETFILE conversation, which
|
||||
* consists of a single controlvm request message and 1 or more controlvm
|
||||
* response messages.
|
||||
*/
|
||||
struct getfile_request {
|
||||
CONTROLVM_MESSAGE_HEADER controlvm_header;
|
||||
atomic_t buffers_in_use;
|
||||
GET_CONTIGUOUS_CONTROLVM_PAYLOAD_FUNC get_contiguous_controlvm_payload;
|
||||
CONTROLVM_RESPOND_WITH_PAYLOAD_FUNC controlvm_respond_with_payload;
|
||||
};
|
||||
|
||||
/* This structure defines a single controlvm PUTFILE conversation, which
|
||||
* consists of a single controlvm request with a filename, and additional
|
||||
* controlvm messages with file data.
|
||||
*/
|
||||
struct putfile_request {
|
||||
GET_CONTROLVM_FILEDATA_FUNC get_controlvm_filedata;
|
||||
CONTROLVM_RESPOND_FUNC controlvm_end_putFile;
|
||||
};
|
||||
|
||||
/* This structure defines a single file transfer operation, which can either
|
||||
* be a GETFILE or PUTFILE.
|
||||
*/
|
||||
struct any_request {
|
||||
struct list_head req_list;
|
||||
ulong2 file_request_number;
|
||||
ulong2 data_sequence_number;
|
||||
TRANSMITFILE_DUMP_FUNC dump_func;
|
||||
BOOL is_get;
|
||||
union {
|
||||
struct getfile_request get;
|
||||
struct putfile_request put;
|
||||
};
|
||||
/* Size of caller_context_data will be
|
||||
* <Caller_req_context_bytes> bytes. I aligned this because I
|
||||
* am paranoid about what happens when an arbitrary data
|
||||
* structure with unknown alignment requirements gets copied
|
||||
* here. I want caller_context_data to be aligned to the
|
||||
* coarsest possible alignment boundary that could be required
|
||||
* for any user data structure.
|
||||
*/
|
||||
u8 caller_context_data[1] __aligned(sizeof(ulong2));
|
||||
};
|
||||
|
||||
/*
|
||||
* Links the any_request into the global list of allocated requests
|
||||
* (<Request_list>).
|
||||
*/
|
||||
static void
|
||||
unit_tracking_create(struct list_head *dev_list_link)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&Request_list_lock, flags);
|
||||
list_add(dev_list_link, &Request_list);
|
||||
spin_unlock_irqrestore(&Request_list_lock, flags);
|
||||
}
|
||||
|
||||
/* Unlinks a any_request from the global list (<Request_list>).
|
||||
*/
|
||||
static void
|
||||
unit_tracking_destroy(struct list_head *dev_list_link)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&Request_list_lock, flags);
|
||||
list_del(dev_list_link);
|
||||
spin_unlock_irqrestore(&Request_list_lock, flags);
|
||||
}
|
||||
|
||||
/* Allocate memory for and return a new any_request struct, and
|
||||
* link it to the global list of outstanding requests.
|
||||
*/
|
||||
static struct any_request *
|
||||
alloc_request(char *fn, int ln)
|
||||
{
|
||||
struct any_request *req = (struct any_request *)
|
||||
(visorchipset_cache_alloc(Request_memory_pool,
|
||||
FALSE,
|
||||
fn, ln));
|
||||
if (!req)
|
||||
return NULL;
|
||||
memset(req, 0, sizeof(struct any_request) + Caller_req_context_bytes);
|
||||
unit_tracking_create(&req->req_list);
|
||||
return req;
|
||||
}
|
||||
|
||||
/* Book-end for alloc_request().
|
||||
*/
|
||||
static void
|
||||
free_request(struct any_request *req, char *fn, int ln)
|
||||
{
|
||||
unit_tracking_destroy(&req->req_list);
|
||||
visorchipset_cache_free(Request_memory_pool, req, fn, ln);
|
||||
}
|
||||
|
||||
/* Constructor for filexfer.o.
|
||||
*/
|
||||
int
|
||||
filexfer_constructor(size_t req_context_bytes)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
Caller_req_context_bytes = req_context_bytes;
|
||||
Request_memory_pool =
|
||||
kmem_cache_create(Request_memory_pool_name,
|
||||
sizeof(struct any_request) +
|
||||
Caller_req_context_bytes,
|
||||
0, SLAB_HWCACHE_ALIGN, NULL);
|
||||
if (!Request_memory_pool) {
|
||||
LOGERR("failed to alloc Request_memory_pool");
|
||||
rc = -ENOMEM;
|
||||
goto Away;
|
||||
}
|
||||
rc = 0;
|
||||
Away:
|
||||
if (rc < 0) {
|
||||
if (Request_memory_pool) {
|
||||
kmem_cache_destroy(Request_memory_pool);
|
||||
Request_memory_pool = NULL;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Destructor for filexfer.o.
|
||||
*/
|
||||
void
|
||||
filexfer_destructor(void)
|
||||
{
|
||||
if (Request_memory_pool) {
|
||||
kmem_cache_destroy(Request_memory_pool);
|
||||
Request_memory_pool = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function will obtain an available chunk from the controlvm payload area,
|
||||
* store the size in bytes of the chunk in <actual_size>, and return a pointer
|
||||
* to the chunk. The function is passed to the sparfilexfer driver, which calls
|
||||
* it whenever payload space is required to copy file data into.
|
||||
*/
|
||||
static void *
|
||||
get_empty_bucket_for_getfile_data(void *context,
|
||||
ulong min_size, ulong max_size,
|
||||
ulong *actual_size)
|
||||
{
|
||||
void *bucket;
|
||||
struct any_request *req = (struct any_request *) context;
|
||||
|
||||
if (!req->is_get) {
|
||||
LOGERR("%s - unexpected call", __func__);
|
||||
return NULL;
|
||||
}
|
||||
bucket = (*req->get.get_contiguous_controlvm_payload)
|
||||
(min_size, max_size, actual_size);
|
||||
if (bucket != NULL) {
|
||||
atomic_inc(&req->get.buffers_in_use);
|
||||
DBGINF("%s - sent %lu-byte buffer", __func__, *actual_size);
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
|
||||
/* This function will send a controlvm response with data in the payload
|
||||
* (whose space was obtained with get_empty_bucket_for_getfile_data). The
|
||||
* function is passed to the sparfilexfer driver, which calls it whenever it
|
||||
* wants to send file data back across the controlvm channel.
|
||||
*/
|
||||
static int
|
||||
send_full_getfile_data_bucket(void *context, void *bucket,
|
||||
ulong bucket_actual_size, ulong bucket_used_size)
|
||||
{
|
||||
struct any_request *req = (struct any_request *) context;
|
||||
|
||||
if (!req->is_get) {
|
||||
LOGERR("%s - unexpected call", __func__);
|
||||
return 0;
|
||||
}
|
||||
DBGINF("sending buffer for %lu/%lu",
|
||||
bucket_used_size, bucket_actual_size);
|
||||
if (!(*req->get.controlvm_respond_with_payload)
|
||||
(&req->get.controlvm_header,
|
||||
req->file_request_number,
|
||||
req->data_sequence_number++,
|
||||
0, bucket, bucket_actual_size, bucket_used_size, TRUE))
|
||||
atomic_dec(&req->get.buffers_in_use);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function will send a controlvm response indicating the end of a
|
||||
* GETFILE transfer. The function is passed to the sparfilexfer driver.
|
||||
*/
|
||||
static void
|
||||
send_end_of_getfile_data(void *context, int status)
|
||||
{
|
||||
struct any_request *req = (struct any_request *) context;
|
||||
if (!req->is_get) {
|
||||
LOGERR("%s - unexpected call", __func__);
|
||||
return;
|
||||
}
|
||||
LOGINF("status=%d", status);
|
||||
(*req->get.controlvm_respond_with_payload)
|
||||
(&req->get.controlvm_header,
|
||||
req->file_request_number,
|
||||
req->data_sequence_number++, status, NULL, 0, 0, FALSE);
|
||||
free_request(req, __FILE__, __LINE__);
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
/* This function supplies data for a PUTFILE transfer.
|
||||
* The function is passed to the sparfilexfer driver.
|
||||
*/
|
||||
static int
|
||||
get_putfile_data(void *context, void *pbuf, size_t bufsize,
|
||||
BOOL buf_is_userspace, size_t *bytes_transferred)
|
||||
{
|
||||
struct any_request *req = (struct any_request *) context;
|
||||
if (req->is_get) {
|
||||
LOGERR("%s - unexpected call", __func__);
|
||||
return -1;
|
||||
}
|
||||
return (*req->put.get_controlvm_filedata) (&req->caller_context_data[0],
|
||||
pbuf, bufsize,
|
||||
buf_is_userspace,
|
||||
bytes_transferred);
|
||||
}
|
||||
|
||||
/* This function is called to indicate the end of a PUTFILE transfer.
|
||||
* The function is passed to the sparfilexfer driver.
|
||||
*/
|
||||
static void
|
||||
end_putfile(void *context, int status)
|
||||
{
|
||||
struct any_request *req = (struct any_request *) context;
|
||||
if (req->is_get) {
|
||||
LOGERR("%s - unexpected call", __func__);
|
||||
return;
|
||||
}
|
||||
(*req->put.controlvm_end_putFile) (&req->caller_context_data[0],
|
||||
status);
|
||||
free_request(req, __FILE__, __LINE__);
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
/* Refer to filexfer.h for description. */
|
||||
BOOL
|
||||
filexfer_getFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
|
||||
ulong2 file_request_number,
|
||||
uint uplink_index,
|
||||
uint disk_index,
|
||||
char *file_name,
|
||||
GET_CONTIGUOUS_CONTROLVM_PAYLOAD_FUNC
|
||||
get_contiguous_controlvm_payload,
|
||||
CONTROLVM_RESPOND_WITH_PAYLOAD_FUNC
|
||||
controlvm_respond_with_payload,
|
||||
TRANSMITFILE_DUMP_FUNC dump_func)
|
||||
{
|
||||
BOOL use_count_up = FALSE;
|
||||
BOOL failed = TRUE;
|
||||
struct any_request *req = alloc_request(__FILE__, __LINE__);
|
||||
|
||||
if (!req) {
|
||||
LOGERR("allocation of any_request failed");
|
||||
goto Away;
|
||||
}
|
||||
/* We need to increment this module's use count because we're handing
|
||||
* off pointers to functions within this module to be used by
|
||||
* another module.
|
||||
*/
|
||||
__module_get(THIS_MODULE);
|
||||
use_count_up = TRUE;
|
||||
req->is_get = TRUE;
|
||||
req->file_request_number = file_request_number;
|
||||
req->data_sequence_number = 0;
|
||||
req->dump_func = dump_func;
|
||||
req->get.controlvm_header = *msgHdr;
|
||||
atomic_set(&req->get.buffers_in_use, 0);
|
||||
req->get.get_contiguous_controlvm_payload =
|
||||
get_contiguous_controlvm_payload;
|
||||
req->get.controlvm_respond_with_payload =
|
||||
controlvm_respond_with_payload;
|
||||
if (sparfilexfer_local2remote(req, /* context, passed to
|
||||
* callback funcs */
|
||||
file_name,
|
||||
file_request_number,
|
||||
uplink_index,
|
||||
disk_index,
|
||||
get_empty_bucket_for_getfile_data,
|
||||
send_full_getfile_data_bucket,
|
||||
send_end_of_getfile_data) < 0) {
|
||||
LOGERR("sparfilexfer_local2remote failed");
|
||||
goto Away;
|
||||
}
|
||||
failed = FALSE;
|
||||
Away:
|
||||
if (failed) {
|
||||
if (use_count_up) {
|
||||
module_put(THIS_MODULE);
|
||||
use_count_up = FALSE;
|
||||
}
|
||||
if (req) {
|
||||
free_request(req, __FILE__, __LINE__);
|
||||
req = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
/* success; send callbacks will be called for responses */
|
||||
}
|
||||
}
|
||||
|
||||
/* Refer to filexfer.h for description. */
|
||||
void *
|
||||
filexfer_putFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
|
||||
ulong2 file_request_number,
|
||||
uint uplink_index,
|
||||
uint disk_index,
|
||||
char *file_name,
|
||||
TRANSMITFILE_INIT_CONTEXT_FUNC init_context,
|
||||
GET_CONTROLVM_FILEDATA_FUNC get_controlvm_filedata,
|
||||
CONTROLVM_RESPOND_FUNC controlvm_end_putFile,
|
||||
TRANSMITFILE_DUMP_FUNC dump_func)
|
||||
{
|
||||
BOOL use_count_up = FALSE;
|
||||
BOOL failed = TRUE;
|
||||
struct any_request *req = alloc_request(__FILE__, __LINE__);
|
||||
void *caller_ctx = NULL;
|
||||
|
||||
if (!req) {
|
||||
LOGERR("allocation of any_request failed");
|
||||
goto Away;
|
||||
}
|
||||
caller_ctx = (void *) (&(req->caller_context_data[0]));
|
||||
/* We need to increment this module's use count because we're handing
|
||||
* off pointers to functions within this module to be used by
|
||||
* another module.
|
||||
*/
|
||||
__module_get(THIS_MODULE);
|
||||
use_count_up = TRUE;
|
||||
req->is_get = FALSE;
|
||||
req->file_request_number = file_request_number;
|
||||
req->data_sequence_number = 0;
|
||||
req->dump_func = dump_func;
|
||||
req->put.get_controlvm_filedata = get_controlvm_filedata;
|
||||
req->put.controlvm_end_putFile = controlvm_end_putFile;
|
||||
(*init_context) (caller_ctx, msgHdr, file_request_number);
|
||||
if (sparfilexfer_remote2local(req, /* context, passed to
|
||||
* callback funcs */
|
||||
file_name,
|
||||
file_request_number,
|
||||
uplink_index,
|
||||
disk_index,
|
||||
get_putfile_data, end_putfile) < 0) {
|
||||
LOGERR("sparfilexfer_remote2local failed");
|
||||
goto Away;
|
||||
}
|
||||
failed = FALSE;
|
||||
Away:
|
||||
if (failed) {
|
||||
if (use_count_up) {
|
||||
module_put(THIS_MODULE);
|
||||
use_count_up = FALSE;
|
||||
}
|
||||
if (req) {
|
||||
free_request(req, __FILE__, __LINE__);
|
||||
req = NULL;
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
return caller_ctx;
|
||||
/* success; callbacks will be called for responses */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_get_request(struct seq_file *f, struct getfile_request *getreq)
|
||||
{
|
||||
seq_printf(f, " buffers_in_use=%d\n",
|
||||
atomic_read(&getreq->buffers_in_use));
|
||||
}
|
||||
|
||||
static void
|
||||
dump_put_request(struct seq_file *f, struct putfile_request *putreq)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
dump_request(struct seq_file *f, struct any_request *req)
|
||||
{
|
||||
seq_printf(f, "* %s id=%llu seq=%llu\n",
|
||||
((req->is_get) ? "Get" : "Put"),
|
||||
req->file_request_number, req->data_sequence_number);
|
||||
if (req->is_get)
|
||||
dump_get_request(f, &req->get);
|
||||
else
|
||||
dump_put_request(f, &req->put);
|
||||
if (req->dump_func)
|
||||
(*req->dump_func) (f, &(req->caller_context_data[0]), " ");
|
||||
}
|
||||
|
||||
void
|
||||
filexfer_dump(struct seq_file *f)
|
||||
{
|
||||
ulong flags;
|
||||
struct list_head *entry;
|
||||
|
||||
seq_puts(f, "Outstanding TRANSMIT_FILE requests:\n");
|
||||
spin_lock_irqsave(&Request_list_lock, flags);
|
||||
list_for_each(entry, &Request_list) {
|
||||
struct any_request *req;
|
||||
req = list_entry(entry, struct any_request, req_list);
|
||||
dump_request(f, req);
|
||||
}
|
||||
spin_unlock_irqrestore(&Request_list_lock, flags);
|
||||
}
|
||||
|
||||
#else /* ifdef ENABLE_SPARFILEXFER */
|
||||
int
|
||||
filexfer_constructor(size_t req_context_bytes)
|
||||
{
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
void
|
||||
filexfer_destructor(void)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL
|
||||
filexfer_getFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
|
||||
u64 file_request_number,
|
||||
uint uplink_index,
|
||||
uint disk_index,
|
||||
char *file_name,
|
||||
GET_CONTIGUOUS_CONTROLVM_PAYLOAD_FUNC
|
||||
get_contiguous_controlvm_payload,
|
||||
CONTROLVM_RESPOND_WITH_PAYLOAD_FUNC
|
||||
controlvm_respond_with_payload,
|
||||
TRANSMITFILE_DUMP_FUNC dump_func)
|
||||
{
|
||||
/* since no sparfilexfer module exists to call, we just fail */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void *
|
||||
filexfer_putFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
|
||||
u64 file_request_number,
|
||||
uint uplink_index,
|
||||
uint disk_index,
|
||||
char *file_name,
|
||||
TRANSMITFILE_INIT_CONTEXT_FUNC init_context,
|
||||
GET_CONTROLVM_FILEDATA_FUNC get_controlvm_filedata,
|
||||
CONTROLVM_RESPOND_FUNC controlvm_end_putFile,
|
||||
TRANSMITFILE_DUMP_FUNC dump_func)
|
||||
{
|
||||
/* since no sparfilexfer module exists to call, we just fail */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
filexfer_dump(struct seq_file *f)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* ifdef ENABLE_SPARFILEXFER */
|
|
@ -1,147 +0,0 @@
|
|||
/* filexfer.h
|
||||
*
|
||||
* Copyright © 2013 - 2013 UNISYS CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/* This header file defines the interface that filexfer.c provides to other
|
||||
* code in the visorchipset driver.
|
||||
*/
|
||||
|
||||
#ifndef __FILEXFER_H__
|
||||
#define __FILEXFER_H__
|
||||
|
||||
#include "globals.h"
|
||||
#include "controlvmchannel.h"
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
typedef void *(*GET_CONTIGUOUS_CONTROLVM_PAYLOAD_FUNC) (ulong min_size,
|
||||
ulong max_size,
|
||||
ulong *actual_size);
|
||||
|
||||
typedef BOOL
|
||||
(*CONTROLVM_RESPOND_WITH_PAYLOAD_FUNC) (CONTROLVM_MESSAGE_HEADER *msgHdr,
|
||||
u64 fileRequestNumber,
|
||||
u64 dataSequenceNumber,
|
||||
int response,
|
||||
void *bucket, ulong payloadChunkSize,
|
||||
ulong payloadUsedBytes, BOOL partial);
|
||||
|
||||
typedef void
|
||||
(*TRANSMITFILE_INIT_CONTEXT_FUNC)(void *ctx,
|
||||
const CONTROLVM_MESSAGE_HEADER *hdr,
|
||||
u64 file_request_number);
|
||||
typedef void (*TRANSMITFILE_DUMP_FUNC) (struct seq_file *f, void *ctx,
|
||||
const char *pfx);
|
||||
typedef int (*GET_CONTROLVM_FILEDATA_FUNC) (void *ctx,
|
||||
void *buf, size_t bufsize,
|
||||
BOOL buf_is_userspace,
|
||||
size_t *bytes_transferred);
|
||||
typedef void (*CONTROLVM_RESPOND_FUNC) (void *ctx, int response);
|
||||
|
||||
/* Call once to initialize filexfer.o.
|
||||
* req_context_bytes number of bytes the caller needs to keep track of each file
|
||||
* transfer conversation. The <ctx_init_value> passed to filexfer_putFile() is
|
||||
* assumed to be this many bytes in size. Code within filexfer.o will copy this
|
||||
* into a dynamically-allocated area, and pass back a pointer to that area in
|
||||
* callback functions.
|
||||
*/
|
||||
int filexfer_constructor(size_t req_context_bytes);
|
||||
|
||||
/* Call once to clean up filexfer.o */
|
||||
void filexfer_destructor(void);
|
||||
|
||||
/* Call this to dump diagnostic info about all outstanding getFiles/putFiles */
|
||||
void filexfer_dump(struct seq_file *f);
|
||||
|
||||
/* Call to transfer a file from the local filesystem (i.e., from the environment
|
||||
* where this driver is running) across the controlvm channel to a remote
|
||||
* environment. 1 or more controlvm responses will be sent as a result, each
|
||||
* of which whose payload contains file data. Only the last controlvm message
|
||||
* will have Flags.partialCompletion==0.
|
||||
*
|
||||
* msgHdr the controlvm message header of the GETFILE request which
|
||||
* we just received
|
||||
* file_request_number this is all data from the GETFILE request that
|
||||
* uplink_index define which file is to be transferred
|
||||
* disk_index
|
||||
* file_name
|
||||
* get_contiguous_controlvm_payload function to call when space is needed
|
||||
* in the payload area
|
||||
* controlvm_respond_with_payload function to call to send each controlvm
|
||||
* response containing file data as the
|
||||
* payload; returns FALSE only if the
|
||||
* payload buffer was freed inline
|
||||
* dump_func function to dump context data in
|
||||
* human-readable format
|
||||
*
|
||||
* Returns TRUE iff the file transfer request has been successfully initiated,
|
||||
* or FALSE to indicate failure.
|
||||
*/
|
||||
BOOL
|
||||
filexfer_getFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
|
||||
u64 file_request_number,
|
||||
uint uplink_index,
|
||||
uint disk_index,
|
||||
char *file_name,
|
||||
GET_CONTIGUOUS_CONTROLVM_PAYLOAD_FUNC
|
||||
get_contiguous_controlvm_payload,
|
||||
CONTROLVM_RESPOND_WITH_PAYLOAD_FUNC
|
||||
controlvm_respond_with_payload,
|
||||
TRANSMITFILE_DUMP_FUNC dump_func);
|
||||
|
||||
/* Call to create a file in the local filesystem (i.e., in the environment
|
||||
* where this driver is running) from data received as payload in
|
||||
* controlvm channel messages from a remote environment. 1 or more controlvm
|
||||
* messages will be received for this transfer, and only the last will have
|
||||
* Flags.partialCompletion==0.
|
||||
*
|
||||
* msgHdr the controlvm message header of the PUTFILE request which
|
||||
* we just received
|
||||
* file_request_number this is all data from the PUTFILE request that
|
||||
* uplink_index define which file is to be created in the local
|
||||
* disk_index filesystem
|
||||
* file_name
|
||||
* init_context function to call to initialize the
|
||||
* <req_context_bytes>-sized storage area returned by
|
||||
* this func; note that it would NOT be sufficient to
|
||||
* allow the caller to initialize this upon return, as
|
||||
* the the other user-supplied callbacks might have
|
||||
* already been called by then
|
||||
* get_controlvm_filedata function to call to obtain more data for the file
|
||||
* being written; refer to get_controlvm_filedata()
|
||||
* in visorchipset_main.c for a complete description
|
||||
* of parameters
|
||||
* controlvm_end_putFile function to call to indicate that creation of the
|
||||
* local file has completed; set <response> to a
|
||||
* negative value to indicate an error
|
||||
* dump_func function to dump context data in human-readable
|
||||
* format
|
||||
*
|
||||
* Returns a pointer to a dynamically-allocated storage area of size
|
||||
* <req_context_bytes> which the caller can use, or NULL for error. The
|
||||
* caller should NEVER free the returned pointer, but should expect to receive
|
||||
* it as the <ctx> argument when callback functions are called.
|
||||
*/
|
||||
void *filexfer_putFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
|
||||
u64 file_request_number,
|
||||
uint uplink_index,
|
||||
uint disk_index,
|
||||
char *file_name,
|
||||
TRANSMITFILE_INIT_CONTEXT_FUNC init_context,
|
||||
GET_CONTROLVM_FILEDATA_FUNC get_controlvm_filedata,
|
||||
CONTROLVM_RESPOND_FUNC controlvm_end_putFile,
|
||||
TRANSMITFILE_DUMP_FUNC dump_func);
|
||||
|
||||
#endif
|
|
@ -28,7 +28,6 @@
|
|||
#include "uisutils.h"
|
||||
#include "controlvmcompletionstatus.h"
|
||||
#include "guestlinuxdebug.h"
|
||||
#include "filexfer.h"
|
||||
|
||||
#include <linux/nls.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
@ -2773,12 +2772,6 @@ visorchipset_init(void)
|
|||
ProcDir, ¶hotplug_proc_fops);
|
||||
memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
|
||||
|
||||
if (filexfer_constructor(sizeof(struct putfile_request)) < 0) {
|
||||
ERRDRV("filexfer_constructor failed: (status=-1)\n");
|
||||
POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC, DIAG_SEVERITY_ERR);
|
||||
rc = -1;
|
||||
goto Away;
|
||||
}
|
||||
Putfile_buffer_list_pool =
|
||||
kmem_cache_create(Putfile_buffer_list_pool_name,
|
||||
sizeof(struct putfile_buffer_entry),
|
||||
|
@ -2862,7 +2855,6 @@ visorchipset_exit(void)
|
|||
kmem_cache_destroy(Putfile_buffer_list_pool);
|
||||
Putfile_buffer_list_pool = NULL;
|
||||
}
|
||||
filexfer_destructor();
|
||||
if (ControlVmObject) {
|
||||
visor_proc_DestroyObject(ControlVmObject);
|
||||
ControlVmObject = NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче