patch-2.3.23 linux/fs/hpfs/file.c
Next file: linux/fs/hpfs/hpfs_fn.h
Previous file: linux/fs/hpfs/dnode.c
Back to the patch index
Back to the overall index
- Lines: 164
- Date:
Tue Oct 19 13:52:52 1999
- Orig file:
v2.3.22/linux/fs/hpfs/file.c
- Orig date:
Sun Jun 27 10:10:41 1999
diff -u --recursive --new-file v2.3.22/linux/fs/hpfs/file.c linux/fs/hpfs/file.c
@@ -58,91 +58,96 @@
hpfs_write_inode(i);
}
-int hpfs_getblk_block(struct inode *inode, long block, int create, int *err, int *created)
+int hpfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
{
- int add;
- int sec = 0;
- down(&inode->i_sem);
- if (err) *err = 0;
- if (created) *created = 0;
- if (!inode->i_blocks) {
- hpfs_error(inode->i_sb, "hpfs_get_block: inode %08x has no blocks", inode->i_ino);
- if (err) *err = -EFSERROR;
- up(&inode->i_sem);
+ secno s;
+ if (iblock < inode->i_blocks - 1) {
+ s = hpfs_bmap(inode, iblock);
+ bh_result->b_dev = inode->i_dev;
+ bh_result->b_blocknr = s;
+ bh_result->b_state |= (1UL << BH_Mapped);
return 0;
}
- if (block < ((add = inode->i_blocks - 1))) {
- int bm;
- if (!(bm = hpfs_bmap(inode, block))) {
- hpfs_error(inode->i_sb, "hpfs_get_block: cound not bmap block %08x, inode %08x, size %08x", (int)block, inode->i_ino, (int)inode->i_size);
- *err = -EFSERROR;
- }
- up(&inode->i_sem);
- return bm;
- }
- if (!create) {
- if (err) *err = -EFBIG;
- up(&inode->i_sem);
- return 0;
+ if (!create) return 0;
+ if (iblock > inode->i_blocks - 1) {
+ //hpfs_error(inode->i_sb, "hpfs_get_block beyond file end (requested %08x, inode size %08x", (int)iblock, (int)inode->i_blocks - 1);
+ printk("HPFS: could not write beyond file end. This is known bug.\n");
+ return -EFSERROR;
}
- if (created) *created = 1;
- while (add <= block) {
- if ((sec = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, add)) == -1) {
- if (err) *err = -ENOSPC;
- hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1);
- return 0;
- } /* FIXME: clear block */
- add++;
+ 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);
+ return -ENOSPC;
}
- inode->i_blocks = add + 1;
- up(&inode->i_sem);
- return sec;
+ inode->i_blocks++;
+ bh_result->b_dev = inode->i_dev;
+ bh_result->b_blocknr = s;
+ bh_result->b_state |= (1UL << BH_Mapped) | (1UL << BH_New);
+ return 0;
}
-/* copied from ext2fs */
-static int hpfs_get_block(struct inode *inode, unsigned long block, struct buffer_head *bh, int update)
+static int hpfs_write_partial_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
{
- if (!bh->b_blocknr) {
- int error, created;
- unsigned long blocknr;
-
- blocknr = hpfs_getblk_block(inode, block, 1, &error, &created);
- if (!blocknr) {
- if (!error)
- error = -ENOSPC;
- return error;
+ struct dentry *dentry = file->f_dentry;
+ struct inode *inode = dentry->d_inode;
+ struct page *new_page, **hash;
+ unsigned long pgpos;
+ unsigned long page_cache = 0;
+ long status;
+
+ printk("- off: %08x\n", (int)page->offset);
+ pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK;
+ while (pgpos < page->offset) {
+long pgp = pgpos;
+ printk("pgpos: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks);
+ hash = page_hash(inode, pgpos);
+repeat_find: new_page = __find_lock_page(inode, pgpos, hash);
+ if (!new_page) {
+ if (!page_cache) {
+ page_cache = page_cache_alloc();
+ if (page_cache)
+ goto repeat_find;
+ status = -ENOMEM;
+ goto out;
+ }
+ new_page = page_cache_entry(page_cache);
+ if (add_to_page_cache_unique(new_page,inode,pgpos,hash))
+ goto repeat_find;
+ page_cache = 0;
}
-
- bh->b_dev = inode->i_dev;
- bh->b_blocknr = blocknr;
-
- if (!update)
- return 0;
-
- if (created) {
- memset(bh->b_data, 0, bh->b_size);
- set_bit(BH_Uptodate, &bh->b_state);
- return 0;
+ printk("A\n");
+ status = block_write_cont_page(file, new_page, PAGE_SIZE, 0, NULL);
+ printk("B\n");
+ UnlockPage(new_page);
+ page_cache_release(new_page);
+ if (status < 0)
+ goto out;
+ pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK;
+ printk("pgpos2: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks);
+ if (pgpos == pgp) {
+ status = -1;
+ printk("ERROR\n");
+ goto out;
}
}
-
- if (!update)
- return 0;
-
- lock_kernel();
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- unlock_kernel();
-
- return buffer_uptodate(bh) ? 0 : -EIO;
+ //if ((status = block_write_cont_page(file, page, PAGE_SIZE, 0, NULL)) < 0) goto out;
+ printk("C\n");
+ status = block_write_cont_page(file, page, offset, bytes, buf);
+ printk("D\n");
+out:
+ printk("O\n");
+ if (page_cache)
+ page_cache_free(page_cache);
+ printk("E\n");
+ return status;
}
+
ssize_t hpfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
ssize_t retval;
retval = generic_file_write(file, buf, count,
- ppos, block_write_partial_page);
+ ppos, /*hpfs_write_partial_page*/block_write_partial_page);
if (retval > 0) {
struct inode *inode = file->f_dentry->d_inode;
inode->i_mtime = CURRENT_TIME;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)