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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [efs/] [namei.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * namei.c
3
 *
4
 * Copyright (c) 1999 Al Smith
5
 *
6
 * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
7
 */
8
 
9
#include <linux/buffer_head.h>
10
#include <linux/string.h>
11
#include <linux/efs_fs.h>
12
#include <linux/smp_lock.h>
13
#include <linux/exportfs.h>
14
 
15
 
16
static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
17
        struct buffer_head *bh;
18
 
19
        int                     slot, namelen;
20
        char                    *nameptr;
21
        struct efs_dir          *dirblock;
22
        struct efs_dentry       *dirslot;
23
        efs_ino_t               inodenum;
24
        efs_block_t             block;
25
 
26
        if (inode->i_size & (EFS_DIRBSIZE-1))
27
                printk(KERN_WARNING "EFS: WARNING: find_entry(): directory size not a multiple of EFS_DIRBSIZE\n");
28
 
29
        for(block = 0; block < inode->i_blocks; block++) {
30
 
31
                bh = sb_bread(inode->i_sb, efs_bmap(inode, block));
32
                if (!bh) {
33
                        printk(KERN_ERR "EFS: find_entry(): failed to read dir block %d\n", block);
34
                        return 0;
35
                }
36
 
37
                dirblock = (struct efs_dir *) bh->b_data;
38
 
39
                if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) {
40
                        printk(KERN_ERR "EFS: find_entry(): invalid directory block\n");
41
                        brelse(bh);
42
                        return(0);
43
                }
44
 
45
                for(slot = 0; slot < dirblock->slots; slot++) {
46
                        dirslot  = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot));
47
 
48
                        namelen  = dirslot->namelen;
49
                        nameptr  = dirslot->name;
50
 
51
                        if ((namelen == len) && (!memcmp(name, nameptr, len))) {
52
                                inodenum = be32_to_cpu(dirslot->inode);
53
                                brelse(bh);
54
                                return(inodenum);
55
                        }
56
                }
57
                brelse(bh);
58
        }
59
        return(0);
60
}
61
 
62
struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) {
63
        efs_ino_t inodenum;
64
        struct inode * inode = NULL;
65
 
66
        lock_kernel();
67
        inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
68
        if (inodenum) {
69
                if (!(inode = iget(dir->i_sb, inodenum))) {
70
                        unlock_kernel();
71
                        return ERR_PTR(-EACCES);
72
                }
73
        }
74
        unlock_kernel();
75
 
76
        d_add(dentry, inode);
77
        return NULL;
78
}
79
 
80
static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
81
                u32 generation)
82
{
83
        struct inode *inode;
84
 
85
        if (ino == 0)
86
                return ERR_PTR(-ESTALE);
87
        inode = iget(sb, ino);
88
        if (inode == NULL)
89
                return ERR_PTR(-ENOMEM);
90
 
91
        if (is_bad_inode(inode) ||
92
            (generation && inode->i_generation != generation)) {
93
                iput(inode);
94
                return ERR_PTR(-ESTALE);
95
        }
96
 
97
        return inode;
98
}
99
 
100
struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
101
                int fh_len, int fh_type)
102
{
103
        return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
104
                                    efs_nfs_get_inode);
105
}
106
 
107
struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
108
                int fh_len, int fh_type)
109
{
110
        return generic_fh_to_parent(sb, fid, fh_len, fh_type,
111
                                    efs_nfs_get_inode);
112
}
113
 
114
struct dentry *efs_get_parent(struct dentry *child)
115
{
116
        struct dentry *parent;
117
        struct inode *inode;
118
        efs_ino_t ino;
119
        int error;
120
 
121
        lock_kernel();
122
 
123
        error = -ENOENT;
124
        ino = efs_find_entry(child->d_inode, "..", 2);
125
        if (!ino)
126
                goto fail;
127
 
128
        error = -EACCES;
129
        inode = iget(child->d_inode->i_sb, ino);
130
        if (!inode)
131
                goto fail;
132
 
133
        error = -ENOMEM;
134
        parent = d_alloc_anon(inode);
135
        if (!parent)
136
                goto fail_iput;
137
 
138
        unlock_kernel();
139
        return parent;
140
 
141
 fail_iput:
142
        iput(inode);
143
 fail:
144
        unlock_kernel();
145
        return ERR_PTR(error);
146
}

powered by: WebSVN 2.1.0

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