Import 1.3.16
[davej-history.git] / fs / sysv / dir.c
blob3e97711424c68b02e04cb6ca60382dca784b7f90
1 /*
2 * linux/fs/sysv/dir.c
4 * minix/dir.c
5 * Copyright (C) 1991, 1992 Linus Torvalds
7 * coh/dir.c
8 * Copyright (C) 1993 Pascal Haible, Bruno Haible
10 * sysv/dir.c
11 * Copyright (C) 1993 Bruno Haible
13 * SystemV/Coherent directory handling functions
16 #ifdef MODULE
17 #include <linux/module.h>
18 #endif
20 #include <asm/segment.h>
22 #include <linux/errno.h>
23 #include <linux/fs.h>
24 #include <linux/sysv_fs.h>
25 #include <linux/stat.h>
26 #include <linux/string.h>
28 static intsysv_dir_read(struct inode * inode,struct file * filp,char* buf,int count)
30 return-EISDIR;
33 static intsysv_readdir(struct inode *,struct file *,void*, filldir_t);
35 static struct file_operations sysv_dir_operations = {
36 NULL,/* lseek - default */
37 sysv_dir_read,/* read */
38 NULL,/* write - bad */
39 sysv_readdir,/* readdir */
40 NULL,/* select - default */
41 NULL,/* ioctl - default */
42 NULL,/* mmap */
43 NULL,/* no special open code */
44 NULL,/* no special release code */
45 file_fsync /* default fsync */
49 * directories can handle most operations...
51 struct inode_operations sysv_dir_inode_operations = {
52 &sysv_dir_operations,/* default directory file-ops */
53 sysv_create,/* create */
54 sysv_lookup,/* lookup */
55 sysv_link,/* link */
56 sysv_unlink,/* unlink */
57 sysv_symlink,/* symlink */
58 sysv_mkdir,/* mkdir */
59 sysv_rmdir,/* rmdir */
60 sysv_mknod,/* mknod */
61 sysv_rename,/* rename */
62 NULL,/* readlink */
63 NULL,/* follow_link */
64 NULL,/* bmap */
65 sysv_truncate,/* truncate */
66 NULL /* permission */
69 static intsysv_readdir(struct inode * inode,struct file * filp,
70 void* dirent, filldir_t filldir)
72 struct super_block * sb;
73 unsigned int offset,i;
74 struct buffer_head * bh;
75 char* bh_data;
76 struct sysv_dir_entry * de, sde;
78 if(!inode || !(sb = inode->i_sb) || !S_ISDIR(inode->i_mode))
79 return-EBADF;
80 if((unsigned long)(filp->f_pos) % SYSV_DIRSIZE)
81 return-EBADF;
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);
85 if(!bh) {
86 filp->f_pos += sb->sv_block_size - offset;
87 continue;
89 bh_data = bh->b_data;
90 while(offset < sb->sv_block_size && filp->f_pos < inode->i_size) {
91 de = (struct sysv_dir_entry *) (offset + bh_data);
92 if(de->inode) {
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 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n",
100 inode->i_dev, inode->i_ino, (off_t) filp->f_pos, sde.inode);
102 i =strnlen(sde.name, SYSV_NAMELEN);
103 if(filldir(dirent, sde.name, i, filp->f_pos, sde.inode) <0) {
104 brelse(bh);
105 return0;
108 offset += SYSV_DIRSIZE;
109 filp->f_pos += SYSV_DIRSIZE;
111 brelse(bh);
113 return0;
close