Subversion Repositories HelenOS

Rev

Rev 2404 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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