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