945cd90caf3da4788900d69a952ecd80fea058b9
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
* @(#)lfs_subr.c 8.2 (Berkeley) %G%
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/lfs/lfs_extern.h>
* Return buffer with the contents of block "offset" from the beginning of
* directory "ip". If "res" is non-zero, fill it in with a pointer to the
* remaining space in the directory.
struct vop_blkatoff_args
/* {
lbn
= lblkno(fs
, ap
->a_offset
);
if (error
= bread(ap
->a_vp
, lbn
, bsize
, NOCRED
, &bp
)) {
*ap
->a_res
= (char *)bp
->b_data
+ blkoff(fs
, ap
->a_offset
);
* Single thread the segment writer.
if (fs
->lfs_lockpid
== curproc
->p_pid
) {
fs
->lfs_sp
->seg_flags
|= flags
;
} else while (fs
->lfs_seglock
)
(void)tsleep(&fs
->lfs_seglock
, PRIBIO
+ 1,
fs
->lfs_lockpid
= curproc
->p_pid
;
sp
= fs
->lfs_sp
= malloc(sizeof(struct segment
), M_SEGMENT
, M_WAITOK
);
sp
->bpp
= malloc(((LFS_SUMMARY_SIZE
- sizeof(SEGSUM
)) /
sizeof(daddr_t
) + 1) * sizeof(struct buf
*), M_SEGMENT
, M_WAITOK
);
* Keep a cumulative count of the outstanding I/O operations. If the
* disk drive catches up with us it could go to zero before we finish,
* so we artificially increment it by one until we've scheduled all of
* the writes we intend to do.
* Single thread the segment writer.
if (fs
->lfs_seglock
== 1) {
sync
= sp
->seg_flags
& SEGM_SYNC
;
ckp
= sp
->seg_flags
& SEGM_CKP
;
if (sp
->bpp
!= sp
->cbpp
) {
/* Free allocated segment summary */
fs
->lfs_offset
-= LFS_SUMMARY_SIZE
/ DEV_BSIZE
;
free((*sp
->bpp
)->b_data
, M_SEGMENT
);
free(*sp
->bpp
, M_SEGMENT
);
printf ("unlock to 0 with no summary");
free(sp
->bpp
, M_SEGMENT
);
* If the I/O count is non-zero, sleep until it reaches zero.
* At the moment, the user's process hangs around so we can
* We let checkpoints happen asynchronously. That means
* that during recovery, we have to roll forward between
* the two segments described by the first and second
* superblocks to make sure that the checkpoint described
* by a superblock completed.
if (sync
&& fs
->lfs_iocount
)
(void)tsleep(&fs
->lfs_iocount
, PRIBIO
+ 1, "lfs vflush", 0);
wakeup(&fs
->lfs_seglock
);
} else if (fs
->lfs_seglock
== 0) {
panic ("Seglock not held");