static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { int r; secno s; hpfs_lock(inode->i_sb); s = hpfs_bmap(inode, iblock); if (s) { map_bh(bh_result, inode->i_sb, s); goto ret_0; } if (!create) goto ret_0; if (iblock<<9 != hpfs_i(inode)->mmu_private) { BUG(); r = -EIO; goto ret_r; } if ((s = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1)) == -1) { hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1); r = -ENOSPC; goto ret_r; } inode->i_blocks++; hpfs_i(inode)->mmu_private += 512; set_buffer_new(bh_result); map_bh(bh_result, inode->i_sb, s); ret_0: r = 0; ret_r: hpfs_unlock(inode->i_sb); return r; }
static int hpfs_file_read(struct inode *inode, struct file *filp, char *buf, int count) { unsigned q, r, n, n0; struct buffer_head *bh; char *block; char *start; if (inode == 0 || !S_ISREG(inode->i_mode)) return -EINVAL; /* * truncate count at EOF */ if (count > inode->i_size - (off_t) filp->f_pos) count = inode->i_size - filp->f_pos; start = buf; while (count > 0) { /* * get file sector number, offset in sector, length to end of * sector */ q = filp->f_pos >> 9; r = filp->f_pos & 511; n = 512 - r; /* * get length to copy to user buffer */ if (n > count) n = count; /* * read the sector, copy to user */ block = map_sector(inode->i_dev, hpfs_bmap(inode, q), &bh); if (!block) return -EIO; /* * but first decide if it has \r\n, if the mount option said * to do that */ if (inode->i_hpfs_conv == CONV_AUTO) inode->i_hpfs_conv = choose_conv(block + r, n); if (inode->i_hpfs_conv == CONV_BINARY) { /* * regular copy, output length is same as input * length */ memcpy_tofs(buf, block + r, n); n0 = n; } else { /* * squeeze out \r, output length varies */ n0 = convcpy_tofs(buf, block + r, n); if (count > inode->i_size - (off_t) filp->f_pos - n + n0) count = inode->i_size - filp->f_pos - n + n0; } brelse(bh); /* * advance input n bytes, output n0 bytes */ filp->f_pos += n; buf += n0; count -= n0; } return buf - start; }