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:
parent
e40d1c8ad9
commit
2079c4aaf6
4 changed files with 1 additions and 662 deletions
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset.o
|
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
|
parser.o
|
||||||
|
|
||||||
ccflags-y += -Idrivers/staging/unisys/include
|
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 "uisutils.h"
|
||||||
#include "controlvmcompletionstatus.h"
|
#include "controlvmcompletionstatus.h"
|
||||||
#include "guestlinuxdebug.h"
|
#include "guestlinuxdebug.h"
|
||||||
#include "filexfer.h"
|
|
||||||
|
|
||||||
#include <linux/nls.h>
|
#include <linux/nls.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
@ -2773,12 +2772,6 @@ visorchipset_init(void)
|
||||||
ProcDir, ¶hotplug_proc_fops);
|
ProcDir, ¶hotplug_proc_fops);
|
||||||
memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
|
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 =
|
Putfile_buffer_list_pool =
|
||||||
kmem_cache_create(Putfile_buffer_list_pool_name,
|
kmem_cache_create(Putfile_buffer_list_pool_name,
|
||||||
sizeof(struct putfile_buffer_entry),
|
sizeof(struct putfile_buffer_entry),
|
||||||
|
@ -2862,7 +2855,6 @@ visorchipset_exit(void)
|
||||||
kmem_cache_destroy(Putfile_buffer_list_pool);
|
kmem_cache_destroy(Putfile_buffer_list_pool);
|
||||||
Putfile_buffer_list_pool = NULL;
|
Putfile_buffer_list_pool = NULL;
|
||||||
}
|
}
|
||||||
filexfer_destructor();
|
|
||||||
if (ControlVmObject) {
|
if (ControlVmObject) {
|
||||||
visor_proc_DestroyObject(ControlVmObject);
|
visor_proc_DestroyObject(ControlVmObject);
|
||||||
ControlVmObject = NULL;
|
ControlVmObject = NULL;
|
||||||
|
|
Loading…
Add table
Reference in a new issue