Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/sys/ufs/ffs Pull up moved version (from gnu/sys/ufs/ffs...
details: https://anonhg.NetBSD.org/src/rev/5fd377680ce3
branches: netbsd-1-5
changeset: 488239:5fd377680ce3
user: fvdl <fvdl%NetBSD.org@localhost>
date: Fri Jun 23 14:32:22 2000 +0000
description:
Pull up moved version (from gnu/sys/ufs/ffs) as on the trunk.
diffstat:
sys/ufs/ffs/ffs_softdep.c | 4720 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 4720 insertions(+), 0 deletions(-)
diffs (truncated from 4724 to 300 lines):
diff -r 7a97becfe312 -r 5fd377680ce3 sys/ufs/ffs/ffs_softdep.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/ufs/ffs/ffs_softdep.c Fri Jun 23 14:32:22 2000 +0000
@@ -0,0 +1,4720 @@
+/* $NetBSD: ffs_softdep.c,v 1.2.2.2 2000/06/23 14:32:22 fvdl Exp $ */
+
+/*
+ * Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
+ *
+ * The soft updates code is derived from the appendix of a University
+ * of Michigan technical report (Gregory R. Ganger and Yale N. Patt,
+ * "Soft Updates: A Solution to the Metadata Update Problem in File
+ * Systems", CSE-TR-254-95, August 1995).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)ffs_softdep.c 9.56 (McKusick) 1/17/00
+ */
+
+/*
+ * For now we want the safety net that the DIAGNOSTIC and DEBUG flags provide.
+ */
+#ifndef DIAGNOSTIC
+#define DIAGNOSTIC
+#endif
+#ifndef DEBUG
+#define DEBUG
+#endif
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/callout.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/syslog.h>
+#include <sys/systm.h>
+#include <sys/vnode.h>
+#include <miscfs/specfs/specdev.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/inode.h>
+#include <ufs/ufs/ufsmount.h>
+#include <ufs/ffs/fs.h>
+#include <ufs/ffs/softdep.h>
+#include <ufs/ffs/ffs_extern.h>
+#include <ufs/ufs/ufs_extern.h>
+#include <ufs/ufs/ufs_bswap.h>
+
+/*
+ * These definitions need to be adapted to the system to which
+ * this file is being ported.
+ */
+/*
+ * Mapping of dependency structure types to malloc types.
+ */
+#define D_PAGEDEP M_PAGEDEP
+#define D_INODEDEP M_INODEDEP
+#define D_NEWBLK M_NEWBLK
+#define D_BMSAFEMAP M_BMSAFEMAP
+#define D_ALLOCDIRECT M_ALLOCDIRECT
+#define D_INDIRDEP M_INDIRDEP
+#define D_ALLOCINDIR M_ALLOCINDIR
+#define D_FREEFRAG M_FREEFRAG
+#define D_FREEBLKS M_FREEBLKS
+#define D_FREEFILE M_FREEFILE
+#define D_DIRADD M_DIRADD
+#define D_MKDIR M_MKDIR
+#define D_DIRREM M_DIRREM
+/*
+ * Names of malloc types.
+ */
+extern char *memname[];
+#define TYPENAME(type) ((unsigned)(type) < M_LAST ? memname[type] : "???")
+#define DtoM(type) (type)
+/*
+ * Finding the current process.
+ */
+#define CURPROC curproc
+#define CURPROC_PID (curproc ? curproc->p_pid : 0)
+/*
+ * End system adaptaion definitions.
+ */
+
+/*
+ * Internal function prototypes.
+ */
+static void softdep_error __P((char *, int));
+static void drain_output __P((struct vnode *, int));
+static int getdirtybuf __P((struct buf **, int));
+static void clear_remove __P((struct proc *));
+static void clear_inodedeps __P((struct proc *));
+static int flush_pagedep_deps __P((struct vnode *, struct mount *,
+ struct diraddhd *));
+static int flush_inodedep_deps __P((struct fs *, ino_t));
+static int handle_written_filepage __P((struct pagedep *, struct buf *));
+static void diradd_inode_written __P((struct diradd *, struct inodedep *));
+static int handle_written_inodeblock __P((struct inodedep *, struct buf *));
+static void handle_allocdirect_partdone __P((struct allocdirect *));
+static void handle_allocindir_partdone __P((struct allocindir *));
+static void initiate_write_filepage __P((struct pagedep *, struct buf *));
+static void handle_written_mkdir __P((struct mkdir *, int));
+static void initiate_write_inodeblock __P((struct inodedep *, struct buf *));
+static void handle_workitem_freefile __P((struct freefile *));
+static void handle_workitem_remove __P((struct dirrem *));
+static struct dirrem *newdirrem __P((struct buf *, struct inode *,
+ struct inode *, int, struct dirrem **));
+static void free_diradd __P((struct diradd *));
+static void free_allocindir __P((struct allocindir *, struct inodedep *));
+static int indir_trunc __P((struct inode *, ufs_daddr_t, int, ufs_lbn_t,
+ long *));
+static void deallocate_dependencies __P((struct buf *, struct inodedep *));
+static void free_allocdirect __P((struct allocdirectlst *,
+ struct allocdirect *, int));
+static int check_inode_unwritten __P((struct inodedep *));
+static int free_inodedep __P((struct inodedep *));
+static void handle_workitem_freeblocks __P((struct freeblks *));
+static void merge_inode_lists __P((struct inodedep *));
+static void setup_allocindir_phase2 __P((struct buf *, struct inode *,
+ struct allocindir *));
+static struct allocindir *newallocindir __P((struct inode *, int, ufs_daddr_t,
+ ufs_daddr_t));
+static void handle_workitem_freefrag __P((struct freefrag *));
+static struct freefrag *newfreefrag __P((struct inode *, ufs_daddr_t, long));
+static void allocdirect_merge __P((struct allocdirectlst *,
+ struct allocdirect *, struct allocdirect *));
+static struct bmsafemap *bmsafemap_lookup __P((struct buf *));
+static int newblk_lookup __P((struct fs *, ufs_daddr_t, int,
+ struct newblk **));
+static int inodedep_lookup __P((struct fs *, ino_t, int, struct inodedep **));
+static int pagedep_lookup __P((struct inode *, ufs_lbn_t, int,
+ struct pagedep **));
+static void pause_timer __P((void *));
+static int request_cleanup __P((int, int));
+static void add_to_worklist __P((struct worklist *));
+
+/*
+ * Exported softdep operations.
+ */
+static void softdep_disk_io_initiation __P((struct buf *));
+static void softdep_disk_write_complete __P((struct buf *));
+static void softdep_deallocate_dependencies __P((struct buf *));
+static int softdep_fsync __P((struct vnode *));
+static int softdep_process_worklist __P((struct mount *));
+static void softdep_move_dependencies __P((struct buf *, struct buf *));
+static int softdep_count_dependencies __P((struct buf *bp, int));
+
+struct bio_ops bioops = {
+ softdep_disk_io_initiation, /* io_start */
+ softdep_disk_write_complete, /* io_complete */
+ softdep_deallocate_dependencies, /* io_deallocate */
+ softdep_fsync, /* io_fsync */
+ softdep_process_worklist, /* io_sync */
+ softdep_move_dependencies, /* io_movedeps */
+ softdep_count_dependencies, /* io_countdeps */
+};
+
+/*
+ * Locking primitives.
+ *
+ * For a uniprocessor, all we need to do is protect against disk
+ * interrupts. For a multiprocessor, this lock would have to be
+ * a mutex. A single mutex is used throughout this file, though
+ * finer grain locking could be used if contention warranted it.
+ *
+ * For a multiprocessor, the sleep call would accept a lock and
+ * release it after the sleep processing was complete. In a uniprocessor
+ * implementation there is no such interlock, so we simple mark
+ * the places where it needs to be done with the `interlocked' form
+ * of the lock calls. Since the uniprocessor sleep already interlocks
+ * the spl, there is nothing that really needs to be done.
+ */
+#ifndef /* NOT */ DEBUG
+static struct lockit {
+ int lkt_spl;
+} lk = { 0 };
+#define ACQUIRE_LOCK(lk) (lk)->lkt_spl = splbio()
+#define FREE_LOCK(lk) splx((lk)->lkt_spl)
+#define ACQUIRE_LOCK_INTERLOCKED(lk, s) (lk)->lkt_spl = s
+#define FREE_LOCK_INTERLOCKED(lk) (lk)->lkt_spl
+
+#else /* DEBUG */
+static struct lockit {
+ int lkt_spl;
+ pid_t lkt_held;
+} lk = { 0, -1 };
+static int lockcnt;
+
+static void acquire_lock __P((struct lockit *));
+static void free_lock __P((struct lockit *));
+static void acquire_lock_interlocked __P((struct lockit *, int));
+static int free_lock_interlocked __P((struct lockit *));
+
+#define ACQUIRE_LOCK(lk) acquire_lock(lk)
+#define FREE_LOCK(lk) free_lock(lk)
+#define ACQUIRE_LOCK_INTERLOCKED(lk, s) acquire_lock_interlocked(lk, s)
+#define FREE_LOCK_INTERLOCKED(lk) free_lock_interlocked(lk)
+
+static void
+acquire_lock(lk)
+ struct lockit *lk;
+{
+ if (lk->lkt_held != -1) {
+ if (lk->lkt_held == CURPROC_PID)
+ panic("softdep_lock: locking against myself");
+ else
+ panic("softdep_lock: lock held by %d", lk->lkt_held);
+ }
+ lk->lkt_spl = splbio();
+ lk->lkt_held = CURPROC_PID;
+ lockcnt++;
+}
+
+static void
+free_lock(lk)
+ struct lockit *lk;
+{
+
+ if (lk->lkt_held == -1)
+ panic("softdep_unlock: lock not held");
+ lk->lkt_held = -1;
+ splx(lk->lkt_spl);
+}
+
+static void
+acquire_lock_interlocked(lk, s)
+ struct lockit *lk;
+ int s;
+{
+ if (lk->lkt_held != -1) {
+ if (lk->lkt_held == CURPROC_PID)
+ panic("softdep_lock_interlocked: locking against self");
+ else
+ panic("softdep_lock_interlocked: lock held by %d",
+ lk->lkt_held);
+ }
+ lk->lkt_spl = s;
+ lk->lkt_held = CURPROC_PID;
+ lockcnt++;
+}
+
+static int
+free_lock_interlocked(lk)
+ struct lockit *lk;
+{
+ if (lk->lkt_held == -1)
+ panic("softdep_unlock_interlocked: lock not held");
+ lk->lkt_held = -1;
+ return lk->lkt_spl;
+}
+#endif /* DEBUG */
+
+/*
+ * Place holder for real semaphores.
+ */
+struct sema {
+ int value;
+ pid_t holder;
+ char *name;
+ int prio;
+ int timo;
+};
+static void sema_init __P((struct sema *, char *, int, int));
+static int sema_get __P((struct sema *, struct lockit *));
+static void sema_release __P((struct sema *));
+
+static void
+sema_init(semap, name, prio, timo)
+ struct sema *semap;
+ char *name;
+ int prio, timo;
+{
+
+ semap->holder = -1;
+ semap->value = 0;
+ semap->name = name;
+ semap->prio = prio;
+ semap->timo = timo;
+}
+
Home |
Main Index |
Thread Index |
Old Index