+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
* All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- * 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
*/
#ifndef XFS_REPAIR_INCORE_H
#define XR_E_MULT 5 /* extent is multiply referenced */
#define XR_E_INO 6 /* extent used by inodes (inode blocks) */
#define XR_E_FS_MAP 7 /* extent used by fs space/inode maps */
-#define XR_E_BAD_STATE 8
-
-/* extent states, in 64 bit word chunks */
-#define XR_E_UNKNOWN_LL 0x0000000000000000LL
-#define XR_E_FREE1_LL 0x1111111111111111LL
-#define XR_E_FREE_LL 0x2222222222222222LL
-#define XR_E_INUSE_LL 0x3333333333333333LL
-#define XR_E_INUSE_FS_LL 0x4444444444444444LL
-#define XR_E_MULT_LL 0x5555555555555555LL
-#define XR_E_INO_LL 0x6666666666666666LL
-#define XR_E_FS_MAP_LL 0x7777777777777777LL
+#define XR_E_INUSE1 8 /* used block (marked by rmap btree) */
+#define XR_E_INUSE_FS1 9 /* used by fs ag header or log (rmap btree) */
+#define XR_E_INO1 10 /* used by inodes (marked by rmap btree) */
+#define XR_E_FS_MAP1 11 /* used by fs space/inode maps (rmap btree) */
+#define XR_E_REFC 12 /* used by fs ag reference count btree */
+#define XR_E_COW 13 /* leftover cow extent */
+#define XR_E_BAD_STATE 14
/* separate state bit, OR'ed into high (4th) bit of ex_state field */
#define XR_E_WRITTEN 0x8 /* extent has been written out, can't reclaim */
-#define good_state(state) (((state) & (~XR_E_WRITTEN)) >= XR_E_UNKNOWN && \
- ((state) & (~XR_E_WRITTEN) < XF_E_BAD_STATE))
#define written(state) ((state) & XR_E_WRITTEN)
#define set_written(state) (state) &= XR_E_WRITTEN
#define XR_INO_BLKDEV 8 /* block device */
#define XR_INO_SOCK 9 /* socket */
#define XR_INO_FIFO 10 /* fifo */
-#define XR_INO_MOUNTPOINT 11 /* mountpoint */
+#define XR_INO_UQUOTA 12 /* user quota inode */
+#define XR_INO_GQUOTA 13 /* group quota inode */
+#define XR_INO_PQUOTA 14 /* project quota inode */
/* inode allocation tree */
struct nlink_ops;
typedef struct parent_list {
- __uint64_t pmask;
+ uint64_t pmask;
parent_entry_t *pentries;
#ifdef DEBUG
short cnt;
} parent_list_t;
union ino_nlink {
- __uint8_t *un8;
- __uint16_t *un16;
- __uint32_t *un32;
+ uint8_t *un8;
+ uint16_t *un16;
+ uint32_t *un32;
};
typedef struct ino_ex_data {
- __uint64_t ino_reached; /* bit == 1 if reached */
- __uint64_t ino_processed; /* reference checked bit mask */
+ uint64_t ino_reached; /* bit == 1 if reached */
+ uint64_t ino_processed; /* reference checked bit mask */
parent_list_t *parents;
union ino_nlink counted_nlinks;/* counted nlinks in P6 */
} ino_ex_data_t;
avlnode_t avl_node;
xfs_agino_t ino_startnum; /* starting inode # */
xfs_inofree_t ir_free; /* inode free bit mask */
- __uint64_t ir_sparse; /* sparse inode bitmask */
- __uint64_t ino_confirmed; /* confirmed bitmask */
- __uint64_t ino_isa_dir; /* bit == 1 if a directory */
- __uint8_t nlink_size;
+ uint64_t ir_sparse; /* sparse inode bitmask */
+ uint64_t ino_confirmed; /* confirmed bitmask */
+ uint64_t ino_isa_dir; /* bit == 1 if a directory */
+ uint64_t ino_was_rl; /* bit == 1 if reflink flag set */
+ uint64_t ino_is_rl; /* bit == 1 if reflink flag should be set */
+ uint8_t nlink_size;
union ino_nlink disk_nlinks; /* on-disk nlinks, set in P3 */
union {
ino_ex_data_t *ex_data; /* phases 6,7 */
parent_list_t *plist; /* phases 2-5 */
} ino_un;
- __uint8_t *ftypes; /* phases 3,6 */
+ uint8_t *ftypes; /* phases 3,6 */
+ pthread_mutex_t lock;
} ino_tree_node_t;
-#define INOS_PER_IREC (sizeof(__uint64_t) * NBBY)
-#define IREC_MASK(i) ((__uint64_t)1 << (i))
+#define INOS_PER_IREC (sizeof(uint64_t) * NBBY)
+#define IREC_MASK(i) ((uint64_t)1 << (i))
void add_ino_ex_data(xfs_mount_t *mp);
*/
static inline void add_inode_refchecked(struct ino_tree_node *irec, int offset)
{
+ pthread_mutex_lock(&irec->lock);
irec->ino_un.ex_data->ino_processed |= IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
}
static inline int is_inode_refchecked(struct ino_tree_node *irec, int offset)
*/
static inline void set_inode_isadir(struct ino_tree_node *irec, int offset)
{
+ pthread_mutex_lock(&irec->lock);
irec->ino_isa_dir |= IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
}
static inline void clear_inode_isadir(struct ino_tree_node *irec, int offset)
{
+ pthread_mutex_lock(&irec->lock);
irec->ino_isa_dir &= ~IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
}
static inline int inode_isadir(struct ino_tree_node *irec, int offset)
*/
static inline void set_inode_free(struct ino_tree_node *irec, int offset)
{
+ pthread_mutex_lock(&irec->lock);
set_inode_confirmed(irec, offset);
irec->ir_free |= XFS_INOBT_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
}
static inline void set_inode_used(struct ino_tree_node *irec, int offset)
{
+ pthread_mutex_lock(&irec->lock);
set_inode_confirmed(irec, offset);
irec->ir_free &= ~XFS_INOBT_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
}
static inline int is_inode_free(struct ino_tree_node *irec, int offset)
*/
static inline void set_inode_sparse(struct ino_tree_node *irec, int offset)
{
+ pthread_mutex_lock(&irec->lock);
irec->ir_sparse |= XFS_INOBT_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
}
static inline bool is_inode_sparse(struct ino_tree_node *irec, int offset)
return irec->ir_sparse & XFS_INOBT_MASK(offset);
}
+/*
+ * set/clear/test was inode marked as reflinked
+ */
+static inline void set_inode_was_rl(struct ino_tree_node *irec, int offset)
+{
+ pthread_mutex_lock(&irec->lock);
+ irec->ino_was_rl |= IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
+}
+
+static inline void clear_inode_was_rl(struct ino_tree_node *irec, int offset)
+{
+ pthread_mutex_lock(&irec->lock);
+ irec->ino_was_rl &= ~IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
+}
+
+static inline int inode_was_rl(struct ino_tree_node *irec, int offset)
+{
+ return (irec->ino_was_rl & IREC_MASK(offset)) != 0;
+}
+
+/*
+ * set/clear/test should inode be marked as reflinked
+ */
+static inline void set_inode_is_rl(struct ino_tree_node *irec, int offset)
+{
+ pthread_mutex_lock(&irec->lock);
+ irec->ino_is_rl |= IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
+}
+
+static inline void clear_inode_is_rl(struct ino_tree_node *irec, int offset)
+{
+ pthread_mutex_lock(&irec->lock);
+ irec->ino_is_rl &= ~IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
+}
+
+static inline int inode_is_rl(struct ino_tree_node *irec, int offset)
+{
+ return (irec->ino_is_rl & IREC_MASK(offset)) != 0;
+}
+
/*
* add_inode_reached() is set on inode I only if I has been reached
* by an inode P claiming to be the parent and if I is a directory,
*/
void add_inode_ref(struct ino_tree_node *irec, int offset);
void drop_inode_ref(struct ino_tree_node *irec, int offset);
-__uint32_t num_inode_references(struct ino_tree_node *irec, int offset);
+uint32_t num_inode_references(struct ino_tree_node *irec, int offset);
-void set_inode_disk_nlinks(struct ino_tree_node *irec, int offset, __uint32_t nlinks);
-__uint32_t get_inode_disk_nlinks(struct ino_tree_node *irec, int offset);
+void set_inode_disk_nlinks(struct ino_tree_node *irec, int offset, uint32_t nlinks);
+uint32_t get_inode_disk_nlinks(struct ino_tree_node *irec, int offset);
static inline int is_inode_reached(struct ino_tree_node *irec, int offset)
{
static inline void add_inode_reached(struct ino_tree_node *irec, int offset)
{
add_inode_ref(irec, offset);
+ pthread_mutex_lock(&irec->lock);
irec->ino_un.ex_data->ino_reached |= IREC_MASK(offset);
+ pthread_mutex_unlock(&irec->lock);
}
/*
static inline void
set_inode_ftype(struct ino_tree_node *irec,
int ino_offset,
- __uint8_t ftype)
+ uint8_t ftype)
{
if (irec->ftypes)
irec->ftypes[ino_offset] = ftype;
}
-static inline __uint8_t
+static inline uint8_t
get_inode_ftype(
struct ino_tree_node *irec,
int ino_offset)
xfs_fsblock_t fsbno;
xfs_fsblock_t left_fsbno;
xfs_fsblock_t right_fsbno;
- __uint64_t first_key;
- __uint64_t last_key;
+ uint64_t first_key;
+ uint64_t last_key;
/*
int level;
- __uint64_t prev_last_key;
- xfs_buf_t *bp;
+ uint64_t prev_last_key;
+ struct xfs_buf *bp;
xfs_bmbt_block_t *block;
*/
} bm_level_state_t;