4 * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
10 * Copyright (C) 1991, 1992 Linus Torvalds
12 * ext directory handling functions
15 #include <asm/segment.h>
17 #include <linux/errno.h>
18 #include <linux/kernel.h>
20 #include <linux/ext_fs.h>
21 #include <linux/stat.h>
23 static int ext_dir_read(struct inode
* inode
, struct file
* filp
, char * buf
, int count
)
28 static int ext_readdir(struct inode
*, struct file
*, struct dirent
*, int);
30 static struct file_operations ext_dir_operations
= {
31 NULL
, /* lseek - default */
32 ext_dir_read
, /* read */
33 NULL
, /* write - bad */
34 ext_readdir
, /* readdir */
35 NULL
, /* select - default */
36 NULL
, /* ioctl - default */
38 NULL
, /* no special open code */
39 NULL
, /* no special release code */
40 file_fsync
/* fsync */
44 * directories can handle most operations...
46 struct inode_operations ext_dir_inode_operations
= {
47 &ext_dir_operations
, /* default directory file-ops */
48 ext_create
, /* create */
49 ext_lookup
, /* lookup */
51 ext_unlink
, /* unlink */
52 ext_symlink
, /* symlink */
53 ext_mkdir
, /* mkdir */
54 ext_rmdir
, /* rmdir */
55 ext_mknod
, /* mknod */
56 ext_rename
, /* rename */
58 NULL
, /* follow_link */
60 ext_truncate
, /* truncate */
64 static int ext_readdir(struct inode
* inode
, struct file
* filp
,
65 struct dirent
* dirent
, int count
)
67 unsigned int offset
,i
;
69 struct buffer_head
* bh
;
70 struct ext_dir_entry
* de
;
72 if (!inode
|| !S_ISDIR(inode
->i_mode
))
74 if (filp
->f_pos
% 8 != 0)
76 while (filp
->f_pos
< inode
->i_size
) {
77 offset
= filp
->f_pos
& 1023;
78 bh
= ext_bread(inode
,(filp
->f_pos
)>>BLOCK_SIZE_BITS
,0);
80 filp
->f_pos
+= 1024-offset
;
83 de
= (struct ext_dir_entry
*) (offset
+ bh
->b_data
);
84 while (offset
< 1024 && filp
->f_pos
< inode
->i_size
) {
85 if (de
->rec_len
< 8 || de
->rec_len
% 8 != 0 ||
86 de
->rec_len
< de
->name_len
+ 8 ||
87 (de
->rec_len
+ filp
->f_pos
- 1) / 1024 > (filp
->f_pos
/ 1024)) {
88 printk ("ext_readdir: bad dir entry, skipping\n");
89 printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
90 inode
->i_dev
, inode
->i_ino
, offset
, de
->rec_len
, de
->name_len
);
91 filp
->f_pos
+= 1024-offset
;
92 if (filp
->f_pos
> inode
->i_size
)
93 filp
->f_pos
= inode
->i_size
;
96 offset
+= de
->rec_len
;
97 filp
->f_pos
+= de
->rec_len
;
99 for (i
= 0; i
< de
->name_len
; i
++)
100 if ((c
= de
->name
[i
]) != 0)
101 put_fs_byte(c
,i
+dirent
->d_name
);
105 put_fs_long(de
->inode
,&dirent
->d_ino
);
106 put_fs_byte(0,i
+dirent
->d_name
);
107 put_fs_word(i
,&dirent
->d_reclen
);
112 de
= (struct ext_dir_entry
*) ((char *) de