Import 2.3.99pre7-7
[davej-history.git] / fs / hpfs / file.c
blobc0707b52c9bfaf5822602faa32bd4fd47ee90237
1 /*
2 * linux/fs/hpfs/file.c
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6 * file VFS functions
7 */
9 #include <linux/string.h>
10 #include "hpfs_fn.h"
12 int hpfs_open(struct inode *i, struct file *f)
14 hpfs_lock_inode(i);
15 hpfs_unlock_inode(i); /* make sure nobody is deleting the file */
16 if (!i->i_nlink) return -ENOENT;
17 return 0;
20 int hpfs_file_release(struct inode *inode, struct file *file)
22 hpfs_write_if_changed(inode);
23 return 0;
26 int hpfs_file_fsync(struct file *file, struct dentry *dentry)
28 /*return file_fsync(file, dentry);*/
29 return 0; /* Don't fsync :-) */
33 * generic_file_read often calls bmap with non-existing sector,
34 * so we must ignore such errors.
37 secno hpfs_bmap(struct inode *inode, unsigned file_secno)
39 unsigned n, disk_secno;
40 struct fnode *fnode;
41 struct buffer_head *bh;
42 if (((inode->i_size + 511) >> 9) <= file_secno) return 0;
43 n = file_secno - inode->i_hpfs_file_sec;
44 if (n < inode->i_hpfs_n_secs) return inode->i_hpfs_disk_sec + n;
45 if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0;
46 disk_secno = hpfs_bplus_lookup(inode->i_sb, inode, &fnode->btree, file_secno, bh);
47 if (disk_secno == -1) return 0;
48 if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0;
49 return disk_secno;
52 void hpfs_truncate(struct inode *i)
54 if (IS_IMMUTABLE(i)) return /*-EPERM*/;
55 i->i_hpfs_n_secs = 0;
56 i->i_blocks = 1 + ((i->i_size + 511) >> 9);
57 i->u.hpfs_i.mmu_private = i->i_size;
58 hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
59 hpfs_write_inode(i);
62 int hpfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
64 secno s;
65 s = hpfs_bmap(inode, iblock);
66 if (s) {
67 bh_result->b_dev = inode->i_dev;
68 bh_result->b_blocknr = s;
69 bh_result->b_state |= (1UL << BH_Mapped);
70 return 0;
72 if (!create) return 0;
73 if (iblock<<9 != inode->u.hpfs_i.mmu_private) {
74 BUG();
75 return -EIO;
77 if ((s = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1)) == -1) {
78 hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1);
79 return -ENOSPC;
81 inode->i_blocks++;
82 inode->u.hpfs_i.mmu_private += 512;
83 bh_result->b_dev = inode->i_dev;
84 bh_result->b_blocknr = s;
85 bh_result->b_state |= (1UL << BH_Mapped) | (1UL << BH_New);
86 return 0;
89 static int hpfs_writepage(struct file *file, struct page *page)
91 return block_write_full_page(page,hpfs_get_block);
93 static int hpfs_readpage(struct file *file, struct page *page)
95 return block_read_full_page(page,hpfs_get_block);
97 static int hpfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
99 return cont_prepare_write(page,from,to,hpfs_get_block,
100 &((struct inode*)page->mapping->host)->u.hpfs_i.mmu_private);
102 static int _hpfs_bmap(struct address_space *mapping, long block)
104 return generic_block_bmap(mapping,block,hpfs_get_block);
106 struct address_space_operations hpfs_aops = {
107 readpage: hpfs_readpage,
108 writepage: hpfs_writepage,
109 sync_page: block_sync_page,
110 prepare_write: hpfs_prepare_write,
111 commit_write: generic_commit_write,
112 bmap: _hpfs_bmap
115 ssize_t hpfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
117 ssize_t retval;
119 retval = generic_file_write(file, buf, count, ppos);
120 if (retval > 0) {
121 struct inode *inode = file->f_dentry->d_inode;
122 inode->i_mtime = CURRENT_TIME;
123 inode->i_hpfs_dirty = 1;
125 return retval;