Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * drive disks
3
 * used to be just scsi disks, and issued scsi commands directly to the host
4
 * adapter, but now it just does normal i/o.
5
 */
6
#include "all.h"
7
 
8
enum { Sectorsz = 512, };		/* usual disk sector size */
9
 
10
typedef	struct	Wren	Wren;
11
struct	Wren
12
{
13
	long	block;			/* size of a block -- from config */
14
	Devsize	nblock;			/* number of blocks -- from config */
15
	long	mult;			/* multiplier to get physical blocks */
16
	Devsize	max;			/* number of logical blocks */
17
 
18
//	char	*sddir;			/* /dev/sdXX name */
19
};
20
 
21
char *
22
dataof(char *file)
23
{
24
	char *datanm;
25
	Dir *dir;
26
 
27
	dir = dirstat(file);
28
	if (dir != nil && dir->mode & DMDIR)
29
		datanm = smprint("%s/data", file);
30
	else
31
		datanm = strdup(file);
32
	free(dir);
33
	return datanm;
34
}
35
 
36
void
37
wreninit(Device *d)
38
{
39
	Wren *dr;
40
	Dir *dir;
41
 
42
	if(d->private)
43
		return;
44
	d->private = dr = malloc(sizeof(Wren));
45
 
46
	if (d->wren.file)
47
		d->wren.sddata = dataof(d->wren.file);
48
	else {
49
		d->wren.sddir = sdof(d);
50
		d->wren.sddata = smprint("%s/data", d->wren.sddir);
51
	}
52
 
53
	assert(d->wren.fd <= 0);
54
	d->wren.fd = open(d->wren.sddata, ORDWR);
55
	if (d->wren.fd < 0)
56
		panic("wreninit: can't open %s for %Z: %r", d->wren.sddata, d);
57
 
58
	dr->block = inqsize(d->wren.sddata);
59
	if(dr->block <= 0 || dr->block >= 16*1024) {
60
		print("\twreninit %Z block size %ld, setting to %d\n",
61
			d, dr->block, Sectorsz);
62
		dr->block = Sectorsz;
63
	}
64
 
65
	dir = dirfstat(d->wren.fd);
66
	dr->nblock = dir->length / dr->block;
67
	free(dir);
68
 
69
	dr->mult = (RBUFSIZE + dr->block - 1) / dr->block;
70
	dr->max = (dr->nblock + 1) / dr->mult;
71
	print("\tdisk drive %Z: %,lld %ld-byte sectors, ",
72
		d, (Wideoff)dr->nblock, dr->block);
73
	print("%,lld %d-byte blocks\n", (Wideoff)dr->max, RBUFSIZE);
74
	print("\t\t%ld multiplier\n", dr->mult);
75
}
76
 
77
Devsize
78
wrensize(Device *d)
79
{
80
	return ((Wren *)d->private)->max;
81
}
82
 
83
int
84
wrenread(Device *d, Off b, void *c)
85
{
86
	int r = 0;
87
	Wren *dr = d->private;
88
 
89
	if (dr == nil)
90
		panic("wrenread: no drive (%Z) block %lld", d, (Wideoff)b);
91
	if(b >= dr->max) {
92
		print("wrenread: block out of range %Z(%lld)\n", d, (Wideoff)b);
93
		r = 0x040;
94
	} else if (pread(d->wren.fd, c, RBUFSIZE, (vlong)b*RBUFSIZE) != RBUFSIZE) {
95
		print("wrenread: error on %Z(%lld): %r\n", d, (Wideoff)b);
96
		cons.nwrenre++;
97
		r = 1;
98
	}
99
	return r;
100
}
101
 
102
int
103
wrenwrite(Device *d, Off b, void *c)
104
{
105
	int r = 0;
106
	Wren *dr = d->private;
107
 
108
	if (dr == nil)
109
		panic("wrenwrite: no drive (%Z) block %lld", d, (Wideoff)b);
110
	if(b >= dr->max) {
111
		print("wrenwrite: block out of range %Z(%lld)\n",
112
			d, (Wideoff)b);
113
		r = 0x040;
114
	} else if (pwrite(d->wren.fd, c, RBUFSIZE, (vlong)b*RBUFSIZE) != RBUFSIZE) {
115
		print("wrenwrite: error on %Z(%lld): %r\n", d, (Wideoff)b);
116
		cons.nwrenwe++;
117
		r = 1;
118
	}
119
	return r;
120
}