The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ufs/ufs/inode.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (c) 1982, 1989, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  * (c) UNIX System Laboratories, Inc.
    7  * All or some portions of this file are derived from material licensed
    8  * to the University of California by American Telephone and Telegraph
    9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   10  * the permission of UNIX System Laboratories, Inc.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  *      @(#)inode.h     8.9 (Berkeley) 5/14/95
   37  * $FreeBSD$
   38  */
   39 
   40 #ifndef _UFS_UFS_INODE_H_
   41 #define _UFS_UFS_INODE_H_
   42 
   43 #include <sys/lock.h>
   44 #include <sys/queue.h>
   45 #include <ufs/ufs/dinode.h>
   46 #include <sys/seqc.h>
   47 #ifdef DIAGNOSTIC
   48 #include <sys/stack.h>
   49 #endif
   50 #include <sys/buf.h>
   51 
   52 /*
   53  * This must agree with the definition in <ufs/ufs/dir.h>.
   54  */
   55 #define doff_t          int32_t
   56 
   57 #ifdef DIAGNOSTIC
   58 struct iown_tracker {
   59         struct thread   *tr_owner;
   60         struct stack    tr_st;
   61         struct stack    tr_unlock;
   62         int             tr_gen;
   63 };
   64 #endif
   65 
   66 /*
   67  * The inode is used to describe each active (or recently active) file in the
   68  * UFS filesystem. It is composed of two types of information. The first part
   69  * is the information that is needed only while the file is active (such as
   70  * the identity of the file and linkage to speed its lookup). The second part
   71  * is the permanent meta-data associated with the file which is read in
   72  * from the permanent dinode from long term storage when the file becomes
   73  * active, and is put back when the file is no longer being used.
   74  *
   75  * An inode may only be changed while holding either the exclusive
   76  * vnode lock or the shared vnode lock and the vnode interlock. We use
   77  * the latter only for "read" and "get" operations that require
   78  * changing i_flag, or a timestamp. This locking protocol allows executing
   79  * those operations without having to upgrade the vnode lock from shared to
   80  * exclusive.
   81  */
   82 struct inode {
   83         TAILQ_ENTRY(inode) i_nextsnap; /* snapshot file list. */
   84         struct  vnode  *i_vnode;/* Vnode associated with this inode. */
   85         struct  ufsmount *i_ump;/* Ufsmount point associated with this inode. */
   86         struct   dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
   87         union {
   88                 struct dirhash *dirhash; /* Hashing for large directories. */
   89                 daddr_t *snapblklist;    /* Collect expunged snapshot blocks. */
   90         } i_un;
   91         /*
   92          * The real copy of the on-disk inode.
   93          */
   94         union {
   95                 struct ufs1_dinode *din1;       /* UFS1 on-disk dinode. */
   96                 struct ufs2_dinode *din2;       /* UFS2 on-disk dinode. */
   97         } dinode_u;
   98 
   99         ino_t     i_number;     /* The identity of the inode. */
  100         u_int32_t i_flag;       /* flags, see below */
  101         int       i_effnlink;   /* i_nlink when I/O completes */
  102 
  103         /*
  104          * Side effects; used during directory lookup.
  105          */
  106         int32_t   i_count;      /* Size of free slot in directory. */
  107         doff_t    i_endoff;     /* End of useful stuff in directory. */
  108         doff_t    i_diroff;     /* Offset in dir, where we found last entry. */
  109         doff_t    i_offset;     /* Offset of free space in directory. */
  110 #ifdef DIAGNOSTIC
  111         int                     i_lock_gen;
  112         struct iown_tracker     i_count_tracker;
  113         struct iown_tracker     i_endoff_tracker;
  114         struct iown_tracker     i_offset_tracker;
  115 #endif
  116 
  117         int     i_nextclustercg; /* last cg searched for cluster */
  118 
  119         struct vn_clusterw i_clusterw;  /* Buffer clustering information */
  120 
  121         /*
  122          * Data for extended attribute modification.
  123          */
  124         u_char    *i_ea_area;   /* Pointer to malloced copy of EA area */
  125         unsigned  i_ea_len;     /* Length of i_ea_area */
  126         int       i_ea_error;   /* First errno in transaction */
  127         int       i_ea_refs;    /* Number of users of EA area */
  128 
  129         /*
  130          * Copies from the on-disk dinode itself.
  131          */
  132         u_int64_t i_size;       /* File byte count. */
  133         u_int64_t i_gen;        /* Generation number. */
  134         u_int32_t i_flags;      /* Status flags (chflags). */
  135         u_int32_t i_uid;        /* File owner. */
  136         u_int32_t i_gid;        /* File group. */
  137         u_int16_t i_mode;       /* IFMT, permissions; see below. */
  138         int16_t   i_nlink;      /* File link count. */
  139 };
  140 /*
  141  * These flags are kept in i_flag.
  142  */
  143 #define IN_ACCESS       0x0001          /* Access time update request. */
  144 #define IN_CHANGE       0x0002          /* Inode change time update request. */
  145 #define IN_UPDATE       0x0004          /* Modification time update request. */
  146 #define IN_MODIFIED     0x0008          /* Inode has been modified. */
  147 #define IN_NEEDSYNC     0x0010          /* Inode requires fsync. */
  148 #define IN_LAZYMOD      0x0020          /* Modified, but don't write yet. */
  149 #define IN_LAZYACCESS   0x0040          /* Process IN_ACCESS after the
  150                                            suspension finished */
  151 #define IN_EA_LOCKED    0x0080          /* Extended attributes locked */
  152 #define IN_EA_LOCKWAIT  0x0100          /* Want extended attributes lock */
  153 #define IN_TRUNCATED    0x0200          /* Journaled truncation pending. */
  154 #define IN_UFS2         0x0400          /* UFS2 vs UFS1 */
  155 #define IN_IBLKDATA     0x0800          /* datasync requires inode block
  156                                            update */
  157 #define IN_SIZEMOD      0x1000          /* Inode size has been modified */
  158 #define IN_ENDOFF       0x2000          /* Free space at the end of directory,
  159                                            try to truncate when possible */
  160 
  161 #define PRINT_INODE_FLAGS "\2\20b16\17b15\16b14\15sizemod" \
  162         "\14iblkdata\13is_ufs2\12truncated\11ea_lockwait\10ea_locked" \
  163         "\7lazyaccess\6lazymod\5needsync\4modified\3update\2change\1access"
  164 
  165 #define UFS_INODE_FLAG_LAZY_MASK        \
  166         (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE | IN_LAZYMOD | \
  167          IN_LAZYACCESS)
  168 /*
  169  * Some flags can persist a vnode transitioning to 0 hold count and being tkaen
  170  * off the list.
  171  */
  172 #define UFS_INODE_FLAG_LAZY_MASK_ASSERTABLE \
  173         (UFS_INODE_FLAG_LAZY_MASK & ~(IN_LAZYMOD | IN_LAZYACCESS))
  174 
  175 #define UFS_INODE_SET_MODE(ip, mode) do {                       \
  176         struct inode *_ip = (ip);                               \
  177         int _mode = (mode);                                     \
  178                                                                 \
  179         ASSERT_VOP_IN_SEQC(ITOV(_ip));                          \
  180         atomic_store_short(&(_ip)->i_mode, _mode);              \
  181 } while (0)
  182 
  183 #define UFS_INODE_SET_FLAG(ip, flags) do {                      \
  184         struct inode *_ip = (ip);                               \
  185         struct vnode *_vp = ITOV(_ip);                          \
  186         int _flags = (flags);                                   \
  187                                                                 \
  188         _ip->i_flag |= _flags;                                  \
  189         if (_flags & UFS_INODE_FLAG_LAZY_MASK)                  \
  190                 vlazy(_vp);                                     \
  191 } while (0)
  192 
  193 #define UFS_INODE_SET_FLAG_SHARED(ip, flags) do {               \
  194         struct inode *_ip = (ip);                               \
  195         struct vnode *_vp = ITOV(_ip);                          \
  196         int _flags = (flags);                                   \
  197                                                                 \
  198         ASSERT_VI_UNLOCKED(_vp, __func__);                      \
  199         if ((_ip->i_flag & (_flags)) != _flags) {               \
  200                 VI_LOCK(_vp);                                   \
  201                 _ip->i_flag |= _flags;                          \
  202                 if (_flags & UFS_INODE_FLAG_LAZY_MASK)          \
  203                         vlazy(_vp);                             \
  204                 VI_UNLOCK(_vp);                                 \
  205         }                                                       \
  206 } while (0)
  207 
  208 #define i_dirhash i_un.dirhash
  209 #define i_snapblklist i_un.snapblklist
  210 #define i_din1 dinode_u.din1
  211 #define i_din2 dinode_u.din2
  212 
  213 #define ITOUMP(ip)      ((ip)->i_ump)
  214 #define ITODEV(ip)      (ITOUMP(ip)->um_dev)
  215 #define ITODEVVP(ip)    (ITOUMP(ip)->um_devvp)
  216 #define ITOFS(ip)       (ITOUMP(ip)->um_fs)
  217 #define ITOVFS(ip)      ((ip)->i_vnode->v_mount)
  218 
  219 #ifdef _KERNEL
  220 
  221 static inline _Bool
  222 I_IS_UFS1(const struct inode *ip)
  223 {
  224 
  225         return ((ip->i_flag & IN_UFS2) == 0);
  226 }
  227 
  228 static inline _Bool
  229 I_IS_UFS2(const struct inode *ip)
  230 {
  231 
  232         return ((ip->i_flag & IN_UFS2) != 0);
  233 }
  234 #endif  /* _KERNEL */
  235 
  236 /*
  237  * The DIP macro is used to access fields in the dinode that are
  238  * not cached in the inode itself.
  239  */
  240 #define DIP(ip, field)  (I_IS_UFS1(ip) ? (ip)->i_din1->d##field : \
  241     (ip)->i_din2->d##field)
  242 #define DIP_SET(ip, field, val) do {                            \
  243         if (I_IS_UFS1(ip))                                      \
  244                 (ip)->i_din1->d##field = (val);                 \
  245         else                                                    \
  246                 (ip)->i_din2->d##field = (val);                 \
  247         } while (0)
  248 
  249 #define IS_SNAPSHOT(ip)         ((ip)->i_flags & SF_SNAPSHOT)
  250 #define IS_UFS(vp)              ((vp)->v_data != NULL)
  251 
  252 /*
  253  * Structure used to pass around logical block paths generated by
  254  * ufs_getlbns and used by truncate and bmap code.
  255  */
  256 struct indir {
  257         ufs2_daddr_t in_lbn;            /* Logical block number. */
  258         int     in_off;                 /* Offset in buffer. */
  259 };
  260 
  261 /* Convert between inode pointers and vnode pointers. */
  262 #define VTOI(vp)        ((struct inode *)(vp)->v_data)
  263 #define VTOI_SMR(vp)    ((struct inode *)vn_load_v_data_smr(vp))
  264 #define ITOV(ip)        ((ip)->i_vnode)
  265 
  266 /* Determine if soft dependencies are being done */
  267 #define MOUNTEDSOFTDEP(mp)      (((mp)->mnt_flag & MNT_SOFTDEP) != 0)
  268 #define DOINGSOFTDEP(vp)        MOUNTEDSOFTDEP((vp)->v_mount)
  269 #define MOUNTEDSUJ(mp)          (((mp)->mnt_flag & (MNT_SOFTDEP | MNT_SUJ)) == \
  270     (MNT_SOFTDEP | MNT_SUJ))
  271 #define DOINGSUJ(vp)            MOUNTEDSUJ((vp)->v_mount)
  272 
  273 /* This overlays the fid structure (see mount.h). */
  274 struct ufid {
  275         u_int16_t ufid_len;     /* Length of structure. */
  276         u_int16_t ufid_pad;     /* Force 32-bit alignment. */
  277         uint32_t  ufid_ino;     /* File number (ino). */
  278         uint32_t  ufid_gen;     /* Generation number. */
  279 };
  280 
  281 #ifdef _KERNEL
  282 #ifdef DIAGNOSTIC
  283 void ufs_init_trackers(struct inode *ip);
  284 void ufs_unlock_tracker(struct inode *ip);
  285 
  286 doff_t ufs_get_i_offset(struct inode *ip, const char *file, int line);
  287 void ufs_set_i_offset(struct inode *ip, doff_t off, const char *file, int line);
  288 #define I_OFFSET(ip)            ufs_get_i_offset(ip, __FILE__, __LINE__)
  289 #define SET_I_OFFSET(ip, off)   ufs_set_i_offset(ip, off, __FILE__, __LINE__)
  290 
  291 int32_t ufs_get_i_count(struct inode *ip, const char *file, int line);
  292 void ufs_set_i_count(struct inode *ip, int32_t cnt, const char *file, int line);
  293 #define I_COUNT(ip)             ufs_get_i_count(ip, __FILE__, __LINE__)
  294 #define SET_I_COUNT(ip, cnt)    ufs_set_i_count(ip, cnt, __FILE__, __LINE__)
  295 
  296 doff_t ufs_get_i_endoff(struct inode *ip, const char *file, int line);
  297 void ufs_set_i_endoff(struct inode *ip, doff_t off, const char *file, int line);
  298 #define I_ENDOFF(ip)            ufs_get_i_endoff(ip, __FILE__, __LINE__)
  299 #define SET_I_ENDOFF(ip, off)   ufs_set_i_endoff(ip, off, __FILE__, __LINE__)
  300 
  301 #else
  302 #define I_OFFSET(ip)            ((ip)->i_offset)
  303 #define SET_I_OFFSET(ip, off)   ((ip)->i_offset = (off))
  304 #define I_COUNT(ip)             ((ip)->i_count)
  305 #define SET_I_COUNT(ip, cnt)    ((ip)->i_count = cnt)
  306 #define I_ENDOFF(ip)            ((ip)->i_endoff)
  307 #define SET_I_ENDOFF(ip, off)   ((ip)->i_endoff = off)
  308 #endif
  309 
  310 #endif /* _KERNEL */
  311 
  312 #endif /* !_UFS_UFS_INODE_H_ */

Cache object: dc576186f6dc754e9aedee209f1a4f5e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.