/* ffs_inode.c 3.5 %G% */
#define INOHASH(dev,ino) (((dev)+(ino))%INOHSZ)
* Initialize hash links for inodes
* and build inode free list.
for (i
= 0; i
< NINODE
- 1; i
++)
inode
[NINODE
- 1].i_hlink
= -1;
for (i
= 0; i
< INOHSZ
; i
++)
* Find an inode if it is incore.
* This is the equivalent, for inodes,
* of ``incore'' in bio.c or ``pfind'' in subr.c.
register struct inode
*ip
;
for (ip
= &inode
[inohash
[INOHASH(dev
,ino
)]]; ip
!= &inode
[-1];
ip
= &inode
[ip
->i_hlink
])
if (ino
==ip
->i_number
&& dev
==ip
->i_dev
)
return ((struct inode
*)0);
* Look up an inode by device,inumber.
* If it is in core (in the inode structure),
* honor the locking protocol.
* If it is not in core, read it in from the
* If the inode is mounted on, perform
* the indicated indirection.
* In all cases, a pointer to a locked
* inode structure is returned.
* printf warning: no inodes -- if the inode
* panic: no imt -- if the mounted file
* system is not in the mount table.
register struct inode
*ip
;
register struct mount
*mp
;
register struct dinode
*dp
;
slot
= INOHASH(dev
, ino
);
ip
= &inode
[inohash
[slot
]];
while (ip
!= &inode
[-1]) {
if(ino
== ip
->i_number
&& dev
== ip
->i_dev
) {
if((ip
->i_flag
&ILOCK
) != 0) {
sleep((caddr_t
)ip
, PINOD
);
if((ip
->i_flag
&IMOUNT
) != 0) {
for(mp
= &mount
[0]; mp
< &mount
[NMOUNT
]; mp
++)
ip
= &inode
[ip
->i_hlink
];
printf("Inode table overflow\n");
ip
->i_hlink
= inohash
[slot
];
inohash
[slot
] = ip
- inode
;
bp
= bread(dev
, itod(ino
));
if((bp
->b_flags
&B_ERROR
) != 0) {
register struct inode
*ip
;
register struct dinode
*dp
;
ip
->i_mode
= dp
->di_mode
;
ip
->i_nlink
= dp
->di_nlink
;
ip
->i_size
= dp
->di_size
;
p1
= (char *)ip
->i_un
.i_addr
;
p2
= (char *)dp
->di_addr
;
* Decrement reference count of
* write the inode out and if necessary,
* truncate and deallocate the file.
register struct inode
*ip
;
register struct inode
*jp
;
ifree(ip
->i_dev
, ip
->i_number
);
IUPDAT(ip
, &time
, &time
, 0);
i
= INOHASH(ip
->i_dev
, ip
->i_number
);
inohash
[i
] = ip
->i_hlink
;
for (jp
= &inode
[inohash
[i
]]; jp
!= &inode
[-1];
jp
= &inode
[jp
->i_hlink
])
jp
->i_hlink
= ip
->i_hlink
;
* Check accessed and update flags on
* If any is on, update the inode
* If waitfor is given, then must insure
* i/o order so wait for write to complete.
iupdat(ip
, ta
, tm
, waitfor
)
register struct inode
*ip
;
if((ip
->i_flag
&(IUPD
|IACC
|ICHG
)) != 0) {
if(getfs(ip
->i_dev
)->s_ronly
)
bp
= bread(ip
->i_dev
, itod(ip
->i_number
));
if (bp
->b_flags
& B_ERROR
) {
dp
+= itoo(ip
->i_number
);
dp
->di_mode
= ip
->i_mode
;
dp
->di_nlink
= ip
->i_nlink
;
dp
->di_size
= ip
->i_size
;
p1
= (char *)dp
->di_addr
;
p2
= (char *)ip
->i_un
.i_addr
;
if(*p2
++ != 0 && (ip
->i_mode
&IFMT
)!=IFMPC
&& (ip
->i_mode
&IFMT
)!=IFMPB
)
printf("iaddress > 2^24\n");
ip
->i_flag
&= ~(IUPD
|IACC
|ICHG
);
* Free all the disk blocks associated
* with the specified inode structure.
* The blocks of the file are removed
* in reverse order. This FILO
* algorithm will tend to maintain
* a contiguous free list much longer
register struct inode
*ip
;
if (i
!=IFREG
&& i
!=IFDIR
)
* Clean inode on disk before freeing blocks
* to insure no duplicates if system crashes.
for (i
= 0; i
< NADDR
; i
++)
itmp
.i_flag
|= ICHG
|IUPD
;
iupdat(&itmp
, &time
, &time
, 1);
ip
->i_flag
&= ~(IUPD
|IACC
|ICHG
);
* Now return blocks to free list... if machine
* crashes, they will be harmless MISSING blocks.
for(i
=NADDR
-1; i
>=0; i
--) {
ip
->i_un
.i_addr
[i
] = (daddr_t
)0;
* Inode was written and flags updated above.
* No need to modify flags here.
for(i
=NINDIR
-1; i
>=0; i
--) {
if (bp
->b_flags
& B_ERROR
) {
register struct inode
*ip
;
ip
= ialloc(u
.u_pdir
->i_dev
);
ip
->i_flag
|= IACC
|IUPD
|ICHG
;
ip
->i_mode
= mode
& ~u
.u_cmask
;
* Make sure inode goes to disk before directory entry.
iupdat(ip
, &time
, &time
, 1);
* Write a directory entry with
* parameters left as side effects
u
.u_dent
.d_ino
= ip
->i_number
;
bcopy((caddr_t
)u
.u_dbuf
, (caddr_t
)u
.u_dent
.d_name
, DIRSIZ
);
u
.u_count
= sizeof(struct direct
);
u
.u_base
= (caddr_t
)&u
.u_dent
;