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

Subversion Repositories or1k

[/] [or1k/] [tags/] [LINUX_2_4_26_OR32/] [linux/] [linux-2.4/] [fs/] [coda/] [cnode.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* cnode related routines for the coda kernel code
2
   (C) 1996 Peter Braam
3
   */
4
 
5
#include <linux/types.h>
6
#include <linux/string.h>
7
#include <linux/time.h>
8
 
9
#include <linux/coda.h>
10
#include <linux/coda_linux.h>
11
#include <linux/coda_fs_i.h>
12
#include <linux/coda_psdev.h>
13
 
14
extern int coda_debug;
15
 
16
inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
17
{
18
        if (fid1->Vnode != fid2->Vnode)   return 0;
19
        if (fid1->Volume != fid2->Volume) return 0;
20
        if (fid1->Unique != fid2->Unique) return 0;
21
        return 1;
22
}
23
 
24
inline int coda_isnullfid(ViceFid *fid)
25
{
26
        if (fid->Vnode || fid->Volume || fid->Unique) return 0;
27
        return 1;
28
}
29
 
30
static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque)
31
{
32
        return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid)));
33
}
34
 
35
static struct inode_operations coda_symlink_inode_operations = {
36
        readlink:       page_readlink,
37
        follow_link:    page_follow_link,
38
        setattr:        coda_notify_change,
39
};
40
 
41
/* cnode.c */
42
static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
43
{
44
        CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
45
 
46
        if (coda_debug & D_SUPER )
47
                print_vattr(attr);
48
 
49
        coda_vattr_to_iattr(inode, attr);
50
 
51
        if (S_ISREG(inode->i_mode)) {
52
                inode->i_op = &coda_file_inode_operations;
53
                inode->i_fop = &coda_file_operations;
54
        } else if (S_ISDIR(inode->i_mode)) {
55
                inode->i_op = &coda_dir_inode_operations;
56
                inode->i_fop = &coda_dir_operations;
57
        } else if (S_ISLNK(inode->i_mode)) {
58
                inode->i_op = &coda_symlink_inode_operations;
59
                inode->i_data.a_ops = &coda_symlink_aops;
60
                inode->i_mapping = &inode->i_data;
61
        } else
62
                init_special_inode(inode, inode->i_mode, attr->va_rdev);
63
}
64
 
65
struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
66
                         struct coda_vattr * attr)
67
{
68
        struct inode *inode;
69
        struct coda_inode_info *cii;
70
        ino_t ino = coda_f2i(fid);
71
        struct coda_sb_info *sbi = coda_sbp(sb);
72
 
73
        down(&sbi->sbi_iget4_mutex);
74
        inode = iget4(sb, ino, coda_inocmp, fid);
75
 
76
        if ( !inode ) {
77
                CDEBUG(D_CNODE, "coda_iget: no inode\n");
78
                up(&sbi->sbi_iget4_mutex);
79
                return ERR_PTR(-ENOMEM);
80
        }
81
 
82
        /* check if the inode is already initialized */
83
        cii = ITOC(inode);
84
        if (coda_isnullfid(&cii->c_fid))
85
                /* new, empty inode found... initializing */
86
                cii->c_fid = *fid;
87
        up(&sbi->sbi_iget4_mutex);
88
 
89
        /* always replace the attributes, type might have changed */
90
        coda_fill_inode(inode, attr);
91
        return inode;
92
}
93
 
94
/* this is effectively coda_iget:
95
   - get attributes (might be cached)
96
   - get the inode for the fid using vfs iget
97
   - link the two up if this is needed
98
   - fill in the attributes
99
*/
100
int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
101
{
102
        struct coda_vattr attr;
103
        int error;
104
 
105
        /* We get inode numbers from Venus -- see venus source */
106
        error = venus_getattr(sb, fid, &attr);
107
        if ( error ) {
108
            CDEBUG(D_CNODE,
109
                   "coda_cnode_make: coda_getvattr returned %d for %s.\n",
110
                   error, coda_f2s(fid));
111
            *inode = NULL;
112
            return error;
113
        }
114
 
115
        *inode = coda_iget(sb, fid, &attr);
116
        if ( IS_ERR(*inode) ) {
117
                printk("coda_cnode_make: coda_iget failed\n");
118
                return PTR_ERR(*inode);
119
        }
120
 
121
        CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
122
                (*inode)->i_ino, atomic_read(&(*inode)->i_count),
123
                coda_f2s(&ITOC(*inode)->c_fid));
124
        return 0;
125
}
126
 
127
 
128
void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
129
                      struct ViceFid *newfid)
130
{
131
        struct coda_inode_info *cii;
132
 
133
        cii = ITOC(inode);
134
 
135
        if (!coda_fideq(&cii->c_fid, oldfid))
136
                BUG();
137
 
138
        /* replace fid and rehash inode */
139
        /* XXX we probably need to hold some lock here! */
140
        remove_inode_hash(inode);
141
        cii->c_fid = *newfid;
142
        inode->i_ino = coda_f2i(newfid);
143
        insert_inode_hash(inode);
144
}
145
 
146
/* convert a fid to an inode. */
147
struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
148
{
149
        ino_t nr;
150
        struct inode *inode;
151
        struct coda_inode_info *cii;
152
        struct coda_sb_info *sbi;
153
 
154
        if ( !sb ) {
155
                printk("coda_fid_to_inode: no sb!\n");
156
                return NULL;
157
        }
158
 
159
        CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
160
 
161
        sbi = coda_sbp(sb);
162
        nr = coda_f2i(fid);
163
        down(&sbi->sbi_iget4_mutex);
164
        inode = iget4(sb, nr, coda_inocmp, fid);
165
        if ( !inode ) {
166
                printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
167
                       sb, (long)nr);
168
                goto out_unlock;
169
        }
170
 
171
        cii = ITOC(inode);
172
 
173
        /* The inode could already be purged due to memory pressure */
174
        if (coda_isnullfid(&cii->c_fid)) {
175
                inode->i_nlink = 0;
176
                iput(inode);
177
                goto out_unlock;
178
        }
179
 
180
        CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
181
        up(&sbi->sbi_iget4_mutex);
182
        return inode;
183
 
184
out_unlock:
185
        up(&sbi->sbi_iget4_mutex);
186
        return NULL;
187
}
188
 
189
/* the CONTROL inode is made without asking attributes from Venus */
190
int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
191
{
192
        int error = 0;
193
 
194
        *inode = iget(sb, CTL_INO);
195
        if ( *inode ) {
196
                (*inode)->i_op = &coda_ioctl_inode_operations;
197
                (*inode)->i_fop = &coda_ioctl_operations;
198
                (*inode)->i_mode = 0444;
199
                error = 0;
200
        } else {
201
                error = -ENOMEM;
202
        }
203
 
204
        return error;
205
}
206
 

powered by: WebSVN 2.1.0

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