forked from wesedens/fs-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
io.c
145 lines (112 loc) · 3.44 KB
/
io.c
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
/*
This file contains some low level wrapper routines that manage IO for
the file system as well as handle reading and writing the super block.
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO ([email protected]).
Dominic Giampaolo
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include "myfs.h"
ssize_t
read_blocks(myfs_info *myfs, fs_off_t block_num, void *block, size_t nblocks)
{
ssize_t ret;
/* printf("R 0x%x 0x%x\n", block_num, nblocks); */
if (block_num >= myfs->dsb.num_blocks) {
printf("Yikes! tried to read block %ld but there are only %ld\n",
block_num, myfs->dsb.num_blocks);
return -1;
}
if (block_num < myfs->dsb.num_blocks &&
block_num + nblocks > myfs->dsb.num_blocks) {
printf("Yikes! tried to read %d blocks starting at %ld but only have "
"%ld\n", nblocks, block_num, myfs->dsb.num_blocks);
return -1;
}
ret = cached_read(myfs->fd,
block_num,
block,
nblocks,
myfs->dsb.block_size);
if (ret == 0)
return nblocks;
else
return -1;
}
ssize_t
write_blocks(myfs_info *myfs, fs_off_t block_num, const void *block, size_t nblocks)
{
ssize_t ret;
/* printf("W 0x%x 0x%x\n", block_num, nblocks); */
if (myfs->flags & FS_READ_ONLY) {
printf("write_super_block called on a read-only device! (myfs 0x%x)\n",
myfs);
return -1;
}
if (block_num >= myfs->dsb.num_blocks) {
printf("Yikes! tried to write block %ld but there are only %ld\n",
block_num, myfs->dsb.num_blocks);
return -1;
}
if (block_num < myfs->dsb.num_blocks &&
block_num + nblocks > myfs->dsb.num_blocks) {
printf("Yikes! tried to write %d blocks starting at %ld but only "
"have %ld\n", nblocks, block_num, myfs->dsb.num_blocks);
return -1;
}
ret = cached_write(myfs->fd,
block_num,
block,
nblocks,
myfs->dsb.block_size);
if (ret == 0)
return nblocks;
else
return -1;
return ret;
}
int
read_super_block(myfs_info *myfs)
{
char *buff;
int block_size;
block_size = get_device_block_size(myfs->fd);
if (block_size < 0)
return EINVAL;
myfs->dev_block_size = block_size;
if (block_size < 1024)
block_size = 1024;
buff = (char *)malloc(block_size);
if (buff == NULL)
return ENOMEM;
if (read_pos(myfs->fd, 0, buff, block_size) != block_size) {
free(buff);
return EINVAL;
}
memcpy(&myfs->dsb, buff, sizeof(myfs_super_block));
free(buff);
myfs->dev_block_size = block_size;
myfs->dev_block_conversion = myfs->dsb.block_size / block_size;
return 0;
}
int
write_super_block(myfs_info *myfs)
{
ssize_t amt;
myfs->dsb.flags = MYFS_CLEAN; /* now it's clean! */
amt = write_pos(myfs->fd, 0, &myfs->dsb, myfs->dsb.block_size);
if (amt == myfs->dsb.block_size)
return 0;
else
return -1;
}