Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
file.c
Go to the documentation of this file.
1 /*
2  * linux/fs/affs/file.c
3  *
4  * (c) 1996 Hans-Joachim Widmaier - Rewritten
5  *
6  * (C) 1993 Ray Burr - Modified for Amiga FFS filesystem.
7  *
8  * (C) 1992 Eric Youngdale Modified for ISO 9660 filesystem.
9  *
10  * (C) 1991 Linus Torvalds - minix filesystem
11  *
12  * affs regular file handling primitives
13  */
14 
15 #include "affs.h"
16 
17 #if PAGE_SIZE < 4096
18 #error PAGE_SIZE must be at least 4096
19 #endif
20 
21 static int affs_grow_extcache(struct inode *inode, u32 lc_idx);
22 static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
23 static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
24 static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
25 static int affs_file_open(struct inode *inode, struct file *filp);
26 static int affs_file_release(struct inode *inode, struct file *filp);
27 
29  .llseek = generic_file_llseek,
30  .read = do_sync_read,
31  .aio_read = generic_file_aio_read,
32  .write = do_sync_write,
33  .aio_write = generic_file_aio_write,
34  .mmap = generic_file_mmap,
35  .open = affs_file_open,
36  .release = affs_file_release,
37  .fsync = affs_file_fsync,
38  .splice_read = generic_file_splice_read,
39 };
40 
42  .truncate = affs_truncate,
43  .setattr = affs_notify_change,
44 };
45 
46 static int
47 affs_file_open(struct inode *inode, struct file *filp)
48 {
49  pr_debug("AFFS: open(%lu,%d)\n",
50  inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
51  atomic_inc(&AFFS_I(inode)->i_opencnt);
52  return 0;
53 }
54 
55 static int
56 affs_file_release(struct inode *inode, struct file *filp)
57 {
58  pr_debug("AFFS: release(%lu, %d)\n",
59  inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
60 
61  if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) {
62  mutex_lock(&inode->i_mutex);
63  if (inode->i_size != AFFS_I(inode)->mmu_private)
64  affs_truncate(inode);
65  affs_free_prealloc(inode);
66  mutex_unlock(&inode->i_mutex);
67  }
68 
69  return 0;
70 }
71 
72 static int
73 affs_grow_extcache(struct inode *inode, u32 lc_idx)
74 {
75  struct super_block *sb = inode->i_sb;
76  struct buffer_head *bh;
77  u32 lc_max;
78  int i, j, key;
79 
80  if (!AFFS_I(inode)->i_lc) {
81  char *ptr = (char *)get_zeroed_page(GFP_NOFS);
82  if (!ptr)
83  return -ENOMEM;
84  AFFS_I(inode)->i_lc = (u32 *)ptr;
85  AFFS_I(inode)->i_ac = (struct affs_ext_key *)(ptr + AFFS_CACHE_SIZE / 2);
86  }
87 
88  lc_max = AFFS_LC_SIZE << AFFS_I(inode)->i_lc_shift;
89 
90  if (AFFS_I(inode)->i_extcnt > lc_max) {
91  u32 lc_shift, lc_mask, tmp, off;
92 
93  /* need to recalculate linear cache, start from old size */
94  lc_shift = AFFS_I(inode)->i_lc_shift;
95  tmp = (AFFS_I(inode)->i_extcnt / AFFS_LC_SIZE) >> lc_shift;
96  for (; tmp; tmp >>= 1)
97  lc_shift++;
98  lc_mask = (1 << lc_shift) - 1;
99 
100  /* fix idx and old size to new shift */
101  lc_idx >>= (lc_shift - AFFS_I(inode)->i_lc_shift);
102  AFFS_I(inode)->i_lc_size >>= (lc_shift - AFFS_I(inode)->i_lc_shift);
103 
104  /* first shrink old cache to make more space */
105  off = 1 << (lc_shift - AFFS_I(inode)->i_lc_shift);
106  for (i = 1, j = off; j < AFFS_LC_SIZE; i++, j += off)
107  AFFS_I(inode)->i_ac[i] = AFFS_I(inode)->i_ac[j];
108 
109  AFFS_I(inode)->i_lc_shift = lc_shift;
110  AFFS_I(inode)->i_lc_mask = lc_mask;
111  }
112 
113  /* fill cache to the needed index */
114  i = AFFS_I(inode)->i_lc_size;
115  AFFS_I(inode)->i_lc_size = lc_idx + 1;
116  for (; i <= lc_idx; i++) {
117  if (!i) {
118  AFFS_I(inode)->i_lc[0] = inode->i_ino;
119  continue;
120  }
121  key = AFFS_I(inode)->i_lc[i - 1];
122  j = AFFS_I(inode)->i_lc_mask + 1;
123  // unlock cache
124  for (; j > 0; j--) {
125  bh = affs_bread(sb, key);
126  if (!bh)
127  goto err;
128  key = be32_to_cpu(AFFS_TAIL(sb, bh)->extension);
129  affs_brelse(bh);
130  }
131  // lock cache
132  AFFS_I(inode)->i_lc[i] = key;
133  }
134 
135  return 0;
136 
137 err:
138  // lock cache
139  return -EIO;
140 }
141 
142 static struct buffer_head *
143 affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext)
144 {
145  struct super_block *sb = inode->i_sb;
146  struct buffer_head *new_bh;
147  u32 blocknr, tmp;
148 
149  blocknr = affs_alloc_block(inode, bh->b_blocknr);
150  if (!blocknr)
151  return ERR_PTR(-ENOSPC);
152 
153  new_bh = affs_getzeroblk(sb, blocknr);
154  if (!new_bh) {
155  affs_free_block(sb, blocknr);
156  return ERR_PTR(-EIO);
157  }
158 
159  AFFS_HEAD(new_bh)->ptype = cpu_to_be32(T_LIST);
160  AFFS_HEAD(new_bh)->key = cpu_to_be32(blocknr);
161  AFFS_TAIL(sb, new_bh)->stype = cpu_to_be32(ST_FILE);
162  AFFS_TAIL(sb, new_bh)->parent = cpu_to_be32(inode->i_ino);
163  affs_fix_checksum(sb, new_bh);
164 
165  mark_buffer_dirty_inode(new_bh, inode);
166 
167  tmp = be32_to_cpu(AFFS_TAIL(sb, bh)->extension);
168  if (tmp)
169  affs_warning(sb, "alloc_ext", "previous extension set (%x)", tmp);
170  AFFS_TAIL(sb, bh)->extension = cpu_to_be32(blocknr);
171  affs_adjust_checksum(bh, blocknr - tmp);
172  mark_buffer_dirty_inode(bh, inode);
173 
174  AFFS_I(inode)->i_extcnt++;
175  mark_inode_dirty(inode);
176 
177  return new_bh;
178 }
179 
180 static inline struct buffer_head *
181 affs_get_extblock(struct inode *inode, u32 ext)
182 {
183  /* inline the simplest case: same extended block as last time */
184  struct buffer_head *bh = AFFS_I(inode)->i_ext_bh;
185  if (ext == AFFS_I(inode)->i_ext_last)
186  get_bh(bh);
187  else
188  /* we have to do more (not inlined) */
189  bh = affs_get_extblock_slow(inode, ext);
190 
191  return bh;
192 }
193 
194 static struct buffer_head *
195 affs_get_extblock_slow(struct inode *inode, u32 ext)
196 {
197  struct super_block *sb = inode->i_sb;
198  struct buffer_head *bh;
199  u32 ext_key;
200  u32 lc_idx, lc_off, ac_idx;
201  u32 tmp, idx;
202 
203  if (ext == AFFS_I(inode)->i_ext_last + 1) {
204  /* read the next extended block from the current one */
205  bh = AFFS_I(inode)->i_ext_bh;
206  ext_key = be32_to_cpu(AFFS_TAIL(sb, bh)->extension);
207  if (ext < AFFS_I(inode)->i_extcnt)
208  goto read_ext;
209  if (ext > AFFS_I(inode)->i_extcnt)
210  BUG();
211  bh = affs_alloc_extblock(inode, bh, ext);
212  if (IS_ERR(bh))
213  return bh;
214  goto store_ext;
215  }
216 
217  if (ext == 0) {
218  /* we seek back to the file header block */
219  ext_key = inode->i_ino;
220  goto read_ext;
221  }
222 
223  if (ext >= AFFS_I(inode)->i_extcnt) {
224  struct buffer_head *prev_bh;
225 
226  /* allocate a new extended block */
227  if (ext > AFFS_I(inode)->i_extcnt)
228  BUG();
229 
230  /* get previous extended block */
231  prev_bh = affs_get_extblock(inode, ext - 1);
232  if (IS_ERR(prev_bh))
233  return prev_bh;
234  bh = affs_alloc_extblock(inode, prev_bh, ext);
235  affs_brelse(prev_bh);
236  if (IS_ERR(bh))
237  return bh;
238  goto store_ext;
239  }
240 
241 again:
242  /* check if there is an extended cache and whether it's large enough */
243  lc_idx = ext >> AFFS_I(inode)->i_lc_shift;
244  lc_off = ext & AFFS_I(inode)->i_lc_mask;
245 
246  if (lc_idx >= AFFS_I(inode)->i_lc_size) {
247  int err;
248 
249  err = affs_grow_extcache(inode, lc_idx);
250  if (err)
251  return ERR_PTR(err);
252  goto again;
253  }
254 
255  /* every n'th key we find in the linear cache */
256  if (!lc_off) {
257  ext_key = AFFS_I(inode)->i_lc[lc_idx];
258  goto read_ext;
259  }
260 
261  /* maybe it's still in the associative cache */
262  ac_idx = (ext - lc_idx - 1) & AFFS_AC_MASK;
263  if (AFFS_I(inode)->i_ac[ac_idx].ext == ext) {
264  ext_key = AFFS_I(inode)->i_ac[ac_idx].key;
265  goto read_ext;
266  }
267 
268  /* try to find one of the previous extended blocks */
269  tmp = ext;
270  idx = ac_idx;
271  while (--tmp, --lc_off > 0) {
272  idx = (idx - 1) & AFFS_AC_MASK;
273  if (AFFS_I(inode)->i_ac[idx].ext == tmp) {
274  ext_key = AFFS_I(inode)->i_ac[idx].key;
275  goto find_ext;
276  }
277  }
278 
279  /* fall back to the linear cache */
280  ext_key = AFFS_I(inode)->i_lc[lc_idx];
281 find_ext:
282  /* read all extended blocks until we find the one we need */
283  //unlock cache
284  do {
285  bh = affs_bread(sb, ext_key);
286  if (!bh)
287  goto err_bread;
288  ext_key = be32_to_cpu(AFFS_TAIL(sb, bh)->extension);
289  affs_brelse(bh);
290  tmp++;
291  } while (tmp < ext);
292  //lock cache
293 
294  /* store it in the associative cache */
295  // recalculate ac_idx?
296  AFFS_I(inode)->i_ac[ac_idx].ext = ext;
297  AFFS_I(inode)->i_ac[ac_idx].key = ext_key;
298 
299 read_ext:
300  /* finally read the right extended block */
301  //unlock cache
302  bh = affs_bread(sb, ext_key);
303  if (!bh)
304  goto err_bread;
305  //lock cache
306 
307 store_ext:
308  /* release old cached extended block and store the new one */
309  affs_brelse(AFFS_I(inode)->i_ext_bh);
310  AFFS_I(inode)->i_ext_last = ext;
311  AFFS_I(inode)->i_ext_bh = bh;
312  get_bh(bh);
313 
314  return bh;
315 
316 err_bread:
317  affs_brelse(bh);
318  return ERR_PTR(-EIO);
319 }
320 
321 static int
322 affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
323 {
324  struct super_block *sb = inode->i_sb;
325  struct buffer_head *ext_bh;
326  u32 ext;
327 
328  pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block);
329 
330  BUG_ON(block > (sector_t)0x7fffffffUL);
331 
332  if (block >= AFFS_I(inode)->i_blkcnt) {
333  if (block > AFFS_I(inode)->i_blkcnt || !create)
334  goto err_big;
335  } else
336  create = 0;
337 
338  //lock cache
339  affs_lock_ext(inode);
340 
341  ext = (u32)block / AFFS_SB(sb)->s_hashsize;
342  block -= ext * AFFS_SB(sb)->s_hashsize;
343  ext_bh = affs_get_extblock(inode, ext);
344  if (IS_ERR(ext_bh))
345  goto err_ext;
346  map_bh(bh_result, sb, (sector_t)be32_to_cpu(AFFS_BLOCK(sb, ext_bh, block)));
347 
348  if (create) {
349  u32 blocknr = affs_alloc_block(inode, ext_bh->b_blocknr);
350  if (!blocknr)
351  goto err_alloc;
352  set_buffer_new(bh_result);
353  AFFS_I(inode)->mmu_private += AFFS_SB(sb)->s_data_blksize;
354  AFFS_I(inode)->i_blkcnt++;
355 
356  /* store new block */
357  if (bh_result->b_blocknr)
358  affs_warning(sb, "get_block", "block already set (%x)", bh_result->b_blocknr);
359  AFFS_BLOCK(sb, ext_bh, block) = cpu_to_be32(blocknr);
360  AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(block + 1);
361  affs_adjust_checksum(ext_bh, blocknr - bh_result->b_blocknr + 1);
362  bh_result->b_blocknr = blocknr;
363 
364  if (!block) {
365  /* insert first block into header block */
366  u32 tmp = be32_to_cpu(AFFS_HEAD(ext_bh)->first_data);
367  if (tmp)
368  affs_warning(sb, "get_block", "first block already set (%d)", tmp);
369  AFFS_HEAD(ext_bh)->first_data = cpu_to_be32(blocknr);
370  affs_adjust_checksum(ext_bh, blocknr - tmp);
371  }
372  }
373 
374  affs_brelse(ext_bh);
375  //unlock cache
376  affs_unlock_ext(inode);
377  return 0;
378 
379 err_big:
380  affs_error(inode->i_sb,"get_block","strange block request %d", block);
381  return -EIO;
382 err_ext:
383  // unlock cache
384  affs_unlock_ext(inode);
385  return PTR_ERR(ext_bh);
386 err_alloc:
387  brelse(ext_bh);
388  clear_buffer_mapped(bh_result);
389  bh_result->b_bdev = NULL;
390  // unlock cache
391  affs_unlock_ext(inode);
392  return -ENOSPC;
393 }
394 
395 static int affs_writepage(struct page *page, struct writeback_control *wbc)
396 {
397  return block_write_full_page(page, affs_get_block, wbc);
398 }
399 
400 static int affs_readpage(struct file *file, struct page *page)
401 {
402  return block_read_full_page(page, affs_get_block);
403 }
404 
405 static int affs_write_begin(struct file *file, struct address_space *mapping,
406  loff_t pos, unsigned len, unsigned flags,
407  struct page **pagep, void **fsdata)
408 {
409  int ret;
410 
411  *pagep = NULL;
412  ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
413  affs_get_block,
414  &AFFS_I(mapping->host)->mmu_private);
415  if (unlikely(ret)) {
416  loff_t isize = mapping->host->i_size;
417  if (pos + len > isize)
418  vmtruncate(mapping->host, isize);
419  }
420 
421  return ret;
422 }
423 
424 static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
425 {
426  return generic_block_bmap(mapping,block,affs_get_block);
427 }
428 
430  .readpage = affs_readpage,
431  .writepage = affs_writepage,
432  .write_begin = affs_write_begin,
433  .write_end = generic_write_end,
434  .bmap = _affs_bmap
435 };
436 
437 static inline struct buffer_head *
438 affs_bread_ino(struct inode *inode, int block, int create)
439 {
440  struct buffer_head *bh, tmp_bh;
441  int err;
442 
443  tmp_bh.b_state = 0;
444  err = affs_get_block(inode, block, &tmp_bh, create);
445  if (!err) {
446  bh = affs_bread(inode->i_sb, tmp_bh.b_blocknr);
447  if (bh) {
448  bh->b_state |= tmp_bh.b_state;
449  return bh;
450  }
451  err = -EIO;
452  }
453  return ERR_PTR(err);
454 }
455 
456 static inline struct buffer_head *
457 affs_getzeroblk_ino(struct inode *inode, int block)
458 {
459  struct buffer_head *bh, tmp_bh;
460  int err;
461 
462  tmp_bh.b_state = 0;
463  err = affs_get_block(inode, block, &tmp_bh, 1);
464  if (!err) {
465  bh = affs_getzeroblk(inode->i_sb, tmp_bh.b_blocknr);
466  if (bh) {
467  bh->b_state |= tmp_bh.b_state;
468  return bh;
469  }
470  err = -EIO;
471  }
472  return ERR_PTR(err);
473 }
474 
475 static inline struct buffer_head *
476 affs_getemptyblk_ino(struct inode *inode, int block)
477 {
478  struct buffer_head *bh, tmp_bh;
479  int err;
480 
481  tmp_bh.b_state = 0;
482  err = affs_get_block(inode, block, &tmp_bh, 1);
483  if (!err) {
484  bh = affs_getemptyblk(inode->i_sb, tmp_bh.b_blocknr);
485  if (bh) {
486  bh->b_state |= tmp_bh.b_state;
487  return bh;
488  }
489  err = -EIO;
490  }
491  return ERR_PTR(err);
492 }
493 
494 static int
495 affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
496 {
497  struct inode *inode = page->mapping->host;
498  struct super_block *sb = inode->i_sb;
499  struct buffer_head *bh;
500  char *data;
501  u32 bidx, boff, bsize;
502  u32 tmp;
503 
504  pr_debug("AFFS: read_page(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to);
505  BUG_ON(from > to || to > PAGE_CACHE_SIZE);
506  kmap(page);
507  data = page_address(page);
508  bsize = AFFS_SB(sb)->s_data_blksize;
509  tmp = (page->index << PAGE_CACHE_SHIFT) + from;
510  bidx = tmp / bsize;
511  boff = tmp % bsize;
512 
513  while (from < to) {
514  bh = affs_bread_ino(inode, bidx, 0);
515  if (IS_ERR(bh))
516  return PTR_ERR(bh);
517  tmp = min(bsize - boff, to - from);
518  BUG_ON(from + tmp > to || tmp > bsize);
519  memcpy(data + from, AFFS_DATA(bh) + boff, tmp);
520  affs_brelse(bh);
521  bidx++;
522  from += tmp;
523  boff = 0;
524  }
525  flush_dcache_page(page);
526  kunmap(page);
527  return 0;
528 }
529 
530 static int
531 affs_extent_file_ofs(struct inode *inode, u32 newsize)
532 {
533  struct super_block *sb = inode->i_sb;
534  struct buffer_head *bh, *prev_bh;
535  u32 bidx, boff;
536  u32 size, bsize;
537  u32 tmp;
538 
539  pr_debug("AFFS: extent_file(%u, %d)\n", (u32)inode->i_ino, newsize);
540  bsize = AFFS_SB(sb)->s_data_blksize;
541  bh = NULL;
542  size = AFFS_I(inode)->mmu_private;
543  bidx = size / bsize;
544  boff = size % bsize;
545  if (boff) {
546  bh = affs_bread_ino(inode, bidx, 0);
547  if (IS_ERR(bh))
548  return PTR_ERR(bh);
549  tmp = min(bsize - boff, newsize - size);
550  BUG_ON(boff + tmp > bsize || tmp > bsize);
551  memset(AFFS_DATA(bh) + boff, 0, tmp);
552  be32_add_cpu(&AFFS_DATA_HEAD(bh)->size, tmp);
553  affs_fix_checksum(sb, bh);
554  mark_buffer_dirty_inode(bh, inode);
555  size += tmp;
556  bidx++;
557  } else if (bidx) {
558  bh = affs_bread_ino(inode, bidx - 1, 0);
559  if (IS_ERR(bh))
560  return PTR_ERR(bh);
561  }
562 
563  while (size < newsize) {
564  prev_bh = bh;
565  bh = affs_getzeroblk_ino(inode, bidx);
566  if (IS_ERR(bh))
567  goto out;
568  tmp = min(bsize, newsize - size);
569  BUG_ON(tmp > bsize);
570  AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
571  AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino);
572  AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx);
573  AFFS_DATA_HEAD(bh)->size = cpu_to_be32(tmp);
574  affs_fix_checksum(sb, bh);
575  bh->b_state &= ~(1UL << BH_New);
576  mark_buffer_dirty_inode(bh, inode);
577  if (prev_bh) {
578  u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
579  if (tmp)
580  affs_warning(sb, "extent_file_ofs", "next block already set for %d (%d)", bidx, tmp);
581  AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
582  affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
583  mark_buffer_dirty_inode(prev_bh, inode);
584  affs_brelse(prev_bh);
585  }
586  size += bsize;
587  bidx++;
588  }
589  affs_brelse(bh);
590  inode->i_size = AFFS_I(inode)->mmu_private = newsize;
591  return 0;
592 
593 out:
594  inode->i_size = AFFS_I(inode)->mmu_private = newsize;
595  return PTR_ERR(bh);
596 }
597 
598 static int
599 affs_readpage_ofs(struct file *file, struct page *page)
600 {
601  struct inode *inode = page->mapping->host;
602  u32 to;
603  int err;
604 
605  pr_debug("AFFS: read_page(%u, %ld)\n", (u32)inode->i_ino, page->index);
606  to = PAGE_CACHE_SIZE;
607  if (((page->index + 1) << PAGE_CACHE_SHIFT) > inode->i_size) {
608  to = inode->i_size & ~PAGE_CACHE_MASK;
609  memset(page_address(page) + to, 0, PAGE_CACHE_SIZE - to);
610  }
611 
612  err = affs_do_readpage_ofs(file, page, 0, to);
613  if (!err)
614  SetPageUptodate(page);
615  unlock_page(page);
616  return err;
617 }
618 
619 static int affs_write_begin_ofs(struct file *file, struct address_space *mapping,
620  loff_t pos, unsigned len, unsigned flags,
621  struct page **pagep, void **fsdata)
622 {
623  struct inode *inode = mapping->host;
624  struct page *page;
625  pgoff_t index;
626  int err = 0;
627 
628  pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
629  if (pos > AFFS_I(inode)->mmu_private) {
630  /* XXX: this probably leaves a too-big i_size in case of
631  * failure. Should really be updating i_size at write_end time
632  */
633  err = affs_extent_file_ofs(inode, pos);
634  if (err)
635  return err;
636  }
637 
638  index = pos >> PAGE_CACHE_SHIFT;
639  page = grab_cache_page_write_begin(mapping, index, flags);
640  if (!page)
641  return -ENOMEM;
642  *pagep = page;
643 
644  if (PageUptodate(page))
645  return 0;
646 
647  /* XXX: inefficient but safe in the face of short writes */
648  err = affs_do_readpage_ofs(file, page, 0, PAGE_CACHE_SIZE);
649  if (err) {
650  unlock_page(page);
651  page_cache_release(page);
652  }
653  return err;
654 }
655 
656 static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
657  loff_t pos, unsigned len, unsigned copied,
658  struct page *page, void *fsdata)
659 {
660  struct inode *inode = mapping->host;
661  struct super_block *sb = inode->i_sb;
662  struct buffer_head *bh, *prev_bh;
663  char *data;
664  u32 bidx, boff, bsize;
665  unsigned from, to;
666  u32 tmp;
667  int written;
668 
669  from = pos & (PAGE_CACHE_SIZE - 1);
670  to = pos + len;
671  /*
672  * XXX: not sure if this can handle short copies (len < copied), but
673  * we don't have to, because the page should always be uptodate here,
674  * due to write_begin.
675  */
676 
677  pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
678  bsize = AFFS_SB(sb)->s_data_blksize;
679  data = page_address(page);
680 
681  bh = NULL;
682  written = 0;
683  tmp = (page->index << PAGE_CACHE_SHIFT) + from;
684  bidx = tmp / bsize;
685  boff = tmp % bsize;
686  if (boff) {
687  bh = affs_bread_ino(inode, bidx, 0);
688  if (IS_ERR(bh))
689  return PTR_ERR(bh);
690  tmp = min(bsize - boff, to - from);
691  BUG_ON(boff + tmp > bsize || tmp > bsize);
692  memcpy(AFFS_DATA(bh) + boff, data + from, tmp);
693  be32_add_cpu(&AFFS_DATA_HEAD(bh)->size, tmp);
694  affs_fix_checksum(sb, bh);
695  mark_buffer_dirty_inode(bh, inode);
696  written += tmp;
697  from += tmp;
698  bidx++;
699  } else if (bidx) {
700  bh = affs_bread_ino(inode, bidx - 1, 0);
701  if (IS_ERR(bh))
702  return PTR_ERR(bh);
703  }
704  while (from + bsize <= to) {
705  prev_bh = bh;
706  bh = affs_getemptyblk_ino(inode, bidx);
707  if (IS_ERR(bh))
708  goto out;
709  memcpy(AFFS_DATA(bh), data + from, bsize);
710  if (buffer_new(bh)) {
711  AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
712  AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino);
713  AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx);
714  AFFS_DATA_HEAD(bh)->size = cpu_to_be32(bsize);
715  AFFS_DATA_HEAD(bh)->next = 0;
716  bh->b_state &= ~(1UL << BH_New);
717  if (prev_bh) {
718  u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
719  if (tmp)
720  affs_warning(sb, "commit_write_ofs", "next block already set for %d (%d)", bidx, tmp);
721  AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
722  affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
723  mark_buffer_dirty_inode(prev_bh, inode);
724  }
725  }
726  affs_brelse(prev_bh);
727  affs_fix_checksum(sb, bh);
728  mark_buffer_dirty_inode(bh, inode);
729  written += bsize;
730  from += bsize;
731  bidx++;
732  }
733  if (from < to) {
734  prev_bh = bh;
735  bh = affs_bread_ino(inode, bidx, 1);
736  if (IS_ERR(bh))
737  goto out;
738  tmp = min(bsize, to - from);
739  BUG_ON(tmp > bsize);
740  memcpy(AFFS_DATA(bh), data + from, tmp);
741  if (buffer_new(bh)) {
742  AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
743  AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino);
744  AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx);
745  AFFS_DATA_HEAD(bh)->size = cpu_to_be32(tmp);
746  AFFS_DATA_HEAD(bh)->next = 0;
747  bh->b_state &= ~(1UL << BH_New);
748  if (prev_bh) {
749  u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
750  if (tmp)
751  affs_warning(sb, "commit_write_ofs", "next block already set for %d (%d)", bidx, tmp);
752  AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
753  affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
754  mark_buffer_dirty_inode(prev_bh, inode);
755  }
756  } else if (be32_to_cpu(AFFS_DATA_HEAD(bh)->size) < tmp)
757  AFFS_DATA_HEAD(bh)->size = cpu_to_be32(tmp);
758  affs_brelse(prev_bh);
759  affs_fix_checksum(sb, bh);
760  mark_buffer_dirty_inode(bh, inode);
761  written += tmp;
762  from += tmp;
763  bidx++;
764  }
765  SetPageUptodate(page);
766 
767 done:
768  affs_brelse(bh);
769  tmp = (page->index << PAGE_CACHE_SHIFT) + from;
770  if (tmp > inode->i_size)
771  inode->i_size = AFFS_I(inode)->mmu_private = tmp;
772 
773  unlock_page(page);
774  page_cache_release(page);
775 
776  return written;
777 
778 out:
779  bh = prev_bh;
780  if (!written)
781  written = PTR_ERR(bh);
782  goto done;
783 }
784 
786  .readpage = affs_readpage_ofs,
787  //.writepage = affs_writepage_ofs,
788  .write_begin = affs_write_begin_ofs,
789  .write_end = affs_write_end_ofs
790 };
791 
792 /* Free any preallocated blocks. */
793 
794 void
795 affs_free_prealloc(struct inode *inode)
796 {
797  struct super_block *sb = inode->i_sb;
798 
799  pr_debug("AFFS: free_prealloc(ino=%lu)\n", inode->i_ino);
800 
801  while (AFFS_I(inode)->i_pa_cnt) {
802  AFFS_I(inode)->i_pa_cnt--;
803  affs_free_block(sb, ++AFFS_I(inode)->i_lastalloc);
804  }
805 }
806 
807 /* Truncate (or enlarge) a file to the requested size. */
808 
809 void
810 affs_truncate(struct inode *inode)
811 {
812  struct super_block *sb = inode->i_sb;
813  u32 ext, ext_key;
814  u32 last_blk, blkcnt, blk;
815  u32 size;
816  struct buffer_head *ext_bh;
817  int i;
818 
819  pr_debug("AFFS: truncate(inode=%d, oldsize=%u, newsize=%u)\n",
820  (u32)inode->i_ino, (u32)AFFS_I(inode)->mmu_private, (u32)inode->i_size);
821 
822  last_blk = 0;
823  ext = 0;
824  if (inode->i_size) {
825  last_blk = ((u32)inode->i_size - 1) / AFFS_SB(sb)->s_data_blksize;
826  ext = last_blk / AFFS_SB(sb)->s_hashsize;
827  }
828 
829  if (inode->i_size > AFFS_I(inode)->mmu_private) {
830  struct address_space *mapping = inode->i_mapping;
831  struct page *page;
832  void *fsdata;
833  u32 size = inode->i_size;
834  int res;
835 
836  res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
837  if (!res)
838  res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
839  else
840  inode->i_size = AFFS_I(inode)->mmu_private;
841  mark_inode_dirty(inode);
842  return;
843  } else if (inode->i_size == AFFS_I(inode)->mmu_private)
844  return;
845 
846  // lock cache
847  ext_bh = affs_get_extblock(inode, ext);
848  if (IS_ERR(ext_bh)) {
849  affs_warning(sb, "truncate", "unexpected read error for ext block %u (%d)",
850  ext, PTR_ERR(ext_bh));
851  return;
852  }
853  if (AFFS_I(inode)->i_lc) {
854  /* clear linear cache */
855  i = (ext + 1) >> AFFS_I(inode)->i_lc_shift;
856  if (AFFS_I(inode)->i_lc_size > i) {
857  AFFS_I(inode)->i_lc_size = i;
858  for (; i < AFFS_LC_SIZE; i++)
859  AFFS_I(inode)->i_lc[i] = 0;
860  }
861  /* clear associative cache */
862  for (i = 0; i < AFFS_AC_SIZE; i++)
863  if (AFFS_I(inode)->i_ac[i].ext >= ext)
864  AFFS_I(inode)->i_ac[i].ext = 0;
865  }
866  ext_key = be32_to_cpu(AFFS_TAIL(sb, ext_bh)->extension);
867 
868  blkcnt = AFFS_I(inode)->i_blkcnt;
869  i = 0;
870  blk = last_blk;
871  if (inode->i_size) {
872  i = last_blk % AFFS_SB(sb)->s_hashsize + 1;
873  blk++;
874  } else
875  AFFS_HEAD(ext_bh)->first_data = 0;
876  AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i);
877  size = AFFS_SB(sb)->s_hashsize;
878  if (size > blkcnt - blk + i)
879  size = blkcnt - blk + i;
880  for (; i < size; i++, blk++) {
881  affs_free_block(sb, be32_to_cpu(AFFS_BLOCK(sb, ext_bh, i)));
882  AFFS_BLOCK(sb, ext_bh, i) = 0;
883  }
884  AFFS_TAIL(sb, ext_bh)->extension = 0;
885  affs_fix_checksum(sb, ext_bh);
886  mark_buffer_dirty_inode(ext_bh, inode);
887  affs_brelse(ext_bh);
888 
889  if (inode->i_size) {
890  AFFS_I(inode)->i_blkcnt = last_blk + 1;
891  AFFS_I(inode)->i_extcnt = ext + 1;
892  if (AFFS_SB(sb)->s_flags & SF_OFS) {
893  struct buffer_head *bh = affs_bread_ino(inode, last_blk, 0);
894  u32 tmp;
895  if (IS_ERR(bh)) {
896  affs_warning(sb, "truncate", "unexpected read error for last block %u (%d)",
897  ext, PTR_ERR(bh));
898  return;
899  }
900  tmp = be32_to_cpu(AFFS_DATA_HEAD(bh)->next);
901  AFFS_DATA_HEAD(bh)->next = 0;
902  affs_adjust_checksum(bh, -tmp);
903  affs_brelse(bh);
904  }
905  } else {
906  AFFS_I(inode)->i_blkcnt = 0;
907  AFFS_I(inode)->i_extcnt = 1;
908  }
909  AFFS_I(inode)->mmu_private = inode->i_size;
910  // unlock cache
911 
912  while (ext_key) {
913  ext_bh = affs_bread(sb, ext_key);
914  size = AFFS_SB(sb)->s_hashsize;
915  if (size > blkcnt - blk)
916  size = blkcnt - blk;
917  for (i = 0; i < size; i++, blk++)
918  affs_free_block(sb, be32_to_cpu(AFFS_BLOCK(sb, ext_bh, i)));
919  affs_free_block(sb, ext_key);
920  ext_key = be32_to_cpu(AFFS_TAIL(sb, ext_bh)->extension);
921  affs_brelse(ext_bh);
922  }
923  affs_free_prealloc(inode);
924 }
925 
926 int affs_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
927 {
928  struct inode *inode = filp->f_mapping->host;
929  int ret, err;
930 
931  err = filemap_write_and_wait_range(inode->i_mapping, start, end);
932  if (err)
933  return err;
934 
935  mutex_lock(&inode->i_mutex);
936  ret = write_inode_now(inode, 0);
937  err = sync_blockdev(inode->i_sb->s_bdev);
938  if (!ret)
939  ret = err;
940  mutex_unlock(&inode->i_mutex);
941  return ret;
942 }