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