Uninitialized vector entry?
[minix3.git] / lib / other / fslib.c
bloba24c886ce8c50ef9db7f8ae1eccbfcea1cbacd73
1 /* fslib.c - routines needed by fs and fs utilities */
3 #include <minix/config.h> /* for unused stuff in <minix/type.h> :-( */
4 #include <ansi.h>
5 #include <limits.h>
6 #include <dirent.h>
7 #include <sys/types.h>
8 #include <minix/const.h>
9 #include <minix/type.h> /* for unshort :-( */
10 #include "mfs/const.h" /* depends of -I flag in Makefile */
11 #include "mfs/type.h" /* ditto */
12 #include "mfs/inode.h" /* ditto */
13 #include "mfs/super.h"
14 #include <minix/fslib.h>
16 /* The next routine is copied from fsck.c and mkfs.c... (Re)define some
17 * things for consistency. Some things should be done better.
20 /* Convert from bit count to a block count. The usual expression
22 * (nr_bits + (1 << BITMAPSHIFT) - 1) >> BITMAPSHIFT
24 * doesn't work because of overflow.
26 * Other overflow bugs, such as the expression for N_ILIST overflowing when
27 * s_inodes is just over V*_INODES_PER_BLOCK less than the maximum+1, are not
28 * fixed yet, because that number of inodes is silly.
30 /* The above comment doesn't all apply now bit_t is long. Overflow is now
31 * unlikely, but negative bit counts are now possible (though unlikely)
32 * and give silly results.
33 */
34 PUBLIC int bitmapsize(nr_bits, block_size)
35 bit_t nr_bits;
36 int block_size;
38 int nr_blocks;
40 nr_blocks = (int) (nr_bits / FS_BITS_PER_BLOCK(block_size));
41 if (((bit_t) nr_blocks * FS_BITS_PER_BLOCK(block_size)) < nr_bits) ++nr_blocks;
42 return(nr_blocks);
46 /*===========================================================================*
47 * conv2 *
48 *===========================================================================*/
49 PUBLIC unsigned conv2(norm, w)
50 int norm; /* TRUE if no swap, FALSE for byte swap */
51 int w; /* promotion of 16-bit word to be swapped */
53 /* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
55 if (norm) return( (unsigned) w & 0xFFFF);
56 return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
60 /*===========================================================================*
61 * conv4 *
62 *===========================================================================*/
63 PUBLIC long conv4(norm, x)
64 int norm; /* TRUE if no swap, FALSE for byte swap */
65 long x; /* 32-bit long to be byte swapped */
67 /* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
69 unsigned lo, hi;
70 long l;
72 if (norm) return(x); /* byte order was already ok */
73 lo = conv2(FALSE, (int) x & 0xFFFF); /* low-order half, byte swapped */
74 hi = conv2(FALSE, (int) (x>>16) & 0xFFFF); /* high-order half, swapped */
75 l = ( (long) lo <<16) | hi;
76 return(l);
80 /*===========================================================================*
81 * conv_inode *
82 *===========================================================================*/
83 PUBLIC void conv_inode(rip, dip, dip2, rw_flag, magic)
84 register struct inode *rip; /* pointer to the in-core inode struct */
85 register d1_inode *dip; /* pointer to the V1 on-disk inode struct */
86 register d2_inode *dip2; /* pointer to the V2 on-disk inode struct */
87 int rw_flag; /* READING or WRITING */
88 int magic; /* magic number of file system */
90 /* Copy the inode from the disk block to the in-core table or vice versa.
91 * If the fourth parameter below is FALSE, the bytes are swapped.
93 switch (magic) {
94 case SUPER_MAGIC: old_icopy(rip, dip, rw_flag, TRUE); break;
95 case SUPER_REV: old_icopy(rip, dip, rw_flag, FALSE); break;
96 case SUPER_V3:
97 case SUPER_V2: new_icopy(rip, dip2, rw_flag, TRUE); break;
98 case SUPER_V2_REV: new_icopy(rip, dip2, rw_flag, FALSE); break;
103 /*===========================================================================*
104 * old_icopy *
105 *===========================================================================*/
106 PUBLIC void old_icopy(rip, dip, direction, norm)
107 register struct inode *rip; /* pointer to the in-core inode struct */
108 register d1_inode *dip; /* pointer to the d1_inode inode struct */
109 int direction; /* READING (from disk) or WRITING (to disk) */
110 int norm; /* TRUE = do not swap bytes; FALSE = swap */
113 /* 4 different on-disk inode layouts are supported, one for each combination
114 * of V1.x/V2.x * bytes-swapped/not-swapped. When an inode is read or written
115 * this routine handles the conversions so that the information in the inode
116 * table is independent of the disk structure from which the inode came.
117 * The old_icopy routine copies to and from V1 disks.
120 int i;
122 if (direction == READING) {
123 /* Copy V1.x inode to the in-core table, swapping bytes if need be. */
124 rip->i_mode = conv2(norm, dip->d1_mode);
125 rip->i_uid = conv2(norm,dip->d1_uid );
126 rip->i_size = conv4(norm,dip->d1_size);
127 rip->i_mtime = conv4(norm,dip->d1_mtime);
128 rip->i_atime = 0;
129 rip->i_ctime = 0;
130 rip->i_nlinks = (nlink_t) dip->d1_nlinks; /* 1 char */
131 rip->i_gid = (gid_t) dip->d1_gid; /* 1 char */
132 rip->i_ndzones = V1_NR_DZONES;
133 rip->i_nindirs = V1_INDIRECTS;
134 for (i = 0; i < V1_NR_TZONES; i++)
135 rip->i_zone[i] = conv2(norm, (int) dip->d1_zone[i]);
136 } else {
137 /* Copying V1.x inode to disk from the in-core table. */
138 dip->d1_mode = conv2(norm,rip->i_mode);
139 dip->d1_uid = conv2(norm,rip->i_uid );
140 dip->d1_size = conv4(norm,rip->i_size);
141 dip->d1_mtime = conv4(norm,rip->i_mtime);
142 dip->d1_nlinks = (nlink_t) rip->i_nlinks; /* 1 char */
143 dip->d1_gid = (gid_t) rip->i_gid; /* 1 char */
144 for (i = 0; i < V1_NR_TZONES; i++)
145 dip->d1_zone[i] = conv2(norm, (int) rip->i_zone[i]);
150 /*===========================================================================*
151 * new_icopy *
152 *===========================================================================*/
153 PUBLIC void new_icopy(rip, dip, direction, norm)
154 register struct inode *rip; /* pointer to the in-core inode struct */
155 register d2_inode *dip; /* pointer to the d2_inode struct */
156 int direction; /* READING (from disk) or WRITING (to disk) */
157 int norm; /* TRUE = do not swap bytes; FALSE = swap */
160 /* Same as old_icopy, but to/from V2 disk layout. */
162 int i;
164 if (direction == READING) {
165 /* Copy V2.x inode to the in-core table, swapping bytes if need be. */
166 rip->i_mode = conv2(norm,dip->d2_mode);
167 rip->i_uid = conv2(norm,dip->d2_uid );
168 rip->i_nlinks = conv2(norm,(int) dip->d2_nlinks);
169 rip->i_gid = conv2(norm,(int) dip->d2_gid );
170 rip->i_size = conv4(norm,dip->d2_size);
171 rip->i_atime = conv4(norm,dip->d2_atime);
172 rip->i_ctime = conv4(norm,dip->d2_ctime);
173 rip->i_mtime = conv4(norm,dip->d2_mtime);
174 rip->i_ndzones = V2_NR_DZONES;
175 rip->i_nindirs = V2_INDIRECTS(rip->i_sp->s_block_size);
176 for (i = 0; i < V2_NR_TZONES; i++)
177 rip->i_zone[i] = conv4(norm, (long) dip->d2_zone[i]);
178 } else {
179 /* Copying V2.x inode to disk from the in-core table. */
180 dip->d2_mode = conv2(norm,rip->i_mode);
181 dip->d2_uid = conv2(norm,rip->i_uid );
182 dip->d2_nlinks = conv2(norm,rip->i_nlinks);
183 dip->d2_gid = conv2(norm,rip->i_gid );
184 dip->d2_size = conv4(norm,rip->i_size);
185 dip->d2_atime = conv4(norm,rip->i_atime);
186 dip->d2_ctime = conv4(norm,rip->i_ctime);
187 dip->d2_mtime = conv4(norm,rip->i_mtime);
188 for (i = 0; i < V2_NR_TZONES; i++)
189 dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);