xref: /csrg-svn/sys/ufs/lfs/lfs_subr.c (revision 51557)
1 /*
2  * Copyright (c) 1991 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)lfs_subr.c	7.3 (Berkeley) 11/05/91
8  */
9 
10 #include <sys/param.h>
11 #include <sys/namei.h>
12 #include <sys/vnode.h>
13 #include <sys/buf.h>
14 
15 #include <ufs/ufs/quota.h>
16 #include <ufs/ufs/inode.h>
17 
18 #include <ufs/lfs/lfs.h>
19 #include <ufs/lfs/lfs_extern.h>
20 
21 /*
22  * Return buffer with the contents of block "offset" from the beginning of
23  * directory "ip".  If "res" is non-zero, fill it in with a pointer to the
24  * remaining space in the directory.
25  */
26 int
27 lfs_blkatoff(vp, offset, res, bpp)
28 	struct vnode *vp;
29 	off_t offset;
30 	char **res;
31 	struct buf **bpp;
32 {
33 	register struct lfs *fs;
34 	struct inode *ip;
35 	struct buf *bp;
36 	daddr_t lbn;
37 	int bsize, error;
38 
39 	ip = VTOI(vp);
40 	fs = ip->i_lfs;
41 	lbn = lblkno(fs, offset);
42 	bsize = blksize(fs);
43 
44 	*bpp = NULL;
45 	if (error = bread(vp, lbn, bsize, NOCRED, &bp)) {
46 		brelse(bp);
47 		return (error);
48 	}
49 	if (res)
50 		*res = bp->b_un.b_addr + blkoff(fs, offset);
51 	*bpp = bp;
52 	return (0);
53 }
54 
55 /* Return the current version number for a specific inode. */
56 u_long
57 lfs_getversion(fs, ino)
58 	struct lfs *fs;
59 	ino_t ino;
60 {
61 	BUF *bp;
62 	IFILE *ifp;
63 	u_long version;
64 
65 	/*
66 	 * Read the appropriate block from the ifile.  Return the
67 	 * version number.
68 	 */
69 	LFS_IENTRY(ifp, fs, ino, bp);
70 	version = ifp->if_version;
71 	brelse(bp);
72 	return (version);
73 }
74 
75 /* Search a block for a specific dinode. */
76 DINODE *
77 lfs_ifind(fs, ino, page)
78 	struct lfs *fs;
79 	ino_t ino;
80 	void *page;
81 {
82 	register DINODE *dip;
83 	register int cnt;
84 
85 #ifdef ALLOCPRINT
86 	printf("lfs_ifind: inode %d\n", ino);
87 #endif
88 	dip = page;
89 	for (cnt = INOPB(fs); cnt--; ++dip)
90 		if (dip->di_inum == ino)
91 			return (dip);
92 
93 	panic("lfs_ifind: dinode %u not found", ino);
94 	/* NOTREACHED */
95 }
96 
97 /* Set values in the ifile for the inode. */
98 void
99 lfs_iset(ip, daddr, atime)
100 	INODE *ip;
101 	daddr_t daddr;
102 	time_t atime;
103 {
104 	BUF *bp;
105 	IFILE *ifp;
106 	struct lfs *fs;
107 	ino_t ino;
108 
109 #ifdef ALLOCPRINT
110 	printf("lfs_iset: setting ino %d daddr %lx time %lx\n",
111 	    ip->i_number, daddr, atime);
112 #endif
113 
114 	fs = ip->i_lfs;
115 	ino = ip->i_number;
116 	LFS_IENTRY(ifp, fs, ino, bp);
117 
118 	ifp->if_daddr = daddr;
119 	ifp->if_st_atime = atime;
120 	lfs_bwrite(bp);
121 }
122 
123 /* Translate an inode number to a disk address. */
124 daddr_t
125 lfs_itod(fs, ino)
126 	struct lfs *fs;
127 	ino_t ino;
128 {
129 	BUF *bp;
130 	IFILE *ifp;
131 	daddr_t iaddr;
132 
133 	/* Read the appropriate block from the ifile. */
134 	LFS_IENTRY(ifp, fs, ino, bp);
135 
136 	if (ifp->if_daddr == LFS_UNUSED_DADDR)
137 		panic("itod: unused disk address");
138 	iaddr = ifp->if_daddr;
139 	brelse(bp);
140 	return (iaddr);
141 }
142