268 lines
4.8 KiB
C++
268 lines
4.8 KiB
C++
/*
|
|
* Copyright 2012 Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Paweł Dziepak, [email protected]
|
|
*/
|
|
|
|
|
|
#include <fs_interface.h>
|
|
|
|
#include "Connection.h"
|
|
#include "RPCServer.h"
|
|
#include "NFS4Defs.h"
|
|
#include "Inode.h"
|
|
#include "RequestBuilder.h"
|
|
#include "ReplyInterpreter.h"
|
|
#include "Filesystem.h"
|
|
|
|
|
|
extern fs_volume_ops gNFSv4VolumeOps;
|
|
extern fs_vnode_ops gNFSv4VnodeOps;
|
|
|
|
extern "C" void
|
|
dprintf(const char* format, ...);
|
|
|
|
|
|
RPC::ServerManager* gRPCServerManager;
|
|
|
|
|
|
static status_t
|
|
nfs4_mount(fs_volume* volume, const char* device, uint32 flags,
|
|
const char* args, ino_t* _rootVnodeID)
|
|
{
|
|
status_t result;
|
|
|
|
RPC::Server *server;
|
|
// hardcoded ip 192.168.1.70
|
|
result = gRPCServerManager->Acquire(&server, 0xc0a80146, 2049, ProtocolUDP);
|
|
if (result != B_OK)
|
|
return result;
|
|
|
|
Filesystem* fs;
|
|
// hardcoded path
|
|
result = Filesystem::Mount(&fs, server, "haiku/src/add-ons/kernel",
|
|
volume->id);
|
|
if (result != B_OK) {
|
|
gRPCServerManager->Release(server);
|
|
return result;
|
|
}
|
|
|
|
Inode* inode = fs->CreateRootInode();
|
|
|
|
volume->private_volume = fs;
|
|
volume->ops = &gNFSv4VolumeOps;
|
|
|
|
result = publish_vnode(volume, inode->ID(), inode, &gNFSv4VnodeOps,
|
|
inode->Type(), 0);
|
|
if (result != B_OK)
|
|
return result;
|
|
|
|
*_rootVnodeID = inode->ID();
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_unmount(fs_volume* volume)
|
|
{
|
|
Filesystem* fs = reinterpret_cast<Filesystem*>(volume->private_volume);
|
|
RPC::Server* server = fs->Server();
|
|
|
|
delete fs;
|
|
gRPCServerManager->Release(server);
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_put_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter)
|
|
{
|
|
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
|
delete inode;
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_read_stat(fs_volume* volume, fs_vnode* vnode, struct stat* stat)
|
|
{
|
|
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
|
return inode->Stat(stat);
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
|
|
{
|
|
uint64* cookie = new(std::nothrow) uint64[2];
|
|
if (cookie == NULL)
|
|
return B_NO_MEMORY;
|
|
*_cookie = cookie;
|
|
|
|
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
|
status_t result = inode->OpenDir(cookie);
|
|
if (result != B_OK)
|
|
delete cookie;
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_close_dir(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
|
{
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_free_dir_cookie(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
|
{
|
|
delete[] reinterpret_cast<uint64*>(cookie);
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_read_dir(fs_volume* volume, fs_vnode* vnode, void* _cookie,
|
|
struct dirent* buffer, size_t bufferSize, uint32* _num)
|
|
{
|
|
uint64* cookie = reinterpret_cast<uint64*>(_cookie);
|
|
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
|
return inode->ReadDir(buffer, bufferSize, _num, cookie);
|
|
}
|
|
|
|
|
|
status_t
|
|
nfs4_init()
|
|
{
|
|
dprintf("NFS4 Init\n");
|
|
|
|
status_t result = Connection::Init();
|
|
if (result != B_OK)
|
|
return result;
|
|
|
|
gRPCServerManager = new(std::nothrow) RPC::ServerManager;
|
|
if (gRPCServerManager == NULL)
|
|
return B_NO_MEMORY;
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
status_t
|
|
nfs4_uninit()
|
|
{
|
|
dprintf("NFS4 Uninit\n");
|
|
|
|
delete gRPCServerManager;
|
|
|
|
status_t result = Connection::CleanUp();
|
|
if (result != B_OK)
|
|
return result;
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
static status_t
|
|
nfs4_std_ops(int32 op, ...)
|
|
{
|
|
switch (op) {
|
|
case B_MODULE_INIT:
|
|
return nfs4_init();
|
|
case B_MODULE_UNINIT:
|
|
return nfs4_uninit();
|
|
default:
|
|
return B_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
fs_volume_ops gNFSv4VolumeOps = {
|
|
&nfs4_unmount
|
|
};
|
|
|
|
fs_vnode_ops gNFSv4VnodeOps = {
|
|
NULL, // lookup()
|
|
NULL, // get_vnode_name()
|
|
nfs4_put_vnode,
|
|
NULL, // remove_vnode()
|
|
|
|
/* VM file access */
|
|
NULL, // can_page()
|
|
NULL, // read_pages()
|
|
NULL, // write_pages()
|
|
|
|
NULL, // io()
|
|
NULL, // cancel_io()
|
|
|
|
NULL, // get_file_map()
|
|
|
|
NULL, // ioctl()
|
|
NULL,
|
|
NULL, // fs_select()
|
|
NULL, // fs_deselect()
|
|
NULL, // fsync()
|
|
|
|
NULL, // read_link()
|
|
NULL, // create_symlink()
|
|
|
|
NULL, // link()
|
|
NULL, // unlink()
|
|
NULL, // rename()
|
|
|
|
NULL, // access()
|
|
nfs4_read_stat,
|
|
NULL, // write_stat()
|
|
NULL, // fs_preallocate()
|
|
|
|
/* file operations */
|
|
NULL, // create()
|
|
NULL, // open()
|
|
NULL, // close()
|
|
NULL, // free_cookie()
|
|
NULL, // read()
|
|
NULL, // write,
|
|
|
|
/* directory operations */
|
|
NULL, // create_dir()
|
|
NULL, // remove_dir()
|
|
nfs4_open_dir,
|
|
nfs4_close_dir,
|
|
nfs4_free_dir_cookie,
|
|
nfs4_read_dir,
|
|
NULL, // rewind_dir,
|
|
};
|
|
|
|
static file_system_module_info sNFSv4ModuleInfo = {
|
|
{
|
|
"file_systems/nfs4" B_CURRENT_FS_API_VERSION,
|
|
0,
|
|
nfs4_std_ops,
|
|
},
|
|
|
|
"nfs4", // short_name
|
|
"Network File System version 4", // pretty_name
|
|
|
|
// DDM flags
|
|
0,
|
|
|
|
// scanning
|
|
NULL, // identify_partition()
|
|
NULL, // scan_partition()
|
|
NULL, // free_identify_partition_cookie()
|
|
NULL, // free_partition_content_cookie()
|
|
|
|
nfs4_mount,
|
|
};
|
|
|
|
module_info* modules[] = {
|
|
(module_info* )&sNFSv4ModuleInfo,
|
|
NULL,
|
|
};
|
|
|