2 * linux/fs/hpfs/inode.c
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
11 static struct file_operations hpfs_file_ops
=
13 read
: generic_file_read
,
14 write
: hpfs_file_write
,
15 mmap
: generic_file_mmap
,
17 release
: hpfs_file_release
,
18 fsync
: hpfs_file_fsync
,
21 static struct inode_operations hpfs_file_iops
=
23 truncate
: hpfs_truncate
,
24 setattr
: hpfs_notify_change
,
27 static struct file_operations hpfs_dir_ops
=
29 llseek
: hpfs_dir_lseek
,
30 read
: generic_read_dir
,
31 readdir
: hpfs_readdir
,
33 release
: hpfs_dir_release
,
34 fsync
: hpfs_file_fsync
,
37 static struct inode_operations hpfs_dir_iops
=
42 symlink
: hpfs_symlink
,
47 setattr
: hpfs_notify_change
,
50 struct address_space_operations hpfs_symlink_aops
= {
51 readpage
: hpfs_symlink_readpage
54 void hpfs_read_inode(struct inode
*i
)
56 struct buffer_head
*bh
;
58 struct super_block
*sb
= i
->i_sb
;
61 init_MUTEX(&i
->i_hpfs_sem
);
62 i
->i_uid
= sb
->s_hpfs_uid
;
63 i
->i_gid
= sb
->s_hpfs_gid
;
64 i
->i_mode
= sb
->s_hpfs_mode
;
65 i
->i_hpfs_conv
= sb
->s_hpfs_conv
;
72 i
->i_hpfs_file_sec
= 0;
73 i
->i_hpfs_disk_sec
= 0;
75 i
->i_hpfs_dsubdno
= 0;
76 i
->i_hpfs_ea_mode
= 0;
79 i
->i_hpfs_ea_size
= 0;
80 i
->i_version
= ++event
;
82 i
->i_hpfs_rddir_off
= NULL
;
89 if (!i
->i_sb
->s_hpfs_rd_inode
)
90 hpfs_error(i
->i_sb
, "read_inode: s_hpfs_rd_inode == 0");
91 if (i
->i_sb
->s_hpfs_rd_inode
== 2) {
94 i
->i_op
= &hpfs_file_iops
;
95 i
->i_fop
= &hpfs_file_ops
;
99 if (!(fnode
= hpfs_map_fnode(sb
, i
->i_ino
, &bh
))) {
100 /*i->i_mode |= S_IFREG;
102 i->i_op = &hpfs_file_iops;
103 i->i_fop = &hpfs_file_ops;
108 if (i
->i_sb
->s_hpfs_eas
) {
109 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "UID", &ea_size
))) {
111 i
->i_uid
= ea
[0] + (ea
[1] << 8);
112 i
->i_hpfs_ea_uid
= 1;
116 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "GID", &ea_size
))) {
118 i
->i_gid
= ea
[0] + (ea
[1] << 8);
119 i
->i_hpfs_ea_gid
= 1;
123 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "SYMLINK", &ea_size
))) {
125 i
->i_mode
= S_IFLNK
| 0777;
126 i
->i_op
= &page_symlink_inode_operations
;
127 i
->i_data
.a_ops
= &hpfs_symlink_aops
;
134 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "MODE", &ea_size
))) {
136 umode_t mode
= sb
->s_hpfs_mode
;
138 mode
= ea
[0] + (ea
[1] << 8);
139 i
->i_hpfs_ea_mode
= 1;
143 if (S_ISBLK(mode
) || S_ISCHR(mode
)) {
144 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "DEV", &ea_size
))) {
146 rdev
= ea
[0] + (ea
[1] << 8) + (ea
[2] << 16) + (ea
[3] << 24);
150 if (S_ISBLK(mode
) || S_ISCHR(mode
) || S_ISFIFO(mode
) || S_ISSOCK(mode
)) {
155 init_special_inode(i
, mode
, rdev
);
160 if (fnode
->dirflag
) {
161 unsigned n_dnodes
, n_subdirs
;
162 i
->i_mode
|= S_IFDIR
;
163 i
->i_op
= &hpfs_dir_iops
;
164 i
->i_fop
= &hpfs_dir_ops
;
165 i
->i_hpfs_parent_dir
= fnode
->up
;
166 i
->i_hpfs_dno
= fnode
->u
.external
[0].disk_secno
;
167 if (sb
->s_hpfs_chk
>= 2) {
168 struct buffer_head
*bh0
;
169 if (hpfs_map_fnode(sb
, i
->i_hpfs_parent_dir
, &bh0
)) brelse(bh0
);
171 n_dnodes
= 0; n_subdirs
= 0;
172 hpfs_count_dnodes(i
->i_sb
, i
->i_hpfs_dno
, &n_dnodes
, &n_subdirs
, NULL
);
173 i
->i_blocks
= 4 * n_dnodes
;
174 i
->i_size
= 2048 * n_dnodes
;
175 i
->i_nlink
= 2 + n_subdirs
;
177 i
->i_mode
|= S_IFREG
;
178 if (!i
->i_hpfs_ea_mode
) i
->i_mode
&= ~0111;
179 i
->i_op
= &hpfs_file_iops
;
180 i
->i_fop
= &hpfs_file_ops
;
182 i
->i_size
= fnode
->file_size
;
183 i
->i_blocks
= ((i
->i_size
+ 511) >> 9) + 1;
184 i
->i_data
.a_ops
= &hpfs_aops
;
185 i
->u
.hpfs_i
.mmu_private
= i
->i_size
;
190 void hpfs_write_inode_ea(struct inode
*i
, struct fnode
*fnode
)
192 if (fnode
->acl_size_l
|| fnode
->acl_size_s
) {
193 /* Some unknown structures like ACL may be in fnode,
194 we'd better not overwrite them */
195 hpfs_error(i
->i_sb
, "fnode %08x has some unknown HPFS386 stuctures", i
->i_ino
);
196 } else if (i
->i_sb
->s_hpfs_eas
>= 2) {
198 if ((i
->i_uid
!= i
->i_sb
->s_hpfs_uid
) || i
->i_hpfs_ea_uid
) {
199 ea
[0] = i
->i_uid
& 0xff;
200 ea
[1] = i
->i_uid
>> 8;
201 hpfs_set_ea(i
, fnode
, "UID", ea
, 2);
202 i
->i_hpfs_ea_uid
= 1;
204 if ((i
->i_gid
!= i
->i_sb
->s_hpfs_gid
) || i
->i_hpfs_ea_gid
) {
205 ea
[0] = i
->i_gid
& 0xff;
206 ea
[1] = i
->i_gid
>> 8;
207 hpfs_set_ea(i
, fnode
, "GID", ea
, 2);
208 i
->i_hpfs_ea_gid
= 1;
210 if (!S_ISLNK(i
->i_mode
))
211 if ((i
->i_mode
!= ((i
->i_sb
->s_hpfs_mode
& ~(S_ISDIR(i
->i_mode
) ? 0 : 0111))
212 | (S_ISDIR(i
->i_mode
) ? S_IFDIR
: S_IFREG
))
213 && i
->i_mode
!= ((i
->i_sb
->s_hpfs_mode
& ~(S_ISDIR(i
->i_mode
) ? 0222 : 0333))
214 | (S_ISDIR(i
->i_mode
) ? S_IFDIR
: S_IFREG
))) || i
->i_hpfs_ea_mode
) {
215 ea
[0] = i
->i_mode
& 0xff;
216 ea
[1] = i
->i_mode
>> 8;
217 hpfs_set_ea(i
, fnode
, "MODE", ea
, 2);
218 i
->i_hpfs_ea_mode
= 1;
220 if (S_ISBLK(i
->i_mode
) || S_ISCHR(i
->i_mode
)) {
221 int d
= kdev_t_to_nr(i
->i_rdev
);
223 ea
[1] = (d
>> 8) & 0xff;
224 ea
[2] = (d
>> 16) & 0xff;
226 hpfs_set_ea(i
, fnode
, "DEV", ea
, 4);
231 void hpfs_write_inode(struct inode
*i
)
233 struct inode
*parent
;
234 if (!i
->i_nlink
) return;
235 if (i
->i_ino
== i
->i_sb
->s_hpfs_root
) return;
236 if (i
->i_hpfs_rddir_off
&& !atomic_read(&i
->i_count
)) {
237 if (*i
->i_hpfs_rddir_off
) printk("HPFS: write_inode: some position still there\n");
238 kfree(i
->i_hpfs_rddir_off
);
239 i
->i_hpfs_rddir_off
= NULL
;
242 hpfs_lock_iget(i
->i_sb
, 1);
243 parent
= iget(i
->i_sb
, i
->i_hpfs_parent_dir
);
244 hpfs_unlock_iget(i
->i_sb
);
245 hpfs_lock_inode(parent
);
246 hpfs_write_inode_nolock(i
);
247 hpfs_unlock_inode(parent
);
251 void hpfs_write_inode_nolock(struct inode
*i
)
253 struct buffer_head
*bh
;
255 struct quad_buffer_head qbh
;
256 struct hpfs_dirent
*de
;
257 if (i
->i_ino
== i
->i_sb
->s_hpfs_root
) return;
258 if (!(fnode
= hpfs_map_fnode(i
->i_sb
, i
->i_ino
, &bh
))) return;
259 if (i
->i_ino
!= i
->i_sb
->s_hpfs_root
) {
260 if (!(de
= map_fnode_dirent(i
->i_sb
, i
->i_ino
, fnode
, &qbh
))) {
265 if (S_ISREG(i
->i_mode
)) {
266 fnode
->file_size
= de
->file_size
= i
->i_size
;
267 } else if (S_ISDIR(i
->i_mode
)) {
268 fnode
->file_size
= de
->file_size
= 0;
270 hpfs_write_inode_ea(i
, fnode
);
272 de
->write_date
= gmt_to_local(i
->i_sb
, i
->i_mtime
);
273 de
->read_date
= gmt_to_local(i
->i_sb
, i
->i_atime
);
274 de
->creation_date
= gmt_to_local(i
->i_sb
, i
->i_ctime
);
275 de
->read_only
= !(i
->i_mode
& 0222);
276 de
->ea_size
= i
->i_hpfs_ea_size
;
277 hpfs_mark_4buffers_dirty(&qbh
);
280 if (S_ISDIR(i
->i_mode
)) {
281 if ((de
= map_dirent(i
, i
->i_hpfs_dno
, "\001\001", 2, NULL
, &qbh
))) {
282 de
->write_date
= gmt_to_local(i
->i_sb
, i
->i_mtime
);
283 de
->read_date
= gmt_to_local(i
->i_sb
, i
->i_atime
);
284 de
->creation_date
= gmt_to_local(i
->i_sb
, i
->i_ctime
);
285 de
->read_only
= !(i
->i_mode
& 0222);
286 de
->ea_size
= /*i->i_hpfs_ea_size*/0;
288 hpfs_mark_4buffers_dirty(&qbh
);
290 } else hpfs_error(i
->i_sb
, "directory %08x doesn't have '.' entry", i
->i_ino
);
292 mark_buffer_dirty(bh
, 1);
296 int hpfs_notify_change(struct dentry
*dentry
, struct iattr
*attr
)
298 struct inode
*inode
= dentry
->d_inode
;
300 if (inode
->i_sb
->s_hpfs_root
== inode
->i_ino
) return -EINVAL
;
301 if ((error
= inode_change_ok(inode
, attr
))) return error
;
302 inode_setattr(inode
, attr
);
303 hpfs_write_inode(inode
);
307 void hpfs_write_if_changed(struct inode
*inode
)
309 if (inode
->i_hpfs_dirty
) {
310 hpfs_write_inode(inode
);
314 void hpfs_delete_inode(struct inode
*inode
)
316 hpfs_remove_fnode(inode
->i_sb
, inode
->i_ino
);