4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6 * directory VFS functions
9 #include <linux/slab.h>
12 static int hpfs_dir_release(struct inode
*inode
, struct file
*filp
)
14 hpfs_lock(inode
->i_sb
);
15 hpfs_del_pos(inode
, &filp
->f_pos
);
16 /*hpfs_write_if_changed(inode);*/
17 hpfs_unlock(inode
->i_sb
);
21 /* This is slow, but it's not used often */
23 static loff_t
hpfs_dir_lseek(struct file
*filp
, loff_t off
, int whence
)
25 loff_t new_off
= off
+ (whence
== 1 ? filp
->f_pos
: 0);
27 struct quad_buffer_head qbh
;
28 struct inode
*i
= filp
->f_path
.dentry
->d_inode
;
29 struct hpfs_inode_info
*hpfs_inode
= hpfs_i(i
);
30 struct super_block
*s
= i
->i_sb
;
34 /*printk("dir lseek\n");*/
35 if (new_off
== 0 || new_off
== 1 || new_off
== 11 || new_off
== 12 || new_off
== 13) goto ok
;
36 mutex_lock(&i
->i_mutex
);
37 pos
= ((loff_t
) hpfs_de_as_down_as_possible(s
, hpfs_inode
->i_dno
) << 4) + 1;
38 while (pos
!= new_off
) {
39 if (map_pos_dirent(i
, &pos
, &qbh
)) hpfs_brelse4(&qbh
);
41 if (pos
== 12) goto fail
;
43 mutex_unlock(&i
->i_mutex
);
46 return filp
->f_pos
= new_off
;
48 mutex_unlock(&i
->i_mutex
);
49 /*printk("illegal lseek: %016llx\n", new_off);*/
54 static int hpfs_readdir(struct file
*filp
, void *dirent
, filldir_t filldir
)
56 struct inode
*inode
= filp
->f_path
.dentry
->d_inode
;
57 struct hpfs_inode_info
*hpfs_inode
= hpfs_i(inode
);
58 struct quad_buffer_head qbh
;
59 struct hpfs_dirent
*de
;
62 unsigned char *tempname
;
66 hpfs_lock(inode
->i_sb
);
68 if (hpfs_sb(inode
->i_sb
)->sb_chk
) {
69 if (hpfs_chk_sectors(inode
->i_sb
, inode
->i_ino
, 1, "dir_fnode")) {
73 if (hpfs_chk_sectors(inode
->i_sb
, hpfs_inode
->i_dno
, 4, "dir_dnode")) {
78 if (hpfs_sb(inode
->i_sb
)->sb_chk
>= 2) {
79 struct buffer_head
*bh
;
82 if (!(fno
= hpfs_map_fnode(inode
->i_sb
, inode
->i_ino
, &bh
))) {
88 hpfs_error(inode
->i_sb
, "not a directory, fnode %08lx",
89 (unsigned long)inode
->i_ino
);
91 if (hpfs_inode
->i_dno
!= fno
->u
.external
[0].disk_secno
) {
93 hpfs_error(inode
->i_sb
, "corrupted inode: i_dno == %08x, fnode -> dnode == %08x", hpfs_inode
->i_dno
, fno
->u
.external
[0].disk_secno
);
101 lc
= hpfs_sb(inode
->i_sb
)->sb_lowercase
;
102 if (filp
->f_pos
== 12) { /* diff -r requires this (note, that diff -r */
103 filp
->f_pos
= 13; /* also fails on msdos filesystem in 2.0) */
106 if (filp
->f_pos
== 13) {
113 /* This won't work when cycle is longer than number of dirents
114 accepted by filldir, but what can I do?
115 maybe killall -9 ls helps */
116 if (hpfs_sb(inode
->i_sb
)->sb_chk
)
117 if (hpfs_stop_cycles(inode
->i_sb
, filp
->f_pos
, &c1
, &c2
, "hpfs_readdir")) {
121 if (filp
->f_pos
== 12)
123 if (filp
->f_pos
== 3 || filp
->f_pos
== 4 || filp
->f_pos
== 5) {
124 printk("HPFS: warning: pos==%d\n",(int)filp
->f_pos
);
127 if (filp
->f_pos
== 0) {
128 if (filldir(dirent
, ".", 1, filp
->f_pos
, inode
->i_ino
, DT_DIR
) < 0)
132 if (filp
->f_pos
== 11) {
133 if (filldir(dirent
, "..", 2, filp
->f_pos
, hpfs_inode
->i_parent_dir
, DT_DIR
) < 0)
137 if (filp
->f_pos
== 1) {
138 filp
->f_pos
= ((loff_t
) hpfs_de_as_down_as_possible(inode
->i_sb
, hpfs_inode
->i_dno
) << 4) + 1;
139 hpfs_add_pos(inode
, &filp
->f_pos
);
140 filp
->f_version
= inode
->i_version
;
142 old_pos
= filp
->f_pos
;
143 if (!(de
= map_pos_dirent(inode
, &filp
->f_pos
, &qbh
))) {
147 if (de
->first
|| de
->last
) {
148 if (hpfs_sb(inode
->i_sb
)->sb_chk
) {
149 if (de
->first
&& !de
->last
&& (de
->namelen
!= 2
150 || de
->name
[0] != 1 || de
->name
[1] != 1))
151 hpfs_error(inode
->i_sb
, "hpfs_readdir: bad ^A^A entry; pos = %08lx", old_pos
);
152 if (de
->last
&& (de
->namelen
!= 1 || de
->name
[0] != 255))
153 hpfs_error(inode
->i_sb
, "hpfs_readdir: bad \\377 entry; pos = %08lx", old_pos
);
158 tempname
= hpfs_translate_name(inode
->i_sb
, de
->name
, de
->namelen
, lc
, de
->not_8x3
);
159 if (filldir(dirent
, tempname
, de
->namelen
, old_pos
, de
->fnode
, DT_UNKNOWN
) < 0) {
160 filp
->f_pos
= old_pos
;
161 if (tempname
!= de
->name
) kfree(tempname
);
165 if (tempname
!= de
->name
) kfree(tempname
);
169 hpfs_unlock(inode
->i_sb
);
174 * lookup. Search the specified directory for the specified name, set
175 * *result to the corresponding inode.
177 * lookup uses the inode number to tell read_inode whether it is reading
178 * the inode of a directory or a file -- file ino's are odd, directory
179 * ino's are even. read_inode avoids i/o for file inodes; everything
180 * needed is up here in the directory. (And file fnodes are out in
183 * - M.P.: this is over, sometimes we've got to read file's fnode for eas
184 * inode numbers are just fnode sector numbers; iget lock is used
185 * to tell read_inode to read fnode or not.
188 struct dentry
*hpfs_lookup(struct inode
*dir
, struct dentry
*dentry
, struct nameidata
*nd
)
190 const unsigned char *name
= dentry
->d_name
.name
;
191 unsigned len
= dentry
->d_name
.len
;
192 struct quad_buffer_head qbh
;
193 struct hpfs_dirent
*de
;
196 struct inode
*result
= NULL
;
197 struct hpfs_inode_info
*hpfs_result
;
199 hpfs_lock(dir
->i_sb
);
200 if ((err
= hpfs_chk_name(name
, &len
))) {
201 if (err
== -ENAMETOOLONG
) {
202 hpfs_unlock(dir
->i_sb
);
203 return ERR_PTR(-ENAMETOOLONG
);
209 * '.' and '..' will never be passed here.
212 de
= map_dirent(dir
, hpfs_i(dir
)->i_dno
, name
, len
, NULL
, &qbh
);
215 * This is not really a bailout, just means file not found.
221 * Get inode number, what we're after.
227 * Go find or make an inode.
230 result
= iget_locked(dir
->i_sb
, ino
);
232 hpfs_error(dir
->i_sb
, "hpfs_lookup: can't get inode");
235 if (result
->i_state
& I_NEW
) {
236 hpfs_init_inode(result
);
238 hpfs_read_inode(result
);
239 else if (de
->ea_size
&& hpfs_sb(dir
->i_sb
)->sb_eas
)
240 hpfs_read_inode(result
);
242 result
->i_mode
|= S_IFREG
;
243 result
->i_mode
&= ~0111;
244 result
->i_op
= &hpfs_file_iops
;
245 result
->i_fop
= &hpfs_file_ops
;
248 unlock_new_inode(result
);
250 hpfs_result
= hpfs_i(result
);
251 if (!de
->directory
) hpfs_result
->i_parent_dir
= dir
->i_ino
;
253 hpfs_decide_conv(result
, name
, len
);
255 if (de
->has_acl
|| de
->has_xtd_perm
) if (!(dir
->i_sb
->s_flags
& MS_RDONLY
)) {
256 hpfs_error(result
->i_sb
, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures");
261 * Fill in the info from the directory if this is a newly created
265 if (!result
->i_ctime
.tv_sec
) {
266 if (!(result
->i_ctime
.tv_sec
= local_to_gmt(dir
->i_sb
, de
->creation_date
)))
267 result
->i_ctime
.tv_sec
= 1;
268 result
->i_ctime
.tv_nsec
= 0;
269 result
->i_mtime
.tv_sec
= local_to_gmt(dir
->i_sb
, de
->write_date
);
270 result
->i_mtime
.tv_nsec
= 0;
271 result
->i_atime
.tv_sec
= local_to_gmt(dir
->i_sb
, de
->read_date
);
272 result
->i_atime
.tv_nsec
= 0;
273 hpfs_result
->i_ea_size
= de
->ea_size
;
274 if (!hpfs_result
->i_ea_mode
&& de
->read_only
)
275 result
->i_mode
&= ~0222;
276 if (!de
->directory
) {
277 if (result
->i_size
== -1) {
278 result
->i_size
= de
->file_size
;
279 result
->i_data
.a_ops
= &hpfs_aops
;
280 hpfs_i(result
)->mmu_private
= result
->i_size
;
282 * i_blocks should count the fnode and any anodes.
283 * We count 1 for the fnode and don't bother about
284 * anodes -- the disk heads are on the directory band
285 * and we want them to stay there.
287 result
->i_blocks
= 1 + ((result
->i_size
+ 511) >> 9);
300 hpfs_unlock(dir
->i_sb
);
301 d_add(dentry
, result
);
313 hpfs_unlock(dir
->i_sb
);
314 return ERR_PTR(-ENOENT
);
317 const struct file_operations hpfs_dir_ops
=
319 .llseek
= hpfs_dir_lseek
,
320 .read
= generic_read_dir
,
321 .readdir
= hpfs_readdir
,
322 .release
= hpfs_dir_release
,
323 .fsync
= hpfs_file_fsync
,