-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrdwt.c
117 lines (100 loc) · 3.46 KB
/
rdwt.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
#include "stdio.h"
#include "filesys.h"
unsigned int read(unsigned int user_id, int fd_1, char *buf, unsigned int size)
{
unsigned long off;
int block, block_off, i, j, k;
struct inode *inode;
char temp_buf[size];
char *temp;
temp = temp_buf;
for (j = 0; j < USERNUM; j++)
if (user[j].u_uid == user_id)
{
k = j;
break;
}
inode = sys_ofile[user[k].u_ofile[fd_1]].f_inode;
if (!(sys_ofile[user[k].u_ofile[fd_1]].f_flag & FREAD))
{
printf("\n the file is not opened for read\n");
return 0;
}
off = sys_ofile[user[k].u_ofile[fd_1]].f_off;
if ((off + size) > inode->di_size)
size = inode->di_size - off;
block_off = off % BLOCKSIZ;
block = off / BLOCKSIZ;
if (block_off + size < BLOCKSIZ)
{
fseek(fd, DATASTART + inode->di_addr[block] * BLOCKSIZ + block_off, SEEK_SET);
fread(buf, 1, size, fd);
sys_ofile[user[k].u_ofile[fd_1]].f_off += size; //记录文件读写指针现在的偏移
return size;
}
fseek(fd, DATASTART + inode->di_addr[block] * BLOCKSIZ + block_off, SEEK_SET);
fread(temp, 1, BLOCKSIZ - block_off, fd);
temp += BLOCKSIZ - block_off;
for (i = 0; i < (size - (BLOCKSIZ - block_off)) / BLOCKSIZ; i++)
{
fseek(fd, DATASTART + inode->di_addr[block + 1 + i] * BLOCKSIZ, SEEK_SET);
fread(temp, 1, BLOCKSIZ, fd);
temp += BLOCKSIZ;
}
block_off = (size - block_off) % BLOCKSIZ; //读最后一块
block = inode->di_addr[size / BLOCKSIZ + 1];
fseek(fd, DATASTART + block * BLOCKSIZ, SEEK_SET);
fread(temp, 1, block_off, fd);
sys_ofile[user[k].u_ofile[fd_1]].f_off += size;
memcpy(buf, temp_buf, size);
return size;
}
unsigned int write(unsigned int user_id, int fd_2, char *buf, unsigned int size) /*write*/
{
unsigned long off;
int block, block_off;
int i, j, k;
struct inode *inode;
char *temp_buf;
for (j = 0; j < USERNUM; j++)
if (user[j].u_uid == user_id)
{
k = j;
break;
}
inode = sys_ofile[user[k].u_ofile[fd_2]].f_inode;
if ((!(sys_ofile[user[k].u_ofile[fd_2]].f_flag & FWRITE)) && (!(sys_ofile[user[k].u_ofile[fd_2]].f_flag & (FAPPEND))))
{
printf("\n the file is not opened for write or append\n");
return 0;
}
temp_buf = buf;
off = sys_ofile[user[k].u_ofile[fd_2]].f_off;
block_off = off % BLOCKSIZ; //块内写入的起始位置
block = off / BLOCKSIZ; //要写入的文件内的块序号
if (block_off + size < BLOCKSIZ) //写入后不超过该块的长度
{
fseek(fd, DATASTART + inode->di_addr[block] * BLOCKSIZ + block_off, SEEK_SET);
fwrite(buf, 1, size, fd);
inode->di_size = sys_ofile[user[k].u_ofile[fd_2]].f_off += size; //记录文件大小
return size;
}
//写入后超过该块的长度,写入下一块
fseek(fd, DATASTART + inode->di_addr[block] * BLOCKSIZ + block_off, SEEK_SET);
fwrite(temp_buf, 1, BLOCKSIZ - block_off, fd); //填满该块
temp_buf += BLOCKSIZ - block_off;
for (i = 0; i < (size - (BLOCKSIZ - block_off)) / BLOCKSIZ; i++)
{
inode->di_addr[block + 1 + i] = balloc();
fseek(fd, DATASTART + inode->di_addr[block + 1 + i] * BLOCKSIZ, SEEK_SET);
fwrite(temp_buf, 1, BLOCKSIZ, fd); //写入下一空闲块
temp_buf += BLOCKSIZ;
}
block_off = (size - (temp_buf - buf)) % BLOCKSIZ;
inode->di_addr[block + size / BLOCKSIZ] = balloc();
block = inode->di_addr[block + size / BLOCKSIZ];
fseek(fd, DATASTART + block * BLOCKSIZ, SEEK_SET);
fwrite(temp_buf, 1, block_off, fd); //写入最后一块
inode->di_size = sys_ofile[user[k].u_ofile[fd_2]].f_off += size; //记录文件大小
return size;
}