2005-04-17 02:20:36 +04:00
/*
2005-11-02 06:58:39 +03:00
* Copyright ( c ) 2000 - 2003 , 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
2005-04-17 02:20:36 +04:00
* published by the Free Software Foundation .
*
2005-11-02 06:58:39 +03:00
* This program is distributed in the hope that it would be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
2005-04-17 02:20:36 +04:00
*/
# ifndef __XFS_INODE_H__
# define __XFS_INODE_H__
2013-08-12 14:49:35 +04:00
# include "xfs_inode_buf.h"
2013-08-12 14:49:33 +04:00
# include "xfs_inode_fork.h"
2005-04-17 02:20:36 +04:00
2008-11-28 06:23:41 +03:00
/*
2013-08-12 14:49:35 +04:00
* Kernel only inode definitions
2008-11-28 06:23:41 +03:00
*/
2013-08-12 14:49:35 +04:00
struct xfs_dinode ;
struct xfs_inode ;
2008-10-30 09:05:38 +03:00
struct xfs_buf ;
struct xfs_bmap_free ;
struct xfs_bmbt_irec ;
struct xfs_inode_log_item ;
struct xfs_mount ;
struct xfs_trans ;
struct xfs_dquot ;
2005-04-17 02:20:36 +04:00
typedef struct xfs_inode {
/* Inode linking and identification information. */
struct xfs_mount * i_mount ; /* fs mount struct ptr */
struct xfs_dquot * i_udquot ; /* user dquot */
struct xfs_dquot * i_gdquot ; /* group dquot */
2013-07-11 09:00:40 +04:00
struct xfs_dquot * i_pdquot ; /* project dquot */
2005-04-17 02:20:36 +04:00
/* Inode location stuff */
xfs_ino_t i_ino ; /* inode number (agno/agino)*/
2008-11-28 06:23:41 +03:00
struct xfs_imap i_imap ; /* location for xfs_imap() */
2005-04-17 02:20:36 +04:00
/* Extent information. */
xfs_ifork_t * i_afp ; /* attribute fork pointer */
xfs_ifork_t i_df ; /* data fork */
2013-10-29 15:11:46 +04:00
/* operations vectors */
const struct xfs_dir_ops * d_ops ; /* directory ops vector */
2005-04-17 02:20:36 +04:00
/* Transaction and locking information. */
struct xfs_inode_log_item * i_itemp ; /* logging information */
mrlock_t i_lock ; /* inode lock */
mrlock_t i_iolock ; /* inode IO lock */
atomic_t i_pincount ; /* inode pin count */
2006-09-28 05:06:03 +04:00
spinlock_t i_flags_lock ; /* inode i_flags lock */
2005-04-17 02:20:36 +04:00
/* Miscellaneous state. */
2011-12-19 00:00:08 +04:00
unsigned long i_flags ; /* see defined flags below */
2005-04-17 02:20:36 +04:00
unsigned int i_delayed_blks ; /* count of delay alloc blks */
2007-08-28 07:57:51 +04:00
xfs_icdinode_t i_d ; /* most of ondisk inode */
2005-04-17 02:20:36 +04:00
2008-10-30 09:36:14 +03:00
/* VFS inode */
struct inode i_vnode ; /* embedded VFS inode */
2005-04-17 02:20:36 +04:00
} xfs_inode_t ;
2008-08-13 09:45:15 +04:00
/* Convert from vfs inode to xfs inode */
static inline struct xfs_inode * XFS_I ( struct inode * inode )
{
2008-10-30 09:36:14 +03:00
return container_of ( inode , struct xfs_inode , i_vnode ) ;
2008-08-13 09:45:15 +04:00
}
/* convert from xfs inode to vfs inode */
static inline struct inode * VFS_I ( struct xfs_inode * ip )
{
2008-10-30 09:36:14 +03:00
return & ip - > i_vnode ;
2008-08-13 09:45:15 +04:00
}
2011-12-19 00:00:11 +04:00
/*
* For regular files we only update the on - disk filesize when actually
* writing data back to disk . Until then only the copy in the VFS inode
* is uptodate .
*/
static inline xfs_fsize_t XFS_ISIZE ( struct xfs_inode * ip )
{
if ( S_ISREG ( ip - > i_d . di_mode ) )
return i_size_read ( VFS_I ( ip ) ) ;
return ip - > i_d . di_size ;
}
2012-02-29 13:53:49 +04:00
/*
* If this I / O goes past the on - disk inode size update it unless it would
* be past the current in - core inode size .
*/
static inline xfs_fsize_t
xfs_new_eof ( struct xfs_inode * ip , xfs_fsize_t new_size )
{
xfs_fsize_t i_size = i_size_read ( VFS_I ( ip ) ) ;
2014-10-02 03:21:53 +04:00
if ( new_size > i_size | | new_size < 0 )
2012-02-29 13:53:49 +04:00
new_size = i_size ;
return new_size > ip - > i_d . di_size ? new_size : 0 ;
}
2006-11-11 10:04:54 +03:00
/*
* i_flags helper functions
*/
static inline void
__xfs_iflags_set ( xfs_inode_t * ip , unsigned short flags )
{
ip - > i_flags | = flags ;
}
static inline void
xfs_iflags_set ( xfs_inode_t * ip , unsigned short flags )
{
spin_lock ( & ip - > i_flags_lock ) ;
__xfs_iflags_set ( ip , flags ) ;
spin_unlock ( & ip - > i_flags_lock ) ;
}
static inline void
xfs_iflags_clear ( xfs_inode_t * ip , unsigned short flags )
{
spin_lock ( & ip - > i_flags_lock ) ;
ip - > i_flags & = ~ flags ;
spin_unlock ( & ip - > i_flags_lock ) ;
}
static inline int
__xfs_iflags_test ( xfs_inode_t * ip , unsigned short flags )
{
return ( ip - > i_flags & flags ) ;
}
static inline int
xfs_iflags_test ( xfs_inode_t * ip , unsigned short flags )
{
int ret ;
spin_lock ( & ip - > i_flags_lock ) ;
ret = __xfs_iflags_test ( ip , flags ) ;
spin_unlock ( & ip - > i_flags_lock ) ;
return ret ;
}
2007-08-29 05:44:50 +04:00
static inline int
xfs_iflags_test_and_clear ( xfs_inode_t * ip , unsigned short flags )
{
int ret ;
spin_lock ( & ip - > i_flags_lock ) ;
ret = ip - > i_flags & flags ;
if ( ret )
ip - > i_flags & = ~ flags ;
spin_unlock ( & ip - > i_flags_lock ) ;
return ret ;
}
2005-04-17 02:20:36 +04:00
2011-12-19 00:00:09 +04:00
static inline int
xfs_iflags_test_and_set ( xfs_inode_t * ip , unsigned short flags )
{
int ret ;
spin_lock ( & ip - > i_flags_lock ) ;
ret = ip - > i_flags & flags ;
if ( ! ret )
ip - > i_flags | = flags ;
spin_unlock ( & ip - > i_flags_lock ) ;
return ret ;
}
2010-09-26 10:10:18 +04:00
/*
* Project quota id helpers ( previously projid was 16 bit only
2011-03-31 05:57:33 +04:00
* and using two 16 bit values to hold new 32 bit projid was chosen
2010-09-26 10:10:18 +04:00
* to retain compatibility with " old " filesystems ) .
*/
static inline prid_t
xfs_get_projid ( struct xfs_inode * ip )
{
return ( prid_t ) ip - > i_d . di_projid_hi < < 16 | ip - > i_d . di_projid_lo ;
}
static inline void
xfs_set_projid ( struct xfs_inode * ip ,
prid_t projid )
{
ip - > i_d . di_projid_hi = ( __uint16_t ) ( projid > > 16 ) ;
ip - > i_d . di_projid_lo = ( __uint16_t ) ( projid & 0xffff ) ;
}
2013-12-18 04:22:39 +04:00
static inline prid_t
xfs_get_initial_prid ( struct xfs_inode * dp )
{
if ( dp - > i_d . di_flags & XFS_DIFLAG_PROJINHERIT )
return xfs_get_projid ( dp ) ;
return XFS_PROJID_DEFAULT ;
}
2005-04-17 02:20:36 +04:00
/*
* In - core inode flags .
*/
2011-12-19 00:00:09 +04:00
# define XFS_IRECLAIM (1 << 0) /* started reclaiming this inode */
# define XFS_ISTALE (1 << 1) /* inode has been staled */
# define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */
# define XFS_INEW (1 << 3) /* inode has just been allocated */
# define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */
# define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */
# define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */
# define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT)
2011-12-19 00:00:10 +04:00
# define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */
# define XFS_IPINNED (1 << __XFS_IPINNED_BIT)
2012-03-22 09:15:10 +04:00
# define XFS_IDONTCACHE (1 << 9) /* don't cache the inode long term */
2005-04-17 02:20:36 +04:00
2011-06-23 05:34:59 +04:00
/*
* Per - lifetime flags need to be reset when re - using a reclaimable inode during
2012-03-22 09:15:10 +04:00
* inode lookup . This prevents unintended behaviour on the new inode from
2011-06-23 05:34:59 +04:00
* ocurring .
*/
# define XFS_IRECLAIM_RESET_FLAGS \
( XFS_IRECLAIMABLE | XFS_IRECLAIM | \
2014-04-23 01:11:51 +04:00
XFS_IDIRTY_RELEASE | XFS_ITRUNCATED )
2011-06-23 05:34:59 +04:00
2011-12-19 00:00:09 +04:00
/*
* Synchronize processes attempting to flush the in - core inode back to disk .
*/
extern void __xfs_iflock ( struct xfs_inode * ip ) ;
static inline int xfs_iflock_nowait ( struct xfs_inode * ip )
{
return ! xfs_iflags_test_and_set ( ip , XFS_IFLOCK ) ;
}
static inline void xfs_iflock ( struct xfs_inode * ip )
{
if ( ! xfs_iflock_nowait ( ip ) )
__xfs_iflock ( ip ) ;
}
static inline void xfs_ifunlock ( struct xfs_inode * ip )
{
xfs_iflags_clear ( ip , XFS_IFLOCK ) ;
2013-02-04 20:13:11 +04:00
smp_mb ( ) ;
2011-12-19 00:00:09 +04:00
wake_up_bit ( & ip - > i_flags , __XFS_IFLOCK_BIT ) ;
}
static inline int xfs_isiflocked ( struct xfs_inode * ip )
{
return xfs_iflags_test ( ip , XFS_IFLOCK ) ;
}
2005-04-17 02:20:36 +04:00
/*
* Flags for inode locking .
2007-05-08 07:50:19 +04:00
* Bit ranges : 1 < < 1 - 1 < < 16 - 1 - - iolock / ilock modes ( bitfield )
* 1 < < 16 - 1 < < 32 - 1 - - lockdep annotation ( integers )
2005-04-17 02:20:36 +04:00
*/
2007-05-08 07:50:19 +04:00
# define XFS_IOLOCK_EXCL (1<<0)
# define XFS_IOLOCK_SHARED (1<<1)
# define XFS_ILOCK_EXCL (1<<2)
# define XFS_ILOCK_SHARED (1<<3)
2005-04-17 02:20:36 +04:00
2007-05-08 07:50:19 +04:00
# define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
2008-04-22 11:34:00 +04:00
| XFS_ILOCK_EXCL | XFS_ILOCK_SHARED )
2007-05-08 07:50:19 +04:00
2009-12-15 02:14:59 +03:00
# define XFS_LOCK_FLAGS \
{ XFS_IOLOCK_EXCL , " IOLOCK_EXCL " } , \
{ XFS_IOLOCK_SHARED , " IOLOCK_SHARED " } , \
{ XFS_ILOCK_EXCL , " ILOCK_EXCL " } , \
2012-02-20 06:31:22 +04:00
{ XFS_ILOCK_SHARED , " ILOCK_SHARED " }
2009-12-15 02:14:59 +03:00
2007-05-08 07:50:19 +04:00
/*
* Flags for lockdep annotations .
*
2011-01-25 12:06:21 +03:00
* XFS_LOCK_PARENT - for directory operations that require locking a
* parent directory inode and a child entry inode . The parent gets locked
* with this flag so it gets a lockdep subclass of 1 and the child entry
* lock will have a lockdep subclass of 0.
*
* XFS_LOCK_RTBITMAP / XFS_LOCK_RTSUM - the realtime device bitmap and summary
* inodes do not participate in the normal lock order , and thus have their
* own subclasses .
2007-05-08 07:50:19 +04:00
*
2007-06-29 11:26:09 +04:00
* XFS_LOCK_INUMORDER - for locking several inodes at the some time
2007-05-08 07:50:19 +04:00
* with xfs_lock_inodes ( ) . This flag is used as the starting subclass
* and each subsequent lock acquired will increment the subclass by one .
2011-01-25 12:06:21 +03:00
* So the first lock acquired will have a lockdep subclass of 4 , the
* second lock will have a lockdep subclass of 5 , and so on . It is
2007-06-29 11:26:09 +04:00
* the responsibility of the class builder to shift this to the correct
* portion of the lock_mode lockdep mask .
2007-05-08 07:50:19 +04:00
*/
2007-06-29 11:26:09 +04:00
# define XFS_LOCK_PARENT 1
2011-01-25 12:06:21 +03:00
# define XFS_LOCK_RTBITMAP 2
# define XFS_LOCK_RTSUM 3
# define XFS_LOCK_INUMORDER 4
2007-06-29 11:26:09 +04:00
2007-05-08 07:50:19 +04:00
# define XFS_IOLOCK_SHIFT 16
2007-06-29 11:26:09 +04:00
# define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT)
2007-05-08 07:50:19 +04:00
# define XFS_ILOCK_SHIFT 24
2007-06-29 11:26:09 +04:00
# define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT)
2011-01-25 12:06:21 +03:00
# define XFS_ILOCK_RTBITMAP (XFS_LOCK_RTBITMAP << XFS_ILOCK_SHIFT)
# define XFS_ILOCK_RTSUM (XFS_LOCK_RTSUM << XFS_ILOCK_SHIFT)
2007-05-08 07:50:19 +04:00
# define XFS_IOLOCK_DEP_MASK 0x00ff0000
# define XFS_ILOCK_DEP_MASK 0xff000000
# define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK)
# define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
# define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
2005-04-17 02:20:36 +04:00
/*
* For multiple groups support : if S_ISGID bit is set in the parent
* directory , group of new file is set to that of the parent , and
* new subdirectory gets S_ISGID bit from parent .
*/
2007-08-30 11:21:12 +04:00
# define XFS_INHERIT_GID(pip) \
( ( ( pip ) - > i_mount - > m_flags & XFS_MOUNT_GRPID ) | | \
( ( pip ) - > i_d . di_mode & S_ISGID ) )
2005-04-17 02:20:36 +04:00
2013-08-12 14:49:45 +04:00
int xfs_release ( struct xfs_inode * ip ) ;
2013-09-20 19:06:12 +04:00
void xfs_inactive ( struct xfs_inode * ip ) ;
2013-08-12 14:49:45 +04:00
int xfs_lookup ( struct xfs_inode * dp , struct xfs_name * name ,
struct xfs_inode * * ipp , struct xfs_name * ci_name ) ;
int xfs_create ( struct xfs_inode * dp , struct xfs_name * name ,
umode_t mode , xfs_dev_t rdev , struct xfs_inode * * ipp ) ;
2013-12-18 04:22:40 +04:00
int xfs_create_tmpfile ( struct xfs_inode * dp , struct dentry * dentry ,
2014-04-17 02:15:30 +04:00
umode_t mode , struct xfs_inode * * ipp ) ;
2013-08-12 14:49:45 +04:00
int xfs_remove ( struct xfs_inode * dp , struct xfs_name * name ,
struct xfs_inode * ip ) ;
int xfs_link ( struct xfs_inode * tdp , struct xfs_inode * sip ,
struct xfs_name * target_name ) ;
int xfs_rename ( struct xfs_inode * src_dp , struct xfs_name * src_name ,
struct xfs_inode * src_ip , struct xfs_inode * target_dp ,
struct xfs_name * target_name ,
2014-12-24 00:51:42 +03:00
struct xfs_inode * target_ip , unsigned int flags ) ;
2013-08-12 14:49:45 +04:00
2005-04-17 02:20:36 +04:00
void xfs_ilock ( xfs_inode_t * , uint ) ;
int xfs_ilock_nowait ( xfs_inode_t * , uint ) ;
void xfs_iunlock ( xfs_inode_t * , uint ) ;
void xfs_ilock_demote ( xfs_inode_t * , uint ) ;
2008-04-22 11:34:00 +04:00
int xfs_isilocked ( xfs_inode_t * , uint ) ;
2013-12-07 00:30:09 +04:00
uint xfs_ilock_data_map_shared ( struct xfs_inode * ) ;
2013-12-18 14:14:39 +04:00
uint xfs_ilock_attr_map_shared ( struct xfs_inode * ) ;
2011-07-26 10:50:15 +04:00
int xfs_ialloc ( struct xfs_trans * , xfs_inode_t * , umode_t ,
2010-09-26 10:10:18 +04:00
xfs_nlink_t , xfs_dev_t , prid_t , int ,
2012-07-04 18:54:47 +04:00
struct xfs_buf * * , xfs_inode_t * * ) ;
2007-08-28 07:57:51 +04:00
2005-04-17 02:20:36 +04:00
uint xfs_ip2xflags ( struct xfs_inode * ) ;
2007-12-07 06:07:20 +03:00
uint xfs_dic2xflags ( struct xfs_dinode * ) ;
2005-04-17 02:20:36 +04:00
int xfs_ifree ( struct xfs_trans * , xfs_inode_t * ,
struct xfs_bmap_free * ) ;
2011-07-08 16:34:34 +04:00
int xfs_itruncate_extents ( struct xfs_trans * * , struct xfs_inode * ,
int , xfs_fsize_t ) ;
2005-04-17 02:20:36 +04:00
int xfs_iunlink ( struct xfs_trans * , xfs_inode_t * ) ;
void xfs_iext_realloc ( xfs_inode_t * , int , int ) ;
2013-08-12 14:49:35 +04:00
2010-02-06 04:37:26 +03:00
void xfs_iunpin_wait ( xfs_inode_t * ) ;
2013-08-12 14:49:35 +04:00
# define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
2012-04-23 09:58:36 +04:00
int xfs_iflush ( struct xfs_inode * , struct xfs_buf * * ) ;
2008-04-22 11:34:06 +04:00
void xfs_lock_inodes ( xfs_inode_t * * , int , uint ) ;
2008-08-13 10:18:07 +04:00
void xfs_lock_two_inodes ( xfs_inode_t * , xfs_inode_t * , uint ) ;
2005-04-17 02:20:36 +04:00
2012-04-23 09:59:02 +04:00
xfs_extlen_t xfs_get_extsz_hint ( struct xfs_inode * ip ) ;
2013-08-12 14:49:47 +04:00
int xfs_dir_ialloc ( struct xfs_trans * * , struct xfs_inode * , umode_t ,
xfs_nlink_t , xfs_dev_t , prid_t , int ,
struct xfs_inode * * , int * ) ;
int xfs_droplink ( struct xfs_trans * , struct xfs_inode * ) ;
int xfs_bumplink ( struct xfs_trans * , struct xfs_inode * ) ;
2013-08-12 14:49:45 +04:00
/* from xfs_file.c */
2015-02-02 01:53:56 +03:00
enum xfs_prealloc_flags {
XFS_PREALLOC_SET = ( 1 < < 1 ) ,
XFS_PREALLOC_CLEAR = ( 1 < < 2 ) ,
XFS_PREALLOC_SYNC = ( 1 < < 3 ) ,
XFS_PREALLOC_INVISIBLE = ( 1 < < 4 ) ,
} ;
int xfs_update_prealloc_flags ( struct xfs_inode * ,
enum xfs_prealloc_flags ) ;
2013-08-12 14:49:45 +04:00
int xfs_zero_eof ( struct xfs_inode * , xfs_off_t , xfs_fsize_t ) ;
int xfs_iozero ( struct xfs_inode * , loff_t , size_t ) ;
2008-12-03 14:20:40 +03:00
# define IHOLD(ip) \
do { \
ASSERT ( atomic_read ( & VFS_I ( ip ) - > i_count ) > 0 ) ; \
2010-10-23 19:11:40 +04:00
ihold ( VFS_I ( ip ) ) ; \
2009-12-15 02:14:59 +03:00
trace_xfs_ihold ( ip , _THIS_IP_ ) ; \
2008-12-03 14:20:40 +03:00
} while ( 0 )
# define IRELE(ip) \
do { \
2009-12-15 02:14:59 +03:00
trace_xfs_irele ( ip , _THIS_IP_ ) ; \
2008-12-03 14:20:40 +03:00
iput ( VFS_I ( ip ) ) ; \
} while ( 0 )
2005-04-17 02:20:36 +04:00
extern struct kmem_zone * xfs_inode_zone ;
2014-08-04 07:28:20 +04:00
/*
* Flags for read / write calls
*/
# define XFS_IO_ISDIRECT 0x00001 /* bypass page cache */
# define XFS_IO_INVIS 0x00002 /* don't update inode timestamps */
# define XFS_IO_FLAGS \
{ XFS_IO_ISDIRECT , " DIRECT " } , \
{ XFS_IO_INVIS , " INVIS " }
2005-04-17 02:20:36 +04:00
# endif /* __XFS_INODE_H__ */