* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
* @(#)lfs_alloc.c 8.2 (Berkeley) %G%
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/lfs/lfs_extern.h>
extern u_long nextgennumber
;
/* Allocate a new inode. */
struct vop_valloc_args
/* {
/* Get the head of the freelist. */
fs
= VTOI(ap
->a_pvp
)->i_lfs
;
printf("lfs_ialloc: allocate inode %d\n", new_ino
);
* Remove the inode from the free list and write the new start
* of the free list into the superblock.
LFS_IENTRY(ifp
, fs
, new_ino
, bp
);
if (ifp
->if_daddr
!= LFS_UNUSED_DADDR
)
panic("lfs_ialloc: inuse inode on the free list");
fs
->lfs_free
= ifp
->if_nextfree
;
/* Extend IFILE so that the next lfs_valloc will succeed. */
if (fs
->lfs_free
== LFS_UNUSED_INUM
) {
blkno
= lblkno(fs
, ip
->i_size
);
lfs_balloc(vp
, fs
->lfs_bsize
, blkno
, &bp
);
ip
->i_size
+= fs
->lfs_bsize
;
vnode_pager_setsize(vp
, (u_long
)ip
->i_size
);
i
= (blkno
- fs
->lfs_segtabsz
- fs
->lfs_cleansz
) *
for (ifp
= (struct ifile
*)bp
->b_data
; i
< max
; ++ifp
) {
ifp
->if_daddr
= LFS_UNUSED_DADDR
;
ifp
->if_nextfree
= LFS_UNUSED_INUM
;
if (error
= VOP_BWRITE(bp
))
/* Create a vnode to associate with the inode. */
if (error
= lfs_vcreate(ap
->a_pvp
->v_mount
, new_ino
, &vp
))
/* Zero out the direct and indirect block addresses. */
bzero(&ip
->i_din
, sizeof(struct dinode
));
ip
->i_din
.di_inumber
= new_ino
;
/* Set a new generation number for this inode. */
if (++nextgennumber
< (u_long
)time
.tv_sec
)
nextgennumber
= time
.tv_sec
;
ip
->i_gen
= nextgennumber
;
/* Insert into the inode hash table. */
if (error
= ufs_vinit(vp
->v_mount
, lfs_specop_p
, LFS_FIFOOPS
, &vp
)) {
/* Set superblock modified bit and increment file count. */
/* Create a new vnode/inode pair and initialize what fields we can. */
lfs_vcreate(mp
, ino
, vpp
)
extern int (**lfs_vnodeop_p
)();
if (error
= getnewvnode(VT_LFS
, mp
, lfs_vnodeop_p
, vpp
)) {
/* Get a pointer to the private mount structure. */
/* Initialize the inode. */
MALLOC(ip
, struct inode
*, sizeof(struct inode
), M_LFSNODE
, M_WAITOK
);
ip
->i_devvp
= ump
->um_devvp
;
ip
->i_number
= ip
->i_din
.di_inumber
= ino
;
ip
->i_din
.di_spare
[0] = 0xdeadbeef;
ip
->i_din
.di_spare
[1] = 0xdeadbeef;
for (i
= 0; i
< MAXQUOTAS
; i
++)
ip
->i_dquot
[i
] = NODQUOT
;
++ump
->um_lfs
->lfs_uinodes
;
struct vop_vfree_args
/* {
/* Get the inode number and file system. */
if (ip
->i_flag
& IMODIFIED
) {
ip
->i_flag
&= ~(IMODIFIED
| IACCESS
| IUPDATE
| ICHANGE
);
* Set the ifile's inode entry to unused, increment its version number
* and link it into the free chain.
LFS_IENTRY(ifp
, fs
, ino
, bp
);
old_iaddr
= ifp
->if_daddr
;
ifp
->if_daddr
= LFS_UNUSED_DADDR
;
ifp
->if_nextfree
= fs
->lfs_free
;
if (old_iaddr
!= LFS_UNUSED_DADDR
) {
LFS_SEGENTRY(sup
, fs
, datosn(fs
, old_iaddr
), bp
);
if (sup
->su_nbytes
< sizeof(struct dinode
))
panic("lfs_vfree: negative byte count (segment %d)\n",
sup
->su_nbytes
-= sizeof(struct dinode
);
/* Set superblock modified bit and decrement file count. */