SimpleFS
A Simple File Sytem implementation including Disk and Shell Layers
disk.cpp
Go to the documentation of this file.
1 
9 #include "sfs/disk.h"
10 
11 #include <stdexcept>
12 
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <unistd.h>
17 
18 void Disk::open(const char *path, size_t nblocks) {
24  FileDescriptor = ::open(path, O_RDWR|O_CREAT, 0600);
25 
27  if (FileDescriptor < 0) {
28  char what[BUFSIZ];
29  snprintf(what, BUFSIZ, "Unable to open %s: %s", path, strerror(errno));
30  throw std::runtime_error(what);
31  }
32 
34  if (ftruncate(FileDescriptor, nblocks*BLOCK_SIZE) < 0) {
35  char what[BUFSIZ];
36  snprintf(what, BUFSIZ, "Unable to open %s: %s", path, strerror(errno));
37  throw std::runtime_error(what);
38  }
39 
41  Blocks = nblocks;
42  Reads = 0;
43  Writes = 0;
44 }
45 
52  if (FileDescriptor > 0) {
54  printf("%lu disk block reads\n", Reads);
55  printf("%lu disk block writes\n", Writes);
56  close(FileDescriptor);
57  FileDescriptor = 0;
58  }
59 }
60 
61 void Disk::sanity_check(int blocknum, char *data) {
66  char what[BUFSIZ];
69  if (blocknum < 0) {
70  snprintf(what, BUFSIZ, "blocknum (%d) is negative!", blocknum);
71  throw std::invalid_argument(what);
72  }
73 
74  if (blocknum >= (int)Blocks) {
75  snprintf(what, BUFSIZ, "blocknum (%d) is too big!", blocknum);
76  throw std::invalid_argument(what);
77  }
78 
80  if (data == NULL) {
81  snprintf(what, BUFSIZ, "null data pointer!");
82  throw std::invalid_argument(what);
83  }
84 }
85 
86 void Disk::read(int blocknum, char *data) {
92  sanity_check(blocknum, data);
93 
95  if (lseek(FileDescriptor, blocknum*BLOCK_SIZE, SEEK_SET) < 0) {
96  char what[BUFSIZ];
97  snprintf(what, BUFSIZ, "Unable to lseek %d: %s", blocknum, strerror(errno));
98  throw std::runtime_error(what);
99  }
100 
102  if (::read(FileDescriptor, data, BLOCK_SIZE) != BLOCK_SIZE) {
103  char what[BUFSIZ];
104  snprintf(what, BUFSIZ, "Unable to read %d: %s", blocknum, strerror(errno));
105  throw std::runtime_error(what);
106  }
107 
109  Reads++;
110 }
111 
112 void Disk::write(int blocknum, char *data) {
118  sanity_check(blocknum, data);
119 
121  if (lseek(FileDescriptor, blocknum*BLOCK_SIZE, SEEK_SET) < 0) {
122  char what[BUFSIZ];
123  snprintf(what, BUFSIZ, "Unable to lseek %d: %s", blocknum, strerror(errno));
124  throw std::runtime_error(what);
125  }
126 
128  if (::write(FileDescriptor, data, BLOCK_SIZE) != BLOCK_SIZE) {
129  char what[BUFSIZ];
130  snprintf(what, BUFSIZ, "Unable to write %d: %s", blocknum, strerror(errno));
131  throw std::runtime_error(what);
132  }
133 
135  Writes++;
136 }
Disk::sanity_check
void sanity_check(int blocknum, char *data)
check if the block is within valid range
Definition: disk.cpp:61
Disk::read
void read(int blocknum, char *data)
read from disk
Definition: disk.cpp:86
Disk::Reads
size_t Reads
Definition: disk.h:22
disk.h
Contains the implementation of disk layer to support File System.
Disk::open
void open(const char *path, size_t nblocks)
opens the disk image
Definition: disk.cpp:18
Disk::Writes
size_t Writes
Definition: disk.h:23
Disk::~Disk
~Disk()
destructor of Disk class
Definition: disk.cpp:46
Disk::write
void write(int blocknum, char *data)
write to disk
Definition: disk.cpp:112
Disk::Blocks
size_t Blocks
Definition: disk.h:21