189 lines
5.3 KiB
C++
189 lines
5.3 KiB
C++
/*
|
|
* Copyright (c) 2011-2017 Jonas 'Sortie' Termansen.
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* disk/node.cpp
|
|
* Inode adapter for harddisks.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <errno.h>
|
|
#include <inttypes.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <sortix/stat.h>
|
|
|
|
#include <sortix/kernel/harddisk.h>
|
|
#include <sortix/kernel/inode.h>
|
|
#include <sortix/kernel/kthread.h>
|
|
#include <sortix/kernel/log.h>
|
|
|
|
#include "node.h"
|
|
|
|
namespace Sortix {
|
|
|
|
PortNode::PortNode(Harddisk* harddisk, uid_t owner, gid_t group, mode_t mode,
|
|
dev_t dev, ino_t /*ino*/)
|
|
{
|
|
this->harddisk = harddisk;
|
|
inode_type = INODE_TYPE_FILE;
|
|
this->dev = dev;
|
|
this->ino = (ino_t) this;
|
|
this->stat_uid = owner;
|
|
this->stat_gid = group;
|
|
this->type = S_IFBLK;
|
|
this->stat_size = harddisk->GetSize();
|
|
this->stat_mode = (mode & S_SETABLE) | this->type;
|
|
this->stat_blksize = harddisk->GetBlockSize();
|
|
this->stat_blocks = harddisk->GetBlockCount();
|
|
}
|
|
|
|
PortNode::~PortNode()
|
|
{
|
|
// TODO: Ownership of `port'.
|
|
}
|
|
|
|
int PortNode::sync(ioctx_t* ctx)
|
|
{
|
|
return harddisk->sync(ctx);
|
|
}
|
|
|
|
int PortNode::truncate(ioctx_t* /*ctx*/, off_t length)
|
|
{
|
|
if ( length != harddisk->GetSize() )
|
|
return errno = EPERM, -1;
|
|
return 0;
|
|
}
|
|
|
|
off_t PortNode::lseek(ioctx_t* /*ctx*/, off_t offset, int whence)
|
|
{
|
|
if ( whence == SEEK_END && offset == 0 )
|
|
return (off_t) harddisk->GetSize();
|
|
return errno = EINVAL, -1;
|
|
}
|
|
|
|
ssize_t PortNode::pread(ioctx_t* ctx, uint8_t* buf, size_t count, off_t off)
|
|
{
|
|
return harddisk->pread(ctx, (unsigned char*) buf, count, off);
|
|
}
|
|
|
|
ssize_t PortNode::pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count,
|
|
off_t off)
|
|
{
|
|
return harddisk->pwrite(ctx, (const unsigned char*) buf, count, off);
|
|
}
|
|
|
|
ssize_t PortNode::tcgetblob(ioctx_t* ctx, const char* name, void* buffer,
|
|
size_t count)
|
|
{
|
|
const void* result_pointer = NULL;
|
|
size_t result_size = 0;
|
|
char string[sizeof(uintmax_t) * 3];
|
|
static const char index[] = "harddisk-driver\0"
|
|
"harddisk-model\0"
|
|
"harddisk-serial\0"
|
|
"harddisk-revision\0"
|
|
"harddisk-size\0"
|
|
"harddisk-block-count\0"
|
|
"harddisk-block-size\0"
|
|
"harddisk-cylinders\0"
|
|
"harddisk-heads\0"
|
|
"harddisk-sectors\0"
|
|
"harddisk-ata-identify\0";
|
|
|
|
if ( !name )
|
|
{
|
|
result_pointer = index;
|
|
result_size = sizeof(index) - 1;
|
|
}
|
|
else if ( !strcmp(name, "harddisk-driver") )
|
|
{
|
|
result_pointer = harddisk->GetDriver();
|
|
result_size = strlen((const char*) result_pointer);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-model") )
|
|
{
|
|
result_pointer = harddisk->GetModel();
|
|
result_size = strlen((const char*) result_pointer);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-serial") )
|
|
{
|
|
result_pointer = harddisk->GetSerial();
|
|
result_size = strlen((const char*) result_pointer);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-revision") )
|
|
{
|
|
result_pointer = harddisk->GetRevision();
|
|
result_size = strlen((const char*) result_pointer);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-size") )
|
|
{
|
|
snprintf(string, sizeof(string), "%" PRIiOFF, harddisk->GetSize());
|
|
result_pointer = string;
|
|
result_size = strlen(string);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-block-count") )
|
|
{
|
|
snprintf(string, sizeof(string), "%" PRIiBLKCNT, harddisk->GetBlockCount());
|
|
result_pointer = string;
|
|
result_size = strlen(string);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-block-size") )
|
|
{
|
|
snprintf(string, sizeof(string), "%" PRIiBLKSIZE, harddisk->GetBlockSize());
|
|
result_pointer = string;
|
|
result_size = strlen(string);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-cylinders") )
|
|
{
|
|
snprintf(string, sizeof(string), "%" PRIu16, harddisk->GetCylinderCount());
|
|
result_pointer = string;
|
|
result_size = strlen(string);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-heads") )
|
|
{
|
|
snprintf(string, sizeof(string), "%" PRIu16, harddisk->GetHeadCount());
|
|
result_pointer = string;
|
|
result_size = strlen(string);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-sectors") )
|
|
{
|
|
snprintf(string, sizeof(string), "%" PRIu16, harddisk->GetSectorCount());
|
|
result_pointer = string;
|
|
result_size = strlen(string);
|
|
}
|
|
else if ( !strcmp(name, "harddisk-ata-identify") )
|
|
{
|
|
if ( !(result_pointer = harddisk->GetATAIdentify(&result_size)) )
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
return errno = ENOENT, -1;
|
|
}
|
|
|
|
if ( SSIZE_MAX < result_size )
|
|
return errno = EOVERFLOW, -1;
|
|
if ( buffer && count < result_size )
|
|
return errno = ERANGE, -1;
|
|
if ( buffer && !ctx->copy_to_dest(buffer, result_pointer, result_size) )
|
|
return -1;
|
|
return (ssize_t) result_size;
|
|
}
|
|
|
|
} // namespace Sortix
|