OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [ufs/] [ufs_dir.c] - Blame information for rev 1628

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  linux/fs/ufs/ufs_dir.c
3
 *
4
 * Copyright (C) 1996
5
 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
6
 * Laboratory for Computer Science Research Computing Facility
7
 * Rutgers, The State University of New Jersey
8
 *
9
 * $Id: ufs_dir.c,v 1.1 2005-12-20 10:26:35 jcastillo Exp $
10
 *
11
 */
12
 
13
#include <linux/fs.h>
14
 
15
/* XXX */
16
extern int ufs_lookup (struct inode *, const char *, int, struct inode **);
17
extern int ufs_bmap (struct inode *, int);
18
extern void ufs_print_inode (struct inode *);
19
 
20
/*
21
 * This is blatantly stolen from ext2fs
22
 */
23
static int
24
ufs_readdir (struct inode * inode, struct file * filp, void * dirent,
25
             filldir_t filldir)
26
{
27
        int error = 0;
28
        unsigned long offset, lblk, blk;
29
        int i, stored;
30
        struct buffer_head * bh;
31
        struct ufs_direct * de;
32
        struct super_block * sb;
33
 
34
        if (!inode || !S_ISDIR(inode->i_mode))
35
                return -EBADF;
36
        sb = inode->i_sb;
37
 
38
        if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
39
                printk("ufs_readdir: ino %lu  f_pos %lu\n",
40
                       inode->i_ino, (unsigned long) filp->f_pos);
41
                ufs_print_inode(inode);
42
        }
43
 
44
        stored = 0;
45
        bh = NULL;
46
        offset = filp->f_pos & (sb->s_blocksize - 1);
47
 
48
        while (!error && !stored && filp->f_pos < inode->i_size) {
49
                lblk = (filp->f_pos) >> sb->s_blocksize_bits;
50
                blk = ufs_bmap(inode, lblk);
51
                /* XXX - ufs_bmap() call needs error checking */
52
                blk = ufs_bmap(inode, lblk);
53
                bh = bread (sb->s_dev, blk, sb->s_blocksize);
54
                if (!bh) {
55
                        /* XXX - error - skip to the next block */
56
                        printk("ufs_readdir: dir inode %lu has a hole at offset %lu\n",
57
                               inode->i_ino, (unsigned long int)filp->f_pos);
58
                        filp->f_pos += sb->s_blocksize - offset;
59
                        continue;
60
                }
61
 
62
revalidate:
63
                /* If the dir block has changed since the last call to
64
                 * readdir(2), then we might be pointing to an invalid
65
                 * dirent right now.  Scan from the start of the block
66
                 * to make sure. */
67
                if (filp->f_version != inode->i_version) {
68
                        for (i = 0; i < sb->s_blocksize && i < offset; ) {
69
                                de = (struct ufs_direct *)
70
                                        (bh->b_data + i);
71
                                /* It's too expensive to do a full
72
                                 * dirent test each time round this
73
                                 * loop, but we do have to test at
74
                                 * least that it is non-zero.  A
75
                                 * failure will be detected in the
76
                                 * dirent test below. */
77
                                if (de->d_reclen < 1)
78
                                        break;
79
                                i += de->d_reclen;
80
                        }
81
                        offset = i;
82
                        filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
83
                                | offset;
84
                        filp->f_version = inode->i_version;
85
                }
86
 
87
                while (!error && filp->f_pos < inode->i_size
88
                       && offset < sb->s_blocksize) {
89
                        de = (struct ufs_direct *) (bh->b_data + offset);
90
                        /* XXX - put in a real ufs_check_dir_entry() */
91
                        if ((de->d_reclen == 0) || (de->d_namlen == 0)) {
92
                                filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1)) + sb->s_blocksize;
93
                                brelse(bh);
94
                                return stored;
95
                        }
96
#if 0
97
                        if (!ext2_check_dir_entry ("ext2_readdir", inode, de,
98
                                                   bh, offset)) {
99
                                /* On error, skip the f_pos to the
100
                                   next block. */
101
                                filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
102
                                              + sb->s_blocksize;
103
                                brelse (bh);
104
                                return stored;
105
                        }
106
#endif /* XXX */
107
                        offset += de->d_reclen;
108
                        if (de->d_ino) {
109
                                /* We might block in the next section
110
                                 * if the data destination is
111
                                 * currently swapped out.  So, use a
112
                                 * version stamp to detect whether or
113
                                 * not the directory has been modified
114
                                 * during the copy operation. */
115
                                unsigned long version;
116
                                dcache_add(inode, de->d_name, de->d_namlen,
117
                                           de->d_ino);
118
                                version = inode->i_version;
119
                                if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
120
                                        printk("ufs_readdir: filldir(%s,%u)\n",
121
                                               de->d_name, de->d_ino);
122
                                }
123
                                error = filldir(dirent, de->d_name, de->d_namlen, filp->f_pos, de->d_ino);
124
                                if (error)
125
                                        break;
126
                                if (version != inode->i_version)
127
                                        goto revalidate;
128
                                stored ++;
129
                        }
130
                        filp->f_pos += de->d_reclen;
131
                }
132
                offset = 0;
133
                brelse (bh);
134
        }
135
#if 0 /* XXX */
136
        if (!IS_RDONLY(inode)) {
137
                inode->i_atime = CURRENT_TIME;
138
                inode->i_dirt = 1;
139
        }
140
#endif /* XXX */
141
        return 0;
142
}
143
 
144
static struct file_operations ufs_dir_operations = {
145
        NULL,                   /* lseek */
146
        NULL,                   /* read */
147
        NULL,                   /* write */
148
        ufs_readdir,            /* readdir */
149
        NULL,                   /* select */
150
        NULL,                   /* ioctl */
151
        NULL,                   /* mmap */
152
        NULL,                   /* open */
153
        NULL,                   /* release */
154
        file_fsync,             /* fsync */
155
        NULL,                   /* fasync */
156
        NULL,                   /* check_media_change */
157
        NULL,                   /* revalidate */
158
};
159
 
160
struct inode_operations ufs_dir_inode_operations = {
161
        &ufs_dir_operations,    /* default directory file operations */
162
        NULL,                   /* create */
163
        ufs_lookup,             /* lookup */
164
        NULL,                   /* link */
165
        NULL,                   /* unlink */
166
        NULL,                   /* symlink */
167
        NULL,                   /* mkdir */
168
        NULL,                   /* rmdir */
169
        NULL,                   /* mknod */
170
        NULL,                   /* rename */
171
        NULL,                   /* readlink */
172
        NULL,                   /* follow_link */
173
        NULL,                   /* readpage */
174
        NULL,                   /* writepage */
175
        NULL,                   /* bmap */
176
        NULL,                   /* truncate */
177
        NULL,                   /* permission */
178
        NULL,                   /* smap */
179
};
180
 
181
/*
182
 * Local Variables: ***
183
 * c-indent-level: 8 ***
184
 * c-continued-statement-offset: 8 ***
185
 * c-brace-offset: -8 ***
186
 * c-argdecl-indent: 0 ***
187
 * c-label-offset: -8 ***
188
 * End: ***
189
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.