1 /* fslib.c - routines needed by fs and fs utilities */
3 #include <minix/config.h> /* for unused stuff in <minix/type.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.
33 int bitmapsize(nr_bits
, block_size
)
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
;
45 /*===========================================================================*
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 /*===========================================================================*
61 *===========================================================================*/
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. */
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
;
79 /*===========================================================================*
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.
93 case SUPER_MAGIC
: old_icopy(rip
, dip
, rw_flag
, TRUE
); break;
94 case SUPER_REV
: old_icopy(rip
, dip
, rw_flag
, FALSE
); break;
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 /*===========================================================================*
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.
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
);
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
]);
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 /*===========================================================================*
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. */
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
]);
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
]);