nfsd: nfsd should drop CAP_MKNOD for non-root
[safe/jmp/linux-2.6] / fs / xfs / xfs_dinode.h
index 10f9204..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 {
        __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, the offsets table in xfs_ialloc_log_di() and struct xfs_icdinode
- * in xfs_inode.h.
+ * 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 {
+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 */
@@ -69,33 +66,12 @@ typedef struct xfs_dinode_core {
        __be16          di_dmstate;     /* DMIG state info */
        __be16          di_flags;       /* random flags, XFS_DIFLAG_... */
        __be32          di_gen;         /* generation number */
-} xfs_dinode_core_t;
 
-#define DI_MAX_FLUSH 0xffff
+       /* 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;
 
-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.
-        */
-       __be32                  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 */
-               __be32          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;
+#define DI_MAX_FLUSH 0xffff
 
 /*
  * The 32 bit link count in the inode theoretically maxes out at UINT_MAX.
@@ -108,14 +84,12 @@ typedef struct xfs_dinode
 /*
  * 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;
 
 /*
@@ -136,8 +110,8 @@ typedef enum xfs_dinode_fmt
 /*
  * Inode data & attribute fork sizes, per inode.
  */
-#define XFS_DFORK_Q(dip)               ((dip)->di_core.di_forkoff != 0)
-#define XFS_DFORK_BOFF(dip)            ((int)((dip)->di_core.di_forkoff << 3))
+#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_DFORK_Q(dip) ? \
@@ -152,23 +126,42 @@ typedef enum xfs_dinode_fmt
                XFS_DFORK_DSIZE(dip, mp) : \
                XFS_DFORK_ASIZE(dip, mp))
 
-#define XFS_DFORK_DPTR(dip)                ((dip)->di_u.di_c)
+/*
+ * Return pointers to the data or attribute forks.
+ */
+#define XFS_DFORK_DPTR(dip) \
+       ((char *)(dip) + sizeof(struct xfs_dinode))
 #define XFS_DFORK_APTR(dip)    \
-       ((dip)->di_u.di_c + XFS_DFORK_BOFF(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_DFORK_FORMAT(dip,w) \
        ((w) == XFS_DATA_FORK ? \
-               (dip)->di_core.di_format : \
-               (dip)->di_core.di_aformat)
+               (dip)->di_format : \
+               (dip)->di_aformat)
 #define XFS_DFORK_NEXTENTS(dip,w) \
        ((w) == XFS_DATA_FORK ? \
-               be32_to_cpu((dip)->di_core.di_nextents) : \
-               be16_to_cpu((dip)->di_core.di_anextents))
+               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.