xref: /openbmc/linux/fs/hpfs/buffer.c (revision e4c0d0e2)
1 /*
2  *  linux/fs/hpfs/buffer.c
3  *
4  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5  *
6  *  general buffer i/o
7  */
8 #include <linux/sched.h>
9 #include <linux/slab.h>
10 #include "hpfs_fn.h"
11 
12 /* Map a sector into a buffer and return pointers to it and to the buffer. */
13 
14 void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp,
15 		 int ahead)
16 {
17 	struct buffer_head *bh;
18 
19 	hpfs_lock_assert(s);
20 
21 	cond_resched();
22 
23 	*bhp = bh = sb_bread(s, secno);
24 	if (bh != NULL)
25 		return bh->b_data;
26 	else {
27 		printk("HPFS: hpfs_map_sector: read error\n");
28 		return NULL;
29 	}
30 }
31 
32 /* Like hpfs_map_sector but don't read anything */
33 
34 void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp)
35 {
36 	struct buffer_head *bh;
37 	/*return hpfs_map_sector(s, secno, bhp, 0);*/
38 
39 	hpfs_lock_assert(s);
40 
41 	cond_resched();
42 
43 	if ((*bhp = bh = sb_getblk(s, secno)) != NULL) {
44 		if (!buffer_uptodate(bh)) wait_on_buffer(bh);
45 		set_buffer_uptodate(bh);
46 		return bh->b_data;
47 	} else {
48 		printk("HPFS: hpfs_get_sector: getblk failed\n");
49 		return NULL;
50 	}
51 }
52 
53 /* Map 4 sectors into a 4buffer and return pointers to it and to the buffer. */
54 
55 void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh,
56 		   int ahead)
57 {
58 	struct buffer_head *bh;
59 	char *data;
60 
61 	hpfs_lock_assert(s);
62 
63 	cond_resched();
64 
65 	if (secno & 3) {
66 		printk("HPFS: hpfs_map_4sectors: unaligned read\n");
67 		return NULL;
68 	}
69 
70 	qbh->data = data = kmalloc(2048, GFP_NOFS);
71 	if (!data) {
72 		printk("HPFS: hpfs_map_4sectors: out of memory\n");
73 		goto bail;
74 	}
75 
76 	qbh->bh[0] = bh = sb_bread(s, secno);
77 	if (!bh)
78 		goto bail0;
79 	memcpy(data, bh->b_data, 512);
80 
81 	qbh->bh[1] = bh = sb_bread(s, secno + 1);
82 	if (!bh)
83 		goto bail1;
84 	memcpy(data + 512, bh->b_data, 512);
85 
86 	qbh->bh[2] = bh = sb_bread(s, secno + 2);
87 	if (!bh)
88 		goto bail2;
89 	memcpy(data + 2 * 512, bh->b_data, 512);
90 
91 	qbh->bh[3] = bh = sb_bread(s, secno + 3);
92 	if (!bh)
93 		goto bail3;
94 	memcpy(data + 3 * 512, bh->b_data, 512);
95 
96 	return data;
97 
98  bail3:
99 	brelse(qbh->bh[2]);
100  bail2:
101 	brelse(qbh->bh[1]);
102  bail1:
103 	brelse(qbh->bh[0]);
104  bail0:
105 	kfree(data);
106 	printk("HPFS: hpfs_map_4sectors: read error\n");
107  bail:
108 	return NULL;
109 }
110 
111 /* Don't read sectors */
112 
113 void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
114                           struct quad_buffer_head *qbh)
115 {
116 	cond_resched();
117 
118 	hpfs_lock_assert(s);
119 
120 	if (secno & 3) {
121 		printk("HPFS: hpfs_get_4sectors: unaligned read\n");
122 		return NULL;
123 	}
124 
125 	/*return hpfs_map_4sectors(s, secno, qbh, 0);*/
126 	if (!(qbh->data = kmalloc(2048, GFP_NOFS))) {
127 		printk("HPFS: hpfs_get_4sectors: out of memory\n");
128 		return NULL;
129 	}
130 	if (!(hpfs_get_sector(s, secno, &qbh->bh[0]))) goto bail0;
131 	if (!(hpfs_get_sector(s, secno + 1, &qbh->bh[1]))) goto bail1;
132 	if (!(hpfs_get_sector(s, secno + 2, &qbh->bh[2]))) goto bail2;
133 	if (!(hpfs_get_sector(s, secno + 3, &qbh->bh[3]))) goto bail3;
134 	memcpy(qbh->data, qbh->bh[0]->b_data, 512);
135 	memcpy(qbh->data + 512, qbh->bh[1]->b_data, 512);
136 	memcpy(qbh->data + 2*512, qbh->bh[2]->b_data, 512);
137 	memcpy(qbh->data + 3*512, qbh->bh[3]->b_data, 512);
138 	return qbh->data;
139 
140 	bail3:	brelse(qbh->bh[2]);
141 	bail2:	brelse(qbh->bh[1]);
142 	bail1:	brelse(qbh->bh[0]);
143 	bail0:
144 	return NULL;
145 }
146 
147 
148 void hpfs_brelse4(struct quad_buffer_head *qbh)
149 {
150 	brelse(qbh->bh[3]);
151 	brelse(qbh->bh[2]);
152 	brelse(qbh->bh[1]);
153 	brelse(qbh->bh[0]);
154 	kfree(qbh->data);
155 }
156 
157 void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh)
158 {
159 	PRINTK(("hpfs_mark_4buffers_dirty\n"));
160 	memcpy(qbh->bh[0]->b_data, qbh->data, 512);
161 	memcpy(qbh->bh[1]->b_data, qbh->data + 512, 512);
162 	memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512);
163 	memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512);
164 	mark_buffer_dirty(qbh->bh[0]);
165 	mark_buffer_dirty(qbh->bh[1]);
166 	mark_buffer_dirty(qbh->bh[2]);
167 	mark_buffer_dirty(qbh->bh[3]);
168 }
169