File: offset.c

package info (click to toggle)
palo 2.27
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 512 kB
  • sloc: ansic: 6,304; asm: 218; makefile: 196; sh: 61
file content (70 lines) | stat: -rw-r--r-- 1,833 bytes parent folder | download | duplicates (3)
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
/* 
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com
 */
#include "bootloader.h"

/* this is the stupidest "file system" imaginable -- it applies an */
/* offset to the seek pointers and optionally checks against a length */

struct offsets {
    int fd;
    __u64 start;
    __u64 length;
} ofd [MAX_FD];

static int offset_read(int fd, char *buf, unsigned count, __u64 devaddr)
{
    struct offsets *o = &ofd[fd];

    if (Debug) printf("offset_read(%d, 0x%p, %d, %lld)\r\n",
		    fd, buf, count, devaddr);

    /* abort early if we reach firmware limit */
    if (disk_2gb_limit && ((devaddr + count) >> 31)) {
	printf("offset_read(%lld): block not reachable via firmware call\r\n",
		devaddr + count);
	return -1;
    }

    /* truncate 'count' according to max device/file size */
    if (o->length > 0 && devaddr < o->length && devaddr + count > o->length)
	count = o->length - devaddr;
    else if (o->length > 0 && devaddr + count > o->length)
    {
	printf("offset_read(%d, 0x%p, %d, %lld) can't seek past %lld\r\n",
			fd, buf, count, devaddr, o->length);
	return -1;
    }

    return seekread(o->fd, buf, count, devaddr + o->start);
}

static void offset_describe(int fd, int *bufalign,
				int *blocksize)
{
    describe(ofd[fd].fd, bufalign, blocksize);
}

/* returns true if OK */
int offset_open(int otherfd, __u64 offset, __u64 length)
{
    int fd = fileio_open(offset_describe, offset_read);

    if (fd >= 0)
    {
	struct offsets *o = &ofd[fd];

	o->fd = otherfd;
	o->start = offset;
	o->length = length;
    }

     if (Debug) printf("offset_open(%d, %lld, %lld) = %d\n",
	otherfd, offset, length, fd);

    return fd;
}