00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "fs.h"
00020 #include "buf.h"
00021 #include "file.h"
00022 #include "fproc.h"
00023 #include "inode.h"
00024 #include "super.h"
00025
00026 FORWARD _PROTOTYPE( void old_icopy, (struct inode *rip, d1_inode *dip,
00027 int direction, int norm));
00028 FORWARD _PROTOTYPE( void new_icopy, (struct inode *rip, d2_inode *dip,
00029 int direction, int norm));
00030
00031
00032
00033
00034 PUBLIC struct inode *get_inode(dev, numb)
00035 dev_t dev;
00036 int numb;
00037 {
00038
00039
00040
00041
00042 register struct inode *rip, *xp;
00043
00044
00045 xp = NIL_INODE;
00046 for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++) {
00047 if (rip->i_count > 0) {
00048 if (rip->i_dev == dev && rip->i_num == numb) {
00049
00050 rip->i_count++;
00051 return(rip);
00052 }
00053 } else {
00054 xp = rip;
00055 }
00056 }
00057
00058
00059 if (xp == NIL_INODE) {
00060 err_code = ENFILE;
00061 return(NIL_INODE);
00062 }
00063
00064
00065 xp->i_dev = dev;
00066 xp->i_num = numb;
00067 xp->i_count = 1;
00068 if (dev != NO_DEV) rw_inode(xp, READING);
00069 xp->i_update = 0;
00070
00071 return(xp);
00072 }
00073
00074
00075
00076
00077 PUBLIC void put_inode(rip)
00078 register struct inode *rip;
00079 {
00080
00081
00082
00083
00084
00085 if (rip == NIL_INODE) return;
00086 if (--rip->i_count == 0) {
00087 if (rip->i_nlinks == 0) {
00088
00089 truncate_inode(rip, 0);
00090 rip->i_mode = I_NOT_ALLOC;
00091 rip->i_dirt = DIRTY;
00092 free_inode(rip->i_dev, rip->i_num);
00093 } else {
00094 if (rip->i_pipe == I_PIPE) truncate_inode(rip, 0);
00095 }
00096 rip->i_pipe = NO_PIPE;
00097 if (rip->i_dirt == DIRTY) rw_inode(rip, WRITING);
00098 }
00099 }
00100
00101
00102
00103
00104 PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
00105 {
00106
00107
00108 register struct inode *rip;
00109 register struct super_block *sp;
00110 int major, minor, inumb;
00111 bit_t b;
00112
00113 sp = get_super(dev);
00114 if (sp->s_rd_only) {
00115 err_code = EROFS;
00116 return(NIL_INODE);
00117 }
00118
00119
00120 b = alloc_bit(sp, IMAP, sp->s_isearch);
00121 if (b == NO_BIT) {
00122 err_code = ENFILE;
00123 major = (int) (sp->s_dev >> MAJOR) & BYTE;
00124 minor = (int) (sp->s_dev >> MINOR) & BYTE;
00125 printf("Out of i-nodes on %sdevice %d/%d\n",
00126 sp->s_dev == root_dev ? "root " : "", major, minor);
00127 return(NIL_INODE);
00128 }
00129 sp->s_isearch = b;
00130 inumb = (int) b;
00131
00132
00133 if ((rip = get_inode(NO_DEV, inumb)) == NIL_INODE) {
00134
00135 free_bit(sp, IMAP, b);
00136 } else {
00137
00138 rip->i_mode = bits;
00139 rip->i_nlinks = 0;
00140 rip->i_uid = fp->fp_effuid;
00141 rip->i_gid = fp->fp_effgid;
00142 rip->i_dev = dev;
00143 rip->i_ndzones = sp->s_ndzones;
00144 rip->i_nindirs = sp->s_nindirs;
00145 rip->i_sp = sp;
00146
00147
00148
00149
00150
00151
00152 wipe_inode(rip);
00153 }
00154
00155 return(rip);
00156 }
00157
00158
00159
00160
00161 PUBLIC void wipe_inode(rip)
00162 register struct inode *rip;
00163 {
00164
00165
00166
00167
00168
00169 register int i;
00170
00171 rip->i_size = 0;
00172 rip->i_update = ATIME | CTIME | MTIME;
00173 rip->i_dirt = DIRTY;
00174 for (i = 0; i < V2_NR_TZONES; i++) rip->i_zone[i] = NO_ZONE;
00175 }
00176
00177
00178
00179
00180 PUBLIC void free_inode(dev, inumb)
00181 dev_t dev;
00182 ino_t inumb;
00183 {
00184
00185
00186 register struct super_block *sp;
00187 bit_t b;
00188
00189
00190 sp = get_super(dev);
00191 if (inumb <= 0 || inumb > sp->s_ninodes) return;
00192 b = inumb;
00193 free_bit(sp, IMAP, b);
00194 if (b < sp->s_isearch) sp->s_isearch = b;
00195 }
00196
00197
00198
00199
00200 PUBLIC void update_times(rip)
00201 register struct inode *rip;
00202 {
00203
00204
00205
00206
00207
00208
00209
00210 time_t cur_time;
00211 struct super_block *sp;
00212
00213 sp = rip->i_sp;
00214 if (sp->s_rd_only) return;
00215
00216 cur_time = clock_time();
00217 if (rip->i_update & ATIME) rip->i_atime = cur_time;
00218 if (rip->i_update & CTIME) rip->i_ctime = cur_time;
00219 if (rip->i_update & MTIME) rip->i_mtime = cur_time;
00220 rip->i_update = 0;
00221 }
00222
00223
00224
00225
00226 PUBLIC void rw_inode(rip, rw_flag)
00227 register struct inode *rip;
00228 int rw_flag;
00229 {
00230
00231
00232 register struct buf *bp;
00233 register struct super_block *sp;
00234 d1_inode *dip;
00235 d2_inode *dip2;
00236 block_t b, offset;
00237
00238
00239 sp = get_super(rip->i_dev);
00240 rip->i_sp = sp;
00241 offset = sp->s_imap_blocks + sp->s_zmap_blocks + 2;
00242 b = (block_t) (rip->i_num - 1)/sp->s_inodes_per_block + offset;
00243 bp = get_block(rip->i_dev, b, NORMAL);
00244 dip = bp->b_v1_ino + (rip->i_num - 1) % V1_INODES_PER_BLOCK;
00245 dip2 = bp->b_v2_ino + (rip->i_num - 1) %
00246 V2_INODES_PER_BLOCK(sp->s_block_size);
00247
00248
00249 if (rw_flag == WRITING) {
00250 if (rip->i_update) update_times(rip);
00251 if (sp->s_rd_only == FALSE) bp->b_dirt = DIRTY;
00252 }
00253
00254
00255
00256
00257 if (sp->s_version == V1)
00258 old_icopy(rip, dip, rw_flag, sp->s_native);
00259 else
00260 new_icopy(rip, dip2, rw_flag, sp->s_native);
00261
00262 put_block(bp, INODE_BLOCK);
00263 rip->i_dirt = CLEAN;
00264 }
00265
00266
00267
00268
00269 PRIVATE void old_icopy(rip, dip, direction, norm)
00270 register struct inode *rip;
00271 register d1_inode *dip;
00272 int direction;
00273 int norm;
00274
00275 {
00276
00277
00278
00279
00280
00281
00282
00283 int i;
00284
00285 if (direction == READING) {
00286
00287 rip->i_mode = conv2(norm, (int) dip->d1_mode);
00288 rip->i_uid = conv2(norm, (int) dip->d1_uid );
00289 rip->i_size = conv4(norm, dip->d1_size);
00290 rip->i_mtime = conv4(norm, dip->d1_mtime);
00291 rip->i_atime = rip->i_mtime;
00292 rip->i_ctime = rip->i_mtime;
00293 rip->i_nlinks = dip->d1_nlinks;
00294 rip->i_gid = dip->d1_gid;
00295 rip->i_ndzones = V1_NR_DZONES;
00296 rip->i_nindirs = V1_INDIRECTS;
00297 for (i = 0; i < V1_NR_TZONES; i++)
00298 rip->i_zone[i] = conv2(norm, (int) dip->d1_zone[i]);
00299 } else {
00300
00301 dip->d1_mode = conv2(norm, (int) rip->i_mode);
00302 dip->d1_uid = conv2(norm, (int) rip->i_uid );
00303 dip->d1_size = conv4(norm, rip->i_size);
00304 dip->d1_mtime = conv4(norm, rip->i_mtime);
00305 dip->d1_nlinks = rip->i_nlinks;
00306 dip->d1_gid = rip->i_gid;
00307 for (i = 0; i < V1_NR_TZONES; i++)
00308 dip->d1_zone[i] = conv2(norm, (int) rip->i_zone[i]);
00309 }
00310 }
00311
00312
00313
00314
00315 PRIVATE void new_icopy(rip, dip, direction, norm)
00316 register struct inode *rip;
00317 register d2_inode *dip;
00318 int direction;
00319 int norm;
00320
00321 {
00322
00323
00324 int i;
00325
00326 if (direction == READING) {
00327
00328 rip->i_mode = conv2(norm,dip->d2_mode);
00329 rip->i_uid = conv2(norm,dip->d2_uid);
00330 rip->i_nlinks = conv2(norm,dip->d2_nlinks);
00331 rip->i_gid = conv2(norm,dip->d2_gid);
00332 rip->i_size = conv4(norm,dip->d2_size);
00333 rip->i_atime = conv4(norm,dip->d2_atime);
00334 rip->i_ctime = conv4(norm,dip->d2_ctime);
00335 rip->i_mtime = conv4(norm,dip->d2_mtime);
00336 rip->i_ndzones = V2_NR_DZONES;
00337 rip->i_nindirs = V2_INDIRECTS(rip->i_sp->s_block_size);
00338 for (i = 0; i < V2_NR_TZONES; i++)
00339 rip->i_zone[i] = conv4(norm, (long) dip->d2_zone[i]);
00340 } else {
00341
00342 dip->d2_mode = conv2(norm,rip->i_mode);
00343 dip->d2_uid = conv2(norm,rip->i_uid);
00344 dip->d2_nlinks = conv2(norm,rip->i_nlinks);
00345 dip->d2_gid = conv2(norm,rip->i_gid);
00346 dip->d2_size = conv4(norm,rip->i_size);
00347 dip->d2_atime = conv4(norm,rip->i_atime);
00348 dip->d2_ctime = conv4(norm,rip->i_ctime);
00349 dip->d2_mtime = conv4(norm,rip->i_mtime);
00350 for (i = 0; i < V2_NR_TZONES; i++)
00351 dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);
00352 }
00353 }
00354
00355
00356
00357
00358 PUBLIC void dup_inode(ip)
00359 struct inode *ip;
00360 {
00361
00362
00363
00364
00365 ip->i_count++;
00366 }