xref: /original-bsd/sys/ufs/lfs/lfs_subr.c (revision 5133e8a4)
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.13 (Berkeley) 07/05/92
8  */
9 
10 #include <sys/param.h>
11 #include <sys/namei.h>
12 #include <sys/vnode.h>
13 #include <sys/buf.h>
14 #include <sys/mount.h>
15 
16 #include <ufs/ufs/quota.h>
17 #include <ufs/ufs/inode.h>
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(ap)
28 	struct vop_blkatoff_args /* {
29 		struct vnode *a_vp;
30 		off_t a_offset;
31 		char **a_res;
32 		struct buf **a_bpp;
33 	} */ *ap;
34 {
35 	register struct lfs *fs;
36 	struct inode *ip;
37 	struct buf *bp;
38 	daddr_t lbn;
39 	int bsize, error;
40 
41 	ip = VTOI(ap->a_vp);
42 	fs = ip->i_lfs;
43 	lbn = lblkno(fs, ap->a_offset);
44 	bsize = blksize(fs);
45 
46 	*ap->a_bpp = NULL;
47 	if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) {
48 		brelse(bp);
49 		return (error);
50 	}
51 	if (ap->a_res)
52 		*ap->a_res = bp->b_un.b_addr + blkoff(fs, ap->a_offset);
53 	*ap->a_bpp = bp;
54 	return (0);
55 }
56 
57 /*
58  * lfs_seglock --
59  *	Single thread the segment writer.
60  */
61 void
62 lfs_seglock(fs)
63 	struct lfs *fs;
64 {
65 	while (fs->lfs_seglock)
66 		(void)tsleep(&fs->lfs_seglock, PRIBIO + 1, "lfs seglock", 0);
67 	fs->lfs_seglock = 1;
68 }
69 
70 /*
71  * lfs_segunlock --
72  *	Single thread the segment writer.
73  */
74 void
75 lfs_segunlock(fs)
76 	struct lfs *fs;
77 {
78 	fs->lfs_seglock = 0;
79 	wakeup(&fs->lfs_seglock);	/* XXX: May not be necessary. */
80 }
81