xref: /minix3/minix/fs/isofs/utility.c (revision b80da2a01d0bb632707b7b4e974aa32eaebbcc6f)
1 #include "inc.h"
2 
3 static struct dir_extent dir_extents[NR_DIR_EXTENT_RECORDS];
4 
5 struct dir_extent* alloc_extent(void)
6 {
7 	/* Return a free extent from the pool. */
8 	int i;
9 	struct dir_extent *extent;
10 
11 	for (i = 0; i < NR_DIR_EXTENT_RECORDS; i++) {
12 		extent = &dir_extents[i];
13 
14 		if (extent->in_use == 0) {
15 			memset(extent, 0, sizeof(*extent));
16 			extent->in_use = 1;
17 
18 			return extent;
19 		}
20 	}
21 
22 	panic("No free extents in cache");
23 }
24 
25 void free_extent(struct dir_extent *e)
26 {
27 	if (e == NULL)
28 		return;
29 
30 	if (e->in_use == 0)
31 		panic("Trying to free unused extent");
32 
33 	free_extent(e->next);
34 	e->in_use = 0;
35 }
36 
37 struct buf* read_extent_block(struct dir_extent *e, size_t block)
38 {
39 	struct buf *bp;
40 	size_t block_id;
41 	int r;
42 
43 	block_id = get_extent_absolute_block_id(e, block);
44 
45 	if (block_id == 0 || block_id >= v_pri.volume_space_size_l)
46 		return NULL;
47 
48 	/* Not all callers deal well with failure, so panic on I/O error. */
49 	if ((r = lmfs_get_block(&bp, fs_dev, block_id, NORMAL)) != OK)
50 		panic("ISOFS: error getting block (%llu,%zu): %d",
51 		    fs_dev, block_id, r);
52 
53 	return bp;
54 }
55 
56 size_t get_extent_absolute_block_id(struct dir_extent *e, size_t block)
57 {
58 	size_t extent_offset = 0;
59 
60 	if (e == NULL)
61 		return 0;
62 
63 	/* Retrieve the extent on which the block lies. */
64 	while(block > extent_offset + e->length) {
65 		if (e->next == NULL)
66 			return 0;
67 
68 		extent_offset += e->length;
69 		e = e->next;
70 	}
71 
72 	return e->location + block - extent_offset;
73 }
74 
75 time_t date7_to_time_t(const u8_t *date)
76 {
77 	/* This function converts from the ISO 9660 7-byte time format to a
78 	 * time_t.
79 	 */
80 	struct tm ltime;
81 	signed char time_zone = (signed char)date[6];
82 
83 	ltime.tm_year = date[0];
84 	ltime.tm_mon = date[1] - 1;
85 	ltime.tm_mday = date[2];
86 	ltime.tm_hour = date[3];
87 	ltime.tm_min = date[4];
88 	ltime.tm_sec = date[5];
89 	ltime.tm_isdst = 0;
90 
91 	/* Offset from Greenwich Mean Time */
92 	if (time_zone >= -52 && time_zone <= 52)
93 		ltime.tm_hour += time_zone;
94 
95 	return mktime(&ltime);
96 }
97