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:
Ken Cox 2014-05-22 12:31:14 -05:00 committed by Greg Kroah-Hartman
parent e40d1c8ad9
commit 2079c4aaf6
4 changed files with 1 additions and 662 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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, &parahotplug_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;