5 * Copyright (C) 1991, 1992 Linus Torvalds
8 * Copyright (C) 1993 Pascal Haible, Bruno Haible
11 * Copyright (C) 1993 Bruno Haible
13 * SystemV/Coherent directory handling functions
16 #include <linux/errno.h>
18 #include <linux/sysv_fs.h>
19 #include <linux/stat.h>
20 #include <linux/string.h>
22 #include <asm/uaccess.h>
24 static ssize_t
sysv_dir_read(struct file
* filp
, char * buf
,
25 size_t count
, loff_t
*ppos
)
30 static int sysv_readdir(struct file
*, void *, filldir_t
);
32 static struct file_operations sysv_dir_operations
= {
33 NULL
, /* lseek - default */
34 sysv_dir_read
, /* read */
35 NULL
, /* write - bad */
36 sysv_readdir
, /* readdir */
37 NULL
, /* poll - default */
38 NULL
, /* ioctl - default */
40 NULL
, /* no special open code */
42 NULL
, /* no special release code */
43 file_fsync
/* default fsync */
47 * directories can handle most operations...
49 struct inode_operations sysv_dir_inode_operations
= {
50 &sysv_dir_operations
, /* default directory file-ops */
51 sysv_create
, /* create */
52 sysv_lookup
, /* lookup */
54 sysv_unlink
, /* unlink */
55 sysv_symlink
, /* symlink */
56 sysv_mkdir
, /* mkdir */
57 sysv_rmdir
, /* rmdir */
58 sysv_mknod
, /* mknod */
59 sysv_rename
, /* rename */
61 NULL
, /* follow_link */
65 sysv_truncate
, /* truncate */
69 static int sysv_readdir(struct file
* filp
, void * dirent
, filldir_t filldir
)
71 struct inode
*inode
= filp
->f_dentry
->d_inode
;
72 struct super_block
* sb
;
73 unsigned int offset
,i
;
74 struct buffer_head
* bh
;
76 struct sysv_dir_entry
* de
, sde
;
78 if (!inode
|| !(sb
= inode
->i_sb
) || !S_ISDIR(inode
->i_mode
))
80 if ((unsigned long)(filp
->f_pos
) % SYSV_DIRSIZE
)
82 while (filp
->f_pos
< inode
->i_size
) {
83 offset
= filp
->f_pos
& sb
->sv_block_size_1
;
84 bh
= sysv_file_bread(inode
, filp
->f_pos
>> sb
->sv_block_size_bits
, 0);
86 filp
->f_pos
+= sb
->sv_block_size
- offset
;
90 while (offset
< sb
->sv_block_size
&& filp
->f_pos
< inode
->i_size
) {
91 de
= (struct sysv_dir_entry
*) (offset
+ bh_data
);
93 /* Copy the directory entry first, because the directory
94 * might be modified while we sleep in filldir()...
96 memcpy(&sde
, de
, sizeof(struct sysv_dir_entry
));
98 if (sde
.inode
> inode
->i_sb
->sv_ninodes
)
99 printk("sysv_readdir: Bad inode number on dev "
100 "%s, ino %ld, offset 0x%04lx: %d is out of range\n",
101 kdevname(inode
->i_dev
),
102 inode
->i_ino
, (off_t
) filp
->f_pos
, sde
.inode
);
104 i
= strnlen(sde
.name
, SYSV_NAMELEN
);
105 if (filldir(dirent
, sde
.name
, i
, filp
->f_pos
, sde
.inode
) < 0) {
110 offset
+= SYSV_DIRSIZE
;
111 filp
->f_pos
+= SYSV_DIRSIZE
;