2 * linux/fs/hpfs/inode.c
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
11 static const struct file_operations hpfs_file_ops
=
13 NULL
, /* lseek - default */
14 hpfs_file_read
, /* read */
15 hpfs_file_write
, /* write */
16 NULL
, /* readdir - bad */
17 NULL
, /* poll - default */
18 NULL
, /* ioctl - default */
19 generic_file_mmap
/*hpfs_mmap*/, /* mmap */
22 hpfs_file_release
, /* release */
23 hpfs_file_fsync
, /* fsync */
25 NULL
, /* check_media_change */
26 NULL
, /* revalidate */
30 static const struct inode_operations hpfs_file_iops
=
32 (nonconst
*) & hpfs_file_ops
, /* default file operations */
43 NULL
, /* follow_link */
44 generic_readpage
, /* readpage */
46 (int (*)(struct inode
*, int))
47 &hpfs_bmap
, /* bmap */
48 &hpfs_truncate
, /* truncate */
49 NULL
, /* permission */
51 NULL
, /* updatepage */
52 NULL
, /* revalidate */
55 static const struct file_operations hpfs_dir_ops
=
57 NULL
, /* lseek - default */
58 hpfs_dir_read
, /* read */
59 NULL
, /* write - bad */
60 hpfs_readdir
, /* readdir */
61 NULL
, /* poll - default */
62 NULL
, /* ioctl - default */
66 hpfs_dir_release
, /* no special release code */
67 hpfs_file_fsync
, /* fsync */
69 NULL
, /* check_media_change */
70 NULL
, /* revalidate */
74 static const struct inode_operations hpfs_dir_iops
=
76 (nonconst
*) & hpfs_dir_ops
, /* default directory file ops */
77 hpfs_create
, /* create */
78 hpfs_lookup
, /* lookup */
80 hpfs_unlink
, /* unlink */
81 hpfs_symlink
, /* symlink */
82 hpfs_mkdir
, /* mkdir */
83 hpfs_rmdir
, /* rmdir */
84 hpfs_mknod
, /* mknod */
85 hpfs_rename
, /* rename */
87 NULL
, /* follow_link */
92 NULL
, /* permission */
94 NULL
, /* updatepage */
95 NULL
, /* revalidate */
98 const struct inode_operations hpfs_symlink_iops
=
100 NULL
, /* default file operations */
110 hpfs_readlink
, /* readlink */
111 hpfs_follow_link
, /* follow_link */
113 NULL
, /* writepage */
116 NULL
, /* permission */
118 NULL
, /* updatepage */
119 NULL
, /* revalidate */
123 void hpfs_read_inode(struct inode
*i
)
125 struct buffer_head
*bh
;
127 struct super_block
*sb
= i
->i_sb
;
131 /*i->i_hpfs_sem = MUTEX;*/
132 init_MUTEX(&i
->i_hpfs_sem
);
133 i
->i_uid
= sb
->s_hpfs_uid
;
134 i
->i_gid
= sb
->s_hpfs_gid
;
135 i
->i_mode
= sb
->s_hpfs_mode
;
136 i
->i_hpfs_conv
= sb
->s_hpfs_conv
;
142 i
->i_hpfs_n_secs
= 0;
143 i
->i_hpfs_file_sec
= 0;
144 i
->i_hpfs_disk_sec
= 0;
146 i
->i_hpfs_dsubdno
= 0;
147 i
->i_hpfs_ea_mode
= 0;
148 i
->i_hpfs_ea_uid
= 0;
149 i
->i_hpfs_ea_gid
= 0;
150 i
->i_hpfs_ea_size
= 0;
151 i
->i_version
= ++event
;
153 i
->i_hpfs_rddir_off
= NULL
;
160 if (!i
->i_sb
->s_hpfs_rd_inode
)
161 hpfs_error(i
->i_sb
, "read_inode: s_hpfs_rd_inode == 0");
162 if (i
->i_sb
->s_hpfs_rd_inode
== 2) {
163 i
->i_mode
|= S_IFREG
;
165 i
->i_op
= (struct inode_operations
*) &hpfs_file_iops
;
169 if (!(fnode
= hpfs_map_fnode(sb
, i
->i_ino
, &bh
))) {
170 /*i->i_mode |= S_IFREG;
172 i->i_op = (struct inode_operations *) &hpfs_file_iops;
177 if (i
->i_sb
->s_hpfs_eas
) {
178 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "UID", &ea_size
))) {
180 i
->i_uid
= ea
[0] + (ea
[1] << 8);
181 i
->i_hpfs_ea_uid
= 1;
185 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "GID", &ea_size
))) {
187 i
->i_gid
= ea
[0] + (ea
[1] << 8);
188 i
->i_hpfs_ea_gid
= 1;
192 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "SYMLINK", &ea_size
))) {
194 i
->i_mode
= S_IFLNK
| 0777;
195 i
->i_op
= (struct inode_operations
*) &hpfs_symlink_iops
;
202 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "MODE", &ea_size
))) {
204 umode_t mode
= sb
->s_hpfs_mode
;
206 mode
= ea
[0] + (ea
[1] << 8);
207 i
->i_hpfs_ea_mode
= 1;
211 if (S_ISBLK(mode
) || S_ISCHR(mode
)) {
212 if ((ea
= hpfs_get_ea(i
->i_sb
, fnode
, "DEV", &ea_size
))) {
214 rdev
= ea
[0] + (ea
[1] << 8) + (ea
[2] << 16) + (ea
[3] << 24);
218 if (S_ISBLK(mode
) || S_ISCHR(mode
) || S_ISFIFO(mode
) || S_ISSOCK(mode
)) {
223 init_special_inode(i
, mode
, rdev
);
228 if (fnode
->dirflag
) {
229 unsigned n_dnodes
, n_subdirs
;
230 i
->i_mode
|= S_IFDIR
;
231 i
->i_op
= (struct inode_operations
*) &hpfs_dir_iops
;
232 i
->i_hpfs_parent_dir
= fnode
->up
;
233 i
->i_hpfs_dno
= fnode
->u
.external
[0].disk_secno
;
234 if (sb
->s_hpfs_chk
>= 2) {
235 struct buffer_head
*bh0
;
236 if (hpfs_map_fnode(sb
, i
->i_hpfs_parent_dir
, &bh0
)) brelse(bh0
);
238 n_dnodes
= 0; n_subdirs
= 0;
239 hpfs_count_dnodes(i
->i_sb
, i
->i_hpfs_dno
, &n_dnodes
, &n_subdirs
, NULL
);
240 i
->i_blocks
= 4 * n_dnodes
;
241 i
->i_size
= 2048 * n_dnodes
;
242 i
->i_nlink
= 2 + n_subdirs
;
244 i
->i_mode
|= S_IFREG
;
245 if (!i
->i_hpfs_ea_mode
) i
->i_mode
&= ~0111;
246 i
->i_op
= (struct inode_operations
*) &hpfs_file_iops
;
248 i
->i_size
= fnode
->file_size
;
249 i
->i_blocks
= ((i
->i_size
+ 511) >> 9) + 1;
254 void hpfs_write_inode_ea(struct inode
*i
, struct fnode
*fnode
)
256 if (fnode
->acl_size_l
|| fnode
->acl_size_s
) {
257 /* Some unknown structures like ACL may be in fnode,
258 we'd better not overwrite them */
259 hpfs_error(i
->i_sb
, "fnode %08x has some unknown HPFS386 stuctures", i
->i_ino
);
260 } else if (i
->i_sb
->s_hpfs_eas
>= 2) {
262 if ((i
->i_uid
!= i
->i_sb
->s_hpfs_uid
) || i
->i_hpfs_ea_uid
) {
263 ea
[0] = i
->i_uid
& 0xff;
264 ea
[1] = i
->i_uid
>> 8;
265 hpfs_set_ea(i
, fnode
, "UID", ea
, 2);
266 i
->i_hpfs_ea_uid
= 1;
268 if ((i
->i_gid
!= i
->i_sb
->s_hpfs_gid
) || i
->i_hpfs_ea_gid
) {
269 ea
[0] = i
->i_gid
& 0xff;
270 ea
[1] = i
->i_gid
>> 8;
271 hpfs_set_ea(i
, fnode
, "GID", ea
, 2);
272 i
->i_hpfs_ea_gid
= 1;
274 if (!S_ISLNK(i
->i_mode
))
275 if ((i
->i_mode
!= ((i
->i_sb
->s_hpfs_mode
& ~(S_ISDIR(i
->i_mode
) ? 0 : 0111))
276 | (S_ISDIR(i
->i_mode
) ? S_IFDIR
: S_IFREG
))
277 && i
->i_mode
!= ((i
->i_sb
->s_hpfs_mode
& ~(S_ISDIR(i
->i_mode
) ? 0222 : 0333))
278 | (S_ISDIR(i
->i_mode
) ? S_IFDIR
: S_IFREG
))) || i
->i_hpfs_ea_mode
) {
279 ea
[0] = i
->i_mode
& 0xff;
280 ea
[1] = i
->i_mode
>> 8;
281 hpfs_set_ea(i
, fnode
, "MODE", ea
, 2);
282 i
->i_hpfs_ea_mode
= 1;
284 if (S_ISBLK(i
->i_mode
) || S_ISCHR(i
->i_mode
)) {
285 int d
= kdev_t_to_nr(i
->i_rdev
);
287 ea
[1] = (d
>> 8) & 0xff;
288 ea
[2] = (d
>> 16) & 0xff;
290 hpfs_set_ea(i
, fnode
, "DEV", ea
, 4);
295 void hpfs_write_inode(struct inode
*i
)
297 struct inode
*parent
;
298 if (!i
->i_nlink
) return;
299 if (i
->i_ino
== i
->i_sb
->s_hpfs_root
) return;
300 if (i
->i_hpfs_rddir_off
&& !i
->i_count
) {
301 if (*i
->i_hpfs_rddir_off
) printk("HPFS: write_inode: some position still there\n");
302 kfree(i
->i_hpfs_rddir_off
);
303 i
->i_hpfs_rddir_off
= NULL
;
306 hpfs_lock_iget(i
->i_sb
, 1);
307 parent
= iget(i
->i_sb
, i
->i_hpfs_parent_dir
);
308 hpfs_unlock_iget(i
->i_sb
);
309 hpfs_lock_inode(parent
);
310 hpfs_write_inode_nolock(i
);
311 hpfs_unlock_inode(parent
);
315 void hpfs_write_inode_nolock(struct inode
*i
)
317 struct buffer_head
*bh
;
319 struct quad_buffer_head qbh
;
320 struct hpfs_dirent
*de
;
321 if (i
->i_ino
== i
->i_sb
->s_hpfs_root
) return;
322 if (!(fnode
= hpfs_map_fnode(i
->i_sb
, i
->i_ino
, &bh
))) return;
323 if (i
->i_ino
!= i
->i_sb
->s_hpfs_root
) {
324 if (!(de
= map_fnode_dirent(i
->i_sb
, i
->i_ino
, fnode
, &qbh
))) {
329 if (S_ISREG(i
->i_mode
)) {
330 fnode
->file_size
= de
->file_size
= i
->i_size
;
331 } else if (S_ISDIR(i
->i_mode
)) {
332 fnode
->file_size
= de
->file_size
= 0;
334 hpfs_write_inode_ea(i
, fnode
);
336 de
->write_date
= gmt_to_local(i
->i_sb
, i
->i_mtime
);
337 de
->read_date
= gmt_to_local(i
->i_sb
, i
->i_atime
);
338 de
->creation_date
= gmt_to_local(i
->i_sb
, i
->i_ctime
);
339 de
->read_only
= !(i
->i_mode
& 0222);
340 de
->ea_size
= i
->i_hpfs_ea_size
;
341 hpfs_mark_4buffers_dirty(&qbh
);
344 if (S_ISDIR(i
->i_mode
)) {
345 if ((de
= map_dirent(i
, i
->i_hpfs_dno
, "\001\001", 2, NULL
, &qbh
))) {
346 de
->write_date
= gmt_to_local(i
->i_sb
, i
->i_mtime
);
347 de
->read_date
= gmt_to_local(i
->i_sb
, i
->i_atime
);
348 de
->creation_date
= gmt_to_local(i
->i_sb
, i
->i_ctime
);
349 de
->read_only
= !(i
->i_mode
& 0222);
350 de
->ea_size
= /*i->i_hpfs_ea_size*/0;
352 hpfs_mark_4buffers_dirty(&qbh
);
354 } else hpfs_error(i
->i_sb
, "directory %08x doesn't have '.' entry", i
->i_ino
);
356 mark_buffer_dirty(bh
, 1);
360 int hpfs_notify_change(struct dentry
*dentry
, struct iattr
*attr
)
362 struct inode
*inode
= dentry
->d_inode
;
364 if (inode
->i_sb
->s_hpfs_root
== inode
->i_ino
) return -EINVAL
;
365 if ((error
= inode_change_ok(inode
, attr
))) return error
;
366 inode_setattr(inode
, attr
);
367 hpfs_write_inode(inode
);
371 void hpfs_write_if_changed(struct inode
*inode
)
373 if (inode
->i_hpfs_dirty
) {
374 hpfs_write_inode(inode
);
378 void hpfs_delete_inode(struct inode
*inode
)
380 hpfs_remove_fnode(inode
->i_sb
, inode
->i_ino
);