| 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) %G% |
| 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 | } |