Commit Graph

82 Commits

Author SHA1 Message Date
provos
0f09ed48a5 remove trailing \n in panic(). approved perry. 2002-09-27 15:35:29 +00:00
jdolecek
e305eb63e8 don't need <sys/conf.h> here 2002-09-22 19:32:54 +00:00
perseant
32ae84b188 Deal with fragment size changes better. For each fragment that can
exist on an on-disk inode, we keep a record of its size in struct inode,
which is updated when we write the block to disk.  The cleaner routines
thus have ready access to what size is the correct size for this block,
on disk.

Fixed a related bug: if a file with fragments is being cleaned
(fragments being cleaned) at the same time it is being extended beyond
NDADDR blocks, we could write a bogus FINFO record that has a frag in the
middle; when it was cleaned this would give back bogus file data.  Don't
write the indirect blocks in this case, since there is no need.

lfs_fragextend and lfs_truncate no longer require the seglock, but instead
take a shared lock, which the seglock locks exclusively.
2002-07-06 01:30:11 +00:00
perseant
ddfb1dbb92 For synchronous writes, keep separate i/o counters for each write, so
processes don't have to wait for one another to finish (e.g., nfsd seems
to be a little happier now, though I haven't measured the difference).
Synchronous checkpoints, however, must always wait for all i/o to finish.

Take the contents of the callback functions and have them run in thread
context instead (aiodoned thread).  lfs_iocount no longer has to be
protected in splbio(), and quite a bit less of the segment construction
loop needs to be in splbio() as well.

If lfs_markv is handed a block that is not the correct size according to
the inode, refuse to process it.  (Formerly it was extended to the "correct"
size.)  This is possibly more prone to deadlock, but less prone to corruption.

lfs_segclean now outright refuses to clean segments that appear to have live
bytes in them.  Again this may be more prone to deadlock but avoids
corruption.

Replace ufsspec_close and ufsfifo_close with LFS equivalents; this means
that no UFS functions need to know about LFS_ITIMES any more.  Remove
the reference from ufs/inode.h.

Tested on i386, test-compiled on alpha.
2002-06-16 00:13:15 +00:00
perseant
d67a5bbb21 Fix a couple of instances where reassignbuf() was not done at splbio.
Tested on i386.
2002-05-24 22:13:57 +00:00
perseant
43ca783b4a Back out rev 1.174 of vfs_subr.c, because the splbio() wasn't protecting
enough to be useful, and broadening it so that it did would have meant
that operations possibly requiring synchronous disk activity would have
to be done in splbio().  This clearly was not going to work.

Worked around this in the LFS case by having lfs_cluster_callback put an
extra hold on the vnode before calling biodone(), and taking the hold
off without HOLDRELE's problematic list swapping.  lfs_vunref() will take
care of that---in thread context---on the next write if need be.

Also, ensure that the list walking in lfs_{writevnodes,segunlock,gather}
takes into account the possibility that the list may change
underneath it (possibly because it itself deleted an element).

Tested on i386, test-compiled on alpha.
2002-05-23 23:05:25 +00:00
perseant
ec0ca919be Protect v_freelist with splbio(), since HOLDRELE can be called in
interrupt context (through brelvp).  (LFS may be the only subsystem
affected by this problem.)

Tested on i386.
2002-05-20 22:50:57 +00:00
perseant
36efaa3565 use macros from <sys/queue.h> 2002-05-17 21:42:38 +00:00
perseant
8886b0f4b2 Phase one of my three-phase plan to make LFS play nice with UBC, and bug-fixes
I found while making sure there weren't any new ones.

* Make the write clusters keep track of the buffers whose blocks they contain.
  This should make it possible to (1) write clusters using a page mapping
  instead of malloc, if desired, and (2) schedule blocks for rewriting
  (somewhere else) if a write error occurs.  Code is present to use
  pagemove() to construct the clusters but that is untested and will go away
  anyway in favor of page mapping.
* DEBUG now keeps a log of Ifile writes, so that any lingering instances of
  the "dirty bufs" problem can be properly debugged.
* Keep track of whether the Ifile has been dirtied by various routines that
  can be called by lfs_segwrite, and loop on that until it is clean, for
  a checkpoint.  Checkpoints need to be squeaky clean.
* Warn the user (once) if the Ifile grows larger than is reasonable for their
  buffer cache.  Both lfs_mountfs and lfs_unmount check since the Ifile can
  grow.
* If an inode is not found in a disk block, try rereading the block, under
  the assumption that the block was copied to a cluster and then freed.
* Protect WRITEINPROG() with splbio() to fix a hang in lfs_update.
2002-05-14 20:03:53 +00:00
chs
a106161b5a add spaces for KNF. confirmed to produce identical objects. 2001-11-23 21:44:25 +00:00
lukem
ec6245465a add RCSID 2001-11-08 02:39:06 +00:00
lukem
99147a7648 remove #include <ufs/ufs/quota.h> where it was just to appease
<ufs/ufs/inode.h>, since the latter now includes the former.  leave the former
in source that obviously uses specific bits of it (for completeness.)
2001-10-26 05:56:06 +00:00
jdolecek
bd21ec5d2e lfs_writeseg(): make el_size a size_t (cosmetic only, no functional change) 2001-07-26 20:20:15 +00:00
perseant
4e3fced95b Merge the short-lived perseant-lfsv2 branch into the trunk.
Kernels and tools understand both v1 and v2 filesystems; newfs_lfs
generates v2 by default.  Changes for the v2 layout include:

- Segments of non-PO2 size and arbitrary block offset, so these can be
  matched to convenient physical characteristics of the partition (e.g.,
  stripe or track size and offset).

- Address by fragment instead of by disk sector, paving the way for
  non-512-byte-sector devices.  In theory fragments can be as large
  as you like, though in reality they must be smaller than MAXBSIZE in size.

- Use serial number and filesystem identifier to ensure that roll-forward
  doesn't get old data and think it's new.  Roll-forward is enabled for
  v2 filesystems, though not for v1 filesystems by default.

- The inode free list is now a tailq, paving the way for undelete (undelete
  is not yet implemented, but can be without further non-backwards-compatible
  changes to disk structures).

- Inode atime information is kept in the Ifile, instead of on the inode;
  that is, the inode is never written *just* because atime was changed.
  Because of this the inodes remain near the file data on the disk, rather
  than wandering all over as the disk is read repeatedly.  This speeds up
  repeated reads by a small but noticeable amount.

Other changes of note include:

- The ifile written by newfs_lfs can now be of arbitrary length, it is no
  longer restricted to a single indirect block.

- Fixed an old bug where ctime was changed every time a vnode was created.
  I need to look more closely to make sure that the times are only updated
  during write(2) and friends, not after-the-fact during a segment write,
  and certainly not by the cleaner.
2001-07-13 20:30:18 +00:00
mrg
67afbd6270 use _KERNEL_OPT 2001-05-30 11:57:16 +00:00
joff
a6ef389457 If DIAGNOSTIC and the segment writer gets a badly sized buffer, panic()
instead of silently corrupting the filesystem.
2001-01-09 05:05:35 +00:00
perseant
2a53ff5ab9 Get rid of some old unnecessary code that cleared B_NEEDCOMMIT from buffers in
lfs_writeseg (possibly after they had been freed).

If MALLOCLOG is defined, make lfs_newbuf and lfs_freebuf pass along the
caller's file and line to _malloc and _free.
2000-12-03 05:56:27 +00:00
jdolecek
bf558e3b3e only include opt_ddb.h for !LKM 2000-11-30 15:59:47 +00:00
chs
aeda8d3b77 Initial integration of the Unified Buffer Cache project. 2000-11-27 08:39:39 +00:00
perseant
0055236dda If LFS_DO_ROLLFORWARD is defined, roll forward from the older checkpoint
on mount, through the newer checkpoint and on through any newer
partial-segments that may have been written but not checkpointed because
of an intervening crash.

LFS_DO_ROLLFORWARD is not defined by default.
2000-11-27 03:33:57 +00:00
perseant
31fc62d4e9 Correct accounting of lfs_avail, locked_queue_count, and locked_queue_bytes.
(PR #11468).  In the case of fragment allocation, check to see if enough
space is available before extending a fragment already scheduled for writing.

The locked_queue_* variables indicate the number of buffer headers and bytes,
respectively, that are unavailable to getnewbuf() because they are locked up
waiting for LFS to flush them; make sure that that is actually what we're
counting, i.e., never count malloced buffers, and always use b_bufsize instead
of b_bcount.

If DEBUG is defined, the periodic calls to lfs_countlocked will now complain
if either counter is incorrect.  (In the future lfs_countlocked will not need
to be called at all if DEBUG is not defined.)
2000-11-17 19:14:41 +00:00
perseant
c4c7b2adbb Do not needlessly dirty segment table blocks during lfs_segwrite,
preventing needless disk activity when the filesystem is idle.  (PR #10979.)
2000-11-12 07:58:36 +00:00
toshii
af22f56146 Fix obsolete comments in lfs_writeinode since rev. 1.27.
New comments are mostly from perseant, with my additions.
2000-11-12 02:13:51 +00:00
perseant
17cb334f4f oops 2000-09-09 21:03:31 +00:00
perseant
9c7f8050f4 Various bug-fixes to LFS, to wit:
Kernel:

* Add runtime quantity lfs_ravail, the number of disk-blocks reserved
  for writing.  Writes to the filesystem first reserve a maximum amount
  of blocks before their write is allowed to proceed; after the blocks
  are allocated the reserved total is reduced by a corresponding amount.

  If the lfs_reserve function cannot immediately reserve the requested
  number of blocks, the inode is unlocked, and the thread sleeps until
  the cleaner has made enough space available for the blocks to be
  reserved.  In this way large files can be written to the filesystem
  (or, smaller files can be written to a nearly-full but thoroughly
  clean filesystem) and the cleaner can still function properly.

* Remove explicit switching on dlfs_minfreeseg from the kernel code; it
  is now merely a fs-creation parameter used to compute dlfs_avail and
  dlfs_bfree (and used by fsck_lfs(8) to check their accuracy).  Its
  former role is better assumed by a properly computed dlfs_avail.

* Bounds-check inode numbers submitted through lfs_bmapv and lfs_markv.
  This prevents a panic, but, if the cleaner is feeding the filesystem
  the wrong data, you are still in a world of hurt.

* Cleanup: remove explicit references of DEV_BSIZE in favor of
  btodb()/dbtob().

lfs_cleanerd:

* Make -n mean "send N segments' blocks through a single call to
  lfs_markv".  Previously it had meant "clean N segments though N calls
  to lfs_markv, before looking again to see if more need to be cleaned".
  The new behavior gives better packing of direct data on disk with as
  little metadata as possible, largely alleviating the problem that the
  cleaner can consume more disk through inefficient use of metadata than
  it frees by moving dirty data away from clean "holes" to produce
  entirely clean segments.

* Make -b mean "read as many segments as necessary to write N segments
  of dirty data back to disk", rather than its former meaning of "read
  as many segments as necessary to free N segments worth of space".  The
  new meaning, combined with the new -n behavior described above,
  further aids in cleaning storage efficiency as entire segments can be
  written at once, using as few blocks as possible for segment summaries
  and inode blocks.

* Make the cleaner take note of segments which could not be cleaned due
  to error, and not attempt to clean them until they are entirely free
  of dirty blocks.  This prevents the case in which a cleanerd running
  with -n 1 and without -b (formerly the default) would spin trying
  repeatedly to clean a corrupt segment, while the remaining space
  filled and deadlocked the filesystem.

* Update the lfs_cleanerd manual page to describe all the options,
  including the changes mentioned here (in particular, the -b and -n
  flags were previously undocumented).

fsck_lfs:

* Check, and optionally fix, lfs_avail (to an exact figure) and
  lfs_bfree (within a margin of error) in pass 5.

newfs_lfs:

* Reduce the default dlfs_minfreeseg to 1/20 of the total segments.

* Add a warning if the sgs disklabel field is 16 (the default for FFS'
  cpg, but not usually desirable for LFS' sgs: 5--8 is a better range).

* Change the calculation of lfs_avail and lfs_bfree, corresponding to
  the kernel changes mentioned above.

mount_lfs:

* Add -N and -b options to pass corresponding -n and -b options to
  lfs_cleanerd.

* Default to calling lfs_cleanerd with "-b -n 4".


[All of these changes were largely tested in the 1.5 branch, with the
idea that they (along with previous un-pulled-up work) could be applied
to the branch while it was still in ALPHA2; however my test system has
experienced corruption on another filesystem (/dev/console has gone
missing :^), and, while I believe this unrelated to the LFS changes, I
cannot with good conscience request that the changes be pulled up.]
2000-09-09 04:49:54 +00:00
perseant
8cb6723a92 Fix a buffer-cache corrupting bug in lfs_writeseg, where brelse could
be improperly used on an already-queued buffer.
2000-09-09 04:13:43 +00:00
perseant
90b9d9b502 Clean up accounting of lfs_uinodes (dirty but unwritten inodes).
Make lfs_uinodes a signed quantity for debugging purposes, and set it to
zero as fs mount time.

Enclose setting/clearing of the dirty flags (IN_MODIFIED, IN_ACCESSED,
IN_CLEANING) in macros, and use those macros everywhere.  Make
LFS_ITIMES use these macros; updated the ITIMES macro in inode.h to know
about this.  Make ufs_getattr use ITIMES instead of FFS_ITIMES.
2000-07-05 22:25:43 +00:00
perseant
bc303e52cb Fix errors observed while trying to fill the filesystem with yesterday's
fixes:

- Write copies of bfree and avail in the CLEANERINFO block, so the
  cleaner doesn't have to guess which superblock has the current
  information (if indeed any do).

- Tighten up accounting of lfs_avail (more needs to be done).

- When cleansing indirect blocks of UNWRITTEN, make sure not to mark
  them clean, since they'll need to be rewritten later.
2000-07-04 22:30:37 +00:00
perseant
235a4dd595 i_lfs_effnblks fixes. Put debugging printfs under #ifdef DEBUG_LFS. 2000-07-03 08:20:58 +00:00
perseant
ef2da50400 Allow the number of free segments reserved for the cleaner to be
parametrized in the filesystem, defaulting to MIN_FREE_SEGS = 2 but set
to something more reasonable at newfs_lfs time.

Note the number of blocks that have been scheduled for writing but which
are not yet on disk in an inode extension, i_lfs_effnblks.  Move
i_ffs_effnlink out of the ffs extension and onto the main inode, since
it's used all over the shared code and the lfs extension would clobber
it.

At inode write time, indirect blocks and inode-held blocks of inodes
that have i_lfs_effnblks != i_ffs_blocks are cleansed of UNWRITTEN disk
addresses, so that these never make it to disk.
2000-07-03 01:45:46 +00:00
perseant
39b86955ed Fixes associated with filling an LFS:
Change the space computation to appear to change the size of the *disk*
rather than the *bytes used* when more segment summaries and inode
blocks are written.  Try to estimate the amount of space that these will
take up when more files are written, so the disk size doesn't change too
much.

Regularize error returns from lfs_valloc, lfs_balloc, lfs_truncate: they
now fail entirely, rather than succeeding half-way and leaving the fs in
an inconsistent state.

Rewrite lfs_truncate, mostly stealing from ffs_truncate.  The old
lfs_truncate had difficulty truncating a large file to a non-zero size
(indirect blocks were not handled appropriately).

Unmark VDIROP on fvp after ufs_remove, ufs_rmdir, so these can be
reclaimed immediately: this vnode would not be written to disk again
anyway if the removal succeeded, and if it failed, no directory
operation occurred.

ufs_makeinode and ufs_mkdir now remove IN_ADIROP on error.
2000-06-27 20:57:11 +00:00
perseant
d8584d7769 From John Evans <jevans@cray.com>: use datosn() to convert to segment
number, when remarking the current segment ACTIVE.  See PR #10463.
2000-06-27 20:00:03 +00:00
perseant
973ddee4e5 Update lfs_vunref for the fact that now a vnode can be locked with no
references (locked for VOP_INACTIVE at the end of vrele) and it's okay.
Check the return value of lfs_vref where appropriate.
Fixes PR #s 10285 and 10352.
2000-06-22 18:11:45 +00:00
perseant
9139045320 Protect inode free list with seglock, instead of separate lock, so that
the head of the inode free list (on the superblock) always matches the
rest of the free list (in the ifile).

Protect lfs_fragextend with seglock, to prevent the segment byte count
fudging from making its way to disk.

Don't try to inactivate dirop vnodes that are still in the middle of
their dirop (may address PR#10285).
2000-06-06 20:19:14 +00:00
fredb
ef3785c36a Make this build. (Balance parenthesis. 2000-05-31 03:37:34 +00:00
perseant
61861bace5 update for IN_ACCESSED changes 2000-05-31 01:40:01 +00:00
perseant
29f616cebe Prevent dirops from getting around lfs_check and wedging the buffer cache.
All the dirop vnops now mark the inodes with a new flag, IN_ADIROP, which
is removed as soon as the dirop is done (as opposed to VDIROP which stays
until the file is written).  To address one issue raised in PR#9357.
2000-05-27 00:19:52 +00:00
thorpej
f636538446 NULL != 0 2000-05-19 04:34:39 +00:00
perseant
bcbb008f63 stop vnode reference leak introduced in patch to PR#9994 2000-05-10 16:47:01 +00:00
perseant
737dec82d6 Change the way LFS does block accounting, from trying to infer from the
buffer cache flags, to marking the inode and/or indirect blocks with a
special disk address UNWRITTEN==-2 when a block is accounted for.  (This
address is never written to disk, but only used in-core.  This is essentially
the same method of block accounting as on the UBC branch, where the buffer
headers don't exist.)  Make sure that truncation is handled properly,
especially in the case of holey files.

Fixes PR#9994.
2000-05-05 20:59:20 +00:00
augustss
169ac5b3c1 Remove register declarations. 2000-03-30 12:41:09 +00:00
soren
95054da1a1 Fix doubled 'the's in comments. 2000-03-13 23:52:25 +00:00
perseant
dac789be22 Changes to stabilize LFS. The first two of these should also apply to the
1.4 branch.

* Use a separate per-fs lock, instead of ufs_hashlock, to protect the Inode
  free list.  This seems to prevent the "lockmgr: %d, not exclusive lock holder
  %d, unlocking" message I was mis-attributing last night to an unlocked vnode
  being passed to vrele.

* Change calling semantics of lfs_ifind, to give better error reporting:
  If fed a struct buf, it can report the block number of the offending inode
  block as well as the inode number.

* Back out rev 1.10 of lfs_subr.c, since the replacement code was slightly
  uglier while being functionally identical.

* Make lfs_vunref use the same free list convention as vrele/vput, so that
  vget does not remove vnodes from a hash list they are not on.
2000-01-19 00:03:04 +00:00
perseant
86b0e2dc16 Fix a problem in my changes of Dec 14th, that prevents removed vnodes
from being inactivated under some conditions.  Removed vnodes are now
inactivated when the VDIROP flag is cleared, and to prevent block
accounting problems this clearing has been postponed until
lfs_segunlock.
2000-01-16 05:56:14 +00:00
perseant
dbe30ed5d4 Better handling of various combinations of cleaning, vnode flushing, and
dirop writing.  In particular, lfs_writevnodes now writes all buffers from
a flushed vnode whether cleaning or not, and the same with the Ifile; and
lfs_segwrite does not attempt to write data from other non-cleaning vnodes,
even if a vnode is being flushed.
2000-01-14 21:38:46 +00:00
perseant
22979769c0 Handle the case of a vnode flush while dirops are active correctly in
lfs_segwrite.  Also, make sure a flush is called in SET_DIROP before sleeping
on its results.  Addresses PR #8863.
1999-12-03 21:47:44 +00:00
perseant
ff33b3365d Fix spllevel problem with superblock exclusion and with segment write throttle.
May address PR#8383.
1999-11-17 20:08:30 +00:00
fvdl
0b1963121a Add Kirk McKusick's soft updates code to the trunk. Not enabled by
default, as the copyright on the main file (ffs_softdep.c) is such
that is has been put into gnusrc. options SOFTDEP will pull this
in. This code also contains the trickle syncer.

Bump version number to 1.4O
1999-11-15 18:49:07 +00:00
perseant
fc5ecbb5a8 Back out my patch of the 8th (to address unreferenced inode problem).
Apparently this needs more thought.
1999-11-12 16:56:48 +00:00
perseant
26c34e715f If ifile blocks were written before dirops were complete, and then the
system crashed, inodes could be allocated that were not referenced.  (Though
not a serious problem, it evidences itself in phase 4 of fsck_lfs.)  Fix
this by marking if_daddr with UNASSIGNED before the inodes are actually
written; at mount time the ifile is checked for UNASSIGNED entries and
any that are found are linked back into the free list.  (The latter
functionality should move into the roll-forward agent when it materializes.)
1999-11-09 02:21:05 +00:00