Subversion Repositories HelenOS

Rev

Rev 2372 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2404 konopa 1
/*
2
 * Copyright (c) 1987,1997, Prentice Hall
3
 * All rights reserved.
4
 *
5
 * Redistribution and use of the MINIX operating system in source and
6
 * binary forms, with or without modification, are permitted provided
7
 * that the following conditions are met:
8
 
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 
12
 * - Redistributions in binary form must reproduce the above
13
 *   copyright notice, this list of conditions and the following
14
 *   disclaimer in the documentation and/or other materials provided
15
 *   with the distribution.
16
 
17
 * - Neither the name of Prentice Hall nor the names of the software
18
 *   authors or contributors may be used to endorse or promote
19
 *   products derived from this software without specific prior
20
 *   written permission.
21
 
22
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND
23
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26
 * IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE
27
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 */
35
 
36
 
2372 konopa 37
/* This file manages the inode table.  There are procedures to allocate and
38
* deallocate inodes, acquire, erase, and release them, and read and write
39
* them from the disk.
40
*/
41
 
42
/* Methods:
43
 * get_inode:       search inode table for a given inode; if not there, read it
44
 * read_inode:      read a disk block and extract an inode
45
 * v1_copy_inode    copy from disk inode (V1.x) to in-memory inode struct
46
 * v2_copy_inode    copy from disk inode (V2.x) to in-memory inode structs
47
 * put_inode        indicate that an inode is no longer needed in memory
48
 * dup_inode:       indicate that someone else is using an inode table entry
49
 */
50
 
51
#include "fs.h"
52
#include "block.h"
53
#include "file.h"
54
#include "fproc.h"
55
#include "inode.h"
56
#include "super.h"
57
 
58
 
59
inode_t inode[NR_INODES];
60
 
61
static void v1_copy_inode(inode_t *rip, d1_inode_t *dip, int normal);
62
static void v2_copy_inode(inode_t *rip, d2_inode_t *dip, int normal);
63
 
64
 
65
inode_t *get_inode(int numb)
66
{
67
    /* Find a slot in the inode table, load the specified inode into it, and
68
     * return a pointer to the slot.
69
     */
70
 
71
    register inode_t *rip, *xp;
72
 
73
    /* Search the inode table both for numb and a free slot. */
74
    xp = NIL_INODE;
75
    for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++) {
76
        if (rip->i_count > 0) { /* only check used slots for numb */
77
                if (rip->i_num == numb) {
78
                        /* This is the inode that we are looking for. */
79
                            rip->i_count++;
80
                            return rip;    /* numb found */
81
                    }
82
            }
83
        else {
84
                xp = rip;   /* remember this free slot for later */
85
        }          
86
 
87
    }
88
 
89
    /* Inode we want is not currently in use.  Did we find a free slot? */
90
    if (xp == NIL_INODE) {        /* inode table completely full */
91
        err_code = FS_ENFILE;
92
            return NIL_INODE;
93
    }
94
 
95
    /* A free inode slot has been located.  Load the inode into it. */
96
    xp->i_num = numb;
97
    xp->i_count = 1;
98
    read_inode(xp);
99
 
100
    return xp;
101
}
102
 
103
void read_inode(register inode_t *rip)
104
{
105
 
106
    /* An entry in the inode table is to be copied from the disk. */
107
 
108
    register block_t *bp;
109
    register super_block_t *sp;
110
    d1_inode_t *dip1;
111
    d2_inode_t *dip2;
112
    block_num_t b, offset;
113
 
114
    /* Get the block where the inode resides. */
115
    sp = get_super();           /* get pointer to super block */
116
    rip->i_sp = sp;               /* inode must contain super block pointer */
117
    offset = sp->s_imap_blocks + sp->s_zmap_blocks + 2;
118
    b = (block_num_t)(rip->i_num - 1)/sp->s_inodes_per_block + offset;
119
    bp = get_block(b);
120
    dip1  = bp->b.b__v1_ino + (rip->i_num - 1) % V1_INODES_PER_BLOCK;
121
    dip2  = bp->b.b__v2_ino + (rip->i_num - 1) % V2_INODES_PER_BLOCK;
122
 
123
    /* Copy inode to the in-core table, swapping bytes if need be. */
124
    if (sp->s_version == V1) {
125
        v1_copy_inode(rip, dip1, sp->s_native);
126
    }
127
    else {
128
        v2_copy_inode(rip, dip2, sp->s_native);
129
    }    
130
}
131
 
132
void v1_copy_inode(inode_t *rip, d1_inode_t *dip, int normal)
133
{
134
 
135
 
136
    /* The V1.x IBM disk, the V1.x 68000 disk, and the V2 disk (same for IBM and
137
     * 68000) all have different inode layouts.  When an inode is read or written
138
     * this routine handles the conversions so that the information in the inode
139
     * table is independent of the disk structure from which the inode came.
140
     * This routine copies from V1 disks.
141
     */
142
 
143
    int i;
144
 
145
    /* Some check is made for valid number of inode. */
146
    if (rip == NIL_INODE || dip == NULL)
147
        return;
148
 
149
    /* Copy V1.x inode to the in-memory table, swapping bytes if need be. */
150
    rip->i_mode = conv2(normal, dip->d1_mode);
151
    rip->i_size = conv4(normal, dip->d1_size);
152
    rip->i_nlinks = (nlink_t)dip->d1_nlinks;    /* 1 char */
153
    rip->i_ndzones = V1_NR_DZONES;
154
    rip->i_nindirs = V1_INDIRECTS; 
155
 
156
    for (i = 0; i < V1_NR_TZONES; i++)
157
        rip->i_zone[i] = conv2(normal, dip->d1_zone[i]);   
158
}
159
 
160
void v2_copy_inode(inode_t *rip, d2_inode_t *dip, int normal)
161
{
162
 
163
 
164
    /* Same as old_icopy, but to/from V2 disk layout. */
165
 
166
    int i;
167
 
168
    /* Some check is made for valid number of inode. */
169
    if (rip == NIL_INODE || dip == NULL)
170
        return;
171
 
172
    /* Copy V2.x inode to the in-core table, swapping bytes if need be. */
173
    rip->i_mode = conv2(normal, dip->d2_mode);
174
    rip->i_size = conv4(normal, dip->d2_size);
175
    rip->i_nlinks = conv2(normal, dip->d2_nlinks);
176
    rip->i_ndzones = V2_NR_DZONES;
177
    rip->i_nindirs = V2_INDIRECTS; 
178
 
179
    for (i = 0; i < V2_NR_TZONES; i++)
180
        rip->i_zone[i] = conv4(normal, dip->d2_zone[i]);   
181
}
182
 
183
void put_inode(inode_t *rip)
184
{
185
 
186
    /* The caller is no longer using this inode. */
187
 
188
    if (rip == NIL_INODE)
189
        return;
190
 
191
    rip->i_count--;
192
}
193
 
194
void dup_inode(inode_t *rip)
195
{
196
 
197
    /* This routine is a simplified form of get_inode() for the case where
198
     * the inode pointer is already known.
199
     */
200
 
201
    if (rip == NIL_INODE)
202
        return;
203
 
204
    rip->i_count++;
205
}
206