root/ufs/ufs/inode.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


    1 /*      $OpenBSD: inode.h,v 1.35 2007/06/02 00:45:50 pedro Exp $        */
    2 /*      $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $    */
    3 
    4 /*
    5  * Copyright (c) 1982, 1989, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  *      @(#)inode.h     8.5 (Berkeley) 7/8/94
   38  */
   39 
   40 #include <sys/buf.h>
   41 #include <sys/lock.h>
   42 #include <ufs/ufs/dinode.h>
   43 #include <ufs/ufs/dir.h>
   44 #include <ufs/ext2fs/ext2fs_dinode.h>
   45 
   46 /*
   47  * Per-filesystem inode extensions.
   48  */
   49 struct ext2fs_inode_ext {
   50        int32_t  ext2fs_last_lblk; /* last logical block allocated */
   51        int32_t  ext2fs_last_blk; /* last block allocated on disk */
   52        u_int32_t        ext2fs_effective_uid; /* effective inode uid */
   53        u_int32_t        ext2fs_effective_gid; /* effective inode gid */
   54 };
   55 
   56 /*
   57  * The inode is used to describe each active (or recently active) file in the
   58  * UFS filesystem. It is composed of two types of information. The first part
   59  * is the information that is needed only while the file is active (such as
   60  * the identity of the file and linkage to speed its lookup). The second part
   61  * is * the permanent meta-data associated with the file which is read in
   62  * from the permanent dinode from long term storage when the file becomes
   63  * active, and is put back when the file is no longer being used.
   64  */
   65 struct inode {
   66         LIST_ENTRY(inode) i_hash; /* Hash chain */
   67         struct  vnode  *i_vnode;/* Vnode associated with this inode. */
   68         struct  ufsmount *i_ump;
   69         u_int32_t i_flag;       /* flags, see below */
   70         dev_t     i_dev;        /* Device associated with the inode. */
   71         ino_t     i_number;     /* The identity of the inode. */
   72         int       i_effnlink;   /* i_nlink when I/O completes */
   73 
   74         union {                 /* Associated filesystem. */
   75                 struct  fs *fs;                 /* FFS */
   76                 struct  m_ext2fs *e2fs;         /* EXT2FS */
   77         } inode_u;
   78 
   79 #define i_fs    inode_u.fs
   80 #define i_e2fs  inode_u.e2fs
   81 
   82         struct   cluster_info i_ci;
   83         struct   dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
   84         u_quad_t i_modrev;      /* Revision level for NFS lease. */
   85         struct   lockf *i_lockf;/* Head of byte-level lock list. */
   86         struct   lock i_lock;   /* Inode lock */
   87 
   88         /*
   89          * Side effects; used during directory lookup.
   90          */
   91         int32_t   i_count;      /* Size of free slot in directory. */
   92         doff_t    i_endoff;     /* End of useful stuff in directory. */
   93         doff_t    i_diroff;     /* Offset in dir, where we found last entry. */
   94         doff_t    i_offset;     /* Offset of free space in directory. */
   95         ino_t     i_ino;        /* Inode number of found directory. */
   96         u_int32_t i_reclen;     /* Size of found directory entry. */
   97         /*
   98          * Inode extensions
   99          */
  100         union {
  101                 /* Other extensions could go here... */
  102                 struct ext2fs_inode_ext   e2fs;
  103                 struct dirhash *dirhash;
  104         } inode_ext;
  105 
  106 #define i_e2fs_last_lblk        inode_ext.e2fs.ext2fs_last_lblk
  107 #define i_e2fs_last_blk         inode_ext.e2fs.ext2fs_last_blk
  108 #define i_e2fs_uid              inode_ext.e2fs.ext2fs_effective_uid
  109 #define i_e2fs_gid              inode_ext.e2fs.ext2fs_effective_gid
  110 #define i_dirhash               inode_ext.dirhash
  111 
  112         /*
  113          * The on-disk dinode itself.
  114          */
  115         union {
  116                 struct ufs1_dinode     *ffs1_din;
  117                 struct ufs2_dinode     *ffs2_din;
  118                 struct ext2fs_dinode   *e2fs_din;
  119         } dinode_u;
  120 
  121 #define i_din1  dinode_u.ffs1_din
  122 #define i_din2  dinode_u.ffs2_din
  123 #define i_e2din dinode_u.e2fs_din
  124 
  125         struct inode_vtbl *i_vtbl;
  126 };
  127 
  128 struct inode_vtbl {
  129         int (* iv_truncate)(struct inode *, off_t, int, 
  130             struct ucred *);
  131         int (* iv_update)(struct inode *, struct timespec *, struct timespec *,
  132             int waitfor);
  133         int (* iv_inode_alloc)(struct inode *, mode_t mode, 
  134             struct ucred *, struct vnode **);
  135         int (* iv_inode_free)(struct inode *, ino_t ino, mode_t mode);
  136         int (* iv_buf_alloc)(struct inode *, off_t, int, struct ucred *,
  137             int, struct buf **);
  138         int (* iv_bufatoff)(struct inode *, off_t offset, char **res,
  139             struct buf **bpp);
  140 };
  141 
  142 #define UFS_TRUNCATE(ip, off, flags, cred) \
  143     ((ip)->i_vtbl->iv_truncate)((ip), (off), (flags), (cred))
  144 
  145 #define UFS_UPDATE(ip, sync) \
  146     ((ip)->i_vtbl->iv_update)((ip), NULL, NULL, (sync))
  147 
  148 #define UFS_UPDATE2(ip, atime, mtime, sync) \
  149     ((ip)->i_vtbl->iv_update)((ip), (atime), (mtime), (sync))
  150 
  151 #define UFS_INODE_ALLOC(pip, mode, cred, vpp) \
  152     ((pip)->i_vtbl->iv_inode_alloc)((pip), (mode), (cred), (vpp))
  153 
  154 #define UFS_INODE_FREE(pip, ino, mode) \
  155     ((pip)->i_vtbl->iv_inode_free)((pip), (ino), (mode))
  156 
  157 #define UFS_BUF_ALLOC(ip, startoffset, size, cred, flags, bpp) \
  158     ((ip)->i_vtbl->iv_buf_alloc)((ip), (startoffset), (size), (cred), \
  159         (flags), (bpp))
  160  
  161 #define UFS_BUFATOFF(ip, offset, res, bpp) \
  162     ((ip)->i_vtbl->iv_bufatoff)((ip), (offset), (res), (bpp))
  163 
  164 #define i_ffs1_atime            i_din1->di_atime
  165 #define i_ffs1_atimensec        i_din1->di_atimensec
  166 #define i_ffs1_blocks           i_din1->di_blocks
  167 #define i_ffs1_ctime            i_din1->di_ctime
  168 #define i_ffs1_ctimensec        i_din1->di_ctimensec
  169 #define i_ffs1_db               i_din1->di_db
  170 #define i_ffs1_flags            i_din1->di_flags
  171 #define i_ffs1_gen              i_din1->di_gen
  172 #define i_ffs1_gid              i_din1->di_gid
  173 #define i_ffs1_ib               i_din1->di_ib
  174 #define i_ffs1_mode             i_din1->di_mode
  175 #define i_ffs1_mtime            i_din1->di_mtime
  176 #define i_ffs1_mtimensec        i_din1->di_mtimensec
  177 #define i_ffs1_nlink            i_din1->di_nlink
  178 #define i_ffs1_rdev             i_din1->di_rdev
  179 #define i_ffs1_shortlink        i_din1->di_shortlink
  180 #define i_ffs1_size             i_din1->di_size
  181 #define i_ffs1_uid              i_din1->di_uid
  182 
  183 #define i_ffs2_atime            i_din2->di_atime
  184 #define i_ffs2_atimensec        i_din2->di_atimensec
  185 #define i_ffs2_blocks           i_din2->di_blocks
  186 #define i_ffs2_blksize          i_din2->di_blksize
  187 #define i_ffs2_ctime            i_din2->di_ctime
  188 #define i_ffs2_ctimensec        i_din2->di_ctimensec
  189 #define i_ffs2_db               i_din2->di_db
  190 #define i_ffs2_flags            i_din2->di_flags
  191 #define i_ffs2_gen              i_din2->di_gen
  192 #define i_ffs2_gid              i_din2->di_gid
  193 #define i_ffs2_ib               i_din2->di_ib
  194 #define i_ffs2_mode             i_din2->di_mode
  195 #define i_ffs2_mtime            i_din2->di_mtime
  196 #define i_ffs2_mtimensec        i_din2->di_mtimensec
  197 #define i_ffs2_nlink            i_din2->di_nlink
  198 #define i_ffs2_rdev             i_din2->di_rdev
  199 #define i_ffs2_size             i_din2->di_size
  200 #define i_ffs2_uid              i_din2->di_uid
  201 
  202 #ifndef _KERNEL
  203 /*
  204  * These are here purely for backwards compatibility for userland.
  205  * They allow direct references to FFS structures using the old names.
  206  */
  207 #define i_atime                 i_din1->di_atime
  208 #define i_atimensec             i_din1->di_atimensec
  209 #define i_blocks                i_din1->di_blocks
  210 #define i_ctime                 i_din1->di_ctime
  211 #define i_ctimensec             i_din1->di_ctimensec
  212 #define i_db                    i_din1->di_db
  213 #define i_flags                 i_din1->di_flags
  214 #define i_gen                   i_din1->di_gen
  215 #define i_gid                   i_din1->di_gid
  216 #define i_ib                    i_din1->di_ib
  217 #define i_mode                  i_din1->di_mode
  218 #define i_mtime                 i_din1->di_mtime
  219 #define i_mtimensec             i_din1->di_mtimensec
  220 #define i_nlink                 i_din1->di_nlink
  221 #define i_rdev                  i_din1->di_rdev
  222 #define i_shortlink             i_din1->di_shortlink
  223 #define i_size                  i_din1->di_size
  224 #define i_uid                   i_din1->di_uid
  225 #endif  /* _KERNEL */
  226 
  227 #define i_e2fs_mode             i_e2din->e2di_mode
  228 #define i_e2fs_size             i_e2din->e2di_size
  229 #define i_e2fs_atime            i_e2din->e2di_atime
  230 #define i_e2fs_ctime            i_e2din->e2di_ctime
  231 #define i_e2fs_mtime            i_e2din->e2di_mtime
  232 #define i_e2fs_dtime            i_e2din->e2di_dtime
  233 #define i_e2fs_nlink            i_e2din->e2di_nlink
  234 #define i_e2fs_nblock           i_e2din->e2di_nblock
  235 #define i_e2fs_flags            i_e2din->e2di_flags
  236 #define i_e2fs_blocks           i_e2din->e2di_blocks
  237 #define i_e2fs_gen              i_e2din->e2di_gen
  238 #define i_e2fs_facl             i_e2din->e2di_facl
  239 #define i_e2fs_dacl             i_e2din->e2di_dacl
  240 #define i_e2fs_faddr            i_e2din->e2di_faddr
  241 #define i_e2fs_nfrag            i_e2din->e2di_nfrag
  242 #define i_e2fs_fsize            i_e2din->e2di_fsize
  243 #define i_e2fs_uid_low          i_e2din->e2di_uid_low
  244 #define i_e2fs_gid_low          i_e2din->e2di_gid_low
  245 #define i_e2fs_uid_high         i_e2din->e2di_uid_high
  246 #define i_e2fs_gid_high         i_e2din->e2di_gid_high
  247 
  248 /* These flags are kept in i_flag. */
  249 #define IN_ACCESS       0x0001          /* Access time update request. */
  250 #define IN_CHANGE       0x0002          /* Inode change time update request. */
  251 #define IN_UPDATE       0x0004          /* Modification time update request */
  252 #define IN_MODIFIED     0x0008          /* Inode has been modified. */
  253 #define IN_RENAME       0x0010          /* Inode is being renamed. */
  254 #define IN_SHLOCK       0x0020          /* File has shared lock. */
  255 #define IN_EXLOCK       0x0040          /* File has exclusive lock. */
  256 
  257 #define i_devvp i_ump->um_devvp
  258 
  259 #ifdef _KERNEL
  260 
  261 /*
  262  * The DIP macros are used to access fields in the dinode.
  263  */
  264 #define DIP(ip, field) \
  265         (((ip)->i_ump->um_fstype == UM_UFS1) ? \
  266         (ip)->i_ffs1_##field : (ip)->i_ffs2_##field)
  267 
  268 #define DIP_ASSIGN(ip, field, value)                                    \
  269         do {                                                            \
  270                 if ((ip)->i_ump->um_fstype == UM_UFS1)                  \
  271                         (ip)->i_ffs1_##field = (value);                 \
  272                 else                                                    \
  273                         (ip)->i_ffs2_##field = (value);                 \
  274         } while (0)
  275 
  276 #define DIP_ADD(ip, field, value)                                       \
  277         do {                                                            \
  278                 if ((ip)->i_ump->um_fstype == UM_UFS1)                  \
  279                         (ip)->i_ffs1_##field += (value);                \
  280                 else                                                    \
  281                         (ip)->i_ffs2_##field += (value);                \
  282         } while (0)
  283 
  284 #define SHORTLINK(ip) \
  285         (((ip)->i_ump->um_fstype == UM_UFS1) ? \
  286         (caddr_t)(ip)->i_ffs1_db : (caddr_t)(ip)->i_ffs2_db)
  287 
  288 /*
  289  * Structure used to pass around logical block paths generated by
  290  * ufs_getlbns and used by truncate and bmap code.
  291  */
  292 struct indir {
  293         daddr_t in_lbn;                 /* Logical block number. */
  294         int     in_off;                 /* Offset in buffer. */
  295         int     in_exists;              /* Flag if the block exists. */
  296 };
  297 
  298 /* Convert between inode pointers and vnode pointers. */
  299 #define VTOI(vp)        ((struct inode *)(vp)->v_data)
  300 #define ITOV(ip)        ((ip)->i_vnode)
  301 
  302 #define FFS_ITIMES(ip, t1, t2) {                                        \
  303         if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) {       \
  304                 (ip)->i_flag |= IN_MODIFIED;                            \
  305                 if ((ip)->i_flag & IN_ACCESS)                           \
  306                         DIP_ASSIGN((ip), atime, (t1)->tv_sec);          \
  307                 if ((ip)->i_flag & IN_UPDATE) {                         \
  308                         DIP_ASSIGN((ip), mtime, (t2)->tv_sec);          \
  309                         (ip)->i_modrev++;                               \
  310                 }                                                       \
  311                 if ((ip)->i_flag & IN_CHANGE)                           \
  312                         DIP_ASSIGN((ip), ctime, time_second);           \
  313                 (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);   \
  314         }                                                               \
  315 }
  316 
  317 #define EXT2FS_ITIMES(ip, t1, t2) {                                     \
  318         if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) {       \
  319                 (ip)->i_flag |= IN_MODIFIED;                            \
  320                 if ((ip)->i_flag & IN_ACCESS)                           \
  321                         (ip)->i_e2fs_atime = (t1)->tv_sec;              \
  322                 if ((ip)->i_flag & IN_UPDATE) {                         \
  323                         (ip)->i_e2fs_mtime = (t2)->tv_sec;              \
  324                         (ip)->i_modrev++;                               \
  325                 }                                                       \
  326                 if ((ip)->i_flag & IN_CHANGE)                           \
  327                         (ip)->i_e2fs_ctime = time_second;               \
  328                 (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);   \
  329         }                                                               \
  330 }
  331 
  332 #define ITIMES(ip, t1, t2) {                                            \
  333         if (IS_EXT2_VNODE((ip)->i_vnode)) {                             \
  334                 EXT2FS_ITIMES(ip, t1, t2);                              \
  335         } else {                                                        \
  336                 FFS_ITIMES(ip, t1, t2);                                 \
  337         }                                                               \
  338 }
  339 
  340 /* Determine if soft dependencies are being done */
  341 #ifdef FFS_SOFTUPDATES
  342 #define DOINGSOFTDEP(vp)      ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
  343 #else
  344 #define DOINGSOFTDEP(vp)      (0)
  345 #endif
  346 #define DOINGASYNC(vp)        ((vp)->v_mount->mnt_flag & MNT_ASYNC)
  347 
  348 /* This overlays the fid structure (see mount.h). */
  349 struct ufid {
  350         u_int16_t ufid_len;     /* Length of structure. */
  351         u_int16_t ufid_pad;     /* Force 32-bit alignment. */
  352         ino_t     ufid_ino;     /* File number (ino). */
  353         int32_t   ufid_gen;     /* Generation number. */
  354 };
  355 #endif /* _KERNEL */

/* [<][>][^][v][top][bottom][index][help] */