Print this page
    
re #13613 rb4516 Tunables needs volatile keyword
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/sys/fs/ufs_inode.h
          +++ new/usr/src/uts/common/sys/fs/ufs_inode.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1983, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  23   24   */
  24   25  
  25   26  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  26   27  /*        All Rights Reserved   */
  27   28  
  28   29  /*
  29   30   * University Copyright- Copyright (c) 1982, 1986, 1988
  30   31   * The Regents of the University of California
  31   32   * All Rights Reserved
  32   33   *
  33   34   * University Acknowledgment- Portions of this document are derived from
  34   35   * software developed by the University of California, Berkeley, and its
  35   36   * contributors.
  36   37   */
  37   38  
  38   39  #ifndef _SYS_FS_UFS_INODE_H
  39   40  #define _SYS_FS_UFS_INODE_H
  40   41  
  41   42  #include <sys/isa_defs.h>
  42   43  #include <sys/fbuf.h>
  43   44  #include <sys/fdbuffer.h>
  44   45  #include <sys/fcntl.h>
  45   46  #include <sys/uio.h>
  46   47  #include <sys/t_lock.h>
  47   48  #include <sys/thread.h>
  48   49  #include <sys/cred.h>
  49   50  #include <sys/time.h>
  50   51  #include <sys/types32.h>
  51   52  #include <sys/fs/ufs_fs.h>
  52   53  #include <sys/fs/ufs_lockfs.h>
  53   54  #include <sys/fs/ufs_trans.h>
  54   55  #include <sys/kstat.h>
  55   56  #include <sys/fs/ufs_acl.h>
  56   57  #include <sys/fs/ufs_panic.h>
  57   58  #include <sys/dnlc.h>
  58   59  
  59   60  #ifdef _KERNEL
  60   61  #include <sys/vfs_opreg.h>
  61   62  #endif
  62   63  
  63   64  #ifdef  __cplusplus
  64   65  extern "C" {
  65   66  #endif
  66   67  
  67   68  /*
  68   69   * The I node is the focus of all local file activity in UNIX.
  69   70   * There is a unique inode allocated for each active file,
  70   71   * each current directory, each mounted-on file, each mapping,
  71   72   * and the root.  An inode is `named' by its dev/inumber pair.
  72   73   * Data in icommon is read in from permanent inode on volume.
  73   74   *
  74   75   * Each inode has 5 locks associated with it:
  75   76   *      i_rwlock:       Serializes ufs_write and ufs_setattr request
  76   77   *                      and allows ufs_read requests to proceed in parallel.
  77   78   *                      Serializes reads/updates to directories.
  78   79   *      vfs_dqrwlock:   Manages quota sub-system quiescence.  See below.
  79   80   *      i_contents:     Protects almost all of the fields in the inode
  80   81   *                      except for those listed below. When held
  81   82   *                      in writer mode also protects those fields
  82   83   *                      listed under i_tlock.
  83   84   *      i_tlock:        When i_tlock is held with the i_contents reader
  84   85   *                      lock the i_atime, i_mtime, i_ctime,
  85   86   *                      i_delayoff, i_delaylen, i_nextrio, i_writes, i_flag
  86   87   *                      i_seq, i_writer & i_mapcnt fields are protected.
  87   88   *                      For more i_flag locking info see below.
  88   89   *      ih_lock:        Protects inode hash chain buckets
  89   90   *      ifree_lock:     Protects inode freelist
  90   91   *
  91   92   * Lock ordering:
  92   93   *      i_rwlock > i_contents > i_tlock
  93   94   *      i_rwlock > vfs_dqrwlock > i_contents(writer) > i_tlock
  94   95   *      i_contents > i_tlock
  95   96   *      vfs_dqrwlock > i_contents(writer) > i_tlock
  96   97   *      ih_lock > i_contents > i_tlock
  97   98   *
  98   99   * Making major changes to quota sub-system state, while the file
  99  100   * system is mounted required the addition of another lock.  The
 100  101   * primary lock in the quota sub-system is vfs_dqrwlock in the ufsvfs
 101  102   * structure.  This lock is used to manage quota sub-system quiescence
 102  103   * for a particular file system. Major changes to quota sub-system
 103  104   * state (disabling quotas, enabling quotas, and setting new quota
 104  105   * limits) all require the file system to be quiescent and grabbing
 105  106   * vfs_dqrwlock as writer accomplishes this.  On the other hand,
 106  107   * grabbing vfs_dqrwlock as reader makes the quota sub-system
 107  108   * non-quiescent and lets the quota sub-system know that now is not a
 108  109   * good time to change major quota sub-system state.  Typically
 109  110   * vfs_dqrwlock is grabbed for reading before i_contents is grabbed for
 110  111   * writing.  However, there are cases where vfs_dqrwlock is grabbed for
 111  112   * reading without a corresponding i_contents write grab because there
 112  113   * is no relevant inode.  There are also cases where i_contents is
 113  114   * grabbed for writing when a vfs_dqrwlock read grab is not needed
 114  115   * because the inode changes do not affect quotas.
 115  116   *
 116  117   * Unfortunately, performance considerations have required that we be more
 117  118   * intelligent about using i_tlock when updating i_flag.  Ideally, we would
 118  119   * have simply separated out several of the bits in i_flag into their own
 119  120   * ints to avoid problems.  But, instead, we have implemented the following
 120  121   * rules:
 121  122   *
 122  123   *      o You can update any i_flag field while holding the writer-contents,
 123  124   *        or by holding the reader-contents AND holding i_tlock.
 124  125   *        You can only call ITIMES_NOLOCK while holding the writer-contents,
 125  126   *        or by holding the reader-contents AND holding i_tlock.
 126  127   *
 127  128   *      o For a directory, holding the reader-rw_lock is sufficient for setting
 128  129   *        IACC.
 129  130   *
 130  131   *      o Races with IREF are avoided by holding the reader contents lock
 131  132   *        and by holding i_tlock in ufs_rmidle, ufs_putapage, and ufs_getpage.
 132  133   *        And by holding the writer-contents in ufs_iinactive.
 133  134   *
 134  135   *      o The callers are no longer required to handle the calls to ITIMES
 135  136   *        and ITIMES_NOLOCK.  The functions that set the i_flag bits are
 136  137   *        responsible for managing those calls.  The exceptions are the
 137  138   *        bmap routines.
 138  139   *
 139  140   * SVR4 Extended Fundamental Type (EFT) support:
 140  141   *      The inode structure has been enhanced to support
 141  142   *      32-bit user-id, 32-bit group-id, and 32-bit device number.
 142  143   *      Standard SVR4 ufs also supports 32-bit mode field.  For the reason
 143  144   *      of backward compatibility with the previous ufs disk format,
 144  145   *      32-bit mode field is not supported.
 145  146   *
 146  147   *      The current inode structure is 100% backward compatible with
 147  148   *      the previous inode structure if no user-id or group-id exceeds
 148  149   *      USHRT_MAX, and no major or minor number of a device number
 149  150   *      stored in an inode exceeds 255.
 150  151   *
 151  152   * Rules for managing i_seq:
 152  153   *      o i_seq is locked under the same rules as i_flag
 153  154   *      o The i_ctime or i_mtime MUST never change without increasing
 154  155   *        the value of i_seq.
 155  156   *      o You may increase the value of i_seq without the timestamps
 156  157   *        changing, this may decrease the callers performance but will
 157  158   *        be functionally correct.
 158  159   *      o The common case is when IUPD or ICHG is set, increase i_seq
 159  160   *        and immediately call ITIMES* or ufs_iupdat to create a new timestamp.
 160  161   *      o A less common case is the setting of IUPD or ICHG and while still
 161  162   *        holding the correct lock defer the timestamp and i_seq update
 162  163   *        until later, but it must still be done before the lock is released.
 163  164   *        bmap_write is an example of this, where the caller does the update.
 164  165   *      o If multiple changes are being made with the timestamps being
 165  166   *        updated only at the end, a single increase of i_seq is allowed.
 166  167   *      o If changes are made with IUPD or ICHG being set, but
 167  168   *        the controlling lock is being dropped before the timestamp is
 168  169   *        updated, there is a risk that another thread will also change
 169  170   *        the file, update i_flag, and push just one timestamp update.
 170  171   *        There is also the risk that another thread calls ITIMES or
 171  172   *        ufs_iupdat without setting IUPD|ICHG and thus not changing i_seq,
 172  173   *        this will cause ufs_imark to change the timestamps without changing
 173  174   *        i_seq. If the controlling lock is dropped, ISEQ must be set to
 174  175   *        force i_seq to be increased on next ufs_imark, but i_seq MUST still
 175  176   *        be increased by the original setting thread before its deferred
 176  177   *        call to ITIMES to insure it is increased the correct number of times.
 177  178   */
 178  179  
 179  180  #define UID_LONG  (o_uid_t)65535
 180  181                                  /* flag value to indicate uid is 32-bit long */
 181  182  #define GID_LONG  (o_uid_t)65535
 182  183                                  /* flag value to indicate gid is 32-bit long */
 183  184  
 184  185  #define NDADDR  12              /* direct addresses in inode */
 185  186  #define NIADDR  3               /* indirect addresses in inode */
 186  187  #define FSL_SIZE (NDADDR + NIADDR - 1) * sizeof (daddr32_t)
 187  188                                  /* max fast symbolic name length is 56 */
 188  189  
 189  190  #define i_fs    i_ufsvfs->vfs_bufp->b_un.b_fs
 190  191  #define i_vfs   i_vnode->v_vfsp
 191  192  
 192  193  struct  icommon {
 193  194          o_mode_t ic_smode;      /*  0: mode and type of file */
 194  195          short   ic_nlink;       /*  2: number of links to file */
 195  196          o_uid_t ic_suid;        /*  4: owner's user id */
 196  197          o_gid_t ic_sgid;        /*  6: owner's group id */
 197  198          u_offset_t ic_lsize;    /*  8: number of bytes in file */
 198  199  #ifdef _KERNEL
 199  200          struct timeval32 ic_atime;      /* 16: time last accessed */
 200  201          struct timeval32 ic_mtime;      /* 24: time last modified */
 201  202          struct timeval32 ic_ctime;      /* 32: last time inode changed */
 202  203  #else
 203  204          time32_t ic_atime;      /* 16: time last accessed */
 204  205          int32_t ic_atspare;
 205  206          time32_t ic_mtime;      /* 24: time last modified */
 206  207          int32_t ic_mtspare;
 207  208          time32_t ic_ctime;      /* 32: last time inode changed */
 208  209          int32_t ic_ctspare;
 209  210  #endif
 210  211          daddr32_t       ic_db[NDADDR];  /* 40: disk block addresses */
 211  212          daddr32_t       ic_ib[NIADDR];  /* 88: indirect blocks */
 212  213          int32_t ic_flags;       /* 100: cflags */
 213  214          int32_t ic_blocks;      /* 104: 512 byte blocks actually held */
 214  215          int32_t ic_gen;         /* 108: generation number */
 215  216          int32_t ic_shadow;      /* 112: shadow inode */
 216  217          uid_t   ic_uid;         /* 116: long EFT version of uid */
 217  218          gid_t   ic_gid;         /* 120: long EFT version of gid */
 218  219          uint32_t ic_oeftflag;   /* 124: extended attr directory ino, 0 = none */
 219  220  };
 220  221  
 221  222  /*
 222  223   * Large directories can be cached. Directory caching can take the following
 223  224   * states:
 224  225   */
 225  226  typedef enum {
 226  227          CD_DISABLED_NOMEM = -2,
 227  228          CD_DISABLED_TOOBIG,
 228  229          CD_DISABLED,
 229  230          CD_ENABLED
 230  231  } cachedir_t;
 231  232  
 232  233  /*
 233  234   * Large Files: Note we use the inline functions load_double, store_double
 234  235   * to load and store the long long values of i_size. Therefore the
 235  236   * address of i_size must be eight byte aligned. Kmem_alloc of incore
 236  237   * inode structure makes sure that the structure is 8-byte aligned.
 237  238   * XX64 - reorder this structure?
 238  239   */
 239  240  typedef struct inode {
 240  241          struct  inode *i_chain[2];      /* must be first */
 241  242          struct inode *i_freef;  /* free list forward - must be before i_ic */
 242  243          struct inode *i_freeb;  /* free list back - must be before i_ic */
 243  244          struct  icommon i_ic;   /* Must be here */
 244  245          struct  vnode *i_vnode; /* vnode associated with this inode */
 245  246          struct  vnode *i_devvp; /* vnode for block I/O */
 246  247          dev_t   i_dev;          /* device where inode resides */
 247  248          ino_t   i_number;       /* i number, 1-to-1 with device address */
 248  249          off_t   i_diroff;       /* offset in dir, where we found last entry */
 249  250                                  /* just a hint - no locking needed */
 250  251          struct ufsvfs *i_ufsvfs; /* incore fs associated with inode */
 251  252          struct  dquot *i_dquot; /* quota structure controlling this file */
 252  253          krwlock_t i_rwlock;     /* serializes write/setattr requests */
 253  254          krwlock_t i_contents;   /* protects (most of) inode contents */
 254  255          kmutex_t i_tlock;       /* protects time fields, i_flag */
 255  256          offset_t i_nextr;       /*                                      */
 256  257                                  /* next byte read offset (read-ahead)   */
 257  258                                  /*   No lock required                   */
 258  259                                  /*                                      */
 259  260          uint_t  i_flag;         /* inode flags */
 260  261          uint_t  i_seq;          /* modification sequence number */
 261  262          cachedir_t i_cachedir;  /* Cache this directory on next lookup */
 262  263                                  /* - no locking needed  */
 263  264          long    i_mapcnt;       /* mappings to file pages */
 264  265          int     *i_map;         /* block list for the corresponding file */
 265  266          dev_t   i_rdev;         /* INCORE rdev from i_oldrdev by ufs_iget */
 266  267          size_t  i_delaylen;     /* delayed writes, units=bytes */
 267  268          offset_t i_delayoff;    /* where we started delaying */
 268  269          offset_t i_nextrio;     /* where to start the next clust */
 269  270          long    i_writes;       /* number of outstanding bytes in write q */
 270  271          kcondvar_t i_wrcv;      /* sleep/wakeup for write throttle */
 271  272          offset_t i_doff;        /* dinode byte offset in file system */
 272  273          si_t *i_ufs_acl;        /* pointer to acl entry */
 273  274          dcanchor_t i_danchor;   /* directory cache anchor */
 274  275          kthread_t *i_writer;    /* thread which is in window in wrip() */
 275  276  } inode_t;
 276  277  
 277  278  struct dinode {
 278  279          union {
 279  280                  struct  icommon di_icom;
 280  281                  char    di_size[128];
 281  282          } di_un;
 282  283  };
 283  284  
 284  285  #define i_mode          i_ic.ic_smode
 285  286  #define i_nlink         i_ic.ic_nlink
 286  287  #define i_uid           i_ic.ic_uid
 287  288  #define i_gid           i_ic.ic_gid
 288  289  #define i_smode         i_ic.ic_smode
 289  290  #define i_suid          i_ic.ic_suid
 290  291  #define i_sgid          i_ic.ic_sgid
 291  292  
 292  293  #define i_size          i_ic.ic_lsize
 293  294  #define i_db            i_ic.ic_db
 294  295  #define i_ib            i_ic.ic_ib
 295  296  
 296  297  #define i_atime         i_ic.ic_atime
 297  298  #define i_mtime         i_ic.ic_mtime
 298  299  #define i_ctime         i_ic.ic_ctime
 299  300  
 300  301  #define i_shadow        i_ic.ic_shadow
 301  302  #define i_oeftflag      i_ic.ic_oeftflag
 302  303  #define i_blocks        i_ic.ic_blocks
 303  304  #define i_cflags        i_ic.ic_flags
 304  305  #ifdef _LITTLE_ENDIAN
 305  306  /*
 306  307   * Originally done on x86, but carried on to all other little
 307  308   * architectures, which provides for file system compatibility.
 308  309   */
 309  310  #define i_ordev         i_ic.ic_db[1]   /* USL SVR4 compatibility */
 310  311  #else
 311  312  #define i_ordev         i_ic.ic_db[0]   /* was i_oldrdev */
 312  313  #endif
 313  314  #define i_gen           i_ic.ic_gen
 314  315  #define i_forw          i_chain[0]
 315  316  #define i_back          i_chain[1]
 316  317  
 317  318  /* EFT transition aids - obsolete */
 318  319  #define oEFT_MAGIC      0x90909090
 319  320  #define di_oeftflag     di_ic.ic_oeftflag
 320  321  
 321  322  #define di_ic           di_un.di_icom
 322  323  #define di_mode         di_ic.ic_smode
 323  324  #define di_nlink        di_ic.ic_nlink
 324  325  #define di_uid          di_ic.ic_uid
 325  326  #define di_gid          di_ic.ic_gid
 326  327  #define di_smode        di_ic.ic_smode
 327  328  #define di_suid         di_ic.ic_suid
 328  329  #define di_sgid         di_ic.ic_sgid
 329  330  
 330  331  #define di_size         di_ic.ic_lsize
 331  332  #define di_db           di_ic.ic_db
 332  333  #define di_ib           di_ic.ic_ib
 333  334  
 334  335  #define di_atime        di_ic.ic_atime
 335  336  #define di_mtime        di_ic.ic_mtime
 336  337  #define di_ctime        di_ic.ic_ctime
 337  338  #define di_cflags       di_ic.ic_flags
 338  339  
 339  340  #ifdef _LITTLE_ENDIAN
 340  341  #define di_ordev        di_ic.ic_db[1]
 341  342  #else
 342  343  #define di_ordev        di_ic.ic_db[0]
 343  344  #endif
 344  345  #define di_shadow       di_ic.ic_shadow
 345  346  #define di_blocks       di_ic.ic_blocks
 346  347  #define di_gen          di_ic.ic_gen
 347  348  
 348  349  /* flags */
 349  350  #define IUPD            0x0001          /* file has been modified */
 350  351  #define IACC            0x0002          /* inode access time to be updated */
 351  352  #define IMOD            0x0004          /* inode has been modified */
 352  353  #define ICHG            0x0008          /* inode has been changed */
 353  354  #define INOACC          0x0010          /* no access time update in getpage */
 354  355  #define IMODTIME        0x0020          /* mod time already set */
 355  356  #define IREF            0x0040          /* inode is being referenced */
 356  357  #define ISYNC           0x0080          /* do all allocation synchronously */
 357  358  #define IFASTSYMLNK     0x0100          /* fast symbolic link */
 358  359  #define IMODACC         0x0200          /* only access time changed; */
 359  360                                          /*   filesystem won't become active */
 360  361  #define IATTCHG         0x0400          /* only size/blocks have changed */
 361  362  #define IBDWRITE        0x0800          /* the inode has been scheduled for */
 362  363                                          /* write operation asynchronously */
 363  364  #define ISTALE          0x1000          /* inode couldn't be read from disk */
 364  365  #define IDEL            0x2000          /* inode is being deleted */
 365  366  #define IDIRECTIO       0x4000          /* attempt directio */
 366  367  #define ISEQ            0x8000          /* deferred i_seq increase */
 367  368  #define IJUNKIQ         0x10000         /* on junk idle queue */
 368  369  #define IQUIET          0x20000         /* No file system full messages */
 369  370  
 370  371  /* cflags */
 371  372  #define IXATTR          0x0001          /* extended attribute */
 372  373  #define IFALLOCATE      0x0002          /* fallocate'd file */
 373  374  #define ICOMPRESS       0x0004          /* compressed for dcfs - see */
 374  375                                          /*   `ufs_ioctl()`_FIO_COMPRESSED */
 375  376  
 376  377  /* modes */
 377  378  #define IFMT            0170000         /* type of file */
 378  379  #define IFIFO           0010000         /* named pipe (fifo) */
 379  380  #define IFCHR           0020000         /* character special */
 380  381  #define IFDIR           0040000         /* directory */
 381  382  #define IFBLK           0060000         /* block special */
 382  383  #define IFREG           0100000         /* regular */
 383  384  #define IFLNK           0120000         /* symbolic link */
 384  385  #define IFSHAD          0130000         /* shadow indode */
 385  386  #define IFSOCK          0140000         /* socket */
 386  387  #define IFATTRDIR       0160000         /* Attribute directory */
 387  388  
 388  389  #define ISUID           04000           /* set user id on execution */
 389  390  #define ISGID           02000           /* set group id on execution */
 390  391  #define ISVTX           01000           /* save swapped text even after use */
 391  392  #define IREAD           0400            /* read, write, execute permissions */
 392  393  #define IWRITE          0200
 393  394  #define IEXEC           0100
 394  395  
 395  396  /* specify how the inode info is written in ufs_syncip() */
 396  397  #define I_SYNC          1               /* wait for the inode written to disk */
 397  398  #define I_DSYNC         2               /* wait for the inode written to disk */
 398  399                                          /* only if IATTCHG is set */
 399  400  #define I_ASYNC         0               /* don't wait for the inode written */
 400  401  
 401  402  /* flags passed to ufs_itrunc(), indirtrunc(), and free() */
 402  403  #define I_FREE  0x00000001              /* inode is being freed */
 403  404  #define I_DIR   0x00000002              /* inode is a directory */
 404  405  #define I_IBLK  0x00000004              /* indirect block */
 405  406  #define I_CHEAP 0x00000008              /* cheap free */
 406  407  #define I_SHAD  0x00000010              /* inode is a shadow inode */
 407  408  #define I_QUOTA 0x00000020              /* quota file */
 408  409  #define I_NOCANCEL      0x40            /* Don't cancel these fragments */
 409  410  #define I_ACCT  0x00000080              /* Update ufsvfs' unreclaimed_blocks */
 410  411  
 411  412  /*
 412  413   * If ufs_dircheckforname() fails to find an entry with the given name,
 413  414   * this "slot" structure holds state for ufs_direnter_*() as to where
 414  415   * there is space to put an entry with that name.
 415  416   * If ufs_dircheckforname() finds an entry with the given name, this structure
 416  417   * holds state for ufs_dirrename() and ufs_dirremove() as to where the
 417  418   * entry is. "status" indicates what ufs_dircheckforname() found:
 418  419   *      NONE            name not found, large enough free slot not found,
 419  420   *      FOUND           name not found, large enough free slot found
 420  421   *      EXIST           name found
 421  422   * If ufs_dircheckforname() fails due to an error, this structure is not
 422  423   * filled in.
 423  424   *
 424  425   * After ufs_dircheckforname() succeeds the values are:
 425  426   *      status  offset          size            fbp, ep
 426  427   *      ------  ------          ----            -------
 427  428   *      NONE    end of dir      needed          not valid
 428  429   *      FOUND   start of entry  of ent          both valid if fbp != NULL
 429  430   *      EXIST   start of entry  of prev ent     valid
 430  431   *
 431  432   * "endoff" is set to 0 if the an entry with the given name is found, or if no
 432  433   * free slot could be found or made; this means that the directory should not
 433  434   * be truncated.  If the entry was found, the search terminates so
 434  435   * ufs_dircheckforname() didn't find out where the last valid entry in the
 435  436   * directory was, so it doesn't know where to cut the directory off; if no free
 436  437   * slot could be found or made, the directory has to be extended to make room
 437  438   * for the new entry, so there's nothing to cut off.
 438  439   * Otherwise, "endoff" is set to the larger of the offset of the last
 439  440   * non-empty entry in the directory, or the offset at which the new entry will
 440  441   * be placed, whichever is larger.  This is used by ufs_diraddentry(); if a new
 441  442   * entry is to be added to the directory, any complete directory blocks at the
 442  443   * end of the directory that contain no non-empty entries are lopped off the
 443  444   * end, thus shrinking the directory dynamically.
 444  445   */
 445  446  typedef enum {NONE, FOUND, EXIST} slotstat_t;
 446  447  struct ufs_slot {
 447  448          struct  direct *ep;     /* pointer to slot */
 448  449          struct  fbuf *fbp;      /* dir buf where slot is */
 449  450          off_t   offset;         /* offset of area with free space */
 450  451          off_t   endoff;         /* last useful location found in search */
 451  452          slotstat_t status;      /* status of slot */
 452  453          int     size;           /* size of area at slotoffset */
 453  454          int     cached;         /* cached directory */
 454  455  };
 455  456  
 456  457  /*
 457  458   * Statistics on inodes
 458  459   * Not protected by locks
 459  460   */
 460  461  struct instats {
 461  462          kstat_named_t in_size;          /* current cache size */
 462  463          kstat_named_t in_maxsize;       /* maximum cache size */
 463  464          kstat_named_t in_hits;          /* cache hits */
 464  465          kstat_named_t in_misses;        /* cache misses */
 465  466          kstat_named_t in_malloc;        /* kmem_alloce'd */
 466  467          kstat_named_t in_mfree;         /* kmem_free'd */
 467  468          kstat_named_t in_maxreached;    /* Largest size reached by cache */
 468  469          kstat_named_t in_frfront;       /* # put at front of freelist */
 469  470          kstat_named_t in_frback;        /* # put at back of freelist */
 470  471          kstat_named_t in_qfree;         /* q's to delete thread */
 471  472          kstat_named_t in_scan;          /* # inodes scanned */
 472  473          kstat_named_t in_tidles;        /* # inodes idled by idle thread */
 473  474          kstat_named_t in_lidles;        /* # inodes idled by ufs_lookup */
 474  475          kstat_named_t in_vidles;        /* # inodes idled by ufs_vget */
 475  476          kstat_named_t in_kcalloc;       /* # inodes kmem_cache_alloced */
 476  477          kstat_named_t in_kcfree;        /* # inodes kmem_cache_freed */
  
    | 
      ↓ open down ↓ | 
    444 lines elided | 
    
      ↑ open up ↑ | 
  
 477  478          kstat_named_t in_poc;           /* # push-on-close's */
 478  479  };
 479  480  
 480  481  #ifdef _KERNEL
 481  482  
 482  483  /*
 483  484   * Extended attributes
 484  485   */
 485  486  
 486  487  #define XATTR_DIR_NAME  "/@/"
 487      -extern int      ufs_ninode;             /* high-water mark for inode cache */
      488 +extern volatile int     ufs_ninode;     /* high-water mark for inode cache */
 488  489  
 489  490  extern struct vnodeops *ufs_vnodeops;   /* vnode operations for ufs */
 490  491  extern const struct fs_operation_def ufs_vnodeops_template[];
 491  492  
 492  493  /*
 493  494   * Convert between inode pointers and vnode pointers
 494  495   */
 495  496  #define VTOI(VP)        ((struct inode *)(VP)->v_data)
 496  497  #define ITOV(IP)        ((struct vnode *)(IP)->i_vnode)
 497  498  
 498  499  /*
 499  500   * convert to fs
 500  501   */
 501  502  #define ITOF(IP)        ((struct fs *)(IP)->i_fs)
 502  503  
 503  504  /*
 504  505   * Convert between vnode types and inode formats
 505  506   */
 506  507  extern enum vtype       iftovt_tab[];
 507  508  
 508  509  #ifdef notneeded
 509  510  
 510  511  /* Look at sys/mode.h and os/vnode.c */
 511  512  
 512  513  extern int              vttoif_tab[];
 513  514  
 514  515  #endif
 515  516  
 516  517  /*
 517  518   * Mark an inode with the current (unique) timestamp.
 518  519   * (Note that UFS's concept of time only keeps 32 bits of seconds
 519  520   * in the on-disk format).
 520  521   */
 521  522  struct timeval32 iuniqtime;
 522  523  extern kmutex_t ufs_iuniqtime_lock;
 523  524  
 524  525  #define ITIMES_NOLOCK(ip) ufs_itimes_nolock(ip)
 525  526  
 526  527  #define ITIMES(ip) { \
 527  528          mutex_enter(&(ip)->i_tlock); \
 528  529          ITIMES_NOLOCK(ip); \
 529  530          mutex_exit(&(ip)->i_tlock); \
 530  531  }
 531  532  
 532  533  /*
 533  534   * The following interfaces are used to do atomic loads and stores
 534  535   * of an inode's i_size, which is a long long data type.
 535  536   *
 536  537   * For LP64, we just to a load or a store - atomicity and alignment
 537  538   * are 8-byte guaranteed.  For x86 there are no such instructions,
 538  539   * so we grab i_contents as reader to get the size; we already hold
 539  540   * it as writer when we're setting the size.
 540  541   */
 541  542  
 542  543  #ifdef _LP64
 543  544  
 544  545  #define UFS_GET_ISIZE(resultp, ip)      *(resultp) = (ip)->i_size
 545  546  #define UFS_SET_ISIZE(value, ip)        (ip)->i_size = (value)
 546  547  
 547  548  #else   /* _LP64 */
 548  549  
 549  550  #define UFS_GET_ISIZE(resultp, ip)                              \
 550  551          {                                                       \
 551  552                  rw_enter(&(ip)->i_contents, RW_READER);         \
 552  553                  *(resultp) = (ip)->i_size;                      \
 553  554                  rw_exit(&(ip)->i_contents);                     \
 554  555          }
 555  556  #define UFS_SET_ISIZE(value, ip)                                \
 556  557          {                                                       \
 557  558                  ASSERT(RW_WRITE_HELD(&(ip)->i_contents));       \
 558  559                  (ip)->i_size = (value);                         \
 559  560          }
 560  561  
 561  562  #endif  /* _LP64 */
 562  563  
 563  564  /*
 564  565   * Allocate the specified block in the inode
 565  566   * and make sure any in-core pages are initialized.
 566  567   */
 567  568  #define BMAPALLOC(ip, off, size, cr) \
 568  569          bmap_write((ip), (u_offset_t)(off), (size), BI_NORMAL, NULL, cr)
 569  570  
 570  571  #define ESAME   (-1)            /* trying to rename linked files (special) */
 571  572  
 572  573  #define UFS_HOLE        (daddr32_t)-1   /* value used when no block allocated */
 573  574  
 574  575  /*
 575  576   * enums
 576  577   */
 577  578  
 578  579  /* direnter ops */
 579  580  enum de_op { DE_CREATE, DE_MKDIR, DE_LINK, DE_RENAME, DE_SYMLINK, DE_ATTRDIR};
 580  581  
 581  582  /* dirremove ops */
 582  583  enum dr_op { DR_REMOVE, DR_RMDIR, DR_RENAME };
 583  584  
 584  585  /*
 585  586   * block initialization type for bmap_write
 586  587   *
 587  588   * BI_NORMAL - allocate and zero fill pages in memory
 588  589   * BI_ALLOC_ONLY - only allocate the block, do not zero out pages in mem
 589  590   * BI_FALLOCATE - allocate only, do not zero out pages, and store as negative
 590  591   *                block number in inode block list
 591  592   */
 592  593  enum bi_type { BI_NORMAL, BI_ALLOC_ONLY, BI_FALLOCATE };
 593  594  
 594  595  /*
 595  596   * This overlays the fid structure (see vfs.h)
 596  597   *
 597  598   * LP64 note: we use int32_t instead of ino_t since UFS does not use
 598  599   * inode numbers larger than 32-bits and ufid's are passed to NFS
 599  600   * which expects them to not grow in size beyond 10 bytes (12 including
 600  601   * the length).
 601  602   */
 602  603  struct ufid {
 603  604          ushort_t ufid_len;
 604  605          ushort_t ufid_flags;
 605  606          int32_t ufid_ino;
 606  607          int32_t ufid_gen;
 607  608  };
 608  609  
 609  610  /*
 610  611   * each ufs thread (see ufs_thread.c) is managed by this struct
 611  612   */
 612  613  struct ufs_q {
 613  614          union uq_head {
 614  615                  void            *_uq_generic;   /* first entry on q */
 615  616                  struct inode    *_uq_i;
 616  617                  ufs_failure_t   *_uq_uf;
 617  618          } _uq_head;
 618  619          int             uq_ne;          /* # of entries/failures found */
 619  620          int             uq_lowat;       /* thread runs when ne == lowat */
 620  621          int             uq_hiwat;       /* synchronous idle if ne >= hiwat */
 621  622          ushort_t        uq_flags;       /* flags (see below) */
 622  623          kcondvar_t      uq_cv;          /* for sleep/wakeup */
 623  624          kthread_id_t    uq_threadp;     /* thread managing this q */
 624  625          kmutex_t        uq_mutex;       /* protects this struct */
 625  626  };
 626  627  
 627  628  #define uq_head         _uq_head._uq_generic
 628  629  #define uq_ihead        _uq_head._uq_i
 629  630  #define uq_ufhead       _uq_head._uq_uf
 630  631  
 631  632  /*
 632  633   * uq_flags
 633  634   */
 634  635  #define UQ_EXIT         (0x0001)        /* q server exits at its convenience */
 635  636  #define UQ_WAIT         (0x0002)        /* thread is waiting on q server */
 636  637  #define UQ_SUSPEND      (0x0004)        /* request for suspension */
 637  638  #define UQ_SUSPENDED    (0x0008)        /* thread has suspended itself */
 638  639  
 639  640  /*
 640  641   * When logging is enabled, statvfs must account for blocks and files that
 641  642   * may be on the delete queue.  Protected by ufsvfsp->vfs_delete.uq_mutex
 642  643   */
 643  644  struct ufs_delq_info {
 644  645          u_offset_t      delq_unreclaimed_blocks;
 645  646          ulong_t         delq_unreclaimed_files;
 646  647  };
 647  648  
 648  649  
 649  650  /*
 650  651   * global idle queues
 651  652   * The queues are sized dynamically in proportion to ufs_ninode
 652  653   * which, unless overridden, scales with the amount of memory.
 653  654   * The idle queue is halved whenever it hits the low water mark
 654  655   * (1/4 of ufs_ninode), but can burst to sizes much larger. The number
 655  656   * of hash queues is currently maintained to give on average IQHASHQLEN
 656  657   * entries when the idle queue is at the low water mark.
 657  658   * Note, we do not need to search along the hash queues, but use them
 658  659   * in order to batch together geographically local inodes to allow
 659  660   * their updates (via the log or buffer cache) to require less disk seeks.
 660  661   * This gives an incredible performance boost for logging and a boost for
 661  662   * non logging file systems.
 662  663   */
 663  664  typedef struct {
 664  665          inode_t *i_chain[2];    /* must match inode_t, but unused */
 665  666          inode_t *i_freef;       /* must match inode_t, idle list forward */
 666  667          inode_t *i_freeb;       /* must match inode_t, idle list back  */
 667  668  } iqhead_t;
 668  669  
 669  670  extern struct ufs_q ufs_idle_q;         /* used by global ufs idle thread */
 670  671  extern iqhead_t *ufs_junk_iq;           /* junk idle queues */
 671  672  extern iqhead_t *ufs_useful_iq;         /* useful idle queues */
 672  673  extern int ufs_njunk_iq;                /* number of entries in junk iq */
 673  674  extern int ufs_nuseful_iq;              /* number of entries in useful iq */
 674  675  extern int ufs_niqhash;                 /* number of iq hash qs - power of 2 */
 675  676  extern int ufs_iqhashmask;              /* iq hash mask = ufs_niqhash - 1 */
 676  677  
 677  678  #define IQHASHQLEN 32                   /* see comments above */
 678  679  #define INOCGSHIFT 7                    /* 128 inodes per cylinder group */
 679  680  #define IQHASH(ip) (((ip)->i_number >> INOCGSHIFT) & ufs_iqhashmask)
 680  681  #define IQNEXT(i) ((i) + 1) & ufs_iqhashmask /* next idle queue */
 681  682  
 682  683  extern struct ufs_q     ufs_hlock;      /* used by global ufs hlock thread */
 683  684  
 684  685  /*
 685  686   * vfs_lfflags flags
 686  687   */
 687  688  #define UFS_LARGEFILES  ((ushort_t)0x1) /* set if mount allows largefiles */
 688  689  
 689  690  /*
 690  691   * vfs_dfritime flags
 691  692   */
 692  693  #define UFS_DFRATIME    0x1             /* deferred access time */
 693  694  
 694  695  /*
 695  696   * UFS VFS private data.
 696  697   *
 697  698   * UFS file system instances may be linked on several lists.
 698  699   *
 699  700   * -    The vfs_next field chains together every extant ufs instance; this
 700  701   *      list is rooted at ufs_instances and should be used in preference to
 701  702   *      the overall vfs list (which is properly the province of the generic
 702  703   *      file system code, not of file system implementations).  This same list
 703  704   *      link is used during forcible unmounts to chain together instances that
 704  705   *      can't yet be completely dismantled,
 705  706   *
 706  707   * -    The vfs_wnext field is used within ufs_update to form a work list of
 707  708   *      UFS instances to be synced out.
 708  709   */
 709  710  typedef struct ufsvfs {
 710  711          struct vfs      *vfs_vfs;       /* back link                    */
 711  712          struct ufsvfs   *vfs_next;      /* instance list link           */
 712  713          struct ufsvfs   *vfs_wnext;     /* work list link               */
 713  714          struct vnode    *vfs_root;      /* root vnode                   */
 714  715          struct buf      *vfs_bufp;      /* buffer containing superblock */
 715  716          struct vnode    *vfs_devvp;     /* block device vnode           */
 716  717          ushort_t        vfs_lfflags;    /* Large files (set by mount)   */
 717  718          ushort_t        vfs_qflags;     /* QUOTA: filesystem flags      */
 718  719          struct inode    *vfs_qinod;     /* QUOTA: pointer to quota file */
 719  720          uint_t          vfs_btimelimit; /* QUOTA: block time limit      */
 720  721          uint_t          vfs_ftimelimit; /* QUOTA: file time limit       */
 721  722          krwlock_t       vfs_dqrwlock;   /* QUOTA: protects quota fields */
 722  723          /*
 723  724           * some fs local threads
 724  725           */
 725  726          struct ufs_q    vfs_delete;     /* delayed inode delete */
 726  727          struct ufs_q    vfs_reclaim;    /* reclaim open, deleted files */
 727  728  
 728  729          /*
 729  730           * This is copied from the super block at mount time.
 730  731           */
 731  732          int             vfs_nrpos;      /* # rotational positions */
 732  733          /*
 733  734           * This lock protects cg's and super block pointed at by
 734  735           * vfs_bufp->b_fs.  Locks contents of fs and cg's and contents
 735  736           * of vfs_dio.
 736  737           */
 737  738          kmutex_t        vfs_lock;
 738  739          struct ulockfs  vfs_ulockfs;    /* ufs lockfs support */
 739  740          uint_t          vfs_dio;        /* delayed io (_FIODIO) */
 740  741          uint_t          vfs_nointr;     /* disallow lockfs interrupts */
 741  742          uint_t          vfs_nosetsec;   /* disallow ufs_setsecattr */
 742  743          uint_t          vfs_syncdir;    /* synchronous local directory ops */
 743  744          uint_t          vfs_dontblock;  /* don't block on forced umount */
 744  745  
 745  746          /*
 746  747           * trans (logging ufs) stuff
 747  748           */
 748  749          uint_t          vfs_domatamap;  /* set if matamap enabled */
 749  750          ulong_t         vfs_maxacl;     /* transaction stuff - max acl size */
 750  751          ulong_t         vfs_dirsize;    /* logspace for directory creation */
 751  752          ulong_t         vfs_avgbfree;   /* average free blks in cg (blkpref) */
 752  753          /*
 753  754           * Some useful constants
 754  755           */
 755  756          int     vfs_nindirshift;        /* calc. from fs_nindir */
 756  757          int     vfs_nindiroffset;       /* calc. from fs_ninidr */
 757  758          int     vfs_ioclustsz;          /* bytes in read/write cluster */
 758  759          int     vfs_iotransz;           /* max device i/o transfer size  */
 759  760  
 760  761          vfs_ufsfx_t     vfs_fsfx;       /* lock/fix-on-panic support */
 761  762          /*
 762  763           * More useful constants
 763  764           */
 764  765          int     vfs_minfrags;           /* calc. from fs_minfree */
 765  766          /*
 766  767           * Force DirectIO on all files
 767  768           */
 768  769          uint_t  vfs_forcedirectio;
 769  770          /*
 770  771           * Deferred inode time related fields
 771  772           */
 772  773          clock_t         vfs_iotstamp;   /* last I/O timestamp */
 773  774          uint_t          vfs_dfritime;   /* deferred inode time flags */
 774  775          /*
 775  776           * Some more useful info
 776  777           */
 777  778          dev_t           vfs_dev;        /* device mounted from */
 778  779          struct ml_unit  *vfs_log;       /* pointer to embedded log struct */
 779  780          uint_t          vfs_noatime;    /* disable inode atime updates */
 780  781          /*
 781  782           * snapshot stuff
 782  783           */
 783  784          void            *vfs_snapshot;  /* snapshot handle */
 784  785          /*
 785  786           *  Controls logging "file system full" messages to messages file
 786  787           */
 787  788          clock_t         vfs_lastwhinetime;
 788  789  
 789  790          int             vfs_nolog_si;   /* not logging summary info */
 790  791          int             vfs_validfs;    /* indicates mounted fs */
 791  792  
 792  793          /*
 793  794           * Additional information about vfs_delete above
 794  795           */
 795  796          struct ufs_delq_info vfs_delete_info; /* what's on the delete queue */
 796  797  } ufsvfs_t;
 797  798  
 798  799  #define vfs_fs  vfs_bufp->b_un.b_fs
 799  800  
 800  801  /*
 801  802   * values for vfs_validfs
 802  803   */
 803  804  #define UT_UNMOUNTED    0
 804  805  #define UT_MOUNTED      1
 805  806  #define UT_HLOCKING     2
 806  807  
 807  808  /* inohsz is guaranteed to be a power of 2 */
 808  809  #define INOHASH(ino)    (((int)ino) & (inohsz - 1))
 809  810  
 810  811  #define ISFALLOCBLK(ip, bn)     \
 811  812          (((bn) < 0) && ((bn) % ip->i_fs->fs_frag == 0) && \
 812  813          ((ip)->i_cflags & IFALLOCATE && (bn) != UFS_HOLE))
 813  814  
 814  815  union ihead {
 815  816          union   ihead   *ih_head[2];
 816  817          struct  inode   *ih_chain[2];
 817  818  };
 818  819  
 819  820  extern  union   ihead   *ihead;
 820  821  extern  kmutex_t        *ih_lock;
 821  822  extern  int     *ih_ne;
 822  823  extern  int     inohsz;
 823  824  
 824  825  extern  clock_t ufs_iowait;
 825  826  
 826  827  #endif /* _KERNEL */
 827  828  
 828  829  /*
 829  830   * ufs function prototypes
 830  831   */
 831  832  #if defined(_KERNEL) && !defined(_BOOT)
 832  833  
 833  834  extern  void    ufs_iinit(void);
 834  835  extern  int     ufs_iget(struct vfs *, ino_t, struct inode **, cred_t *);
 835  836  extern  int     ufs_iget_alloced(struct vfs *, ino_t, struct inode **,
 836  837      cred_t *);
 837  838  extern  void    ufs_reset_vnode(vnode_t *);
 838  839  extern  void    ufs_iinactive(struct inode *);
 839  840  extern  void    ufs_iupdat(struct inode *, int);
 840  841  extern  int     ufs_rmidle(struct inode *);
 841  842  extern  int     ufs_itrunc(struct inode *, u_offset_t, int, cred_t *);
 842  843  extern  int     ufs_iaccess(struct inode *, int, cred_t *, int);
 843  844  extern  int     rdip(struct inode *, struct uio *, int, struct cred *);
 844  845  extern  int     wrip(struct inode *, struct uio *, int, struct cred *);
 845  846  
 846  847  extern void     ufs_imark(struct inode *);
 847  848  extern void     ufs_itimes_nolock(struct inode *);
 848  849  
 849  850  extern  int     ufs_diraccess(struct inode *, int, struct cred *);
 850  851  extern  int     ufs_dirlook(struct inode *, char *, struct inode **,
 851  852      cred_t *, int, int);
 852  853  extern  int     ufs_direnter_cm(struct inode *, char *, enum de_op,
 853  854      struct vattr *, struct inode **, cred_t *, int);
 854  855  extern  int     ufs_direnter_lr(struct inode *, char *, enum de_op,
 855  856      struct inode *, struct inode *, cred_t *);
 856  857  extern  int     ufs_dircheckpath(ino_t, struct inode *, struct inode *,
 857  858      struct cred *);
 858  859  extern  int     ufs_dirmakeinode(struct inode *, struct inode **,
 859  860      struct vattr *, enum de_op, cred_t *);
 860  861  extern  int     ufs_dirremove(struct inode *, char *, struct inode *,
 861  862      vnode_t *, enum dr_op, cred_t *);
 862  863  extern  int     ufs_dircheckforname(struct inode *, char *, int,
 863  864      struct ufs_slot *, struct inode **, struct cred *, int);
 864  865  extern  int     ufs_xattrdirempty(struct inode *, ino_t, cred_t *);
 865  866  extern  int     blkatoff(struct inode *, off_t, char **, struct fbuf **);
 866  867  
 867  868  extern  void    sbupdate(struct vfs *);
 868  869  
 869  870  extern  int     ufs_ialloc(struct inode *, ino_t, mode_t, struct inode **,
 870  871      cred_t *);
 871  872  extern  void    ufs_ifree(struct inode *, ino_t, mode_t);
 872  873  extern  void    free(struct inode *, daddr_t, off_t, int);
 873  874  extern  int     alloc(struct inode *, daddr_t, int, daddr_t *, cred_t *);
 874  875  extern  int     realloccg(struct inode *, daddr_t, daddr_t, int, int,
 875  876      daddr_t *, cred_t *);
 876  877  extern  int     ufs_allocsp(struct vnode *, struct flock64 *, cred_t *);
 877  878  extern  int     ufs_freesp(struct vnode *, struct flock64 *, int, cred_t *);
 878  879  extern  ino_t   dirpref(inode_t *);
 879  880  extern  daddr_t blkpref(struct inode *, daddr_t, int, daddr32_t *);
 880  881  extern  daddr_t contigpref(ufsvfs_t *, size_t, size_t);
 881  882  
 882  883  extern  int     ufs_rdwri(enum uio_rw, int, struct inode *, caddr_t, ssize_t,
 883  884          offset_t, enum uio_seg, int *, cred_t *);
 884  885  
 885  886  extern  int     bmap_read(struct inode *, u_offset_t, daddr_t *, int *);
 886  887  extern  int     bmap_write(struct inode *, u_offset_t, int, enum bi_type,
 887  888      daddr_t *, struct cred *);
 888  889  extern  int     bmap_has_holes(struct inode *);
 889  890  extern  int     bmap_find(struct inode *, boolean_t, u_offset_t *);
 890  891  extern  int     bmap_set_bn(struct vnode *, u_offset_t, daddr32_t);
 891  892  
 892  893  extern  void    ufs_vfs_add(struct ufsvfs *);
 893  894  extern  void    ufs_vfs_remove(struct ufsvfs *);
 894  895  
 895  896  extern  void    ufs_sbwrite(struct ufsvfs *);
 896  897  extern  void    ufs_update(int);
 897  898  extern  int     ufs_getsummaryinfo(dev_t, struct ufsvfs *, struct fs *);
 898  899  extern  int     ufs_putsummaryinfo(dev_t, struct ufsvfs *, struct fs *);
 899  900  extern  int     ufs_syncip(struct inode *, int, int, top_t);
 900  901  extern  int     ufs_sync_indir(struct inode *);
 901  902  extern  int     ufs_indirblk_sync(struct inode *, offset_t);
 902  903  extern  int     ufs_badblock(struct inode *, daddr_t);
 903  904  extern  int     ufs_indir_badblock(struct inode *, daddr32_t *);
 904  905  extern  void    ufs_notclean(struct ufsvfs *);
 905  906  extern  void    ufs_checkclean(struct vfs *);
 906  907  extern  int     isblock(struct fs *, uchar_t *, daddr_t);
 907  908  extern  void    setblock(struct fs *, uchar_t *, daddr_t);
 908  909  extern  void    clrblock(struct fs *, uchar_t *, daddr_t);
 909  910  extern  int     isclrblock(struct fs *, uchar_t *, daddr_t);
 910  911  extern  void    fragacct(struct fs *, int, int32_t *, int);
 911  912  extern  int     skpc(char, uint_t, char *);
 912  913  extern  int     ufs_fbwrite(struct fbuf *, struct inode *);
 913  914  extern  int     ufs_fbiwrite(struct fbuf *, struct inode *, daddr_t, long);
 914  915  extern  int     ufs_putapage(struct vnode *, struct page *, u_offset_t *,
 915  916                                  size_t *, int, struct cred *);
 916  917  extern inode_t  *ufs_alloc_inode(ufsvfs_t *, ino_t);
 917  918  extern void     ufs_free_inode(inode_t *);
 918  919  
 919  920  /*
 920  921   * special stuff
 921  922   */
 922  923  extern  void    ufs_setreclaim(struct inode *);
 923  924  extern  int     ufs_scan_inodes(int, int (*)(struct inode *, void *), void *,
 924  925                                  struct ufsvfs *);
 925  926  extern  int     ufs_sync_inode(struct inode *, void *);
 926  927  extern  int     ufs_sticky_remove_access(struct inode *, struct inode *,
 927  928      struct cred *);
 928  929  /*
 929  930   * quota
 930  931   */
 931  932  extern  int     chkiq(struct ufsvfs *, int, struct inode *, uid_t, int,
 932  933                          struct cred *, char **errp, size_t *lenp);
 933  934  
 934  935  /*
 935  936   * ufs thread stuff
 936  937   */
 937  938  extern  void    ufs_thread_delete(struct vfs *);
 938  939  extern  void    ufs_delete_drain(struct vfs *, int, int);
 939  940  extern  void    ufs_delete(struct ufsvfs *, struct inode *, int);
 940  941  extern  void    ufs_inode_cache_reclaim(void *);
 941  942  extern  void    ufs_idle_drain(struct vfs *);
 942  943  extern  void    ufs_idle_some(int);
 943  944  extern  void    ufs_thread_idle(void);
 944  945  extern  void    ufs_thread_reclaim(struct vfs *);
 945  946  extern  void    ufs_thread_init(struct ufs_q *, int);
 946  947  extern  void    ufs_thread_start(struct ufs_q *, void (*)(), struct vfs *);
 947  948  extern  void    ufs_thread_exit(struct ufs_q *);
 948  949  extern  void    ufs_thread_suspend(struct ufs_q *);
 949  950  extern  void    ufs_thread_continue(struct ufs_q *);
 950  951  extern  void    ufs_thread_hlock(void *);
 951  952  extern  void    ufs_delete_init(struct ufsvfs *, int);
 952  953  extern  void    ufs_delete_adjust_stats(struct ufsvfs *, struct statvfs64 *);
 953  954  extern  void    ufs_delete_drain_wait(struct ufsvfs *, int);
 954  955  
 955  956  /*
 956  957   * ufs lockfs stuff
 957  958   */
 958  959  struct seg;
 959  960  extern int ufs_reconcile_fs(struct vfs *, struct ufsvfs *, int);
 960  961  extern int ufs_quiesce(struct ulockfs *);
 961  962  extern int ufs_flush(struct vfs *);
 962  963  extern int ufs_fiolfs(struct vnode *, struct lockfs *, int);
 963  964  extern int ufs__fiolfs(struct vnode *, struct lockfs *, int, int);
 964  965  extern int ufs_fiolfss(struct vnode *, struct lockfs *);
 965  966  extern int ufs_fioffs(struct vnode *, char *, struct cred *);
 966  967  extern int ufs_check_lockfs(struct ufsvfs *, struct ulockfs *, ulong_t);
 967  968  extern int ufs_lockfs_begin(struct ufsvfs *, struct ulockfs **, ulong_t);
 968  969  extern int ufs_lockfs_trybegin(struct ufsvfs *, struct ulockfs **, ulong_t);
 969  970  extern int ufs_lockfs_begin_getpage(struct ufsvfs *, struct ulockfs **,
 970  971                  struct seg *, int, uint_t *);
 971  972  extern void ufs_lockfs_end(struct ulockfs *);
 972  973  /*
 973  974   * ufs acl stuff
 974  975   */
 975  976  extern int ufs_si_inherit(struct inode *, struct inode *, o_mode_t, cred_t *);
 976  977  extern void si_cache_init(void);
 977  978  extern int ufs_si_load(struct inode *, cred_t *);
 978  979  extern void ufs_si_del(struct inode *);
 979  980  extern int ufs_acl_access(struct inode *, int, cred_t *);
 980  981  extern void ufs_si_cache_flush(dev_t);
 981  982  extern int ufs_si_free(si_t *, struct vfs *, cred_t *);
 982  983  extern int ufs_acl_setattr(struct inode *, struct vattr *, cred_t *);
 983  984  extern int ufs_acl_get(struct inode *, vsecattr_t *, int, cred_t *);
 984  985  extern int ufs_acl_set(struct inode *, vsecattr_t *, int, cred_t *);
 985  986  /*
 986  987   * ufs directio stuff
 987  988   */
 988  989  extern void ufs_directio_init();
 989  990  extern int ufs_directio_write(struct inode *, uio_t *, int, int, cred_t *,
 990  991      int *);
 991  992  extern int ufs_directio_read(struct inode *, uio_t *, cred_t *, int *);
 992  993  #define DIRECTIO_FAILURE        (0)
 993  994  #define DIRECTIO_SUCCESS        (1)
 994  995  
 995  996  /*
 996  997   * ufs extensions for PXFS
 997  998   */
 998  999  
 999 1000  int ufs_rdwr_data(vnode_t *vp, u_offset_t offset, size_t len, fdbuffer_t *fdb,
1000 1001      int flags, cred_t *cr);
1001 1002  int ufs_alloc_data(vnode_t *vp, u_offset_t offset, size_t *len, fdbuffer_t *fdb,
1002 1003      int flags, cred_t *cr);
1003 1004  
1004 1005  /*
1005 1006   * prototypes to support the forced unmount
1006 1007   */
1007 1008  
1008 1009  void ufs_freeze(struct ulockfs *, struct lockfs *);
1009 1010  int ufs_thaw(struct vfs *, struct ufsvfs *, struct ulockfs *);
1010 1011  
1011 1012  /*
1012 1013   * extended attributes
1013 1014   */
1014 1015  
1015 1016  int ufs_xattrmkdir(inode_t *, inode_t **, int, struct cred *);
1016 1017  int ufs_xattr_getattrdir(vnode_t *, inode_t **, int, struct cred *);
1017 1018  void ufs_unhook_shadow(inode_t *, inode_t *);
1018 1019  
1019 1020  #endif  /* defined(_KERNEL) && !defined(_BOOT) */
1020 1021  
1021 1022  #ifdef  __cplusplus
1022 1023  }
1023 1024  #endif
1024 1025  
1025 1026  #endif  /* _SYS_FS_UFS_INODE_H */
  
    | 
      ↓ open down ↓ | 
    528 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX