4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
11 int hpfs_open(struct inode
*i
, struct file
*f
)
14 hpfs_unlock_inode(i
); /* make sure nobody is deleting the file */
15 if (!i
->i_nlink
) return -ENOENT
;
19 int hpfs_file_release(struct inode
*inode
, struct file
*file
)
21 hpfs_write_if_changed(inode
);
25 int hpfs_file_fsync(struct file
*file
, struct dentry
*dentry
)
27 /*return file_fsync(file, dentry);*/
28 return 0; /* Don't fsync :-) */
32 * generic_file_read often calls bmap with non-existing sector,
33 * so we must ignore such errors.
36 secno
hpfs_bmap(struct inode
*inode
, unsigned file_secno
)
38 unsigned n
, disk_secno
;
40 struct buffer_head
*bh
;
41 if (((inode
->i_size
+ 511) >> 9) <= file_secno
) return 0;
42 n
= file_secno
- inode
->i_hpfs_file_sec
;
43 if (n
< inode
->i_hpfs_n_secs
) return inode
->i_hpfs_disk_sec
+ n
;
44 if (!(fnode
= hpfs_map_fnode(inode
->i_sb
, inode
->i_ino
, &bh
))) return 0;
45 disk_secno
= hpfs_bplus_lookup(inode
->i_sb
, inode
, &fnode
->btree
, file_secno
, bh
);
46 if (disk_secno
== -1) return 0;
47 if (hpfs_chk_sectors(inode
->i_sb
, disk_secno
, 1, "bmap")) return 0;
51 void hpfs_truncate(struct inode
*i
)
53 if (IS_IMMUTABLE(i
)) return /*-EPERM*/;
55 hpfs_truncate_btree(i
->i_sb
, i
->i_ino
, 1, ((i
->i_size
+ 511) >> 9));
56 i
->i_blocks
= 1 + ((i
->i_size
+ 511) >> 9);
57 /*mark_inode_dirty(i);*/i
->i_hpfs_dirty
= 1;
61 ssize_t
hpfs_file_read(struct file
*filp
, char *buf
, size_t count
, loff_t
*ppos
)
63 struct inode
*inode
= filp
->f_dentry
->d_inode
;
65 int a
= generic_file_read(filp
, buf
, count
, ppos
);
66 if (inode
->i_hpfs_conv
!= CONV_TEXT
|| a
< 0) {
69 for (i
= 0, j
= 0; i
< a
; i
++) {
72 if ((error
= get_user(c
, buf
+ i
))) return error
;
74 if (i
!= j
) put_user(c
, buf
+ j
);
81 ssize_t
hpfs_file_write(struct file
*filp
, const char *buf
, size_t count
,
84 struct inode
*i
= filp
->f_dentry
->d_inode
;
86 const char *start
= buf
;
87 if (!i
) return -EINVAL
;
88 if (!S_ISREG(i
->i_mode
)) return -EINVAL
;
89 if (IS_IMMUTABLE(i
)) return -EPERM
;
90 if (filp
->f_flags
& O_APPEND
) *ppos
= i
->i_size
;
91 if (count
<= 0) return 0;
92 if ((unsigned)(*ppos
+count
) >= 0x80000000U
|| (unsigned)count
>= 0x80000000U
) return -EFBIG
;
94 while (count
|| carry
) {
96 secno sec
= 0; /* Go away, uninitialized variable warning */
97 int offset
, size
, written
;
99 struct buffer_head
*bh
;
101 offset
= *ppos
& 0x1ff;
102 size
= count
> 0x200 - offset
? 0x200 - offset
: count
;
103 if ((*ppos
>> 9) < ((i
->i_size
+ 0x1ff) >> 9)) {
104 i
->i_hpfs_n_secs
= 0;
105 if (!(sec
= hpfs_bmap(i
, *ppos
>> 9))) {
106 hpfs_error(i
->i_sb
, "bmap failed, file %08x, fsec %08x",
107 i
->i_ino
, *ppos
>> 9);
111 } else for (ii
= (i
->i_size
+ 0x1ff) >> 9, add
= 1; ii
<= *ppos
>> 9; ii
++) {
112 if ((sec
= hpfs_add_sector_to_btree(i
->i_sb
, i
->i_ino
, 1, ii
)) == -1) {
116 if (*ppos
!= i
->i_size
)
117 if ((data
= hpfs_get_sector(i
->i_sb
, sec
, &bh
))) {
118 memset(data
, 0, 512);
119 mark_buffer_dirty(bh
, 0);
122 i
->i_size
= 0x200 * ii
+ 1;
124 /*mark_inode_dirty(i);*/i
->i_hpfs_dirty
= 1;
125 if (i
->i_sb
->s_hpfs_chk
>= 2) {
127 bsec
= hpfs_bmap(i
, ii
);
129 hpfs_error(i
->i_sb
, "sec == %08x, bmap returns %08x", sec
, bsec
);
134 PRINTK(("file_write: added %08x\n", sec
));
136 if (!sec
|| sec
== 15) {
137 hpfs_error(i
->i_sb
, "bmap returned empty sector");
141 if (i
->i_sb
->s_hpfs_chk
)
142 if (hpfs_chk_sectors(i
->i_sb
, sec
, 1, "data")) {
146 if ((!offset
&& size
== 0x200) || add
)
147 data
= hpfs_get_sector(i
->i_sb
, sec
, &bh
);
148 else data
= hpfs_map_sector(i
->i_sb
, sec
, &bh
, 0);
153 if (i
->i_hpfs_conv
!= CONV_TEXT
) {
154 memcpy_fromfs(data
+ offset
, buf
, written
= size
);
159 /* LF->CR/LF conversion, stolen from fat fs */
160 written
= left
= 0x200 - offset
;
161 to
= (char *) bh
->b_data
+ (*ppos
& 0x1ff);
167 for (size
= 0; size
< count
&& left
; size
++) {
168 if ((error
= get_user(ch
, buf
++))) break;
173 if (!left
) carry
= 1;
181 update_vm_cache(i
, *ppos
, bh
->b_data
+ (*ppos
& 0x1ff), written
);
183 if (*ppos
> i
->i_size
) {
185 /*mark_inode_dirty(i);*/i
->i_hpfs_dirty
= 1;
187 mark_buffer_dirty(bh
, 0);
191 if (start
== buf
) return error
;
192 i
->i_mtime
= CURRENT_TIME
;
193 /*mark_inode_dirty(i);*/i
->i_hpfs_dirty
= 1;