NetBSD/sys/ufs/lfs/ulfs_inode.h

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_ */