nfsd: nfsd should drop CAP_MKNOD for non-root
[safe/jmp/linux-2.6] / fs / xfs / xfs_dinode.h
index fefd011..162e872 100644 (file)
 #ifndef __XFS_DINODE_H__
 #define        __XFS_DINODE_H__
 
-struct xfs_buf;
-struct xfs_mount;
+#define        XFS_DINODE_MAGIC                0x494e  /* 'IN' */
+#define XFS_DINODE_GOOD_VERSION(v)     (((v) == 1 || (v) == 2))
 
-#define        XFS_DINODE_VERSION_1    1
-#define        XFS_DINODE_VERSION_2    2
-#define XFS_DINODE_GOOD_VERSION(v)     \
-       (((v) == XFS_DINODE_VERSION_1 || (v) == XFS_DINODE_VERSION_2))
-#define        XFS_DINODE_MAGIC        0x494e  /* 'IN' */
-
-/*
- * Disk inode structure.
- * This is just the header; the inode is expanded to fill a variable size
- * with the last field expanding.  It is split into the core and "other"
- * because we only need the core part in the in-core inode.
- */
 typedef struct xfs_timestamp {
-       __int32_t       t_sec;          /* timestamp seconds */
-       __int32_t       t_nsec;         /* timestamp nanoseconds */
+       __be32          t_sec;          /* timestamp seconds */
+       __be32          t_nsec;         /* timestamp nanoseconds */
 } xfs_timestamp_t;
 
 /*
- * Note: Coordinate changes to this structure with the XFS_DI_* #defines
- * below and the offsets table in xfs_ialloc_log_di().
+ * On-disk inode structure.
+ *
+ * This is just the header or "dinode core", the inode is expanded to fill a
+ * variable size the leftover area split into a data and an attribute fork.
+ * The format of the data and attribute fork depends on the format of the
+ * inode as indicated by di_format and di_aformat.  To access the data and
+ * attribute use the XFS_DFORK_PTR, XFS_DFORK_DPTR, and XFS_DFORK_PTR macros
+ * below.
+ *
+ * There is a very similar struct icdinode in xfs_inode which matches the
+ * layout of the first 96 bytes of this structure, but is kept in native
+ * format instead of big endian.
  */
-typedef struct xfs_dinode_core
-{
-       __uint16_t      di_magic;       /* inode magic # = XFS_DINODE_MAGIC */
-       __uint16_t      di_mode;        /* mode and type of file */
-       __int8_t        di_version;     /* inode version */
-       __int8_t        di_format;      /* format of di_c data */
-       __uint16_t      di_onlink;      /* old number of links to file */
-       __uint32_t      di_uid;         /* owner's user id */
-       __uint32_t      di_gid;         /* owner's group id */
-       __uint32_t      di_nlink;       /* number of links to file */
-       __uint16_t      di_projid;      /* owner's project id */
-       __uint8_t       di_pad[8];      /* unused, zeroed space */
-       __uint16_t      di_flushiter;   /* incremented on flush */
+typedef struct xfs_dinode {
+       __be16          di_magic;       /* inode magic # = XFS_DINODE_MAGIC */
+       __be16          di_mode;        /* mode and type of file */
+       __u8            di_version;     /* inode version */
+       __u8            di_format;      /* format of di_c data */
+       __be16          di_onlink;      /* old number of links to file */
+       __be32          di_uid;         /* owner's user id */
+       __be32          di_gid;         /* owner's group id */
+       __be32          di_nlink;       /* number of links to file */
+       __be16          di_projid;      /* owner's project id */
+       __u8            di_pad[8];      /* unused, zeroed space */
+       __be16          di_flushiter;   /* incremented on flush */
        xfs_timestamp_t di_atime;       /* time last accessed */
        xfs_timestamp_t di_mtime;       /* time last modified */
        xfs_timestamp_t di_ctime;       /* time created/inode modified */
-       xfs_fsize_t     di_size;        /* number of bytes in file */
-       xfs_drfsbno_t   di_nblocks;     /* # of direct & btree blocks used */
-       xfs_extlen_t    di_extsize;     /* basic/minimum extent size for file */
-       xfs_extnum_t    di_nextents;    /* number of extents in data fork */
-       xfs_aextnum_t   di_anextents;   /* number of extents in attribute fork*/
-       __uint8_t       di_forkoff;     /* attr fork offs, <<3 for 64b align */
-       __int8_t        di_aformat;     /* format of attr fork's data */
-       __uint32_t      di_dmevmask;    /* DMIG event mask */
-       __uint16_t      di_dmstate;     /* DMIG state info */
-       __uint16_t      di_flags;       /* random flags, XFS_DIFLAG_... */
-       __uint32_t      di_gen;         /* generation number */
-} xfs_dinode_core_t;
+       __be64          di_size;        /* number of bytes in file */
+       __be64          di_nblocks;     /* # of direct & btree blocks used */
+       __be32          di_extsize;     /* basic/minimum extent size for file */
+       __be32          di_nextents;    /* number of extents in data fork */
+       __be16          di_anextents;   /* number of extents in attribute fork*/
+       __u8            di_forkoff;     /* attr fork offs, <<3 for 64b align */
+       __s8            di_aformat;     /* format of attr fork's data */
+       __be32          di_dmevmask;    /* DMIG event mask */
+       __be16          di_dmstate;     /* DMIG state info */
+       __be16          di_flags;       /* random flags, XFS_DIFLAG_... */
+       __be32          di_gen;         /* generation number */
+
+       /* di_next_unlinked is the only non-core field in the old dinode */
+       __be32          di_next_unlinked;/* agi unlinked list ptr */
+} __attribute__((packed)) xfs_dinode_t;
 
 #define DI_MAX_FLUSH 0xffff
 
-typedef struct xfs_dinode
-{
-       xfs_dinode_core_t       di_core;
-       /*
-        * In adding anything between the core and the union, be
-        * sure to update the macros like XFS_LITINO below and
-        * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h.
-        */
-       xfs_agino_t             di_next_unlinked;/* agi unlinked list ptr */
-       union {
-               xfs_bmdr_block_t di_bmbt;       /* btree root block */
-               xfs_bmbt_rec_32_t di_bmx[1];    /* extent list */
-               xfs_dir2_sf_t   di_dir2sf;      /* shortform directory v2 */
-               char            di_c[1];        /* local contents */
-               xfs_dev_t       di_dev;         /* device for S_IFCHR/S_IFBLK */
-               uuid_t          di_muuid;       /* mount point value */
-               char            di_symlink[1];  /* local symbolic link */
-       }               di_u;
-       union {
-               xfs_bmdr_block_t di_abmbt;      /* btree root block */
-               xfs_bmbt_rec_32_t di_abmx[1];   /* extent list */
-               xfs_attr_shortform_t di_attrsf; /* shortform attribute list */
-       }               di_a;
-} xfs_dinode_t;
-
 /*
  * The 32 bit link count in the inode theoretically maxes out at UINT_MAX.
  * Since the pathconf interface is signed, we use 2^31 - 1 instead.
@@ -107,50 +82,14 @@ typedef struct xfs_dinode
 #define        XFS_MAXLINK_1           65535U
 
 /*
- * Bit names for logging disk inodes only
- */
-#define        XFS_DI_MAGIC            0x0000001
-#define        XFS_DI_MODE             0x0000002
-#define        XFS_DI_VERSION          0x0000004
-#define        XFS_DI_FORMAT           0x0000008
-#define        XFS_DI_ONLINK           0x0000010
-#define        XFS_DI_UID              0x0000020
-#define        XFS_DI_GID              0x0000040
-#define        XFS_DI_NLINK            0x0000080
-#define        XFS_DI_PROJID           0x0000100
-#define        XFS_DI_PAD              0x0000200
-#define        XFS_DI_ATIME            0x0000400
-#define        XFS_DI_MTIME            0x0000800
-#define        XFS_DI_CTIME            0x0001000
-#define        XFS_DI_SIZE             0x0002000
-#define        XFS_DI_NBLOCKS          0x0004000
-#define        XFS_DI_EXTSIZE          0x0008000
-#define        XFS_DI_NEXTENTS         0x0010000
-#define        XFS_DI_NAEXTENTS        0x0020000
-#define        XFS_DI_FORKOFF          0x0040000
-#define        XFS_DI_AFORMAT          0x0080000
-#define        XFS_DI_DMEVMASK         0x0100000
-#define        XFS_DI_DMSTATE          0x0200000
-#define        XFS_DI_FLAGS            0x0400000
-#define        XFS_DI_GEN              0x0800000
-#define        XFS_DI_NEXT_UNLINKED    0x1000000
-#define        XFS_DI_U                0x2000000
-#define        XFS_DI_A                0x4000000
-#define        XFS_DI_NUM_BITS         27
-#define        XFS_DI_ALL_BITS         ((1 << XFS_DI_NUM_BITS) - 1)
-#define        XFS_DI_CORE_BITS        (XFS_DI_ALL_BITS & ~(XFS_DI_U|XFS_DI_A))
-
-/*
  * Values for di_format
  */
-typedef enum xfs_dinode_fmt
-{
-       XFS_DINODE_FMT_DEV,             /* CHR, BLK: di_dev */
-       XFS_DINODE_FMT_LOCAL,           /* DIR, REG: di_c */
-                                       /* LNK: di_symlink */
-       XFS_DINODE_FMT_EXTENTS,         /* DIR, REG, LNK: di_bmx */
-       XFS_DINODE_FMT_BTREE,           /* DIR, REG, LNK: di_bmbt */
-       XFS_DINODE_FMT_UUID             /* MNT: di_uuid */
+typedef enum xfs_dinode_fmt {
+       XFS_DINODE_FMT_DEV,             /* xfs_dev_t */
+       XFS_DINODE_FMT_LOCAL,           /* bulk data */
+       XFS_DINODE_FMT_EXTENTS,         /* struct xfs_bmbt_rec */
+       XFS_DINODE_FMT_BTREE,           /* struct xfs_bmdr_block */
+       XFS_DINODE_FMT_UUID             /* uuid_t */
 } xfs_dinode_fmt_t;
 
 /*
@@ -166,79 +105,63 @@ typedef enum xfs_dinode_fmt
  */
 #define        XFS_LITINO(mp)  ((mp)->m_litino)
 #define        XFS_BROOT_SIZE_ADJ      \
-       (sizeof(xfs_bmbt_block_t) - sizeof(xfs_bmdr_block_t))
+       (XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t))
 
 /*
  * Inode data & attribute fork sizes, per inode.
  */
-#define XFS_CFORK_Q(dcp)                    ((dcp)->di_forkoff != 0)
-#define        XFS_CFORK_Q_DISK(dcp)               ((dcp)->di_forkoff != 0)
-
-#define XFS_CFORK_BOFF(dcp)                 ((int)((dcp)->di_forkoff << 3))
-#define        XFS_CFORK_BOFF_DISK(dcp) \
-       ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3))
-
-#define        XFS_CFORK_DSIZE_DISK(dcp,mp) \
-       (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp))
-#define XFS_CFORK_DSIZE(dcp,mp) \
-       (XFS_CFORK_Q(dcp) ? XFS_CFORK_BOFF(dcp) : XFS_LITINO(mp))
-
-#define        XFS_CFORK_ASIZE_DISK(dcp,mp) \
-       (XFS_CFORK_Q_DISK(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF_DISK(dcp) : 0)
-#define XFS_CFORK_ASIZE(dcp,mp) \
-       (XFS_CFORK_Q(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF(dcp) : 0)
-
-#define        XFS_CFORK_SIZE_DISK(dcp,mp,w) \
-       ((w) == XFS_DATA_FORK ? \
-               XFS_CFORK_DSIZE_DISK(dcp, mp) : \
-               XFS_CFORK_ASIZE_DISK(dcp, mp))
-#define XFS_CFORK_SIZE(dcp,mp,w) \
-       ((w) == XFS_DATA_FORK ? \
-               XFS_CFORK_DSIZE(dcp, mp) : XFS_CFORK_ASIZE(dcp, mp))
+#define XFS_DFORK_Q(dip)               ((dip)->di_forkoff != 0)
+#define XFS_DFORK_BOFF(dip)            ((int)((dip)->di_forkoff << 3))
 
 #define XFS_DFORK_DSIZE(dip,mp) \
-       XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp)
-#define XFS_DFORK_DSIZE_HOST(dip,mp) \
-       XFS_CFORK_DSIZE(&(dip)->di_core, mp)
+       (XFS_DFORK_Q(dip) ? \
+               XFS_DFORK_BOFF(dip) : \
+               XFS_LITINO(mp))
 #define XFS_DFORK_ASIZE(dip,mp) \
-       XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp)
-#define XFS_DFORK_ASIZE_HOST(dip,mp) \
-       XFS_CFORK_ASIZE(&(dip)->di_core, mp)
-#define        XFS_DFORK_SIZE(dip,mp,w) \
-       XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w)
-#define        XFS_DFORK_SIZE_HOST(dip,mp,w) \
-       XFS_CFORK_SIZE(&(dip)->di_core, mp, w)
+       (XFS_DFORK_Q(dip) ? \
+               XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : \
+               0)
+#define XFS_DFORK_SIZE(dip,mp,w) \
+       ((w) == XFS_DATA_FORK ? \
+               XFS_DFORK_DSIZE(dip, mp) : \
+               XFS_DFORK_ASIZE(dip, mp))
 
-#define        XFS_DFORK_Q(dip)                    XFS_CFORK_Q_DISK(&(dip)->di_core)
-#define        XFS_DFORK_BOFF(dip)                 XFS_CFORK_BOFF_DISK(&(dip)->di_core)
-#define        XFS_DFORK_DPTR(dip)                 ((dip)->di_u.di_c)
-#define        XFS_DFORK_APTR(dip)     \
-       ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip))
-#define        XFS_DFORK_PTR(dip,w)    \
+/*
+ * Return pointers to the data or attribute forks.
+ */
+#define XFS_DFORK_DPTR(dip) \
+       ((char *)(dip) + sizeof(struct xfs_dinode))
+#define XFS_DFORK_APTR(dip)    \
+       (XFS_DFORK_DPTR(dip) + XFS_DFORK_BOFF(dip))
+#define XFS_DFORK_PTR(dip,w)   \
        ((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip))
-#define        XFS_CFORK_FORMAT(dcp,w) \
-       ((w) == XFS_DATA_FORK ? (dcp)->di_format : (dcp)->di_aformat)
-#define        XFS_CFORK_FMT_SET(dcp,w,n) \
-       ((w) == XFS_DATA_FORK ? \
-               ((dcp)->di_format = (n)) : ((dcp)->di_aformat = (n)))
-#define        XFS_DFORK_FORMAT(dip,w) XFS_CFORK_FORMAT(&(dip)->di_core, w)
 
-#define        XFS_CFORK_NEXTENTS_DISK(dcp,w) \
+#define XFS_DFORK_FORMAT(dip,w) \
        ((w) == XFS_DATA_FORK ? \
-               INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \
-               INT_GET((dcp)->di_anextents, ARCH_CONVERT))
-#define XFS_CFORK_NEXTENTS(dcp,w) \
-       ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents)
-#define        XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
-#define        XFS_DFORK_NEXTENTS_HOST(dip,w) XFS_CFORK_NEXTENTS(&(dip)->di_core, w)
-
-#define        XFS_CFORK_NEXT_SET(dcp,w,n) \
+               (dip)->di_format : \
+               (dip)->di_aformat)
+#define XFS_DFORK_NEXTENTS(dip,w) \
        ((w) == XFS_DATA_FORK ? \
-               ((dcp)->di_nextents = (n)) : ((dcp)->di_anextents = (n)))
+               be32_to_cpu((dip)->di_nextents) : \
+               be16_to_cpu((dip)->di_anextents))
 
 #define        XFS_BUF_TO_DINODE(bp)   ((xfs_dinode_t *)XFS_BUF_PTR(bp))
 
 /*
+ * For block and character special files the 32bit dev_t is stored at the
+ * beginning of the data fork.
+ */
+static inline xfs_dev_t xfs_dinode_get_rdev(struct xfs_dinode *dip)
+{
+       return be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(dip));
+}
+
+static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
+{
+       *(__be32 *)XFS_DFORK_DPTR(dip) = cpu_to_be32(rdev);
+}
+
+/*
  * Values for di_flags
  * There should be a one-to-one correspondence between these flags and the
  * XFS_XFLAG_s.
@@ -274,6 +197,12 @@ typedef enum xfs_dinode_fmt
 #define XFS_DIFLAG_NODEFRAG      (1 << XFS_DIFLAG_NODEFRAG_BIT)
 #define XFS_DIFLAG_FILESTREAM    (1 << XFS_DIFLAG_FILESTREAM_BIT)
 
+#ifdef CONFIG_XFS_RT
+#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
+#else
+#define XFS_IS_REALTIME_INODE(ip) (0)
+#endif
+
 #define XFS_DIFLAG_ANY \
        (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
         XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \