-
Notifications
You must be signed in to change notification settings - Fork 1
/
device.h
170 lines (142 loc) · 3.8 KB
/
device.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* device.h -*- C++ -*- Copyright (c) 2006 Joshua Oreman
* The rawpod tools, of which this file is a part, are licensed
* under the GNU General Public License. See the file COPYING in the
* source distribution for details.
*/
#ifndef _DEVICE_H_
#define _DEVICE_H_
#include "vfs.h"
#include <dirent.h>
#define OPEN_READ 1
#define OPEN_WRITE 2
#define OPEN_CREATE 4
#define OPEN_DEV 8
#ifdef WIN32
#include <windows.h>
#ifndef SEEK_SET
#define SEEK_SET FILE_BEGIN
#define SEEK_CUR FILE_CURRENT
#define SEEK_END FILE_END
#endif
#else
#include <unistd.h>
#endif
class LocalDir : public VFS::Dir
{
public:
LocalDir (const char *path)
: _dp (opendir (path))
{}
~LocalDir() { if (_dp) closedir (_dp); }
int readdir (struct VFS::dirent *de);
int close() { if (_dp) closedir (_dp); _dp = 0; return 0; }
#ifdef WIN32
int error() { if (!_dp) return 1; return 0; }
#else
int error() { if (!_dp) return errno; return 0; }
#endif
private:
DIR *_dp;
};
class LocalFile : public VFS::File
{
public:
LocalFile (const char *path, int flags);
~LocalFile();
int read (void *buf, int len);
int write (const void *buf, int len);
s64 lseek (s64 off, int whence);
int ioctl (unsigned long code, void *dataPtr, size_t dataSize);
int error();
int close();
#ifndef WIN32
int fileno() { return _fd; }
#endif
private:
#ifdef WIN32
HANDLE _fh;
#else
int _fd;
#endif
};
class BlockCache
{
public:
static void cleanup();
static void disable() { _disabled = true; }
static void enable() { _disabled = false; }
static bool enabled() { return !_disabled; }
static void setCommitInterval (int secs) { _comint = secs; }
int dirtySectors();
int totalSectors() { return _nsec; }
int isDirty (int idx);
int flushIndex (int idx);
int flush() { return flushOlderThan (-1); }
void invalidate();
protected:
BlockCache (int nsec = 2048, int ssize = 512);
virtual ~BlockCache();
virtual int doRead (void *buf, u64 sec);
virtual int doWrite (const void *buf, u64 sec);
virtual int doRawRead (void *buf, u64 sec) = 0;
virtual int doRawWrite (const void *buf, u64 sec) = 0;
private:
int flushOlderThan (s64 us);
s64 getTimeval();
int _nsec;
int _ssize, _log_ssize;
char *_cache;
u64 *_sectors;
u64 *_atimes, *_mtimes;
BlockCache *_cache_next;
static BlockCache *_cache_head;
static bool _disabled;
static int _comint;
};
class LocalRawDevice : public VFS::BlockDevice, public BlockCache
{
public:
LocalRawDevice (int n, bool writable = true);
~LocalRawDevice();
int error() {
if (_valid < 0) return _valid;
return 0;
}
#ifdef linux
int fileno() { return _f->fileno(); }
#endif
static void setOverride (const char *filename) {
_override = filename;
}
static bool overridden() { return (_override != 0); }
static void setCOWFile (const char *filename) {
_cowfile = filename;
}
static void setCachedSectors (int num) {
_cachesize = num;
}
protected:
virtual int doRead (void *buf, u64 sec) { return BlockCache::doRead (buf, sec); }
virtual int doWrite (const void *buf, u64 sec) { return BlockCache::doWrite (buf, sec); }
virtual int doRawRead (void *buf, u64 sec);
virtual int doRawWrite (const void *buf, u64 sec);
private:
LocalFile *_f, *_wf;
int _valid;
static const char *_override;
static const char *_cowfile;
static int _cachesize;
};
class PartitionDevice : public VFS::BlockDevice
{
public:
PartitionDevice (VFS::Device *dev, u64 startsec, u64 nsecs);
protected:
virtual int doRead (void *buf, u64 sec);
virtual int doWrite (const void *buf, u64 sec);
private:
VFS::Device *_dev;
u64 _start;
u64 _length;
};
#endif