/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

/*
 * memfile.c: Contains the functions for handling blocks of memory which can
 * be stored in a file. This is the implementation of a sort of virtual memory.
 *
 * A memfile consists of a sequence of blocks. The blocks numbered from 0
 * upwards have been assigned a place in the actual file. The block number
 * is equal to the page number in the file. The
 * blocks with negative numbers are currently in memory only. They can be
 * assigned a place in the file when too much memory is being used. At that
 * moment they get a new, positive, number. A list is used for translation of
 * negative to positive numbers.
 *
 * The size of a block is a multiple of a page size, normally the page size of
 * the device the file is on. Most blocks are 1 page long. A Block of multiple
 * pages is used for a line that does not fit in a single page.
 *
 * Each block can be in memory and/or in a file. The block stays in memory
 * as long as it is locked. If it is no longer locked it can be swapped out to
 * the file. It is only written to the file if it has been changed.
 *
 * Under normal operation the file is created when opening the memory file and
 * deleted when closing the memory file. Only with recovery an existing memory
 * file is opened.
 */

#if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64)
# include "vimio.h"	/* for lseek(), must be before vim.h */
#endif

#include "vim.h"

/*
 * Some systems have the page size in statfs.f_bsize, some in stat.st_blksize
 */
#ifdef HAVE_ST_BLKSIZE
# define STATFS stat
# define F_BSIZE st_blksize
# define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
#else
# ifdef HAVE_SYS_STATFS_H
#  include <sys/statfs.h>
#  define STATFS statfs
#  define F_BSIZE f_bsize
#  ifdef __MINT__		/* do we still need this? */
#   define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
#  endif
# endif
#endif

/*
 * for Amiga Dos 2.0x we use Flush
 */
#ifdef AMIGA
# ifdef FEAT_ARP
extern int dos2;			/* this is in os_amiga.c */
# endif
# ifdef SASC
#  include <proto/dos.h>
#  include <ios1.h>			/* for chkufb() */
# endif
#endif

#define MEMFILE_PAGE_SIZE 4096		/* default page size */

static long_u	total_mem_used = 0;	/* total memory used for memfiles */

static void mf_ins_hash __ARGS((memfile_T *, bhdr_T *));
static void mf_rem_hash __ARGS((memfile_T *, bhdr_T *));
static bhdr_T *mf_find_hash __ARGS((memfile_T *, blocknr_T));
static void mf_ins_used __ARGS((memfile_T *, bhdr_T *));
static void mf_rem_used __ARGS((memfile_T *, bhdr_T *));
static bhdr_T *mf_release __ARGS((memfile_T *, int));
static bhdr_T *mf_alloc_bhdr __ARGS((memfile_T *, int));
static void mf_free_bhdr __ARGS((bhdr_T *));
static void mf_ins_free __ARGS((memfile_T *, bhdr_T *));
static bhdr_T *mf_rem_free __ARGS((memfile_T *));
static int  mf_read __ARGS((memfile_T *, bhdr_T *));
static int  mf_write __ARGS((memfile_T *, bhdr_T *));
static int  mf_trans_add __ARGS((memfile_T *, bhdr_T *));
static void mf_do_open __ARGS((memfile_T *, char_u *, int));

/*
 * The functions for using a memfile:
 *
 * mf_open()	    open a new or existing memfile
 * mf_open_file()   open a swap file for an existing memfile
 * mf_close()	    close (and delete) a memfile
 * mf_new()	    create a new block in a memfile and lock it
 * mf_get()	    get an existing block and lock it
 * mf_put()	    unlock a block, may be marked for writing
 * mf_free()	    remove a block
 * mf_sync()	    sync changed parts of memfile to disk
 * mf_release_all() release as much memory as possible
 * mf_trans_del()   may translate negative to positive block number
 * mf_fullname()    make file name full path (use before first :cd)
 */

/*
 * Open an existing or new memory block file.
 *
 *  fname:	name of file to use (NULL means no file at all)
 *		Note: fname must have been allocated, it is not copied!
 *			If opening the file fails, fname is freed.
 *  flags:	flags for open() call
 *
 *  If fname != NULL and file cannot be opened, fail.
 *
 * return value: identifier for this memory block file.
 */
    memfile_T *
mf_open(fname, flags)
    char_u	*fname;
    int		flags;
{
    memfile_T		*mfp;
    int			i;
    off_t		size;
#if defined(STATFS) && defined(UNIX) && !defined(__QNX__)
# define USE_FSTATFS
    struct STATFS	stf;
#endif

    if ((mfp = (memfile_T *)alloc((unsigned)sizeof(memfile_T))) == NULL)
	return NULL;

    if (fname == NULL)	    /* no file for this memfile, use memory only */
    {
	mfp->mf_fname = NULL;
	mfp->mf_ffname = NULL;
	mfp->mf_fd = -1;
    }
    else
    {
	mf_do_open(mfp, fname, flags);	/* try to open the file */

	/* if the file cannot be opened, return here */
	if (mfp->mf_fd < 0)
	{
	    vim_free(mfp);
	    return NULL;
	}
    }

    mfp->mf_free_first = NULL;		/* free list is empty */
    mfp->mf_used_first = NULL;		/* used list is empty */
    mfp->mf_used_last = NULL;
    mfp->mf_dirty = FALSE;
    mfp->mf_used_count = 0;
    for (i = 0; i < MEMHASHSIZE; ++i)
    {
	mfp->mf_hash[i] = NULL;		/* hash lists are empty */
	mfp->mf_trans[i] = NULL;	/* trans lists are empty */
    }
    mfp->mf_page_size = MEMFILE_PAGE_SIZE;

#ifdef USE_FSTATFS
    /*
     * Try to set the page size equal to the block size of the device.
     * Speeds up I/O a lot.
     * When recovering, the actual block size will be retrieved from block 0
     * in ml_recover().  The size used here may be wrong, therefore
     * mf_blocknr_max must be rounded up.
     */
    if (mfp->mf_fd >= 0
	    && fstatfs(mfp->mf_fd, &stf, sizeof(struct statfs), 0) == 0
	    && stf.F_BSIZE >= MIN_SWAP_PAGE_SIZE
	    && stf.F_BSIZE <= MAX_SWAP_PAGE_SIZE)
	mfp->mf_page_size = stf.F_BSIZE;
#endif

    if (mfp->mf_fd < 0 || (flags & (O_TRUNC|O_EXCL))
		      || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
	mfp->mf_blocknr_max = 0;	/* no file or empty file */
    else
	mfp->mf_blocknr_max = (blocknr_T)((size + mfp->mf_page_size - 1)
							 / mfp->mf_page_size);
    mfp->mf_blocknr_min = -1;
    mfp->mf_neg_count = 0;
    mfp->mf_infile_count = mfp->mf_blocknr_max;

    /*
     * Compute maximum number of pages ('maxmem' is in Kbyte):
     *	'mammem' * 1Kbyte / page-size-in-bytes.
     * Avoid overflow by first reducing page size as much as possible.
     */
    {
	int	    shift = 10;
	unsigned    page_size = mfp->mf_page_size;

	while (shift > 0 && (page_size & 1) == 0)
	{
	    page_size = page_size >> 1;
	    --shift;
	}
	mfp->mf_used_count_max = (p_mm << shift) / page_size;
	if (mfp->mf_used_count_max < 10)
	    mfp->mf_used_count_max = 10;
    }

    return mfp;
}

/*
 * Open a file for an existing memfile.  Used when updatecount set from 0 to
 * some value.
 * If the file already exists, this fails.
 * "fname" is the name of file to use (NULL means no file at all)
 * Note: "fname" must have been allocated, it is not copied!  If opening the
 * file fails, "fname" is freed.
 *
 * return value: FAIL if file could not be opened, OK otherwise
 */
    int
mf_open_file(mfp, fname)
    memfile_T	*mfp;
    char_u	*fname;
{
    mf_do_open(mfp, fname, O_RDWR|O_CREAT|O_EXCL); /* try to open the file */

    if (mfp->mf_fd < 0)
	return FAIL;

    mfp->mf_dirty = TRUE;
    return OK;
}

/*
 * close a memory file and delete the associated file if 'del_file' is TRUE
 */
    void
mf_close(mfp, del_file)
    memfile_T	*mfp;
    int		del_file;
{
    bhdr_T	*hp, *nextp;
    NR_TRANS	*tp, *tpnext;
    int		i;

    if (mfp == NULL)		    /* safety check */
	return;
    if (mfp->mf_fd >= 0)
    {
	if (close(mfp->mf_fd) < 0)
	    EMSG(_(e_swapclose));
    }
    if (del_file && mfp->mf_fname != NULL)
	mch_remove(mfp->mf_fname);
					    /* free entries in used list */
    for (hp = mfp->mf_used_first; hp != NULL; hp = nextp)
    {
	total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
	nextp = hp->bh_next;
	mf_free_bhdr(hp);
    }
    while (mfp->mf_free_first != NULL)	    /* free entries in free list */
	vim_free(mf_rem_free(mfp));
    for (i = 0; i < MEMHASHSIZE; ++i)	    /* free entries in trans lists */
	for (tp = mfp->mf_trans[i]; tp != NULL; tp = tpnext)
	{
	    tpnext = tp->nt_next;
	    vim_free(tp);
	}
    vim_free(mfp->mf_fname);
    vim_free(mfp->mf_ffname);
    vim_free(mfp);
}

/*
 * Close the swap file for a memfile.  Used when 'swapfile' is reset.
 */
    void
mf_close_file(buf, getlines)
    buf_T	*buf;
    int		getlines;	/* get all lines into memory? */
{
    memfile_T	*mfp;
    linenr_T	lnum;

    mfp = buf->b_ml.ml_mfp;
    if (mfp == NULL || mfp->mf_fd < 0)		/* nothing to close */
	return;

    if (getlines)
    {
	/* get all blocks in memory by accessing all lines (clumsy!) */
	mf_dont_release = TRUE;
	for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
	    (void)ml_get_buf(buf, lnum, FALSE);
	mf_dont_release = FALSE;
	/* TODO: should check if all blocks are really in core */
    }

    if (close(mfp->mf_fd) < 0)			/* close the file */
	EMSG(_(e_swapclose));
    mfp->mf_fd = -1;

    if (mfp->mf_fname != NULL)
    {
	mch_remove(mfp->mf_fname);		/* delete the swap file */
	vim_free(mfp->mf_fname);
	vim_free(mfp->mf_ffname);
	mfp->mf_fname = NULL;
	mfp->mf_ffname = NULL;
    }
}

/*
 * Set new size for a memfile.  Used when block 0 of a swapfile has been read
 * and the size it indicates differs from what was guessed.
 */
    void
mf_new_page_size(mfp, new_size)
    memfile_T	*mfp;
    unsigned	new_size;
{
    /* Correct the memory used for block 0 to the new size, because it will be
     * freed with that size later on. */
    total_mem_used += new_size - mfp->mf_page_size;
    mfp->mf_page_size = new_size;
}

/*
 * get a new block
 *
 *   negative: TRUE if negative block number desired (data block)
 */
    bhdr_T *
mf_new(mfp, negative, page_count)
    memfile_T	*mfp;
    int		negative;
    int		page_count;
{
    bhdr_T	*hp;	/* new bhdr_T */
    bhdr_T	*freep;	/* first block in free list */
    char_u	*p;

    /*
     * If we reached the maximum size for the used memory blocks, release one
     * If a bhdr_T is returned, use it and adjust the page_count if necessary.
     */
    hp = mf_release(mfp, page_count);

/*
 * Decide on the number to use:
 * If there is a free block, use its number.
 * Otherwise use mf_block_min for a negative number, mf_block_max for
 * a positive number.
 */
    freep = mfp->mf_free_first;
    if (!negative && freep != NULL && freep->bh_page_count >= page_count)
    {
	/*
	 * If the block in the free list has more pages, take only the number
	 * of pages needed and allocate a new bhdr_T with data
	 *
	 * If the number of pages matches and mf_release() did not return a
	 * bhdr_T, use the bhdr_T from the free list and allocate the data
	 *
	 * If the number of pages matches and mf_release() returned a bhdr_T,
	 * just use the number and free the bhdr_T from the free list
	 */
	if (freep->bh_page_count > page_count)
	{
	    if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
		return NULL;
	    hp->bh_bnum = freep->bh_bnum;
	    freep->bh_bnum += page_count;
	    freep->bh_page_count -= page_count;
	}
	else if (hp == NULL)	    /* need to allocate memory for this block */
	{
	    if ((p = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL)
		return NULL;
	    hp = mf_rem_free(mfp);
	    hp->bh_data = p;
	}
	else		    /* use the number, remove entry from free list */
	{
	    freep = mf_rem_free(mfp);
	    hp->bh_bnum = freep->bh_bnum;
	    vim_free(freep);
	}
    }
    else	/* get a new number */
    {
	if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
	    return NULL;
	if (negative)
	{
	    hp->bh_bnum = mfp->mf_blocknr_min--;
	    mfp->mf_neg_count++;
	}
	else
	{
	    hp->bh_bnum = mfp->mf_blocknr_max;
	    mfp->mf_blocknr_max += page_count;
	}
    }
    hp->bh_flags = BH_LOCKED | BH_DIRTY;	/* new block is always dirty */
    mfp->mf_dirty = TRUE;
    hp->bh_page_count = page_count;
    mf_ins_used(mfp, hp);
    mf_ins_hash(mfp, hp);

    /*
     * Init the data to all zero, to avoid reading uninitialized data.
     * This also avoids that the passwd file ends up in the swap file!
     */
    (void)vim_memset((char *)(hp->bh_data), 0, (size_t)mfp->mf_page_size);

    return hp;
}

/*
 * get existing block 'nr' with 'page_count' pages
 *
 * Note: The caller should first check a negative nr with mf_trans_del()
 */
    bhdr_T *
mf_get(mfp, nr, page_count)
    memfile_T	*mfp;
    blocknr_T	nr;
    int		page_count;
{
    bhdr_T    *hp;
						/* doesn't exist */
    if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
	return NULL;

    /*
     * see if it is in the cache
     */
    hp = mf_find_hash(mfp, nr);
    if (hp == NULL)	/* not in the hash list */
    {
	if (nr < 0 || nr >= mfp->mf_infile_count)   /* can't be in the file */
	    return NULL;

	/* could check here if the block is in the free list */

	/*
	 * Check if we need to flush an existing block.
	 * If so, use that block.
	 * If not, allocate a new block.
	 */
	hp = mf_release(mfp, page_count);
	if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
	    return NULL;

	hp->bh_bnum = nr;
	hp->bh_flags = 0;
	hp->bh_page_count = page_count;
	if (mf_read(mfp, hp) == FAIL)	    /* cannot read the block! */
	{
	    mf_free_bhdr(hp);
	    return NULL;
	}
    }
    else
    {
	mf_rem_used(mfp, hp);	/* remove from list, insert in front below */
	mf_rem_hash(mfp, hp);
    }

    hp->bh_flags |= BH_LOCKED;
    mf_ins_used(mfp, hp);	/* put in front of used list */
    mf_ins_hash(mfp, hp);	/* put in front of hash list */

    return hp;
}

/*
 * release the block *hp
 *
 *   dirty: Block must be written to file later
 *   infile: Block should be in file (needed for recovery)
 *
 *  no return value, function cannot fail
 */
    void
mf_put(mfp, hp, dirty, infile)
    memfile_T	*mfp;
    bhdr_T	*hp;
    int		dirty;
    int		infile;
{
    int		flags;

    flags = hp->bh_flags;

    if ((flags & BH_LOCKED) == 0)
	EMSG(_("E293: block was not locked"));
    flags &= ~BH_LOCKED;
    if (dirty)
    {
	flags |= BH_DIRTY;
	mfp->mf_dirty = TRUE;
    }
    hp->bh_flags = flags;
    if (infile)
	mf_trans_add(mfp, hp);	    /* may translate negative in positive nr */
}

/*
 * block *hp is no longer in used, may put it in the free list of memfile *mfp
 */
    void
mf_free(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    vim_free(hp->bh_data);	/* free the memory */
    mf_rem_hash(mfp, hp);	/* get *hp out of the hash list */
    mf_rem_used(mfp, hp);	/* get *hp out of the used list */
    if (hp->bh_bnum < 0)
    {
	vim_free(hp);		/* don't want negative numbers in free list */
	mfp->mf_neg_count--;
    }
    else
	mf_ins_free(mfp, hp);	/* put *hp in the free list */
}

#if defined(__MORPHOS__) && defined(__libnix__)
/* function is missing in MorphOS libnix version */
extern unsigned long *__stdfiledes;

    static unsigned long
fdtofh(int filedescriptor)
{
    return __stdfiledes[filedescriptor];
}
#endif

/*
 * Sync the memory file *mfp to disk.
 * Flags:
 *  MFS_ALL	If not given, blocks with negative numbers are not synced,
 *		even when they are dirty!
 *  MFS_STOP	Stop syncing when a character becomes available, but sync at
 *		least one block.
 *  MFS_FLUSH	Make sure buffers are flushed to disk, so they will survive a
 *		system crash.
 *  MFS_ZERO	Only write block 0.
 *
 * Return FAIL for failure, OK otherwise
 */
    int
mf_sync(mfp, flags)
    memfile_T	*mfp;
    int		flags;
{
    int		status;
    bhdr_T	*hp;
#if defined(SYNC_DUP_CLOSE) && !defined(MSDOS)
    int		fd;
#endif
    int		got_int_save = got_int;

    if (mfp->mf_fd < 0)	    /* there is no file, nothing to do */
    {
	mfp->mf_dirty = FALSE;
	return FAIL;
    }

    /* Only a CTRL-C while writing will break us here, not one typed
     * previously. */
    got_int = FALSE;

    /*
     * sync from last to first (may reduce the probability of an inconsistent
     * file) If a write fails, it is very likely caused by a full filesystem.
     * Then we only try to write blocks within the existing file. If that also
     * fails then we give up.
     */
    status = OK;
    for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
	if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
		&& (hp->bh_flags & BH_DIRTY)
		&& (status == OK || (hp->bh_bnum >= 0
		    && hp->bh_bnum < mfp->mf_infile_count)))
	{
	    if ((flags & MFS_ZERO) && hp->bh_bnum != 0)
		continue;
	    if (mf_write(mfp, hp) == FAIL)
	    {
		if (status == FAIL)	/* double error: quit syncing */
		    break;
		status = FAIL;
	    }
	    if (flags & MFS_STOP)
	    {
		/* Stop when char available now. */
		if (ui_char_avail())
		    break;
	    }
	    else
		ui_breakcheck();
	    if (got_int)
		break;
	}

    /*
     * If the whole list is flushed, the memfile is not dirty anymore.
     * In case of an error this flag is also set, to avoid trying all the time.
     */
    if (hp == NULL || status == FAIL)
	mfp->mf_dirty = FALSE;

    if ((flags & MFS_FLUSH) && *p_sws != NUL)
    {
#if defined(UNIX)
# ifdef HAVE_FSYNC
	/*
	 * most Unixes have the very useful fsync() function, just what we need.
	 * However, with OS/2 and EMX it is also available, but there are
	 * reports of bad problems with it (a bug in HPFS.IFS).
	 * So we disable use of it here in case someone tries to be smart
	 * and changes os_os2_cfg.h... (even though there is no __EMX__ test
	 * in the #if, as __EMX__ does not have sync(); we hope for a timely
	 * sync from the system itself).
	 */
#  if defined(__EMX__)
   error "Dont use fsync with EMX! Read emxdoc.doc or emxfix01.doc for info."
#  endif
	if (STRCMP(p_sws, "fsync") == 0)
	{
	    if (fsync(mfp->mf_fd))
		status = FAIL;
	}
	else
# endif
	    /* OpenNT is strictly POSIX (Benzinger) */
	    /* Tandem/Himalaya NSK-OSS doesn't have sync() */
# if defined(__OPENNT) || defined(__TANDEM)
	    fflush(NULL);
# else
	    sync();
# endif
#endif
#ifdef VMS
	if (STRCMP(p_sws, "fsync") == 0)
	{
	    if (fsync(mfp->mf_fd))
		status = FAIL;
	}
#endif
#ifdef MSDOS
	if (_dos_commit(mfp->mf_fd))
	    status = FAIL;
#else
# ifdef SYNC_DUP_CLOSE
	/*
	 * Win32 is a bit more work: Duplicate the file handle and close it.
	 * This should flush the file to disk.
	 */
	if ((fd = dup(mfp->mf_fd)) >= 0)
	    close(fd);
# endif
#endif
#ifdef AMIGA
# if defined(__AROS__) || defined(__amigaos4__)
	if (fsync(mfp->mf_fd) != 0)
	    status = FAIL;
# else
	/*
	 * Flush() only exists for AmigaDos 2.0.
	 * For 1.3 it should be done with close() + open(), but then the risk
	 * is that the open() may fail and lose the file....
	 */
#  ifdef FEAT_ARP
	if (dos2)
#  endif
#  ifdef SASC
	{
	    struct UFB *fp = chkufb(mfp->mf_fd);

	    if (fp != NULL)
		Flush(fp->ufbfh);
	}
#  else
#   if defined(_DCC) || defined(__GNUC__) || defined(__MORPHOS__)
	{
#    if defined(__GNUC__) && !defined(__MORPHOS__) && defined(__libnix__)
	    /* Have function (in libnix at least),
	     * but ain't got no prototype anywhere. */
	    extern unsigned long fdtofh(int filedescriptor);
#    endif
#    if !defined(__libnix__)
	    fflush(NULL);
#    else
	    BPTR fh = (BPTR)fdtofh(mfp->mf_fd);

	    if (fh != 0)
		Flush(fh);
#    endif
	}
#   else /* assume Manx */
	    Flush(_devtab[mfp->mf_fd].fd);
#   endif
#  endif
# endif
#endif /* AMIGA */
    }

    got_int |= got_int_save;

    return status;
}

/*
 * For all blocks in memory file *mfp that have a positive block number set
 * the dirty flag.  These are blocks that need to be written to a newly
 * created swapfile.
 */
    void
mf_set_dirty(mfp)
    memfile_T	*mfp;
{
    bhdr_T	*hp;

    for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
	if (hp->bh_bnum > 0)
	    hp->bh_flags |= BH_DIRTY;
    mfp->mf_dirty = TRUE;
}

/*
 * insert block *hp in front of hashlist of memfile *mfp
 */
    static void
mf_ins_hash(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    bhdr_T	*hhp;
    int		hash;

    hash = MEMHASH(hp->bh_bnum);
    hhp = mfp->mf_hash[hash];
    hp->bh_hash_next = hhp;
    hp->bh_hash_prev = NULL;
    if (hhp != NULL)
	hhp->bh_hash_prev = hp;
    mfp->mf_hash[hash] = hp;
}

/*
 * remove block *hp from hashlist of memfile list *mfp
 */
    static void
mf_rem_hash(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    if (hp->bh_hash_prev == NULL)
	mfp->mf_hash[MEMHASH(hp->bh_bnum)] = hp->bh_hash_next;
    else
	hp->bh_hash_prev->bh_hash_next = hp->bh_hash_next;

    if (hp->bh_hash_next)
	hp->bh_hash_next->bh_hash_prev = hp->bh_hash_prev;
}

/*
 * look in hash lists of memfile *mfp for block header with number 'nr'
 */
    static bhdr_T *
mf_find_hash(mfp, nr)
    memfile_T	*mfp;
    blocknr_T	nr;
{
    bhdr_T	*hp;

    for (hp = mfp->mf_hash[MEMHASH(nr)]; hp != NULL; hp = hp->bh_hash_next)
	if (hp->bh_bnum == nr)
	    break;
    return hp;
}

/*
 * insert block *hp in front of used list of memfile *mfp
 */
    static void
mf_ins_used(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    hp->bh_next = mfp->mf_used_first;
    mfp->mf_used_first = hp;
    hp->bh_prev = NULL;
    if (hp->bh_next == NULL)	    /* list was empty, adjust last pointer */
	mfp->mf_used_last = hp;
    else
	hp->bh_next->bh_prev = hp;
    mfp->mf_used_count += hp->bh_page_count;
    total_mem_used += hp->bh_page_count * mfp->mf_page_size;
}

/*
 * remove block *hp from used list of memfile *mfp
 */
    static void
mf_rem_used(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    if (hp->bh_next == NULL)	    /* last block in used list */
	mfp->mf_used_last = hp->bh_prev;
    else
	hp->bh_next->bh_prev = hp->bh_prev;
    if (hp->bh_prev == NULL)	    /* first block in used list */
	mfp->mf_used_first = hp->bh_next;
    else
	hp->bh_prev->bh_next = hp->bh_next;
    mfp->mf_used_count -= hp->bh_page_count;
    total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
}

/*
 * Release the least recently used block from the used list if the number
 * of used memory blocks gets to big.
 *
 * Return the block header to the caller, including the memory block, so
 * it can be re-used. Make sure the page_count is right.
 */
    static bhdr_T *
mf_release(mfp, page_count)
    memfile_T	*mfp;
    int		page_count;
{
    bhdr_T	*hp;
    int		need_release;
    buf_T	*buf;

    /* don't release while in mf_close_file() */
    if (mf_dont_release)
	return NULL;

    /*
     * Need to release a block if the number of blocks for this memfile is
     * higher than the maximum or total memory used is over 'maxmemtot'
     */
    need_release = ((mfp->mf_used_count >= mfp->mf_used_count_max)
				  || (total_mem_used >> 10) >= (long_u)p_mmt);

    /*
     * Try to create a swap file if the amount of memory used is getting too
     * high.
     */
    if (mfp->mf_fd < 0 && need_release && p_uc)
    {
	/* find for which buffer this memfile is */
	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
	    if (buf->b_ml.ml_mfp == mfp)
		break;
	if (buf != NULL && buf->b_may_swap)
	    ml_open_file(buf);
    }

    /*
     * don't release a block if
     *	there is no file for this memfile
     * or
     *	the number of blocks for this memfile is lower than the maximum
     *	  and
     *	total memory used is not up to 'maxmemtot'
     */
    if (mfp->mf_fd < 0 || !need_release)
	return NULL;

    for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
	if (!(hp->bh_flags & BH_LOCKED))
	    break;
    if (hp == NULL)	/* not a single one that can be released */
	return NULL;

    /*
     * If the block is dirty, write it.
     * If the write fails we don't free it.
     */
    if ((hp->bh_flags & BH_DIRTY) && mf_write(mfp, hp) == FAIL)
	return NULL;

    mf_rem_used(mfp, hp);
    mf_rem_hash(mfp, hp);

    /*
     * If a bhdr_T is returned, make sure that the page_count of bh_data is
     * right
     */
    if (hp->bh_page_count != page_count)
    {
	vim_free(hp->bh_data);
	if ((hp->bh_data = alloc(mfp->mf_page_size * page_count)) == NULL)
	{
	    vim_free(hp);
	    return NULL;
	}
	hp->bh_page_count = page_count;
    }
    return hp;
}

/*
 * release as many blocks as possible
 * Used in case of out of memory
 *
 * return TRUE if any memory was released
 */
    int
mf_release_all()
{
    buf_T	*buf;
    memfile_T	*mfp;
    bhdr_T	*hp;
    int		retval = FALSE;

    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
    {
	mfp = buf->b_ml.ml_mfp;
	if (mfp != NULL)
	{
	    /* If no swap file yet, may open one */
	    if (mfp->mf_fd < 0 && buf->b_may_swap)
		ml_open_file(buf);

	    /* only if there is a swapfile */
	    if (mfp->mf_fd >= 0)
	    {
		for (hp = mfp->mf_used_last; hp != NULL; )
		{
		    if (!(hp->bh_flags & BH_LOCKED)
			    && (!(hp->bh_flags & BH_DIRTY)
				|| mf_write(mfp, hp) != FAIL))
		    {
			mf_rem_used(mfp, hp);
			mf_rem_hash(mfp, hp);
			mf_free_bhdr(hp);
			hp = mfp->mf_used_last;	/* re-start, list was changed */
			retval = TRUE;
		    }
		    else
			hp = hp->bh_prev;
		}
	    }
	}
    }
    return retval;
}

/*
 * Allocate a block header and a block of memory for it
 */
    static bhdr_T *
mf_alloc_bhdr(mfp, page_count)
    memfile_T	*mfp;
    int		page_count;
{
    bhdr_T	*hp;

    if ((hp = (bhdr_T *)alloc((unsigned)sizeof(bhdr_T))) != NULL)
    {
	if ((hp->bh_data = (char_u *)alloc(mfp->mf_page_size * page_count))
								      == NULL)
	{
	    vim_free(hp);	    /* not enough memory */
	    return NULL;
	}
	hp->bh_page_count = page_count;
    }
    return hp;
}

/*
 * Free a block header and the block of memory for it
 */
    static void
mf_free_bhdr(hp)
    bhdr_T	*hp;
{
    vim_free(hp->bh_data);
    vim_free(hp);
}

/*
 * insert entry *hp in the free list
 */
    static void
mf_ins_free(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    hp->bh_next = mfp->mf_free_first;
    mfp->mf_free_first = hp;
}

/*
 * remove the first entry from the free list and return a pointer to it
 * Note: caller must check that mfp->mf_free_first is not NULL!
 */
    static bhdr_T *
mf_rem_free(mfp)
    memfile_T	*mfp;
{
    bhdr_T	*hp;

    hp = mfp->mf_free_first;
    mfp->mf_free_first = hp->bh_next;
    return hp;
}

/*
 * read a block from disk
 *
 * Return FAIL for failure, OK otherwise
 */
    static int
mf_read(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    off_t	offset;
    unsigned	page_size;
    unsigned	size;

    if (mfp->mf_fd < 0)	    /* there is no file, can't read */
	return FAIL;

    page_size = mfp->mf_page_size;
    offset = (off_t)page_size * hp->bh_bnum;
    size = page_size * hp->bh_page_count;
    if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
    {
	PERROR(_("E294: Seek error in swap file read"));
	return FAIL;
    }
    if ((unsigned)vim_read(mfp->mf_fd, hp->bh_data, size) != size)
    {
	PERROR(_("E295: Read error in swap file"));
	return FAIL;
    }
    return OK;
}

/*
 * write a block to disk
 *
 * Return FAIL for failure, OK otherwise
 */
    static int
mf_write(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    off_t	offset;	    /* offset in the file */
    blocknr_T	nr;	    /* block nr which is being written */
    bhdr_T	*hp2;
    unsigned	page_size;  /* number of bytes in a page */
    unsigned	page_count; /* number of pages written */
    unsigned	size;	    /* number of bytes written */

    if (mfp->mf_fd < 0)	    /* there is no file, can't write */
	return FAIL;

    if (hp->bh_bnum < 0)	/* must assign file block number */
	if (mf_trans_add(mfp, hp) == FAIL)
	    return FAIL;

    page_size = mfp->mf_page_size;

    /*
     * We don't want gaps in the file. Write the blocks in front of *hp
     * to extend the file.
     * If block 'mf_infile_count' is not in the hash list, it has been
     * freed. Fill the space in the file with data from the current block.
     */
    for (;;)
    {
	nr = hp->bh_bnum;
	if (nr > mfp->mf_infile_count)		/* beyond end of file */
	{
	    nr = mfp->mf_infile_count;
	    hp2 = mf_find_hash(mfp, nr);	/* NULL catched below */
	}
	else
	    hp2 = hp;

	offset = (off_t)page_size * nr;
	if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
	{
	    PERROR(_("E296: Seek error in swap file write"));
	    return FAIL;
	}
	if (hp2 == NULL)	    /* freed block, fill with dummy data */
	    page_count = 1;
	else
	    page_count = hp2->bh_page_count;
	size = page_size * page_count;
	if ((unsigned)vim_write(mfp->mf_fd,
	     (hp2 == NULL ? hp : hp2)->bh_data, size) != size)
	{
	    /*
	     * Avoid repeating the error message, this mostly happens when the
	     * disk is full. We give the message again only after a successful
	     * write or when hitting a key. We keep on trying, in case some
	     * space becomes available.
	     */
	    if (!did_swapwrite_msg)
		EMSG(_("E297: Write error in swap file"));
	    did_swapwrite_msg = TRUE;
	    return FAIL;
	}
	did_swapwrite_msg = FALSE;
	if (hp2 != NULL)		    /* written a non-dummy block */
	    hp2->bh_flags &= ~BH_DIRTY;
					    /* appended to the file */
	if (nr + (blocknr_T)page_count > mfp->mf_infile_count)
	    mfp->mf_infile_count = nr + page_count;
	if (nr == hp->bh_bnum)		    /* written the desired block */
	    break;
    }
    return OK;
}

/*
 * Make block number for *hp positive and add it to the translation list
 *
 * Return FAIL for failure, OK otherwise
 */
    static int
mf_trans_add(mfp, hp)
    memfile_T	*mfp;
    bhdr_T	*hp;
{
    bhdr_T	*freep;
    blocknr_T	new_bnum;
    int		hash;
    NR_TRANS	*np;
    int		page_count;

    if (hp->bh_bnum >= 0)		    /* it's already positive */
	return OK;

    if ((np = (NR_TRANS *)alloc((unsigned)sizeof(NR_TRANS))) == NULL)
	return FAIL;

/*
 * get a new number for the block.
 * If the first item in the free list has sufficient pages, use its number
 * Otherwise use mf_blocknr_max.
 */
    freep = mfp->mf_free_first;
    page_count = hp->bh_page_count;
    if (freep != NULL && freep->bh_page_count >= page_count)
    {
	new_bnum = freep->bh_bnum;
	/*
	 * If the page count of the free block was larger, recude it.
	 * If the page count matches, remove the block from the free list
	 */
	if (freep->bh_page_count > page_count)
	{
	    freep->bh_bnum += page_count;
	    freep->bh_page_count -= page_count;
	}
	else
	{
	    freep = mf_rem_free(mfp);
	    vim_free(freep);
	}
    }
    else
    {
	new_bnum = mfp->mf_blocknr_max;
	mfp->mf_blocknr_max += page_count;
    }

    np->nt_old_bnum = hp->bh_bnum;	    /* adjust number */
    np->nt_new_bnum = new_bnum;

    mf_rem_hash(mfp, hp);		    /* remove from old hash list */
    hp->bh_bnum = new_bnum;
    mf_ins_hash(mfp, hp);		    /* insert in new hash list */

    hash = MEMHASH(np->nt_old_bnum);	    /* insert in trans list */
    np->nt_next = mfp->mf_trans[hash];
    mfp->mf_trans[hash] = np;
    if (np->nt_next != NULL)
	np->nt_next->nt_prev = np;
    np->nt_prev = NULL;

    return OK;
}

/*
 * Lookup a translation from the trans lists and delete the entry
 *
 * Return the positive new number when found, the old number when not found
 */
    blocknr_T
mf_trans_del(mfp, old_nr)
    memfile_T	*mfp;
    blocknr_T	old_nr;
{
    int		hash;
    NR_TRANS	*np;
    blocknr_T	new_bnum;

    hash = MEMHASH(old_nr);
    for (np = mfp->mf_trans[hash]; np != NULL; np = np->nt_next)
	if (np->nt_old_bnum == old_nr)
	    break;
    if (np == NULL)		/* not found */
	return old_nr;

    mfp->mf_neg_count--;
    new_bnum = np->nt_new_bnum;
    if (np->nt_prev != NULL)		/* remove entry from the trans list */
	np->nt_prev->nt_next = np->nt_next;
    else
	mfp->mf_trans[hash] = np->nt_next;
    if (np->nt_next != NULL)
	np->nt_next->nt_prev = np->nt_prev;
    vim_free(np);

    return new_bnum;
}

/*
 * Set mfp->mf_ffname according to mfp->mf_fname and some other things.
 * Only called when creating or renaming the swapfile.	Either way it's a new
 * name so we must work out the full path name.
 */
    void
mf_set_ffname(mfp)
    memfile_T	*mfp;
{
    mfp->mf_ffname = FullName_save(mfp->mf_fname, FALSE);
}

/*
 * Make the name of the file used for the memfile a full path.
 * Used before doing a :cd
 */
    void
mf_fullname(mfp)
    memfile_T	*mfp;
{
    if (mfp != NULL && mfp->mf_fname != NULL && mfp->mf_ffname != NULL)
    {
	vim_free(mfp->mf_fname);
	mfp->mf_fname = mfp->mf_ffname;
	mfp->mf_ffname = NULL;
    }
}

/*
 * return TRUE if there are any translations pending for 'mfp'
 */
    int
mf_need_trans(mfp)
    memfile_T	*mfp;
{
    return (mfp->mf_fname != NULL && mfp->mf_neg_count > 0);
}

/*
 * Open a swap file for a memfile.
 * The "fname" must be in allocated memory, and is consumed (also when an
 * error occurs).
 */
    static void
mf_do_open(mfp, fname, flags)
    memfile_T	*mfp;
    char_u	*fname;
    int		flags;		/* flags for open() */
{
#ifdef HAVE_LSTAT
    struct stat sb;
#endif

    mfp->mf_fname = fname;

    /*
     * Get the full path name before the open, because this is
     * not possible after the open on the Amiga.
     * fname cannot be NameBuff, because it must have been allocated.
     */
    mf_set_ffname(mfp);
#if defined(MSDOS) || defined(MSWIN) || defined(RISCOS)
    /*
     * A ":!cd e:xxx" may change the directory without us knowning, use the
     * full pathname always.  Careful: This frees fname!
     */
    mf_fullname(mfp);
#endif

#ifdef HAVE_LSTAT
    /*
     * Extra security check: When creating a swap file it really shouldn't
     * exist yet.  If there is a symbolic link, this is most likely an attack.
     */
    if ((flags & O_CREAT) && mch_lstat((char *)mfp->mf_fname, &sb) >= 0)
    {
	mfp->mf_fd = -1;
	EMSG(_("E300: Swap file already exists (symlink attack?)"));
    }
    else
#endif
    {
	/*
	 * try to open the file
	 */
	flags |= O_EXTRA | O_NOFOLLOW;
#ifdef WIN32
	/* Prevent handle inheritance that cause problems with Cscope
	 * (swap file may not be deleted if cscope connection was open after
	 * the file) */
	flags |= O_NOINHERIT;
#endif
	mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags);
    }

    /*
     * If the file cannot be opened, use memory only
     */
    if (mfp->mf_fd < 0)
    {
	vim_free(mfp->mf_fname);
	vim_free(mfp->mf_ffname);
	mfp->mf_fname = NULL;
	mfp->mf_ffname = NULL;
    }
    else
    {
#ifdef HAVE_SELINUX
	mch_copy_sec(fname, mfp->mf_fname);
#endif
	mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
    }
}
