Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
buffer.c
Go to the documentation of this file.
1 /*
2  * linux/fs/hpfs/buffer.c
3  *
4  * Mikulas Patocka ([email protected]), 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 
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 
158 {
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 }