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