Import 2.1.118
[davej-history.git] / fs / minix / dir.c
blobdc3e63347cf7d5b325c3d029135223d79fe5be40
1 /*
2 * linux/fs/minix/dir.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * minix directory handling functions
7 */
9 #include <linux/string.h>
10 #include <linux/errno.h>
11 #include <linux/fs.h>
12 #include <linux/minix_fs.h>
13 #include <linux/stat.h>
15 #include <asm/uaccess.h>
17 static ssize_t minix_dir_read(struct file * filp, char * buf,
18 size_t count, loff_t *ppos)
20 return -EISDIR;
23 static int minix_readdir(struct file *, void *, filldir_t);
25 static struct file_operations minix_dir_operations = {
26 NULL, /* lseek - default */
27 minix_dir_read, /* read */
28 NULL, /* write - bad */
29 minix_readdir, /* readdir */
30 NULL, /* poll - default */
31 NULL, /* ioctl - default */
32 NULL, /* mmap */
33 NULL, /* no special open code */
34 NULL, /* flush */
35 NULL, /* no special release code */
36 file_fsync /* default fsync */
40 * directories can handle most operations...
42 struct inode_operations minix_dir_inode_operations = {
43 &minix_dir_operations, /* default directory file-ops */
44 minix_create, /* create */
45 minix_lookup, /* lookup */
46 minix_link, /* link */
47 minix_unlink, /* unlink */
48 minix_symlink, /* symlink */
49 minix_mkdir, /* mkdir */
50 minix_rmdir, /* rmdir */
51 minix_mknod, /* mknod */
52 minix_rename, /* rename */
53 NULL, /* readlink */
54 NULL, /* follow_link */
55 NULL, /* readpage */
56 NULL, /* writepage */
57 NULL, /* bmap */
58 minix_truncate, /* truncate */
59 NULL /* permission */
62 static int minix_readdir(struct file * filp,
63 void * dirent, filldir_t filldir)
65 unsigned int offset;
66 struct buffer_head * bh;
67 struct minix_dir_entry * de;
68 struct minix_sb_info * info;
69 struct inode *inode = filp->f_dentry->d_inode;
71 if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode))
72 return -EBADF;
73 info = &inode->i_sb->u.minix_sb;
74 if (filp->f_pos & (info->s_dirsize - 1))
75 return -EBADF;
76 while (filp->f_pos < inode->i_size) {
77 offset = filp->f_pos & 1023;
78 bh = minix_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
79 if (!bh) {
80 filp->f_pos += 1024-offset;
81 continue;
83 do {
84 de = (struct minix_dir_entry *) (offset + bh->b_data);
85 if (de->inode) {
86 int size = strnlen(de->name, info->s_namelen);
87 if (filldir(dirent, de->name, size, filp->f_pos, de->inode) < 0) {
88 brelse(bh);
89 return 0;
92 offset += info->s_dirsize;
93 filp->f_pos += info->s_dirsize;
94 } while (offset < 1024 && filp->f_pos < inode->i_size);
95 brelse(bh);
97 UPDATE_ATIME(inode);
98 return 0;