* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)lfs_alloc.c 7.32 (Berkeley) %G%
#include "../ufs/quota.h"
#include "../ufs/inode.h"
#include "../ufs/ufsmount.h"
/* Read in the block containing a specific inode from the ifile. */
#define LFS_IENTRY(I, F, IN, BP) \
if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \
(F)->lfs_bsize, NOCRED, &BP)) \
panic("lfs_ientry: read"); \
(I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F);
lfs_ialloc(fs
, pip
, ipp
, cred
)
/* Get the head of the freelist. */
if (new_ino
== LFS_UNUSED_INUM
) {
* Currently, no more inodes are allocated if the ifile fills
* up. The ifile should be extended instead.
uprintf("\n%s: no inodes left\n", fs
->lfs_fsmnt
);
log(LOG_ERR
, "uid %d on %s: out of inodes\n",
cred
->cr_uid
, fs
->lfs_fsmnt
);
printf("lfs_ialloc: allocate inode %d\n", new_ino
);
/* Read the appropriate block from the ifile. */
LFS_IENTRY(ifp
, fs
, new_ino
, bp
);
if (ifp
->if_daddr
!= LFS_UNUSED_DADDR
)
panic("lfs_ialloc: inuse inode on the free list");
/* Remove from the free list, set the access time, write it back. */
fs
->lfs_free
= ifp
->if_nextfree
;
ifp
->if_st_atime
= time
.tv_sec
;
/* Create a vnode to associate with the inode. */
error
= lfs_vcreate(ITOV(pip
)->v_mount
, new_ino
, &vp
);
/* 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. */
/* Set superblock modified bit and increment file count. */
printf("lfs_ifree: free %d\n", ip
->i_number
);
/* Get the inode number and file system. */
* Read the appropriate block from the ifile. Set the inode entry to
* unused, increment its version number and link it into the free chain.
LFS_IENTRY(ifp
, fs
, ino
, bp
);
ifp
->if_daddr
= LFS_UNUSED_DADDR
;
ifp
->if_nextfree
= fs
->lfs_free
;
/* Set superblock modified bit and decrement file count. */
/* Translate an inode number to a disk address. */
/* Read the appropriate block from the ifile. */
LFS_IENTRY(ifp
, fs
, ino
, bp
);
if (ifp
->if_daddr
== LFS_UNUSED_DADDR
)
panic("itod: unused disk address");
/* Search a block for a specific dinode. */
printf("lfs_ifind: inode %d\n", ino
);
for (cnt
= INOPB(fs
); cnt
--; ++dip
)
panic("lfs_ifind: dinode %%u not found", ino
);
/* Create a new vnode/inode pair and initialize what fields we can. */
lfs_vcreate(mp
, ino
, vpp
)
printf("lfs_vcreate: ino %d\n", ino
);
if (error
= getnewvnode(VT_LFS
, mp
, &lfs_vnodeops
, vpp
))
/* Get a pointer to the private mount structure. */
/* Initialize the inode. */
ip
->i_devvp
= ump
->um_devvp
;
ip
->i_number
= ip
->i_din
.di_inum
= ino
;
for (i
= 0; i
< MAXQUOTAS
; i
++)
ip
->i_dquot
[i
] = NODQUOT
;
VREF(ip
->i_devvp
); /* XXX: Why? */
/* Return the current version number for a specific inode. */
* Read the appropriate block from the ifile. Return the
LFS_IENTRY(ifp
, fs
, ino
, bp
);
version
= ifp
->if_version
;
/* Set values in the ifile for the inode. */
lfs_iset(ip
, daddr
, atime
)
printf("lfs_iset: setting ino %d daddr %lx time %lx\n",
ip
->i_number
, daddr
, atime
);
LFS_IENTRY(ifp
, fs
, ino
, bp
);
ifp
->if_st_atime
= atime
;