18 #error PAGE_SIZE must be at least 4096
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);
26 static int affs_file_release(
struct inode *
inode,
struct file *filp);
35 .open = affs_file_open,
36 .release = affs_file_release,
56 affs_file_release(
struct inode *inode,
struct file *filp)
63 if (inode->
i_size != AFFS_I(inode)->mmu_private)
73 affs_grow_extcache(
struct inode *inode,
u32 lc_idx)
76 struct buffer_head *bh;
80 if (!AFFS_I(inode)->i_lc) {
84 AFFS_I(inode)->i_lc = (
u32 *)ptr;
90 if (AFFS_I(inode)->i_extcnt > lc_max) {
91 u32 lc_shift, lc_mask,
tmp, off;
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)
98 lc_mask = (1 << lc_shift) - 1;
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);
105 off = 1 << (lc_shift - AFFS_I(inode)->i_lc_shift);
107 AFFS_I(inode)->i_ac[
i] = AFFS_I(inode)->i_ac[
j];
109 AFFS_I(inode)->i_lc_shift = lc_shift;
110 AFFS_I(inode)->i_lc_mask = lc_mask;
114 i = AFFS_I(inode)->i_lc_size;
115 AFFS_I(inode)->i_lc_size = lc_idx + 1;
116 for (; i <= lc_idx; i++) {
118 AFFS_I(inode)->i_lc[0] = inode->
i_ino;
121 key = AFFS_I(inode)->i_lc[i - 1];
122 j = AFFS_I(inode)->i_lc_mask + 1;
125 bh = affs_bread(sb, key);
132 AFFS_I(inode)->i_lc[
i] =
key;
142 static struct buffer_head *
143 affs_alloc_extblock(
struct inode *inode,
struct buffer_head *bh,
u32 ext)
146 struct buffer_head *new_bh;
153 new_bh = affs_getzeroblk(sb, blocknr);
156 return ERR_PTR(-
EIO);
169 affs_warning(sb,
"alloc_ext",
"previous extension set (%x)", tmp);
171 affs_adjust_checksum(bh, blocknr - tmp);
174 AFFS_I(inode)->i_extcnt++;
175 mark_inode_dirty(inode);
180 static inline struct buffer_head *
181 affs_get_extblock(
struct inode *inode,
u32 ext)
184 struct buffer_head *bh = AFFS_I(inode)->i_ext_bh;
185 if (ext == AFFS_I(inode)->i_ext_last)
189 bh = affs_get_extblock_slow(inode, ext);
194 static struct buffer_head *
195 affs_get_extblock_slow(
struct inode *inode,
u32 ext)
198 struct buffer_head *bh;
200 u32 lc_idx, lc_off, ac_idx;
203 if (ext == AFFS_I(inode)->i_ext_last + 1) {
205 bh = AFFS_I(inode)->i_ext_bh;
207 if (ext < AFFS_I(inode)->i_extcnt)
209 if (ext > AFFS_I(inode)->i_extcnt)
211 bh = affs_alloc_extblock(inode, bh, ext);
219 ext_key = inode->
i_ino;
223 if (ext >= AFFS_I(inode)->i_extcnt) {
224 struct buffer_head *prev_bh;
227 if (ext > AFFS_I(inode)->i_extcnt)
231 prev_bh = affs_get_extblock(inode, ext - 1);
234 bh = affs_alloc_extblock(inode, prev_bh, ext);
235 affs_brelse(prev_bh);
243 lc_idx = ext >> AFFS_I(inode)->i_lc_shift;
244 lc_off = ext & AFFS_I(inode)->i_lc_mask;
246 if (lc_idx >= AFFS_I(inode)->i_lc_size) {
249 err = affs_grow_extcache(inode, lc_idx);
257 ext_key = AFFS_I(inode)->i_lc[lc_idx];
263 if (AFFS_I(inode)->i_ac[ac_idx].ext ==
ext) {
264 ext_key = AFFS_I(inode)->i_ac[ac_idx].key;
271 while (--tmp, --lc_off > 0) {
273 if (AFFS_I(inode)->i_ac[
idx].ext ==
tmp) {
274 ext_key = AFFS_I(inode)->i_ac[
idx].key;
280 ext_key = AFFS_I(inode)->i_lc[lc_idx];
285 bh = affs_bread(sb, ext_key);
296 AFFS_I(inode)->i_ac[ac_idx].ext =
ext;
297 AFFS_I(inode)->i_ac[ac_idx].key = ext_key;
302 bh = affs_bread(sb, ext_key);
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;
318 return ERR_PTR(-
EIO);
322 affs_get_block(
struct inode *inode,
sector_t block,
struct buffer_head *bh_result,
int create)
325 struct buffer_head *ext_bh;
328 pr_debug(
"AFFS: get_block(%u, %lu)\n", (
u32)inode->
i_ino, (
unsigned long)block);
332 if (block >= AFFS_I(inode)->i_blkcnt) {
333 if (block > AFFS_I(inode)->i_blkcnt || !create)
339 affs_lock_ext(inode);
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);
352 set_buffer_new(bh_result);
353 AFFS_I(inode)->mmu_private += AFFS_SB(sb)->s_data_blksize;
354 AFFS_I(inode)->i_blkcnt++;
357 if (bh_result->b_blocknr)
358 affs_warning(sb,
"get_block",
"block already set (%x)", bh_result->b_blocknr);
361 affs_adjust_checksum(ext_bh, blocknr - bh_result->b_blocknr + 1);
362 bh_result->b_blocknr =
blocknr;
368 affs_warning(sb,
"get_block",
"first block already set (%d)", tmp);
370 affs_adjust_checksum(ext_bh, blocknr - tmp);
376 affs_unlock_ext(inode);
380 affs_error(inode->
i_sb,
"get_block",
"strange block request %d", block);
384 affs_unlock_ext(inode);
385 return PTR_ERR(ext_bh);
388 clear_buffer_mapped(bh_result);
389 bh_result->b_bdev =
NULL;
391 affs_unlock_ext(inode);
406 loff_t
pos,
unsigned len,
unsigned flags,
407 struct page **pagep,
void **fsdata)
414 &AFFS_I(mapping->
host)->mmu_private);
416 loff_t isize = mapping->
host->i_size;
417 if (pos + len > isize)
430 .readpage = affs_readpage,
431 .writepage = affs_writepage,
432 .write_begin = affs_write_begin,
437 static inline struct buffer_head *
438 affs_bread_ino(
struct inode *inode,
int block,
int create)
440 struct buffer_head *bh, tmp_bh;
444 err = affs_get_block(inode, block, &tmp_bh, create);
446 bh = affs_bread(inode->
i_sb, tmp_bh.b_blocknr);
448 bh->b_state |= tmp_bh.b_state;
456 static inline struct buffer_head *
457 affs_getzeroblk_ino(
struct inode *inode,
int block)
459 struct buffer_head *bh, tmp_bh;
463 err = affs_get_block(inode, block, &tmp_bh, 1);
465 bh = affs_getzeroblk(inode->
i_sb, tmp_bh.b_blocknr);
467 bh->b_state |= tmp_bh.b_state;
475 static inline struct buffer_head *
476 affs_getemptyblk_ino(
struct inode *inode,
int block)
478 struct buffer_head *bh, tmp_bh;
482 err = affs_get_block(inode, block, &tmp_bh, 1);
484 bh = affs_getemptyblk(inode->
i_sb, tmp_bh.b_blocknr);
486 bh->b_state |= tmp_bh.b_state;
495 affs_do_readpage_ofs(
struct file *file,
struct page *
page,
unsigned from,
unsigned to)
497 struct inode *inode = page->
mapping->host;
499 struct buffer_head *bh;
501 u32 bidx, boff, bsize;
508 bsize = AFFS_SB(sb)->s_data_blksize;
514 bh = affs_bread_ino(inode, bidx, 0);
517 tmp =
min(bsize - boff, to - from);
518 BUG_ON(from + tmp > to || tmp > bsize);
531 affs_extent_file_ofs(
struct inode *inode,
u32 newsize)
534 struct buffer_head *bh, *prev_bh;
540 bsize = AFFS_SB(sb)->s_data_blksize;
542 size = AFFS_I(inode)->mmu_private;
546 bh = affs_bread_ino(inode, bidx, 0);
549 tmp =
min(bsize - boff, newsize - size);
550 BUG_ON(boff + tmp > bsize || tmp > bsize);
558 bh = affs_bread_ino(inode, bidx - 1, 0);
563 while (size < newsize) {
565 bh = affs_getzeroblk_ino(inode, bidx);
568 tmp =
min(bsize, newsize - size);
575 bh->b_state &= ~(1
UL << BH_New);
580 affs_warning(sb,
"extent_file_ofs",
"next block already set for %d (%d)", bidx, tmp);
582 affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
584 affs_brelse(prev_bh);
590 inode->
i_size = AFFS_I(inode)->mmu_private = newsize;
594 inode->
i_size = AFFS_I(inode)->mmu_private = newsize;
599 affs_readpage_ofs(
struct file *file,
struct page *page)
601 struct inode *inode = page->
mapping->host;
612 err = affs_do_readpage_ofs(file, page, 0, to);
614 SetPageUptodate(page);
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)
623 struct inode *inode = mapping->
host;
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) {
633 err = affs_extent_file_ofs(inode, pos);
644 if (PageUptodate(page))
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)
660 struct inode *inode = mapping->
host;
662 struct buffer_head *bh, *prev_bh;
664 u32 bidx, boff, bsize;
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;
687 bh = affs_bread_ino(inode, bidx, 0);
690 tmp =
min(bsize - boff, to - from);
691 BUG_ON(boff + tmp > bsize || tmp > bsize);
700 bh = affs_bread_ino(inode, bidx - 1, 0);
704 while (from + bsize <= to) {
706 bh = affs_getemptyblk_ino(inode, bidx);
710 if (buffer_new(bh)) {
716 bh->b_state &= ~(1
UL << BH_New);
720 affs_warning(sb,
"commit_write_ofs",
"next block already set for %d (%d)", bidx, tmp);
722 affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
726 affs_brelse(prev_bh);
735 bh = affs_bread_ino(inode, bidx, 1);
738 tmp =
min(bsize, to - from);
741 if (buffer_new(bh)) {
747 bh->b_state &= ~(1
UL << BH_New);
751 affs_warning(sb,
"commit_write_ofs",
"next block already set for %d (%d)", bidx, tmp);
753 affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
758 affs_brelse(prev_bh);
765 SetPageUptodate(page);
771 inode->
i_size = AFFS_I(inode)->mmu_private =
tmp;
781 written = PTR_ERR(bh);
786 .readpage = affs_readpage_ofs,
788 .write_begin = affs_write_begin_ofs,
789 .write_end = affs_write_end_ofs
801 while (AFFS_I(inode)->i_pa_cnt) {
802 AFFS_I(inode)->i_pa_cnt--;
814 u32 last_blk, blkcnt,
blk;
816 struct buffer_head *ext_bh;
819 pr_debug(
"AFFS: truncate(inode=%d, oldsize=%u, newsize=%u)\n",
825 last_blk = ((
u32)inode->
i_size - 1) / AFFS_SB(sb)->s_data_blksize;
826 ext = last_blk / AFFS_SB(sb)->s_hashsize;
829 if (inode->
i_size > AFFS_I(inode)->mmu_private) {
836 res = mapping->
a_ops->write_begin(
NULL, mapping, size, 0, 0, &page, &fsdata);
838 res = mapping->
a_ops->write_end(
NULL, mapping, size, 0, 0, page, fsdata);
840 inode->
i_size = AFFS_I(inode)->mmu_private;
841 mark_inode_dirty(inode);
843 }
else if (inode->
i_size == AFFS_I(inode)->mmu_private)
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));
853 if (AFFS_I(inode)->i_lc) {
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;
859 AFFS_I(inode)->i_lc[
i] = 0;
863 if (AFFS_I(inode)->i_ac[i].ext >= ext)
864 AFFS_I(inode)->i_ac[
i].ext = 0;
868 blkcnt = AFFS_I(inode)->i_blkcnt;
872 i = last_blk % AFFS_SB(sb)->s_hashsize + 1;
877 size = AFFS_SB(sb)->s_hashsize;
878 if (size > blkcnt - blk + i)
879 size = blkcnt - blk +
i;
880 for (; i <
size; i++, blk++) {
890 AFFS_I(inode)->i_blkcnt = last_blk + 1;
891 AFFS_I(inode)->i_extcnt = ext + 1;
893 struct buffer_head *bh = affs_bread_ino(inode, last_blk, 0);
896 affs_warning(sb,
"truncate",
"unexpected read error for last block %u (%d)",
902 affs_adjust_checksum(bh, -tmp);
906 AFFS_I(inode)->i_blkcnt = 0;
907 AFFS_I(inode)->i_extcnt = 1;
909 AFFS_I(inode)->mmu_private = inode->
i_size;
913 ext_bh = affs_bread(sb, ext_key);
914 size = AFFS_SB(sb)->s_hashsize;
915 if (size > blkcnt - blk)
917 for (i = 0; i <
size; i++, blk++)
928 struct inode *inode = filp->
f_mapping->host;