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