mirror of
https://github.com/ksherlock/profuse.git
synced 2025-08-09 12:25:13 +00:00
git-svn-id: https://profuse.googlecode.com/svn/branches/v2@70 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
174
RawDevice.cpp
Normal file
174
RawDevice.cpp
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
|
||||||
|
#include <ioctl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <sys/disk.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __LINUX__
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SUN__
|
||||||
|
#include <sys/dkio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "RawDevice.h"
|
||||||
|
#include "auto.h"
|
||||||
|
#include "Exception.h"
|
||||||
|
|
||||||
|
using Namespace ProFUSE;
|
||||||
|
|
||||||
|
#ifdef __SUN__
|
||||||
|
void RawDevice::devSize(int fd)
|
||||||
|
{
|
||||||
|
#undef __METHOD__
|
||||||
|
#define __METHOD__ "RawDevice::devSize"
|
||||||
|
|
||||||
|
struct dk_minfo minfo;
|
||||||
|
|
||||||
|
if (::ioctl(fd, DKIOCGMEDIAINFO, &minfo) < 0)
|
||||||
|
throw Exception(__METHOD__ ": Unable to determine device size.", errno);
|
||||||
|
|
||||||
|
_size = minfo.dki_lbsize * minfo.dki_capacity;
|
||||||
|
_blockSize = 512; // not really, but whatever.
|
||||||
|
_blocks = _size / 512;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
void RawDevice::devSize(int fd)
|
||||||
|
{
|
||||||
|
#undef __METHOD__
|
||||||
|
#define __METHOD__ "RawDevice::devSize"
|
||||||
|
|
||||||
|
uint32_t blockSize; // 32 bit
|
||||||
|
uint64_t blockCount; // 64 bit
|
||||||
|
|
||||||
|
if (::ioctl(fd, DKIOCGETBLOCKSIZE, &blockSize) < 0)
|
||||||
|
throw Exception(__METHOD__ ": Unable to determine block size.", errno);
|
||||||
|
|
||||||
|
|
||||||
|
if (::ioctl(fd, DKIOCGETBLOCKCOUNT, &blockCount) < 0)
|
||||||
|
throw Exception(__METHOD__ ": Unable to determine block count.", errno);
|
||||||
|
|
||||||
|
_blockSize = blockSize;
|
||||||
|
_size = _blockSize * _blockCount;
|
||||||
|
_blocks = _size / 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __LINUX__
|
||||||
|
|
||||||
|
void RawDevice::devSize(int fd)
|
||||||
|
{
|
||||||
|
#undef __METHOD__
|
||||||
|
#define __METHOD__ "RawDevice::devSize"
|
||||||
|
|
||||||
|
int blocks;
|
||||||
|
|
||||||
|
if (::ioctl(fd, BLKGETSIZE, &blocks) < 0)
|
||||||
|
throw Exception(__METHOD__ ": Unable to determine device size.", errno);
|
||||||
|
|
||||||
|
_size = 512 * blocks;
|
||||||
|
_blockSize = 512; //
|
||||||
|
_blocks = blocks;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RawDevice::RawDevice(const char *name, bool readOnly) :
|
||||||
|
{
|
||||||
|
// open read-only, verify if device is readable, and then try to upgrade to read/write?
|
||||||
|
|
||||||
|
auto_fd fd(::open(name, readOnly ? O_RDONLY : O_RDWR));
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
throw Exception(__METHOD__ ": Unable to open device.", errno);
|
||||||
|
|
||||||
|
_fd = -1;
|
||||||
|
|
||||||
|
_readOnly = readOnly;
|
||||||
|
_size = 0;
|
||||||
|
_blocks = 0;
|
||||||
|
_blockSize = 0;
|
||||||
|
|
||||||
|
|
||||||
|
devSize(fd);
|
||||||
|
|
||||||
|
_fd = fd.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RawDevice::~RawDevice()
|
||||||
|
{
|
||||||
|
if (_fd >= 0) ::close(_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawDevice::read(unsigned block, void *bp)
|
||||||
|
{
|
||||||
|
#undef __METHOD__
|
||||||
|
#define __METHOD__ "RawDevice::read"
|
||||||
|
|
||||||
|
if (block >= _blocks) throw Exception(__METHOD__ ": Invalid block number.");
|
||||||
|
if (bp == 0) throw Exception(__METHOD__ ": Invalid address.");
|
||||||
|
|
||||||
|
// sun -- use pread
|
||||||
|
// apple - read full native block(s) ?
|
||||||
|
|
||||||
|
size_t ok = ::pread(_fd, bp, 512, block * 512);
|
||||||
|
|
||||||
|
// TODO -- EINTR?
|
||||||
|
if (ok != 512)
|
||||||
|
throw Exception(__METHOD__ : ": Error reading block.",
|
||||||
|
ok < 0 : errno, 0);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
void RawDevice::write(unsigned block, const void *bp)
|
||||||
|
{
|
||||||
|
#undef __METHOD__
|
||||||
|
#define __METHOD__ "RawDevice::write"
|
||||||
|
|
||||||
|
if (block > _blocks) throw Exception(__METHOD__ ": Invalid block number.");
|
||||||
|
|
||||||
|
if (_readOnly)
|
||||||
|
throw Exception(__METHOD__ ": File is readonly.");
|
||||||
|
|
||||||
|
|
||||||
|
size_t ok = ::pwrite(_fd, bp, 512, block * 512);
|
||||||
|
|
||||||
|
if (ok != 512)
|
||||||
|
throw Exception(__METHOD__ : ": Error writing block.",
|
||||||
|
ok < 0 : errno, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool RawDevice::readOnly()
|
||||||
|
{
|
||||||
|
return _readOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawDevice::sync()
|
||||||
|
{
|
||||||
|
#undef __METHOD__
|
||||||
|
#define __METHOD__ "RawDevice::sync"
|
||||||
|
|
||||||
|
if (_readOnly) return;
|
||||||
|
|
||||||
|
if (::fsync(_fd) < 0)
|
||||||
|
throw Exception(__METHOD__ ": msync error.", errno);
|
||||||
|
}
|
40
RawDevice.h
Normal file
40
RawDevice.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef __RAWDEVICE_H__
|
||||||
|
#define __RAWDEVICE_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "BlockDevice.h"
|
||||||
|
|
||||||
|
namespace ProFUSE {
|
||||||
|
|
||||||
|
// /dev/xxx
|
||||||
|
|
||||||
|
|
||||||
|
class RawDevice : BlockDevice {
|
||||||
|
public:
|
||||||
|
|
||||||
|
RawDevice(const char *name, bool readOnly);
|
||||||
|
|
||||||
|
virtual ~RawDevice();
|
||||||
|
|
||||||
|
virtual void read(unsigned block, void *bp);
|
||||||
|
virtual void write(unsigned block, const void *bp);
|
||||||
|
|
||||||
|
virtual bool readOnly();
|
||||||
|
virtual void sync();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void devSize(int fd);
|
||||||
|
|
||||||
|
int _fd;
|
||||||
|
bool _readOnly;
|
||||||
|
|
||||||
|
uint64_t _size;
|
||||||
|
unsigned _blocks;
|
||||||
|
|
||||||
|
unsigned _blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user