Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
util.c
Go to the documentation of this file.
1 /*
2  * linux/fs/ufs/util.c
3  *
4  * Copyright (C) 1998
5  * Daniel Pirkl <[email protected]>
6  * Charles University, Faculty of Mathematics and Physics
7  */
8 
9 #include <linux/string.h>
10 #include <linux/slab.h>
11 #include <linux/buffer_head.h>
12 
13 #include "ufs_fs.h"
14 #include "ufs.h"
15 #include "swab.h"
16 #include "util.h"
17 
19  struct super_block *sb, u64 fragment, u64 size)
20 {
21  struct ufs_buffer_head * ubh;
22  unsigned i, j ;
23  u64 count = 0;
24  if (size & ~uspi->s_fmask)
25  return NULL;
26  count = size >> uspi->s_fshift;
27  if (count > UFS_MAXFRAG)
28  return NULL;
29  ubh = (struct ufs_buffer_head *)
30  kmalloc (sizeof (struct ufs_buffer_head), GFP_NOFS);
31  if (!ubh)
32  return NULL;
33  ubh->fragment = fragment;
34  ubh->count = count;
35  for (i = 0; i < count; i++)
36  if (!(ubh->bh[i] = sb_bread(sb, fragment + i)))
37  goto failed;
38  for (; i < UFS_MAXFRAG; i++)
39  ubh->bh[i] = NULL;
40  return ubh;
41 failed:
42  for (j = 0; j < i; j++)
43  brelse (ubh->bh[j]);
44  kfree(ubh);
45  return NULL;
46 }
47 
49  struct super_block *sb, u64 fragment, u64 size)
50 {
51  unsigned i, j;
52  u64 count = 0;
53  if (size & ~uspi->s_fmask)
54  return NULL;
55  count = size >> uspi->s_fshift;
56  if (count <= 0 || count > UFS_MAXFRAG)
57  return NULL;
58  USPI_UBH(uspi)->fragment = fragment;
59  USPI_UBH(uspi)->count = count;
60  for (i = 0; i < count; i++)
61  if (!(USPI_UBH(uspi)->bh[i] = sb_bread(sb, fragment + i)))
62  goto failed;
63  for (; i < UFS_MAXFRAG; i++)
64  USPI_UBH(uspi)->bh[i] = NULL;
65  return USPI_UBH(uspi);
66 failed:
67  for (j = 0; j < i; j++)
68  brelse (USPI_UBH(uspi)->bh[j]);
69  return NULL;
70 }
71 
72 void ubh_brelse (struct ufs_buffer_head * ubh)
73 {
74  unsigned i;
75  if (!ubh)
76  return;
77  for (i = 0; i < ubh->count; i++)
78  brelse (ubh->bh[i]);
79  kfree (ubh);
80 }
81 
83 {
84  unsigned i;
85  if (!USPI_UBH(uspi))
86  return;
87  for ( i = 0; i < USPI_UBH(uspi)->count; i++ ) {
88  brelse (USPI_UBH(uspi)->bh[i]);
89  USPI_UBH(uspi)->bh[i] = NULL;
90  }
91 }
92 
94 {
95  unsigned i;
96  if (!ubh)
97  return;
98  for ( i = 0; i < ubh->count; i++ )
99  mark_buffer_dirty (ubh->bh[i]);
100 }
101 
103 {
104  unsigned i;
105  if (!ubh)
106  return;
107  if (flag) {
108  for ( i = 0; i < ubh->count; i++ )
109  set_buffer_uptodate (ubh->bh[i]);
110  } else {
111  for ( i = 0; i < ubh->count; i++ )
112  clear_buffer_uptodate (ubh->bh[i]);
113  }
114 }
115 
117 {
118  if (ubh) {
119  unsigned i;
120 
121  for (i = 0; i < ubh->count; i++)
122  write_dirty_buffer(ubh->bh[i], WRITE);
123 
124  for (i = 0; i < ubh->count; i++)
125  wait_on_buffer(ubh->bh[i]);
126  }
127 }
128 
129 void ubh_bforget (struct ufs_buffer_head * ubh)
130 {
131  unsigned i;
132  if (!ubh)
133  return;
134  for ( i = 0; i < ubh->count; i++ ) if ( ubh->bh[i] )
135  bforget (ubh->bh[i]);
136 }
137 
139 {
140  unsigned i;
141  unsigned result = 0;
142  if (!ubh)
143  return 0;
144  for ( i = 0; i < ubh->count; i++ )
145  result |= buffer_dirty(ubh->bh[i]);
146  return result;
147 }
148 
150  unsigned char * mem, struct ufs_buffer_head * ubh, unsigned size)
151 {
152  unsigned len, bhno;
153  if (size > (ubh->count << uspi->s_fshift))
154  size = ubh->count << uspi->s_fshift;
155  bhno = 0;
156  while (size) {
157  len = min_t(unsigned int, size, uspi->s_fsize);
158  memcpy (mem, ubh->bh[bhno]->b_data, len);
159  mem += uspi->s_fsize;
160  size -= len;
161  bhno++;
162  }
163 }
164 
166  struct ufs_buffer_head * ubh, unsigned char * mem, unsigned size)
167 {
168  unsigned len, bhno;
169  if (size > (ubh->count << uspi->s_fshift))
170  size = ubh->count << uspi->s_fshift;
171  bhno = 0;
172  while (size) {
173  len = min_t(unsigned int, size, uspi->s_fsize);
174  memcpy (ubh->bh[bhno]->b_data, mem, len);
175  mem += uspi->s_fsize;
176  size -= len;
177  bhno++;
178  }
179 }
180 
181 dev_t
183 {
184  __u32 fs32;
185  dev_t dev;
186 
187  if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
188  fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[1]);
189  else
190  fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[0]);
191  switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
192  case UFS_ST_SUNx86:
193  case UFS_ST_SUN:
194  if ((fs32 & 0xffff0000) == 0 ||
195  (fs32 & 0xffff0000) == 0xffff0000)
196  dev = old_decode_dev(fs32 & 0x7fff);
197  else
198  dev = MKDEV(sysv_major(fs32), sysv_minor(fs32));
199  break;
200 
201  default:
202  dev = old_decode_dev(fs32);
203  break;
204  }
205  return dev;
206 }
207 
208 void
210 {
211  __u32 fs32;
212 
213  switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
214  case UFS_ST_SUNx86:
215  case UFS_ST_SUN:
216  fs32 = sysv_encode_dev(dev);
217  if ((fs32 & 0xffff8000) == 0) {
218  fs32 = old_encode_dev(dev);
219  }
220  break;
221 
222  default:
223  fs32 = old_encode_dev(dev);
224  break;
225  }
226  if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
227  ufsi->i_u1.i_data[1] = cpu_to_fs32(sb, fs32);
228  else
229  ufsi->i_u1.i_data[0] = cpu_to_fs32(sb, fs32);
230 }
231 
245  pgoff_t index)
246 {
247  struct page *page;
248 
249  page = find_lock_page(mapping, index);
250  if (!page) {
251  page = read_mapping_page(mapping, index, NULL);
252 
253  if (IS_ERR(page)) {
254  printk(KERN_ERR "ufs_change_blocknr: "
255  "read_mapping_page error: ino %lu, index: %lu\n",
256  mapping->host->i_ino, index);
257  goto out;
258  }
259 
260  lock_page(page);
261 
262  if (unlikely(page->mapping == NULL)) {
263  /* Truncate got there first */
264  unlock_page(page);
265  page_cache_release(page);
266  page = NULL;
267  goto out;
268  }
269 
270  if (!PageUptodate(page) || PageError(page)) {
271  unlock_page(page);
272  page_cache_release(page);
273 
274  printk(KERN_ERR "ufs_change_blocknr: "
275  "can not read page: ino %lu, index: %lu\n",
276  mapping->host->i_ino, index);
277 
278  page = ERR_PTR(-EIO);
279  }
280  }
281 out:
282  return page;
283 }