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