233 lines
8.1 KiB
C
233 lines
8.1 KiB
C
/* $NetBSD: ulfs_inode.h,v 1.25 2024/02/17 09:08:21 mlelstv Exp $ */
|
|
/* from NetBSD: inode.h,v 1.72 2016/06/03 15:36:03 christos Exp */
|
|
|
|
/*
|
|
* Copyright (c) 1982, 1989, 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
* (c) UNIX System Laboratories, Inc.
|
|
* All or some portions of this file are derived from material licensed
|
|
* to the University of California by American Telephone and Telegraph
|
|
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
|
* the permission of UNIX System Laboratories, Inc.
|
|
*
|
|
* 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.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
|
|
*
|
|
* @(#)inode.h 8.9 (Berkeley) 5/14/95
|
|
*/
|
|
|
|
#ifndef _UFS_LFS_ULFS_INODE_H_
|
|
#define _UFS_LFS_ULFS_INODE_H_
|
|
|
|
#include <sys/vnode.h>
|
|
#include <ufs/lfs/lfs_inode.h>
|
|
#include <ufs/lfs/ulfs_dinode.h>
|
|
#include <ufs/lfs/ulfs_quotacommon.h>
|
|
|
|
/*
|
|
* These macros are used to bracket ULFS directory ops, so that we can
|
|
* identify all the pages touched during directory ops which need to
|
|
* be ordered and flushed atomically, so that they may be recovered.
|
|
*
|
|
* Because we have to mark nodes VU_DIROP in order to prevent
|
|
* the cache from reclaiming them while a dirop is in progress, we must
|
|
* also manage the number of nodes so marked (otherwise we can run out).
|
|
* We do this by setting lfs_dirvcount to the number of marked vnodes; it
|
|
* is decremented during segment write, when VU_DIROP is taken off.
|
|
*/
|
|
#define MARK_VNODE(vp) lfs_mark_vnode(vp)
|
|
#define UNMARK_VNODE(vp) lfs_unmark_vnode(vp)
|
|
int lfs_set_dirop(struct vnode *, struct vnode *);
|
|
void lfs_unset_dirop(struct lfs *, struct vnode *, const char *);
|
|
|
|
/* Misc. definitions */
|
|
#define BW_CLEAN 1 /* Flag for lfs_bwrite_ext() */
|
|
#define PG_DELWRI PG_PAGER1 /* Local def for delayed pageout */
|
|
|
|
/* Resource limits */
|
|
#define LFS_MAX_RESOURCE(x, u) (((x) >> 2) - 10 * (u))
|
|
#define LFS_WAIT_RESOURCE(x, u) (((x) >> 1) - ((x) >> 3) - 10 * (u))
|
|
#define LFS_INVERSE_MAX_RESOURCE(x, u) (((x) + 10 * (u)) << 2)
|
|
#define LFS_MAX_BUFS lfs_max_bufs()
|
|
#define LFS_WAIT_BUFS lfs_wait_bufs()
|
|
#define LFS_INVERSE_MAX_BUFS(n) LFS_INVERSE_MAX_RESOURCE(n, 1)
|
|
#define LFS_MAX_BYTES LFS_MAX_RESOURCE(bufmem_lowater, PAGE_SIZE)
|
|
#define LFS_INVERSE_MAX_BYTES(n) LFS_INVERSE_MAX_RESOURCE(n, PAGE_SIZE)
|
|
#define LFS_WAIT_BYTES LFS_WAIT_RESOURCE(bufmem_lowater, PAGE_SIZE)
|
|
#define LFS_MAX_DIROP ((desiredvnodes >> 2) + (desiredvnodes >> 3))
|
|
#define SIZEOF_DIROP(fs) (2 * (lfs_sb_getbsize(fs) + DINOSIZE(fs)))
|
|
#define LFS_MAX_FSDIROP(fs) \
|
|
(lfs_sb_getnclean(fs) <= lfs_sb_getresvseg(fs) ? 0 : \
|
|
((lfs_sb_getnclean(fs) - lfs_sb_getresvseg(fs)) * lfs_sb_getssize(fs)) / \
|
|
(2 * SIZEOF_DIROP(fs)))
|
|
#define LFS_MAX_PAGES lfs_max_pages()
|
|
#define LFS_WAIT_PAGES lfs_wait_pages()
|
|
#define LFS_BUFWAIT 2 /* How long to wait if over *_WAIT_* */
|
|
|
|
#ifdef _KERNEL
|
|
extern u_long bufmem_lowater, bufmem_hiwater; /* XXX */
|
|
|
|
int lfs_wait_pages(void);
|
|
int lfs_max_pages(void);
|
|
#endif /* _KERNEL */
|
|
|
|
/* How starved can we be before we start holding back page writes */
|
|
#define LFS_STARVED_FOR_SEGS(fs) (lfs_sb_getnclean(fs) < lfs_sb_getresvseg(fs))
|
|
|
|
/*
|
|
* Reserved blocks for lfs_malloc
|
|
*/
|
|
|
|
/* Structure to keep reserved blocks */
|
|
typedef struct lfs_res_blk {
|
|
void *p;
|
|
LIST_ENTRY(lfs_res_blk) res;
|
|
int size;
|
|
char inuse;
|
|
} res_t;
|
|
|
|
/* Types for lfs_newbuf and lfs_malloc */
|
|
#define LFS_NB_UNKNOWN -1
|
|
#define LFS_NB_SUMMARY 0
|
|
#define LFS_NB_SBLOCK 1
|
|
#define LFS_NB_IBLOCK 2
|
|
#define LFS_NB_CLUSTER 3
|
|
#define LFS_NB_CLEAN 4
|
|
#define LFS_NB_BLKIOV 5
|
|
#define LFS_NB_COUNT 6 /* always last */
|
|
|
|
/* Number of reserved memory blocks of each type */
|
|
#define LFS_N_SUMMARIES 2
|
|
#define LFS_N_SBLOCKS 1 /* Always 1, to throttle superblock writes */
|
|
#define LFS_N_IBLOCKS 16 /* In theory ssize/bsize; in practice around 2 */
|
|
#define LFS_N_CLUSTERS 16 /* In theory ssize/MAXPHYS */
|
|
#define LFS_N_CLEAN 0
|
|
#define LFS_N_BLKIOV 1
|
|
|
|
/* Total count of "large" (non-pool) types */
|
|
#define LFS_N_TOTAL (LFS_N_SUMMARIES + LFS_N_SBLOCKS + LFS_N_IBLOCKS + \
|
|
LFS_N_CLUSTERS + LFS_N_CLEAN + LFS_N_BLKIOV)
|
|
|
|
/* Counts for pool types */
|
|
#define LFS_N_CL LFS_N_CLUSTERS
|
|
#define LFS_N_BPP 2
|
|
#define LFS_N_SEG 2
|
|
|
|
/*
|
|
* "struct buf" associated definitions
|
|
*/
|
|
|
|
/* Determine if a buffer belongs to the ifile */
|
|
#define IS_IFILE(bp) (VTOI(bp->b_vp)->i_number == LFS_IFILE_INUM)
|
|
|
|
#ifdef _KERNEL
|
|
/* This overlays the fid structure (see fstypes.h). */
|
|
struct ulfs_ufid {
|
|
uint16_t ufid_len; /* Length of structure. */
|
|
uint16_t ufid_pad; /* Force 32-bit alignment. */
|
|
uint32_t ufid_ino; /* File number (ino). XXX should be 64 */
|
|
int32_t ufid_gen; /* Generation number. */
|
|
};
|
|
/* Filehandle structure for exported LFSes */
|
|
struct lfid {
|
|
struct ulfs_ufid lfid_ufid;
|
|
#define lfid_len lfid_ufid.ufid_len
|
|
#define lfid_ino lfid_ufid.ufid_ino
|
|
#define lfid_gen lfid_ufid.ufid_gen
|
|
uint32_t lfid_ident;
|
|
};
|
|
#endif /* _KERNEL */
|
|
|
|
/* Address calculations for metadata located in the inode */
|
|
#define S_INDIR(fs) -ULFS_NDADDR
|
|
#define D_INDIR(fs) (S_INDIR(fs) - LFS_NINDIR(fs) - 1)
|
|
#define T_INDIR(fs) (D_INDIR(fs) - LFS_NINDIR(fs) * LFS_NINDIR(fs) - 1)
|
|
|
|
/*
|
|
* "struct vnode" associated definitions
|
|
*/
|
|
|
|
/* Heuristic emptiness measure */
|
|
#define VPISEMPTY(vp) (LIST_EMPTY(&(vp)->v_dirtyblkhd) && \
|
|
!(vp->v_type == VREG && (vp)->v_iflag & VI_ONWORKLST) &&\
|
|
VTOI(vp)->i_lfs_nbtree == 0)
|
|
|
|
#define WRITEINPROG(vp) ((vp)->v_numoutput > 0 || \
|
|
(!LIST_EMPTY(&(vp)->v_dirtyblkhd) && \
|
|
!(VTOI(vp)->i_state & (IN_MODIFIED | IN_ACCESSED | IN_CLEANING))))
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(_KERNEL)
|
|
|
|
/*
|
|
* The DIP macro is used to access fields in the dinode that are
|
|
* not cached in the inode itself.
|
|
*/
|
|
#define DIP(ip, field) \
|
|
(((ip)->i_ump->um_fstype == ULFS1) ? \
|
|
(ip)->i_din->u_32.di_##field : (ip)->i_din->u_64.di_##field)
|
|
|
|
#define DIP_ASSIGN(ip, field, value) \
|
|
do { \
|
|
if ((ip)->i_ump->um_fstype == ULFS1) \
|
|
(ip)->i_din->u_32.di_##field = (value); \
|
|
else \
|
|
(ip)->i_din->u_64.di_##field = (value); \
|
|
} while(0)
|
|
|
|
#define DIP_ADD(ip, field, value) \
|
|
do { \
|
|
if ((ip)->i_ump->um_fstype == ULFS1) \
|
|
(ip)->i_din->u_32.di_##field += (value); \
|
|
else \
|
|
(ip)->i_din->u_64.di_##field += (value); \
|
|
} while(0)
|
|
|
|
/* XXX rework this better */
|
|
#define SHORTLINK(ip) \
|
|
(((ip)->i_ump->um_fstype == ULFS1) ? \
|
|
(void *)(ip)->i_din->u_32.di_db : (void *)(ip)->i_din->u_64.di_db)
|
|
|
|
|
|
/*
|
|
* Structure used to pass around logical block paths generated by
|
|
* ulfs_getlbns and used by truncate and bmap code.
|
|
*/
|
|
struct indir {
|
|
daddr_t in_lbn; /* Logical block number. */
|
|
int in_off; /* Offset in buffer. */
|
|
int in_exists; /* Flag if the block exists. */
|
|
};
|
|
|
|
/* Convert between inode pointers and vnode pointers. */
|
|
#define VTOI(vp) ((struct inode *)(vp)->v_data)
|
|
#define ITOV(ip) ((ip)->i_vnode)
|
|
|
|
#endif /* _KERNEL */
|
|
|
|
#endif /* !_UFS_LFS_ULFS_INODE_H_ */
|