summaryrefslogtreecommitdiff
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_attr.c14
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c5
-rw-r--r--fs/xfs/libxfs/xfs_bmap.h2
-rw-r--r--fs/xfs/libxfs/xfs_btree_mem.c6
-rw-r--r--fs/xfs/libxfs/xfs_dquot_buf.c13
-rw-r--r--fs/xfs/libxfs/xfs_errortag.h6
-rw-r--r--fs/xfs/libxfs/xfs_exchmaps.c1
-rw-r--r--fs/xfs/libxfs/xfs_exchmaps.h3
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c2
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.c1
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.h5
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c4
-rw-r--r--fs/xfs/libxfs/xfs_inode_util.h2
-rw-r--r--fs/xfs/libxfs/xfs_metadir.c32
-rw-r--r--fs/xfs/libxfs/xfs_metadir.h5
-rw-r--r--fs/xfs/libxfs/xfs_parent.h1
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.c16
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.h26
-rw-r--r--fs/xfs/libxfs/xfs_rmap.c13
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.c16
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.h26
-rw-r--r--fs/xfs/libxfs/xfs_rtrefcount_btree.c121
-rw-r--r--fs/xfs/libxfs/xfs_rtrefcount_btree.h5
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.c236
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.h3
-rw-r--r--fs/xfs/libxfs/xfs_sb.c40
-rw-r--r--fs/xfs/libxfs/xfs_sb.h1
-rw-r--r--fs/xfs/libxfs/xfs_symlink_remote.c8
-rw-r--r--fs/xfs/libxfs/xfs_symlink_remote.h2
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.c45
-rw-r--r--fs/xfs/libxfs/xfs_trans_space.c6
-rw-r--r--fs/xfs/libxfs/xfs_types.c7
-rw-r--r--fs/xfs/libxfs/xfs_types.h7
-rw-r--r--fs/xfs/scrub/alloc_repair.c15
-rw-r--r--fs/xfs/scrub/bmap.c11
-rw-r--r--fs/xfs/scrub/bmap_repair.c4
-rw-r--r--fs/xfs/scrub/inode_repair.c32
-rw-r--r--fs/xfs/scrub/orphanage.c2
-rw-r--r--fs/xfs/scrub/quota.c2
-rw-r--r--fs/xfs/scrub/quota_repair.c9
-rw-r--r--fs/xfs/scrub/quotacheck_repair.c54
-rw-r--r--fs/xfs/scrub/rtrefcount_repair.c3
-rw-r--r--fs/xfs/scrub/rtrmap_repair.c2
-rw-r--r--fs/xfs/scrub/xfarray.c201
-rw-r--r--fs/xfs/scrub/xfarray.h9
-rw-r--r--fs/xfs/xfs_acl.c2
-rw-r--r--fs/xfs/xfs_acl.h2
-rw-r--r--fs/xfs/xfs_aops.c13
-rw-r--r--fs/xfs/xfs_bmap_item.c2
-rw-r--r--fs/xfs/xfs_buf.c11
-rw-r--r--fs/xfs/xfs_dquot.c20
-rw-r--r--fs/xfs/xfs_dquot.h2
-rw-r--r--fs/xfs/xfs_exchmaps_item.c4
-rw-r--r--fs/xfs/xfs_exchrange.c2
-rw-r--r--fs/xfs/xfs_file.c33
-rw-r--r--fs/xfs/xfs_handle.c8
-rw-r--r--fs/xfs/xfs_inode.c24
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_ioctl.c427
-rw-r--r--fs/xfs/xfs_ioctl.h6
-rw-r--r--fs/xfs/xfs_ioctl32.c188
-rw-r--r--fs/xfs/xfs_ioend.c137
-rw-r--r--fs/xfs/xfs_ioend.h2
-rw-r--r--fs/xfs/xfs_iops.c24
-rw-r--r--fs/xfs/xfs_iops.h2
-rw-r--r--fs/xfs/xfs_itable.c2
-rw-r--r--fs/xfs/xfs_itable.h2
-rw-r--r--fs/xfs/xfs_mount.h8
-rw-r--r--fs/xfs/xfs_qm.c6
-rw-r--r--fs/xfs/xfs_rmap_item.c2
-rw-r--r--fs/xfs/xfs_rtalloc.h49
-rw-r--r--fs/xfs/xfs_super.c3
-rw-r--r--fs/xfs/xfs_symlink.c6
-rw-r--r--fs/xfs/xfs_symlink.h2
-rw-r--r--fs/xfs/xfs_sysfs.c78
-rw-r--r--fs/xfs/xfs_trace.h29
-rw-r--r--fs/xfs/xfs_trans_dquot.c6
-rw-r--r--fs/xfs/xfs_xattr.c2
-rw-r--r--fs/xfs/xfs_zone_alloc.c4
79 files changed, 1149 insertions, 985 deletions
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index b3f7b2c34ad7..c4bb59633ce8 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -59,8 +59,7 @@ STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
static int xfs_attr_node_try_addname(struct xfs_attr_intent *attr);
STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_intent *attr);
STATIC int xfs_attr_node_remove_attr(struct xfs_attr_intent *attr);
-STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
- struct xfs_da_state *state);
+STATIC int xfs_attr_node_lookup(struct xfs_da_state *state);
int
xfs_inode_hasattr(
@@ -709,7 +708,7 @@ int xfs_attr_node_removename_setup(
int error;
xfs_attr_item_init_da_state(attr);
- error = xfs_attr_node_lookup(args, attr->xattri_da_state);
+ error = xfs_attr_node_lookup(attr->xattri_da_state);
if (error != -EEXIST)
goto out;
error = 0;
@@ -985,7 +984,7 @@ xfs_attr_lookup(
}
state = xfs_da_state_alloc(args);
- error = xfs_attr_node_lookup(args, state);
+ error = xfs_attr_node_lookup(state);
xfs_da_state_free(state);
return error;
}
@@ -1014,7 +1013,7 @@ xfs_attr_add_fork(
if (xfs_inode_has_attr_fork(ip))
goto trans_cancel;
- error = xfs_bmap_add_attrfork(tp, ip, size, rsvd);
+ error = xfs_bmap_add_attrfork(tp, ip, size);
if (error)
goto trans_cancel;
@@ -1386,7 +1385,6 @@ xfs_attr_leaf_get(
/* Return EEXIST if attr is found, or ENOATTR if not. */
STATIC int
xfs_attr_node_lookup(
- struct xfs_da_args *args,
struct xfs_da_state *state)
{
int retval, error;
@@ -1417,7 +1415,7 @@ xfs_attr_node_addname_find_attr(
* to where it should go.
*/
xfs_attr_item_init_da_state(attr);
- error = xfs_attr_node_lookup(args, attr->xattri_da_state);
+ error = xfs_attr_node_lookup(attr->xattri_da_state);
switch (error) {
case -ENOATTR:
if (args->op_flags & XFS_DA_OP_REPLACE)
@@ -1588,7 +1586,7 @@ xfs_attr_node_get(
* Search to see if name exists, and get back a pointer to it.
*/
state = xfs_da_state_alloc(args);
- error = xfs_attr_node_lookup(args, state);
+ error = xfs_attr_node_lookup(state);
if (error != -EEXIST)
goto out_release;
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index d64defeda645..ae91f63455c5 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1026,8 +1026,7 @@ int /* error code */
xfs_bmap_add_attrfork(
struct xfs_trans *tp,
struct xfs_inode *ip, /* incore inode pointer */
- int size, /* space new attribute needs */
- int rsvd) /* xact may use reserved blks */
+ int size) /* space new attribute needs */
{
struct xfs_mount *mp = tp->t_mountp;
int logflags; /* logging flags */
@@ -6088,7 +6087,7 @@ xfs_bmap_validate_extent_raw(
int whichfork,
struct xfs_bmbt_irec *irec)
{
- if (!xfs_verify_fileext(mp, irec->br_startoff, irec->br_blockcount))
+ if (!xfs_verify_fileext(irec->br_startoff, irec->br_blockcount))
return __this_address;
if (rtfile && whichfork == XFS_DATA_FORK) {
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index d5f2729305fa..60f6df4ce057 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -181,7 +181,7 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
xfs_filblks_t len);
unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp);
int xfs_bmap_add_attrfork(struct xfs_trans *tp, struct xfs_inode *ip,
- int size, int rsvd);
+ int size);
void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
struct xfs_inode *ip, int whichfork);
int xfs_bmap_local_to_extents(struct xfs_trans *tp, struct xfs_inode *ip,
diff --git a/fs/xfs/libxfs/xfs_btree_mem.c b/fs/xfs/libxfs/xfs_btree_mem.c
index 1d83a4251cee..3d5c7a014d4f 100644
--- a/fs/xfs/libxfs/xfs_btree_mem.c
+++ b/fs/xfs/libxfs/xfs_btree_mem.c
@@ -73,9 +73,7 @@ xfbtree_destroy(
/* Compute the number of bytes available for records. */
static inline unsigned int
-xfbtree_rec_bytes(
- struct xfs_mount *mp,
- const struct xfs_btree_ops *ops)
+xfbtree_rec_bytes(void)
{
return XMBUF_BLOCKSIZE - XFS_BTREE_LBLOCK_CRC_LEN;
}
@@ -118,7 +116,7 @@ xfbtree_init(
const struct xfs_btree_ops *ops)
{
unsigned long long owner = xfbt->owner;
- unsigned int blocklen = xfbtree_rec_bytes(mp, ops);
+ unsigned int blocklen = xfbtree_rec_bytes();
unsigned int keyptr_len;
int error;
diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c
index 77954d1d924c..6c8a9afdfb1c 100644
--- a/fs/xfs/libxfs/xfs_dquot_buf.c
+++ b/fs/xfs/libxfs/xfs_dquot_buf.c
@@ -454,19 +454,8 @@ xfs_dqinode_metadir_link(
.path = xfs_dqinode_path(type),
.ip = ip,
};
- int error;
- error = xfs_metadir_start_link(&upd);
- if (error)
- return error;
-
- error = xfs_metadir_link(&upd);
- if (error)
- return error;
-
- xfs_trans_log_inode(upd.tp, upd.ip, XFS_ILOG_CORE);
-
- return xfs_metadir_commit(&upd);
+ return xfs_metadir_link_file(&upd);
}
#endif /* __KERNEL__ */
diff --git a/fs/xfs/libxfs/xfs_errortag.h b/fs/xfs/libxfs/xfs_errortag.h
index f0c83f1f0b3b..d14aa289699f 100644
--- a/fs/xfs/libxfs/xfs_errortag.h
+++ b/fs/xfs/libxfs/xfs_errortag.h
@@ -75,7 +75,8 @@
#define XFS_ERRTAG_METAFILE_RESV_CRITICAL 45
#define XFS_ERRTAG_FORCE_ZERO_RANGE 46
#define XFS_ERRTAG_ZONE_RESET 47
-#define XFS_ERRTAG_MAX 48
+#define XFS_ERRTAG_BOUNCE_REREAD 48
+#define XFS_ERRTAG_MAX 49
/*
* Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -137,7 +138,8 @@ XFS_ERRTAG(WRITE_DELAY_MS, write_delay_ms, 3000) \
XFS_ERRTAG(EXCHMAPS_FINISH_ONE, exchmaps_finish_one, 1) \
XFS_ERRTAG(METAFILE_RESV_CRITICAL, metafile_resv_crit, 4) \
XFS_ERRTAG(FORCE_ZERO_RANGE, force_zero_range, 4) \
-XFS_ERRTAG(ZONE_RESET, zone_reset, 1)
+XFS_ERRTAG(ZONE_RESET, zone_reset, 1) \
+XFS_ERRTAG(BOUNCE_REREAD, bounce_reread, XFS_RANDOM_DEFAULT)
#endif /* XFS_ERRTAG */
#endif /* __XFS_ERRORTAG_H_ */
diff --git a/fs/xfs/libxfs/xfs_exchmaps.c b/fs/xfs/libxfs/xfs_exchmaps.c
index 6a66b6075e0a..ccb97da3765f 100644
--- a/fs/xfs/libxfs/xfs_exchmaps.c
+++ b/fs/xfs/libxfs/xfs_exchmaps.c
@@ -135,7 +135,6 @@ xmi_has_postop_work(const struct xfs_exchmaps_intent *xmi)
/* Check all mappings to make sure we can actually exchange them. */
int
xfs_exchmaps_check_forks(
- struct xfs_mount *mp,
const struct xfs_exchmaps_req *req)
{
struct xfs_ifork *ifp1, *ifp2;
diff --git a/fs/xfs/libxfs/xfs_exchmaps.h b/fs/xfs/libxfs/xfs_exchmaps.h
index fa822dff202a..055b8dbabd5b 100644
--- a/fs/xfs/libxfs/xfs_exchmaps.h
+++ b/fs/xfs/libxfs/xfs_exchmaps.h
@@ -115,8 +115,7 @@ void xfs_exchmaps_upgrade_extent_counts(struct xfs_trans *tp,
int xfs_exchmaps_finish_one(struct xfs_trans *tp,
struct xfs_exchmaps_intent *xmi);
-int xfs_exchmaps_check_forks(struct xfs_mount *mp,
- const struct xfs_exchmaps_req *req);
+int xfs_exchmaps_check_forks(const struct xfs_exchmaps_req *req);
void xfs_exchange_mappings(struct xfs_trans *tp,
const struct xfs_exchmaps_req *req);
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 58dac4d505ba..19b513b11692 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -615,7 +615,7 @@ xfs_inobt_insert_sprec(
trace_xfs_irec_merge_post(pag, nrec);
- error = xfs_inobt_rec_check_count(mp, nrec);
+ error = xfs_inobt_rec_check_count(nrec);
if (error)
goto error;
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index 1376e8630449..1f0bace2f144 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -687,7 +687,6 @@ xfs_inobt_irec_to_allocmask(
*/
int
xfs_inobt_rec_check_count(
- struct xfs_mount *mp,
struct xfs_inobt_rec_incore *rec)
{
int inocount = 0;
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h
index 300edf5bc009..e04c63c66f39 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.h
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.h
@@ -57,10 +57,9 @@ unsigned int xfs_inobt_maxrecs(struct xfs_mount *mp, unsigned int blocklen,
uint64_t xfs_inobt_irec_to_allocmask(const struct xfs_inobt_rec_incore *irec);
#if defined(DEBUG) || defined(XFS_WARN)
-int xfs_inobt_rec_check_count(struct xfs_mount *,
- struct xfs_inobt_rec_incore *);
+int xfs_inobt_rec_check_count(struct xfs_inobt_rec_incore *);
#else
-#define xfs_inobt_rec_check_count(mp, rec) 0
+#define xfs_inobt_rec_check_count(rec) 0
#endif /* DEBUG */
int xfs_finobt_calc_reserves(struct xfs_perag *perag, struct xfs_trans *tp,
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 606a36526ce2..486fe7ab8b61 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -683,9 +683,7 @@ xfs_ifork_verify_local_data(
break;
}
case S_IFLNK: {
- struct xfs_ifork *ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
-
- fa = xfs_symlink_shortform_verify(ifp->if_data, ifp->if_bytes);
+ fa = xfs_symlink_shortform_verify(ip);
break;
}
default:
diff --git a/fs/xfs/libxfs/xfs_inode_util.h b/fs/xfs/libxfs/xfs_inode_util.h
index 060242998a23..e9eac35159c3 100644
--- a/fs/xfs/libxfs/xfs_inode_util.h
+++ b/fs/xfs/libxfs/xfs_inode_util.h
@@ -27,7 +27,7 @@ prid_t xfs_get_initial_prid(struct xfs_inode *dp);
* idmap to NULL. To create a tree root, set pip to NULL.
*/
struct xfs_icreate_args {
- struct mnt_idmap *idmap;
+ const struct mnt_idmap *idmap;
struct xfs_inode *pip; /* parent inode or null */
dev_t rdev;
umode_t mode;
diff --git a/fs/xfs/libxfs/xfs_metadir.c b/fs/xfs/libxfs/xfs_metadir.c
index 7c6b086b73db..79b37cb27273 100644
--- a/fs/xfs/libxfs/xfs_metadir.c
+++ b/fs/xfs/libxfs/xfs_metadir.c
@@ -163,7 +163,7 @@ xfs_metadir_teardown(
trace_xfs_metadir_teardown(upd, error);
if (upd->ppargs) {
- xfs_parent_finish(upd->dp->i_mount, upd->ppargs);
+ xfs_parent_finish(upd->ppargs);
upd->ppargs = NULL;
}
@@ -317,7 +317,7 @@ xfs_metadir_create(
* Begin the process of linking a metadata file by allocating transactions
* and locking whatever resources we're going to need.
*/
-int
+static int
xfs_metadir_start_link(
struct xfs_metadir_update *upd)
{
@@ -364,7 +364,7 @@ out_teardown:
* The path (up to the final component) must already exist, but the final
* component must not already exist.
*/
-int
+static int
xfs_metadir_link(
struct xfs_metadir_update *upd)
{
@@ -409,7 +409,7 @@ xfs_metadir_link(
#endif /* ! __KERNEL__ */
/* Commit a metadir update and unlock/drop all resources. */
-int
+static int
xfs_metadir_commit(
struct xfs_metadir_update *upd)
{
@@ -499,3 +499,27 @@ xfs_metadir_mkdir(
return xfs_metadir_create_file(&upd, S_IFDIR, NULL, NULL, ipp);
}
+
+#ifndef __KERNEL__
+/* Link a metadata file into a metadata directory. */
+int
+xfs_metadir_link_file(
+ struct xfs_metadir_update *upd)
+{
+ int error;
+
+ error = xfs_metadir_start_link(upd);
+ if (error)
+ return error;
+
+ error = xfs_metadir_link(upd);
+ if (error) {
+ xfs_metadir_cancel(upd, error);
+ return error;
+ }
+
+ xfs_trans_log_inode(upd->tp, upd->ip, XFS_ILOG_CORE);
+
+ return xfs_metadir_commit(upd);
+}
+#endif /* ! __KERNEL__ */
diff --git a/fs/xfs/libxfs/xfs_metadir.h b/fs/xfs/libxfs/xfs_metadir.h
index e434b9d1c932..b64f9fc5ca78 100644
--- a/fs/xfs/libxfs/xfs_metadir.h
+++ b/fs/xfs/libxfs/xfs_metadir.h
@@ -38,10 +38,7 @@ int xfs_metadir_create_file(struct xfs_metadir_update *upd, umode_t mode,
xfs_metadir_createfn create, void *priv,
struct xfs_inode **ipp);
-int xfs_metadir_start_link(struct xfs_metadir_update *upd);
-int xfs_metadir_link(struct xfs_metadir_update *upd);
-
-int xfs_metadir_commit(struct xfs_metadir_update *upd);
+int xfs_metadir_link_file(struct xfs_metadir_update *upd);
int xfs_metadir_mkdir(struct xfs_inode *dp, const char *path,
struct xfs_inode **ipp);
diff --git a/fs/xfs/libxfs/xfs_parent.h b/fs/xfs/libxfs/xfs_parent.h
index 8eb4de9c5f1a..1dd3968a78b1 100644
--- a/fs/xfs/libxfs/xfs_parent.h
+++ b/fs/xfs/libxfs/xfs_parent.h
@@ -72,7 +72,6 @@ xfs_parent_start(
/* Finish a parent pointer update by freeing the context object. */
static inline void
xfs_parent_finish(
- struct xfs_mount *mp,
struct xfs_parent_args *ppargs)
{
if (ppargs)
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c
index 7e5f92c1ac56..2c6148a97994 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.c
+++ b/fs/xfs/libxfs/xfs_refcount_btree.c
@@ -127,7 +127,7 @@ xfs_refcountbt_get_maxrecs(
return cur->bc_mp->m_refc_mxr[level != 0];
}
-STATIC void
+void
xfs_refcountbt_init_key_from_rec(
union xfs_btree_key *key,
const union xfs_btree_rec *rec)
@@ -135,7 +135,7 @@ xfs_refcountbt_init_key_from_rec(
key->refc.rc_startblock = rec->refc.rc_startblock;
}
-STATIC void
+void
xfs_refcountbt_init_high_key_from_rec(
union xfs_btree_key *key,
const union xfs_btree_rec *rec)
@@ -147,7 +147,7 @@ xfs_refcountbt_init_high_key_from_rec(
key->refc.rc_startblock = cpu_to_be32(x);
}
-STATIC void
+void
xfs_refcountbt_init_rec_from_cur(
struct xfs_btree_cur *cur,
union xfs_btree_rec *rec)
@@ -174,7 +174,7 @@ xfs_refcountbt_init_ptr_from_cur(
ptr->s = agf->agf_refcount_root;
}
-STATIC int
+int
xfs_refcountbt_cmp_key_with_cur(
struct xfs_btree_cur *cur,
const union xfs_btree_key *key)
@@ -188,7 +188,7 @@ xfs_refcountbt_cmp_key_with_cur(
return cmp_int(be32_to_cpu(kp->rc_startblock), start);
}
-STATIC int
+int
xfs_refcountbt_cmp_two_keys(
struct xfs_btree_cur *cur,
const union xfs_btree_key *k1,
@@ -283,7 +283,7 @@ const struct xfs_buf_ops xfs_refcountbt_buf_ops = {
.verify_struct = xfs_refcountbt_verify,
};
-STATIC int
+int
xfs_refcountbt_keys_inorder(
struct xfs_btree_cur *cur,
const union xfs_btree_key *k1,
@@ -293,7 +293,7 @@ xfs_refcountbt_keys_inorder(
be32_to_cpu(k2->refc.rc_startblock);
}
-STATIC int
+int
xfs_refcountbt_recs_inorder(
struct xfs_btree_cur *cur,
const union xfs_btree_rec *r1,
@@ -304,7 +304,7 @@ xfs_refcountbt_recs_inorder(
be32_to_cpu(r2->refc.rc_startblock);
}
-STATIC enum xbtree_key_contig
+enum xbtree_key_contig
xfs_refcountbt_keys_contiguous(
struct xfs_btree_cur *cur,
const union xfs_btree_key *key1,
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h
index beb93bef6a81..40eedfae6846 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.h
+++ b/fs/xfs/libxfs/xfs_refcount_btree.h
@@ -15,6 +15,8 @@ struct xfs_btree_cur;
struct xfs_mount;
struct xfs_perag;
struct xbtree_afakeroot;
+union xfs_btree_key;
+union xfs_btree_rec;
/*
* Btree block header size
@@ -69,4 +71,28 @@ unsigned int xfs_refcountbt_maxlevels_ondisk(void);
int __init xfs_refcountbt_init_cur_cache(void);
void xfs_refcountbt_destroy_cur_cache(void);
+/*
+ * Key and record btree ops. The refcount on-disk key/record format is
+ * identical for the AG refcount btree and the realtime refcount btree, so
+ * these are shared by both.
+ */
+void xfs_refcountbt_init_key_from_rec(union xfs_btree_key *key,
+ const union xfs_btree_rec *rec);
+void xfs_refcountbt_init_high_key_from_rec(union xfs_btree_key *key,
+ const union xfs_btree_rec *rec);
+void xfs_refcountbt_init_rec_from_cur(struct xfs_btree_cur *cur,
+ union xfs_btree_rec *rec);
+int xfs_refcountbt_cmp_key_with_cur(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *key);
+int xfs_refcountbt_cmp_two_keys(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *k1, const union xfs_btree_key *k2,
+ const union xfs_btree_key *mask);
+int xfs_refcountbt_keys_inorder(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *k1, const union xfs_btree_key *k2);
+int xfs_refcountbt_recs_inorder(struct xfs_btree_cur *cur,
+ const union xfs_btree_rec *r1, const union xfs_btree_rec *r2);
+enum xbtree_key_contig xfs_refcountbt_keys_contiguous(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *key1, const union xfs_btree_key *key2,
+ const union xfs_btree_key *mask);
+
#endif /* __XFS_REFCOUNT_BTREE_H__ */
diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
index 34d218de21a9..14aef87837a9 100644
--- a/fs/xfs/libxfs/xfs_rmap.c
+++ b/fs/xfs/libxfs/xfs_rmap.c
@@ -260,7 +260,7 @@ xfs_rmap_check_irec(
/* Check for a valid fork offset, if applicable. */
if (is_inode && !is_bmbt &&
- !xfs_verify_fileext(mp, irec->rm_offset, irec->rm_blockcount))
+ !xfs_verify_fileext(irec->rm_offset, irec->rm_blockcount))
return __this_address;
return NULL;
@@ -310,7 +310,7 @@ xfs_rtrmap_check_inode_irec(
return __this_address;
if (!xfs_verify_rgbext(rtg, irec->rm_startblock, irec->rm_blockcount))
return __this_address;
- if (!xfs_verify_fileext(mp, irec->rm_offset, irec->rm_blockcount))
+ if (!xfs_verify_fileext(irec->rm_offset, irec->rm_blockcount))
return __this_address;
return NULL;
}
@@ -904,7 +904,6 @@ xfs_rmap_hook_enable(void)
/* Call downstream hooks for a reverse mapping update. */
static inline void
xfs_rmap_update_hook(
- struct xfs_trans *tp,
struct xfs_group *xg,
enum xfs_rmap_intent_type op,
xfs_agblock_t startblock,
@@ -952,7 +951,7 @@ xfs_rmap_hook_setup(
xfs_hook_setup(&hook->rmap_hook, mod_fn);
}
#else
-# define xfs_rmap_update_hook(t, p, o, s, b, u, oi) do { } while (0)
+# define xfs_rmap_update_hook(p, o, s, b, u, oi) do { } while (0)
#endif /* CONFIG_XFS_LIVE_HOOKS */
/*
@@ -975,7 +974,7 @@ xfs_rmap_free(
return 0;
cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
- xfs_rmap_update_hook(tp, pag_group(pag), XFS_RMAP_UNMAP, bno, len,
+ xfs_rmap_update_hook(pag_group(pag), XFS_RMAP_UNMAP, bno, len,
false, oinfo);
error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
@@ -1220,7 +1219,7 @@ xfs_rmap_alloc(
return 0;
cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
- xfs_rmap_update_hook(tp, pag_group(pag), XFS_RMAP_MAP, bno, len, false,
+ xfs_rmap_update_hook(pag_group(pag), XFS_RMAP_MAP, bno, len, false,
oinfo);
error = xfs_rmap_map(cur, bno, len, false, oinfo);
@@ -2721,7 +2720,7 @@ xfs_rmap_finish_one(
if (error)
return error;
- xfs_rmap_update_hook(tp, ri->ri_group, ri->ri_type, bno,
+ xfs_rmap_update_hook(ri->ri_group, ri->ri_type, bno,
ri->ri_bmap.br_blockcount, unwritten, &oinfo);
return 0;
}
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index 10b3272238eb..5b283a5ddd13 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -170,7 +170,7 @@ static inline __be64 ondisk_rec_offset_to_key(const union xfs_btree_rec *rec)
return rec->rmap.rm_offset & ~cpu_to_be64(XFS_RMAP_OFF_UNWRITTEN);
}
-STATIC void
+void
xfs_rmapbt_init_key_from_rec(
union xfs_btree_key *key,
const union xfs_btree_rec *rec)
@@ -187,7 +187,7 @@ xfs_rmapbt_init_key_from_rec(
* the startblock for all records, and if the record is for a data/attr
* fork mapping, we add blockcount-1 to the offset too.
*/
-STATIC void
+void
xfs_rmapbt_init_high_key_from_rec(
union xfs_btree_key *key,
const union xfs_btree_rec *rec)
@@ -209,7 +209,7 @@ xfs_rmapbt_init_high_key_from_rec(
key->rmap.rm_offset = cpu_to_be64(off);
}
-STATIC void
+void
xfs_rmapbt_init_rec_from_cur(
struct xfs_btree_cur *cur,
union xfs_btree_rec *rec)
@@ -243,7 +243,7 @@ static inline uint64_t offset_keymask(uint64_t offset)
return offset & ~XFS_RMAP_OFF_UNWRITTEN;
}
-STATIC int
+int
xfs_rmapbt_cmp_key_with_cur(
struct xfs_btree_cur *cur,
const union xfs_btree_key *key)
@@ -257,7 +257,7 @@ xfs_rmapbt_cmp_key_with_cur(
offset_keymask(xfs_rmap_irec_offset_pack(rec)));
}
-STATIC int
+int
xfs_rmapbt_cmp_two_keys(
struct xfs_btree_cur *cur,
const union xfs_btree_key *k1,
@@ -390,7 +390,7 @@ const struct xfs_buf_ops xfs_rmapbt_buf_ops = {
.verify_struct = xfs_rmapbt_verify,
};
-STATIC int
+int
xfs_rmapbt_keys_inorder(
struct xfs_btree_cur *cur,
const union xfs_btree_key *k1,
@@ -420,7 +420,7 @@ xfs_rmapbt_keys_inorder(
return 0;
}
-STATIC int
+int
xfs_rmapbt_recs_inorder(
struct xfs_btree_cur *cur,
const union xfs_btree_rec *r1,
@@ -450,7 +450,7 @@ xfs_rmapbt_recs_inorder(
return 0;
}
-STATIC enum xbtree_key_contig
+enum xbtree_key_contig
xfs_rmapbt_keys_contiguous(
struct xfs_btree_cur *cur,
const union xfs_btree_key *key1,
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h
index 119b1567cd0e..7071dac745e1 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.h
+++ b/fs/xfs/libxfs/xfs_rmap_btree.h
@@ -11,6 +11,8 @@ struct xfs_btree_cur;
struct xfs_mount;
struct xbtree_afakeroot;
struct xfbtree;
+union xfs_btree_key;
+union xfs_btree_rec;
/* rmaps only exist on crc enabled filesystems */
#define XFS_RMAP_BLOCK_LEN XFS_BTREE_SBLOCK_CRC_LEN
@@ -69,4 +71,28 @@ struct xfs_btree_cur *xfs_rmapbt_mem_cursor(struct xfs_perag *pag,
int xfs_rmapbt_mem_init(struct xfs_mount *mp, struct xfbtree *xfbtree,
struct xfs_buftarg *btp, xfs_agnumber_t agno);
+/*
+ * Key and record btree ops. The rmap on-disk key/record format is identical
+ * for the AG rmap btree and the realtime rmap btree, so these are shared by
+ * both.
+ */
+void xfs_rmapbt_init_key_from_rec(union xfs_btree_key *key,
+ const union xfs_btree_rec *rec);
+void xfs_rmapbt_init_high_key_from_rec(union xfs_btree_key *key,
+ const union xfs_btree_rec *rec);
+void xfs_rmapbt_init_rec_from_cur(struct xfs_btree_cur *cur,
+ union xfs_btree_rec *rec);
+int xfs_rmapbt_cmp_key_with_cur(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *key);
+int xfs_rmapbt_cmp_two_keys(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *k1, const union xfs_btree_key *k2,
+ const union xfs_btree_key *mask);
+int xfs_rmapbt_keys_inorder(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *k1, const union xfs_btree_key *k2);
+int xfs_rmapbt_recs_inorder(struct xfs_btree_cur *cur,
+ const union xfs_btree_rec *r1, const union xfs_btree_rec *r2);
+enum xbtree_key_contig xfs_rmapbt_keys_contiguous(struct xfs_btree_cur *cur,
+ const union xfs_btree_key *key1, const union xfs_btree_key *key2,
+ const union xfs_btree_key *mask);
+
#endif /* __XFS_RMAP_BTREE_H__ */
diff --git a/fs/xfs/libxfs/xfs_rtrefcount_btree.c b/fs/xfs/libxfs/xfs_rtrefcount_btree.c
index dcc89b8e149b..697f5e622685 100644
--- a/fs/xfs/libxfs/xfs_rtrefcount_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrefcount_btree.c
@@ -20,6 +20,7 @@
#include "xfs_btree_staging.h"
#include "xfs_rtrefcount_btree.h"
#include "xfs_refcount.h"
+#include "xfs_refcount_btree.h"
#include "xfs_trace.h"
#include "xfs_cksum.h"
#include "xfs_error.h"
@@ -114,41 +115,6 @@ xfs_rtrefcountbt_get_dmaxrecs(
}
STATIC void
-xfs_rtrefcountbt_init_key_from_rec(
- union xfs_btree_key *key,
- const union xfs_btree_rec *rec)
-{
- key->refc.rc_startblock = rec->refc.rc_startblock;
-}
-
-STATIC void
-xfs_rtrefcountbt_init_high_key_from_rec(
- union xfs_btree_key *key,
- const union xfs_btree_rec *rec)
-{
- __u32 x;
-
- x = be32_to_cpu(rec->refc.rc_startblock);
- x += be32_to_cpu(rec->refc.rc_blockcount) - 1;
- key->refc.rc_startblock = cpu_to_be32(x);
-}
-
-STATIC void
-xfs_rtrefcountbt_init_rec_from_cur(
- struct xfs_btree_cur *cur,
- union xfs_btree_rec *rec)
-{
- const struct xfs_refcount_irec *irec = &cur->bc_rec.rc;
- uint32_t start;
-
- start = xfs_refcount_encode_startblock(irec->rc_startblock,
- irec->rc_domain);
- rec->refc.rc_startblock = cpu_to_be32(start);
- rec->refc.rc_blockcount = cpu_to_be32(cur->bc_rec.rc.rc_blockcount);
- rec->refc.rc_refcount = cpu_to_be32(cur->bc_rec.rc.rc_refcount);
-}
-
-STATIC void
xfs_rtrefcountbt_init_ptr_from_cur(
struct xfs_btree_cur *cur,
union xfs_btree_ptr *ptr)
@@ -156,33 +122,6 @@ xfs_rtrefcountbt_init_ptr_from_cur(
ptr->l = 0;
}
-STATIC int
-xfs_rtrefcountbt_cmp_key_with_cur(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *key)
-{
- const struct xfs_refcount_key *kp = &key->refc;
- const struct xfs_refcount_irec *irec = &cur->bc_rec.rc;
- uint32_t start;
-
- start = xfs_refcount_encode_startblock(irec->rc_startblock,
- irec->rc_domain);
- return cmp_int(be32_to_cpu(kp->rc_startblock), start);
-}
-
-STATIC int
-xfs_rtrefcountbt_cmp_two_keys(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *k1,
- const union xfs_btree_key *k2,
- const union xfs_btree_key *mask)
-{
- ASSERT(!mask || mask->refc.rc_startblock);
-
- return cmp_int(be32_to_cpu(k1->refc.rc_startblock),
- be32_to_cpu(k2->refc.rc_startblock));
-}
-
static xfs_failaddr_t
xfs_rtrefcountbt_verify(
struct xfs_buf *bp)
@@ -249,40 +188,6 @@ const struct xfs_buf_ops xfs_rtrefcountbt_buf_ops = {
.verify_struct = xfs_rtrefcountbt_verify,
};
-STATIC int
-xfs_rtrefcountbt_keys_inorder(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *k1,
- const union xfs_btree_key *k2)
-{
- return be32_to_cpu(k1->refc.rc_startblock) <
- be32_to_cpu(k2->refc.rc_startblock);
-}
-
-STATIC int
-xfs_rtrefcountbt_recs_inorder(
- struct xfs_btree_cur *cur,
- const union xfs_btree_rec *r1,
- const union xfs_btree_rec *r2)
-{
- return be32_to_cpu(r1->refc.rc_startblock) +
- be32_to_cpu(r1->refc.rc_blockcount) <=
- be32_to_cpu(r2->refc.rc_startblock);
-}
-
-STATIC enum xbtree_key_contig
-xfs_rtrefcountbt_keys_contiguous(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *key1,
- const union xfs_btree_key *key2,
- const union xfs_btree_key *mask)
-{
- ASSERT(!mask || mask->refc.rc_startblock);
-
- return xbtree_key_contig(be32_to_cpu(key1->refc.rc_startblock),
- be32_to_cpu(key2->refc.rc_startblock));
-}
-
static inline void
xfs_rtrefcountbt_move_ptrs(
struct xfs_mount *mp,
@@ -311,7 +216,7 @@ xfs_rtrefcountbt_broot_realloc(
unsigned int old_size = ifp->if_broot_bytes;
const unsigned int level = cur->bc_nlevels - 1;
- new_size = xfs_rtrefcount_broot_space_calc(mp, level, new_numrecs);
+ new_size = xfs_rtrefcount_broot_space_calc(level, new_numrecs);
/* Handle the nop case quietly. */
if (new_size == old_size)
@@ -383,16 +288,16 @@ const struct xfs_btree_ops xfs_rtrefcountbt_ops = {
.get_minrecs = xfs_rtrefcountbt_get_minrecs,
.get_maxrecs = xfs_rtrefcountbt_get_maxrecs,
.get_dmaxrecs = xfs_rtrefcountbt_get_dmaxrecs,
- .init_key_from_rec = xfs_rtrefcountbt_init_key_from_rec,
- .init_high_key_from_rec = xfs_rtrefcountbt_init_high_key_from_rec,
- .init_rec_from_cur = xfs_rtrefcountbt_init_rec_from_cur,
+ .init_key_from_rec = xfs_refcountbt_init_key_from_rec,
+ .init_high_key_from_rec = xfs_refcountbt_init_high_key_from_rec,
+ .init_rec_from_cur = xfs_refcountbt_init_rec_from_cur,
.init_ptr_from_cur = xfs_rtrefcountbt_init_ptr_from_cur,
- .cmp_key_with_cur = xfs_rtrefcountbt_cmp_key_with_cur,
+ .cmp_key_with_cur = xfs_refcountbt_cmp_key_with_cur,
.buf_ops = &xfs_rtrefcountbt_buf_ops,
- .cmp_two_keys = xfs_rtrefcountbt_cmp_two_keys,
- .keys_inorder = xfs_rtrefcountbt_keys_inorder,
- .recs_inorder = xfs_rtrefcountbt_recs_inorder,
- .keys_contiguous = xfs_rtrefcountbt_keys_contiguous,
+ .cmp_two_keys = xfs_refcountbt_cmp_two_keys,
+ .keys_inorder = xfs_refcountbt_keys_inorder,
+ .recs_inorder = xfs_refcountbt_recs_inorder,
+ .keys_contiguous = xfs_refcountbt_keys_contiguous,
.broot_realloc = xfs_rtrefcountbt_broot_realloc,
};
@@ -602,7 +507,7 @@ xfs_rtrefcountbt_from_disk(
unsigned int maxrecs;
unsigned int rblocklen;
- rblocklen = xfs_rtrefcount_broot_space(mp, dblock);
+ rblocklen = xfs_rtrefcount_broot_space(dblock);
xfs_btree_init_block(mp, rblock, &xfs_rtrefcountbt_ops, 0, 0,
I_INO(ip));
@@ -661,7 +566,7 @@ xfs_iformat_rtrefcount(
}
broot = xfs_broot_alloc(xfs_ifork_ptr(ip, XFS_DATA_FORK),
- xfs_rtrefcount_broot_space_calc(mp, level, numrecs));
+ xfs_rtrefcount_broot_space_calc(level, numrecs));
if (broot)
xfs_rtrefcountbt_from_disk(ip, dfp, dsize, broot);
return 0;
@@ -751,7 +656,7 @@ xfs_rtrefcountbt_create(
/* Initialize the empty incore btree root. */
broot = xfs_broot_realloc(ifp,
- xfs_rtrefcount_broot_space_calc(mp, 0, 0));
+ xfs_rtrefcount_broot_space_calc(0, 0));
if (broot)
xfs_btree_init_block(mp, broot, &xfs_rtrefcountbt_ops, 0, 0,
I_INO(ip));
diff --git a/fs/xfs/libxfs/xfs_rtrefcount_btree.h b/fs/xfs/libxfs/xfs_rtrefcount_btree.h
index a99b7a8aec86..9ab6ecf90ba5 100644
--- a/fs/xfs/libxfs/xfs_rtrefcount_btree.h
+++ b/fs/xfs/libxfs/xfs_rtrefcount_btree.h
@@ -129,7 +129,6 @@ xfs_rtrefcount_broot_ptr_addr(
*/
static inline size_t
xfs_rtrefcount_broot_space_calc(
- struct xfs_mount *mp,
unsigned int level,
unsigned int nrecs)
{
@@ -146,9 +145,9 @@ xfs_rtrefcount_broot_space_calc(
* btree root block.
*/
static inline size_t
-xfs_rtrefcount_broot_space(struct xfs_mount *mp, struct xfs_rtrefcount_root *bb)
+xfs_rtrefcount_broot_space(struct xfs_rtrefcount_root *bb)
{
- return xfs_rtrefcount_broot_space_calc(mp, be16_to_cpu(bb->bb_level),
+ return xfs_rtrefcount_broot_space_calc(be16_to_cpu(bb->bb_level),
be16_to_cpu(bb->bb_numrecs));
}
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.c b/fs/xfs/libxfs/xfs_rtrmap_btree.c
index a15e460a1ec7..2f00d0698ae1 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c
@@ -20,6 +20,7 @@
#include "xfs_btree_staging.h"
#include "xfs_metafile.h"
#include "xfs_rmap.h"
+#include "xfs_rmap_btree.h"
#include "xfs_rtrmap_btree.h"
#include "xfs_trace.h"
#include "xfs_cksum.h"
@@ -113,60 +114,6 @@ xfs_rtrmapbt_get_dmaxrecs(
return xfs_rtrmapbt_droot_maxrecs(cur->bc_ino.forksize, level == 0);
}
-/*
- * Convert the ondisk record's offset field into the ondisk key's offset field.
- * Fork and bmbt are significant parts of the rmap record key, but written
- * status is merely a record attribute.
- */
-static inline __be64 ondisk_rec_offset_to_key(const union xfs_btree_rec *rec)
-{
- return rec->rmap.rm_offset & ~cpu_to_be64(XFS_RMAP_OFF_UNWRITTEN);
-}
-
-STATIC void
-xfs_rtrmapbt_init_key_from_rec(
- union xfs_btree_key *key,
- const union xfs_btree_rec *rec)
-{
- key->rmap.rm_startblock = rec->rmap.rm_startblock;
- key->rmap.rm_owner = rec->rmap.rm_owner;
- key->rmap.rm_offset = ondisk_rec_offset_to_key(rec);
-}
-
-STATIC void
-xfs_rtrmapbt_init_high_key_from_rec(
- union xfs_btree_key *key,
- const union xfs_btree_rec *rec)
-{
- uint64_t off;
- int adj;
-
- adj = be32_to_cpu(rec->rmap.rm_blockcount) - 1;
-
- key->rmap.rm_startblock = rec->rmap.rm_startblock;
- be32_add_cpu(&key->rmap.rm_startblock, adj);
- key->rmap.rm_owner = rec->rmap.rm_owner;
- key->rmap.rm_offset = ondisk_rec_offset_to_key(rec);
- if (XFS_RMAP_NON_INODE_OWNER(be64_to_cpu(rec->rmap.rm_owner)) ||
- XFS_RMAP_IS_BMBT_BLOCK(be64_to_cpu(rec->rmap.rm_offset)))
- return;
- off = be64_to_cpu(key->rmap.rm_offset);
- off = (XFS_RMAP_OFF(off) + adj) | (off & ~XFS_RMAP_OFF_MASK);
- key->rmap.rm_offset = cpu_to_be64(off);
-}
-
-STATIC void
-xfs_rtrmapbt_init_rec_from_cur(
- struct xfs_btree_cur *cur,
- union xfs_btree_rec *rec)
-{
- rec->rmap.rm_startblock = cpu_to_be32(cur->bc_rec.r.rm_startblock);
- rec->rmap.rm_blockcount = cpu_to_be32(cur->bc_rec.r.rm_blockcount);
- rec->rmap.rm_owner = cpu_to_be64(cur->bc_rec.r.rm_owner);
- rec->rmap.rm_offset = cpu_to_be64(
- xfs_rmap_irec_offset_pack(&cur->bc_rec.r));
-}
-
STATIC void
xfs_rtrmapbt_init_ptr_from_cur(
struct xfs_btree_cur *cur,
@@ -175,69 +122,6 @@ xfs_rtrmapbt_init_ptr_from_cur(
ptr->l = 0;
}
-/*
- * Mask the appropriate parts of the ondisk key field for a key comparison.
- * Fork and bmbt are significant parts of the rmap record key, but written
- * status is merely a record attribute.
- */
-static inline uint64_t offset_keymask(uint64_t offset)
-{
- return offset & ~XFS_RMAP_OFF_UNWRITTEN;
-}
-
-STATIC int
-xfs_rtrmapbt_cmp_key_with_cur(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *key)
-{
- struct xfs_rmap_irec *rec = &cur->bc_rec.r;
- const struct xfs_rmap_key *kp = &key->rmap;
-
- return cmp_int(be32_to_cpu(kp->rm_startblock), rec->rm_startblock) ?:
- cmp_int(be64_to_cpu(kp->rm_owner), rec->rm_owner) ?:
- cmp_int(offset_keymask(be64_to_cpu(kp->rm_offset)),
- offset_keymask(xfs_rmap_irec_offset_pack(rec)));
-}
-
-STATIC int
-xfs_rtrmapbt_cmp_two_keys(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *k1,
- const union xfs_btree_key *k2,
- const union xfs_btree_key *mask)
-{
- const struct xfs_rmap_key *kp1 = &k1->rmap;
- const struct xfs_rmap_key *kp2 = &k2->rmap;
- int d;
-
- /* Doesn't make sense to mask off the physical space part */
- ASSERT(!mask || mask->rmap.rm_startblock);
-
- d = cmp_int(be32_to_cpu(kp1->rm_startblock),
- be32_to_cpu(kp2->rm_startblock));
- if (d)
- return d;
-
- if (!mask || mask->rmap.rm_owner) {
- d = cmp_int(be64_to_cpu(kp1->rm_owner),
- be64_to_cpu(kp2->rm_owner));
- if (d)
- return d;
- }
-
- if (!mask || mask->rmap.rm_offset) {
- /* Doesn't make sense to allow offset but not owner */
- ASSERT(!mask || mask->rmap.rm_owner);
-
- d = cmp_int(offset_keymask(be64_to_cpu(kp1->rm_offset)),
- offset_keymask(be64_to_cpu(kp2->rm_offset)));
- if (d)
- return d;
- }
-
- return 0;
-}
-
static xfs_failaddr_t
xfs_rtrmapbt_verify(
struct xfs_buf *bp)
@@ -304,86 +188,6 @@ const struct xfs_buf_ops xfs_rtrmapbt_buf_ops = {
.verify_struct = xfs_rtrmapbt_verify,
};
-STATIC int
-xfs_rtrmapbt_keys_inorder(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *k1,
- const union xfs_btree_key *k2)
-{
- uint32_t x;
- uint32_t y;
- uint64_t a;
- uint64_t b;
-
- x = be32_to_cpu(k1->rmap.rm_startblock);
- y = be32_to_cpu(k2->rmap.rm_startblock);
- if (x < y)
- return 1;
- else if (x > y)
- return 0;
- a = be64_to_cpu(k1->rmap.rm_owner);
- b = be64_to_cpu(k2->rmap.rm_owner);
- if (a < b)
- return 1;
- else if (a > b)
- return 0;
- a = offset_keymask(be64_to_cpu(k1->rmap.rm_offset));
- b = offset_keymask(be64_to_cpu(k2->rmap.rm_offset));
- if (a <= b)
- return 1;
- return 0;
-}
-
-STATIC int
-xfs_rtrmapbt_recs_inorder(
- struct xfs_btree_cur *cur,
- const union xfs_btree_rec *r1,
- const union xfs_btree_rec *r2)
-{
- uint32_t x;
- uint32_t y;
- uint64_t a;
- uint64_t b;
-
- x = be32_to_cpu(r1->rmap.rm_startblock);
- y = be32_to_cpu(r2->rmap.rm_startblock);
- if (x < y)
- return 1;
- else if (x > y)
- return 0;
- a = be64_to_cpu(r1->rmap.rm_owner);
- b = be64_to_cpu(r2->rmap.rm_owner);
- if (a < b)
- return 1;
- else if (a > b)
- return 0;
- a = offset_keymask(be64_to_cpu(r1->rmap.rm_offset));
- b = offset_keymask(be64_to_cpu(r2->rmap.rm_offset));
- if (a <= b)
- return 1;
- return 0;
-}
-
-STATIC enum xbtree_key_contig
-xfs_rtrmapbt_keys_contiguous(
- struct xfs_btree_cur *cur,
- const union xfs_btree_key *key1,
- const union xfs_btree_key *key2,
- const union xfs_btree_key *mask)
-{
- ASSERT(!mask || mask->rmap.rm_startblock);
-
- /*
- * We only support checking contiguity of the physical space component.
- * If any callers ever need more specificity than that, they'll have to
- * implement it here.
- */
- ASSERT(!mask || (!mask->rmap.rm_owner && !mask->rmap.rm_offset));
-
- return xbtree_key_contig(be32_to_cpu(key1->rmap.rm_startblock),
- be32_to_cpu(key2->rmap.rm_startblock));
-}
-
static inline void
xfs_rtrmapbt_move_ptrs(
struct xfs_mount *mp,
@@ -412,7 +216,7 @@ xfs_rtrmapbt_broot_realloc(
unsigned int old_size = ifp->if_broot_bytes;
const unsigned int level = cur->bc_nlevels - 1;
- new_size = xfs_rtrmap_broot_space_calc(mp, level, new_numrecs);
+ new_size = xfs_rtrmap_broot_space_calc(level, new_numrecs);
/* Handle the nop case quietly. */
if (new_size == old_size)
@@ -486,16 +290,16 @@ const struct xfs_btree_ops xfs_rtrmapbt_ops = {
.get_minrecs = xfs_rtrmapbt_get_minrecs,
.get_maxrecs = xfs_rtrmapbt_get_maxrecs,
.get_dmaxrecs = xfs_rtrmapbt_get_dmaxrecs,
- .init_key_from_rec = xfs_rtrmapbt_init_key_from_rec,
- .init_high_key_from_rec = xfs_rtrmapbt_init_high_key_from_rec,
- .init_rec_from_cur = xfs_rtrmapbt_init_rec_from_cur,
+ .init_key_from_rec = xfs_rmapbt_init_key_from_rec,
+ .init_high_key_from_rec = xfs_rmapbt_init_high_key_from_rec,
+ .init_rec_from_cur = xfs_rmapbt_init_rec_from_cur,
.init_ptr_from_cur = xfs_rtrmapbt_init_ptr_from_cur,
- .cmp_key_with_cur = xfs_rtrmapbt_cmp_key_with_cur,
+ .cmp_key_with_cur = xfs_rmapbt_cmp_key_with_cur,
.buf_ops = &xfs_rtrmapbt_buf_ops,
- .cmp_two_keys = xfs_rtrmapbt_cmp_two_keys,
- .keys_inorder = xfs_rtrmapbt_keys_inorder,
- .recs_inorder = xfs_rtrmapbt_recs_inorder,
- .keys_contiguous = xfs_rtrmapbt_keys_contiguous,
+ .cmp_two_keys = xfs_rmapbt_cmp_two_keys,
+ .keys_inorder = xfs_rmapbt_keys_inorder,
+ .recs_inorder = xfs_rmapbt_recs_inorder,
+ .keys_contiguous = xfs_rmapbt_keys_contiguous,
.broot_realloc = xfs_rtrmapbt_broot_realloc,
};
@@ -595,16 +399,16 @@ const struct xfs_btree_ops xfs_rtrmapbt_mem_ops = {
.free_block = xfbtree_free_block,
.get_minrecs = xfbtree_get_minrecs,
.get_maxrecs = xfbtree_get_maxrecs,
- .init_key_from_rec = xfs_rtrmapbt_init_key_from_rec,
- .init_high_key_from_rec = xfs_rtrmapbt_init_high_key_from_rec,
- .init_rec_from_cur = xfs_rtrmapbt_init_rec_from_cur,
+ .init_key_from_rec = xfs_rmapbt_init_key_from_rec,
+ .init_high_key_from_rec = xfs_rmapbt_init_high_key_from_rec,
+ .init_rec_from_cur = xfs_rmapbt_init_rec_from_cur,
.init_ptr_from_cur = xfbtree_init_ptr_from_cur,
- .cmp_key_with_cur = xfs_rtrmapbt_cmp_key_with_cur,
+ .cmp_key_with_cur = xfs_rmapbt_cmp_key_with_cur,
.buf_ops = &xfs_rtrmapbt_mem_buf_ops,
- .cmp_two_keys = xfs_rtrmapbt_cmp_two_keys,
- .keys_inorder = xfs_rtrmapbt_keys_inorder,
- .recs_inorder = xfs_rtrmapbt_recs_inorder,
- .keys_contiguous = xfs_rtrmapbt_keys_contiguous,
+ .cmp_two_keys = xfs_rmapbt_cmp_two_keys,
+ .keys_inorder = xfs_rmapbt_keys_inorder,
+ .recs_inorder = xfs_rmapbt_recs_inorder,
+ .keys_contiguous = xfs_rmapbt_keys_contiguous,
};
/* Create a cursor for an in-memory btree. */
@@ -895,7 +699,7 @@ xfs_iformat_rtrmap(
}
broot = xfs_broot_alloc(xfs_ifork_ptr(ip, XFS_DATA_FORK),
- xfs_rtrmap_broot_space_calc(mp, level, numrecs));
+ xfs_rtrmap_broot_space_calc(level, numrecs));
if (broot)
xfs_rtrmapbt_from_disk(ip, dfp, dsize, broot);
return 0;
@@ -980,7 +784,7 @@ xfs_rtrmapbt_create(
ASSERT(ifp->if_bytes == 0);
/* Initialize the empty incore btree root. */
- broot = xfs_broot_realloc(ifp, xfs_rtrmap_broot_space_calc(mp, 0, 0));
+ broot = xfs_broot_realloc(ifp, xfs_rtrmap_broot_space_calc(0, 0));
if (broot)
xfs_btree_init_block(mp, broot, &xfs_rtrmapbt_ops, 0, 0,
I_INO(ip));
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.h b/fs/xfs/libxfs/xfs_rtrmap_btree.h
index e328fd62a149..c59a144b4bbf 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.h
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.h
@@ -140,7 +140,6 @@ xfs_rtrmap_broot_ptr_addr(
*/
static inline size_t
xfs_rtrmap_broot_space_calc(
- struct xfs_mount *mp,
unsigned int level,
unsigned int nrecs)
{
@@ -159,7 +158,7 @@ xfs_rtrmap_broot_space_calc(
static inline size_t
xfs_rtrmap_broot_space(struct xfs_mount *mp, struct xfs_rtrmap_root *bb)
{
- return xfs_rtrmap_broot_space_calc(mp, be16_to_cpu(bb->bb_level),
+ return xfs_rtrmap_broot_space_calc(be16_to_cpu(bb->bb_level),
be16_to_cpu(bb->bb_numrecs));
}
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index f0341adbb879..d2ef7b20a49f 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -1460,46 +1460,6 @@ xfs_update_secondary_sbs(
return saved_error ? saved_error : error;
}
-/*
- * Same behavior as xfs_sync_sb, except that it is always synchronous and it
- * also writes the superblock buffer to disk sector 0 immediately.
- */
-int
-xfs_sync_sb_buf(
- struct xfs_mount *mp,
- bool update_rtsb)
-{
- struct xfs_trans *tp;
- int error;
-
- error = xfs_trans_alloc(mp, &M_RES(mp)->tr_sb, 0, 0, 0, &tp);
- if (error)
- return error;
-
- xfs_log_sb(tp);
- if (update_rtsb)
- xfs_log_rtsb(tp, xfs_trans_getsb(tp));
- xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp);
- if (error)
- return error;
-
- /* Re-acquire and write the sb and rtsb to disk. */
- xfs_buf_lock(mp->m_sb_bp);
- error = xfs_bwrite(mp->m_sb_bp);
- xfs_buf_unlock(mp->m_sb_bp);
- if (error)
- return error;
-
- if (update_rtsb && mp->m_rtsb_bp) {
- xfs_buf_lock(mp->m_rtsb_bp);
- error = xfs_bwrite(mp->m_rtsb_bp);
- xfs_buf_unlock(mp->m_rtsb_bp);
- }
-
- return error;
-}
-
void
xfs_fs_geometry(
struct xfs_mount *mp,
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index 34d0dd374e9b..77de65922213 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -15,7 +15,6 @@ struct xfs_perag;
extern void xfs_log_sb(struct xfs_trans *tp);
extern int xfs_sync_sb(struct xfs_mount *mp, bool wait);
-extern int xfs_sync_sb_buf(struct xfs_mount *mp, bool update_rtsb);
extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp);
void xfs_sb_mount_rextsize(struct xfs_mount *mp, struct xfs_sb *sbp);
void xfs_mount_sb_set_rextsize(struct xfs_mount *mp,
diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c
index b0dc3888bf1b..0201a3d59b1a 100644
--- a/fs/xfs/libxfs/xfs_symlink_remote.c
+++ b/fs/xfs/libxfs/xfs_symlink_remote.c
@@ -208,11 +208,15 @@ xfs_symlink_local_to_remote(
*/
xfs_failaddr_t
xfs_symlink_shortform_verify(
- void *sfp,
- int64_t size)
+ struct xfs_inode *ip)
{
+ struct xfs_ifork *ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
+ char *sfp = (char *)ifp->if_data;
+ int size = ifp->if_bytes;
char *endp = sfp + size;
+ ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
+
/*
* Zero length symlinks should never occur in memory as they are
* never allowed to exist on disk.
diff --git a/fs/xfs/libxfs/xfs_symlink_remote.h b/fs/xfs/libxfs/xfs_symlink_remote.h
index c1672fe1f17b..3f6590602473 100644
--- a/fs/xfs/libxfs/xfs_symlink_remote.h
+++ b/fs/xfs/libxfs/xfs_symlink_remote.h
@@ -18,7 +18,7 @@ bool xfs_symlink_hdr_ok(xfs_ino_t ino, uint32_t offset,
void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
struct xfs_inode *ip, struct xfs_ifork *ifp,
void *priv);
-xfs_failaddr_t xfs_symlink_shortform_verify(void *sfp, int64_t size);
+xfs_failaddr_t xfs_symlink_shortform_verify(struct xfs_inode *ip);
int xfs_symlink_remote_read(struct xfs_inode *ip, char *link);
int xfs_symlink_write_target(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_ino_t owner, const char *target_path, int pathlen,
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index 3151e97ca8ff..b09c88aec185 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -606,10 +606,10 @@ static inline unsigned int xfs_calc_pptr_replace_overhead(void)
*/
STATIC uint
xfs_calc_rename_reservation(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_trans_resv *resp)
{
unsigned int overhead = XFS_DQUOT_LOGRES;
- struct xfs_trans_resv *resp = M_RES(mp);
unsigned int t1, t2, t3 = 0;
t1 = xfs_calc_inode_res(mp, 5) +
@@ -715,10 +715,10 @@ xfs_link_log_count(
*/
STATIC uint
xfs_calc_link_reservation(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_trans_resv *resp)
{
unsigned int overhead = XFS_DQUOT_LOGRES;
- struct xfs_trans_resv *resp = M_RES(mp);
unsigned int t1, t2, t3 = 0;
overhead += xfs_calc_iunlink_remove_reservation(mp);
@@ -777,10 +777,10 @@ xfs_remove_log_count(
*/
STATIC uint
xfs_calc_remove_reservation(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_trans_resv *resp)
{
unsigned int overhead = XFS_DQUOT_LOGRES;
- struct xfs_trans_resv *resp = M_RES(mp);
unsigned int t1, t2, t3 = 0;
overhead += xfs_calc_iunlink_add_reservation(mp);
@@ -862,9 +862,9 @@ xfs_icreate_log_count(
STATIC uint
xfs_calc_icreate_reservation(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_trans_resv *resp)
{
- struct xfs_trans_resv *resp = M_RES(mp);
unsigned int overhead = XFS_DQUOT_LOGRES;
unsigned int t1, t2, t3 = 0;
@@ -911,9 +911,10 @@ xfs_mkdir_log_count(
*/
STATIC uint
xfs_calc_mkdir_reservation(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_trans_resv *resp)
{
- return xfs_calc_icreate_reservation(mp);
+ return xfs_calc_icreate_reservation(mp, resp);
}
static inline unsigned int
@@ -940,9 +941,10 @@ xfs_symlink_log_count(
*/
STATIC uint
xfs_calc_symlink_reservation(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_trans_resv *resp)
{
- return xfs_calc_icreate_reservation(mp) +
+ return xfs_calc_icreate_reservation(mp, resp) +
xfs_calc_buf_res(1, XFS_SYMLINK_MAXLEN);
}
@@ -1265,34 +1267,33 @@ xfs_calc_namespace_reservations(
{
ASSERT(resp->tr_attrsetm.tr_logres > 0);
- resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp);
+ resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp, resp);
resp->tr_rename.tr_logcount = xfs_rename_log_count(mp, resp);
resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
- resp->tr_link.tr_logres = xfs_calc_link_reservation(mp);
+ resp->tr_link.tr_logres = xfs_calc_link_reservation(mp, resp);
resp->tr_link.tr_logcount = xfs_link_log_count(mp, resp);
resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
- resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp);
+ resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp, resp);
resp->tr_remove.tr_logcount = xfs_remove_log_count(mp, resp);
resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
- resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp);
+ resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp, resp);
resp->tr_symlink.tr_logcount = xfs_symlink_log_count(mp, resp);
resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
- resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp);
+ resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp, resp);
resp->tr_create.tr_logcount = xfs_icreate_log_count(mp, resp);
resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
- resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp);
+ resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp, resp);
resp->tr_mkdir.tr_logcount = xfs_mkdir_log_count(mp, resp);
resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
}
STATIC void
xfs_calc_default_atomic_ioend_reservation(
- struct xfs_mount *mp,
struct xfs_trans_resv *resp)
{
/* Pick a default that will scale reasonably for the log size. */
@@ -1398,7 +1399,7 @@ xfs_trans_resv_calc(
* Now that we've finished computing the static reservations, we can
* compute the dynamic reservation for atomic writes.
*/
- xfs_calc_default_atomic_ioend_reservation(mp, resp);
+ xfs_calc_default_atomic_ioend_reservation(resp);
}
/*
@@ -1508,7 +1509,7 @@ xfs_calc_atomic_write_log_geometry(
ASSERT(blockcount > 0);
- xfs_calc_default_atomic_ioend_reservation(mp, M_RES(mp));
+ xfs_calc_default_atomic_ioend_reservation(M_RES(mp));
per_intent = xfs_calc_atomic_write_ioend_geometry(mp, &step_size);
@@ -1545,7 +1546,7 @@ xfs_calc_atomic_write_reservation(
* use the defaults.
*/
if (blockcount == 0) {
- xfs_calc_default_atomic_ioend_reservation(mp, M_RES(mp));
+ xfs_calc_default_atomic_ioend_reservation(M_RES(mp));
return 0;
}
diff --git a/fs/xfs/libxfs/xfs_trans_space.c b/fs/xfs/libxfs/xfs_trans_space.c
index c4cd547033e5..7edd0d86f0bd 100644
--- a/fs/xfs/libxfs/xfs_trans_space.c
+++ b/fs/xfs/libxfs/xfs_trans_space.c
@@ -127,10 +127,10 @@ xfs_rename_space_res(
if (has_whiteout)
ret += xfs_parent_calc_space_res(mp, src_namelen);
ret += 2 * xfs_parent_calc_space_res(mp, target_namelen);
- }
- if (target_exists)
- ret += xfs_parent_calc_space_res(mp, target_namelen);
+ if (target_exists)
+ ret += xfs_parent_calc_space_res(mp, target_namelen);
+ }
return ret;
}
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c
index 67c947a47f14..f195a04dbf66 100644
--- a/fs/xfs/libxfs/xfs_types.c
+++ b/fs/xfs/libxfs/xfs_types.c
@@ -222,7 +222,6 @@ xfs_verify_icount(
/* Sanity-checking of dir/attr block offsets. */
bool
xfs_verify_dablk(
- struct xfs_mount *mp,
xfs_fileoff_t dabno)
{
xfs_dablk_t max_dablk = -1U;
@@ -233,7 +232,6 @@ xfs_verify_dablk(
/* Check that a file block offset does not exceed the maximum. */
bool
xfs_verify_fileoff(
- struct xfs_mount *mp,
xfs_fileoff_t off)
{
return off <= XFS_MAX_FILEOFF;
@@ -242,15 +240,14 @@ xfs_verify_fileoff(
/* Check that a range of file block offsets do not exceed the maximum. */
bool
xfs_verify_fileext(
- struct xfs_mount *mp,
xfs_fileoff_t off,
xfs_fileoff_t len)
{
if (off + len <= off)
return false;
- if (!xfs_verify_fileoff(mp, off))
+ if (!xfs_verify_fileoff(off))
return false;
- return xfs_verify_fileoff(mp, off + len - 1);
+ return xfs_verify_fileoff(off + len - 1);
}
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index f6f4f2d4b5db..19dd5e7c8b12 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -277,11 +277,10 @@ bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
bool xfs_verify_rtbext(struct xfs_mount *mp, xfs_rtblock_t rtbno,
xfs_filblks_t len);
bool xfs_verify_icount(struct xfs_mount *mp, unsigned long long icount);
-bool xfs_verify_dablk(struct xfs_mount *mp, xfs_fileoff_t off);
+bool xfs_verify_dablk(xfs_fileoff_t off);
void xfs_icount_range(struct xfs_mount *mp, unsigned long long *min,
unsigned long long *max);
-bool xfs_verify_fileoff(struct xfs_mount *mp, xfs_fileoff_t off);
-bool xfs_verify_fileext(struct xfs_mount *mp, xfs_fileoff_t off,
- xfs_fileoff_t len);
+bool xfs_verify_fileoff(xfs_fileoff_t off);
+bool xfs_verify_fileext(xfs_fileoff_t off, xfs_fileoff_t len);
#endif /* __XFS_TYPES_H__ */
diff --git a/fs/xfs/scrub/alloc_repair.c b/fs/xfs/scrub/alloc_repair.c
index 2398e3819597..6e8352405361 100644
--- a/fs/xfs/scrub/alloc_repair.c
+++ b/fs/xfs/scrub/alloc_repair.c
@@ -108,9 +108,6 @@ struct xrep_abt {
struct xfs_scrub *sc;
- /* Number of non-null records in @free_records. */
- uint64_t nr_real_records;
-
/* get_records()'s position in the free space record array. */
xfarray_idx_t array_cur;
@@ -403,7 +400,6 @@ xrep_abt_find_freespace(
if (error)
goto err_agfl;
- ra->nr_real_records = xfarray_length(ra->free_records);
err_agfl:
xfs_trans_brelse(sc->tp, agfl_bp);
err:
@@ -446,15 +442,17 @@ xrep_abt_reserve_space(
uint64_t required;
unsigned int desired;
unsigned int len;
+ const uint64_t nr_records =
+ xfarray_length(ra->free_records);
/* Compute how many blocks we'll need. */
error = xfs_btree_bload_compute_geometry(cnt_cur,
- &ra->new_cntbt.bload, ra->nr_real_records);
+ &ra->new_cntbt.bload, nr_records);
if (error)
break;
error = xfs_btree_bload_compute_geometry(bno_cur,
- &ra->new_bnobt.bload, ra->nr_real_records);
+ &ra->new_bnobt.bload, nr_records);
if (error)
break;
@@ -470,7 +468,7 @@ xrep_abt_reserve_space(
desired = required - allocated;
/* We need space but there's none left; bye! */
- if (ra->nr_real_records == 0) {
+ if (nr_records == 0) {
error = -ENOSPC;
break;
}
@@ -517,10 +515,9 @@ xrep_abt_reserve_space(
* records (but doesn't break the sorting order), so we must
* go around the loop once more to re-run _bload_init.
*/
- error = xfarray_unset(ra->free_records, record_nr);
+ error = xfarray_trim(ra->free_records, 1);
if (error)
break;
- ra->nr_real_records--;
record_nr--;
} while (1);
diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index 4f3c7f681bd9..c190590bc562 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -453,18 +453,17 @@ xchk_bmap_dirattr_extent(
struct xchk_bmap_info *info,
struct xfs_bmbt_irec *irec)
{
- struct xfs_mount *mp = ip->i_mount;
xfs_fileoff_t off;
if (!S_ISDIR(VFS_I(ip)->i_mode) && info->whichfork != XFS_ATTR_FORK)
return;
- if (!xfs_verify_dablk(mp, irec->br_startoff))
+ if (!xfs_verify_dablk(irec->br_startoff))
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
off = irec->br_startoff + irec->br_blockcount - 1;
- if (!xfs_verify_dablk(mp, off))
+ if (!xfs_verify_dablk(off))
xchk_fblock_set_corrupt(info->sc, info->whichfork, off);
}
@@ -486,7 +485,7 @@ xchk_bmap_iextent(
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
- if (!xfs_verify_fileext(mp, irec->br_startoff, irec->br_blockcount))
+ if (!xfs_verify_fileext(irec->br_startoff, irec->br_blockcount))
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
@@ -877,8 +876,6 @@ xchk_bmap_iextent_delalloc(
struct xchk_bmap_info *info,
struct xfs_bmbt_irec *irec)
{
- struct xfs_mount *mp = info->sc->mp;
-
/*
* Check for out-of-order extents. This record could have come
* from the incore list, for which there is no ordering check.
@@ -888,7 +885,7 @@ xchk_bmap_iextent_delalloc(
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
- if (!xfs_verify_fileext(mp, irec->br_startoff, irec->br_blockcount))
+ if (!xfs_verify_fileext(irec->br_startoff, irec->br_blockcount))
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
diff --git a/fs/xfs/scrub/bmap_repair.c b/fs/xfs/scrub/bmap_repair.c
index eabffba47776..03af6cb92fcf 100644
--- a/fs/xfs/scrub/bmap_repair.c
+++ b/fs/xfs/scrub/bmap_repair.c
@@ -211,7 +211,7 @@ xrep_bmap_check_fork_rmap(
/* Check the file offset range. */
if (!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
- !xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount))
+ !xfs_verify_fileext(rec->rm_offset, rec->rm_blockcount))
return -EFSCORRUPTED;
/* No contradictory flags. */
@@ -389,7 +389,7 @@ xrep_bmap_check_rtfork_rmap(
return -EFSCORRUPTED;
/* Check the file offsets and physical extents. */
- if (!xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount))
+ if (!xfs_verify_fileext(rec->rm_offset, rec->rm_blockcount))
return -EFSCORRUPTED;
/* Check that this is within the rtgroup. */
diff --git a/fs/xfs/scrub/inode_repair.c b/fs/xfs/scrub/inode_repair.c
index b87c22146233..c65912d87659 100644
--- a/fs/xfs/scrub/inode_repair.c
+++ b/fs/xfs/scrub/inode_repair.c
@@ -933,7 +933,7 @@ xrep_dinode_bad_bmbt_fork(
fkp = xfs_bmdr_key_addr(dfp, i);
fileoff = be64_to_cpu(fkp->br_startoff);
- if (!xfs_verify_fileoff(sc->mp, fileoff))
+ if (!xfs_verify_fileoff(fileoff))
return true;
fpp = xfs_bmdr_ptr_addr(dfp, i, dmxr);
@@ -1024,6 +1024,30 @@ xrep_dinode_bad_metabt_fork(
return false;
}
+static xfs_failaddr_t
+xrep_symlink_shortform_verify(
+ void *sfp,
+ int64_t size)
+{
+ /*
+ * Zero length symlinks should never occur in memory as they are
+ * never allowed to exist on disk.
+ */
+ if (!size)
+ return __this_address;
+
+ /* No negative sizes or overly long symlink targets. */
+ if (size < 0 || size > XFS_SYMLINK_MAXLEN)
+ return __this_address;
+
+ /* No NULLs in the target either. */
+ if (memchr(sfp, 0, size))
+ return __this_address;
+
+ /* ondisk symlink target isn't null terminated, unlike incore */
+ return NULL;
+}
+
/*
* Check the data fork for things that will fail the ifork verifiers or the
* ifork formatters.
@@ -1099,7 +1123,7 @@ xrep_dinode_check_dfork(
return true;
/* symlink structure must pass verification. */
if (S_ISLNK(mode) &&
- xfs_symlink_shortform_verify(dfork_ptr, data_size) != NULL)
+ xrep_symlink_shortform_verify(dfork_ptr, data_size) != NULL)
return true;
break;
case XFS_DINODE_FMT_EXTENTS:
@@ -1405,7 +1429,7 @@ xrep_dinode_ensure_forkoff(
break;
case XFS_METAFILE_RTREFCOUNT:
rcdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
- dfork_min = xfs_rtrefcount_broot_space(sc->mp, rcdr);
+ dfork_min = xfs_rtrefcount_broot_space(rcdr);
break;
default:
dfork_min = 0;
@@ -1949,7 +1973,7 @@ xrep_inode_pptr(
return 0;
return xfs_bmap_add_attrfork(sc->tp, ip,
- sizeof(struct xfs_attr_sf_hdr), true);
+ sizeof(struct xfs_attr_sf_hdr));
}
/* Fix COW extent size hint problems. */
diff --git a/fs/xfs/scrub/orphanage.c b/fs/xfs/scrub/orphanage.c
index 21e31eeaa042..d8e1457f0d5e 100644
--- a/fs/xfs/scrub/orphanage.c
+++ b/fs/xfs/scrub/orphanage.c
@@ -550,7 +550,7 @@ xrep_adoption_move(
if (!xfs_inode_has_attr_fork(sc->ip) && xfs_has_parent(sc->mp)) {
int sf_size = xrep_adoption_attr_sizeof(adopt);
- error = xfs_bmap_add_attrfork(sc->tp, sc->ip, sf_size, true);
+ error = xfs_bmap_add_attrfork(sc->tp, sc->ip, sf_size);
if (error)
return error;
}
diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 222812fe202c..8c6ba1240fd5 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -89,7 +89,7 @@ xchk_quota_item_bmap(
int nmaps = 1;
int error;
- if (!xfs_verify_fileoff(mp, offset)) {
+ if (!xfs_verify_fileoff(offset)) {
xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
return 0;
}
diff --git a/fs/xfs/scrub/quota_repair.c b/fs/xfs/scrub/quota_repair.c
index 59302e8afc7e..40bb85e8f909 100644
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -116,8 +116,8 @@ xrep_quota_item_bmap(
int error;
/* The computed file offset should always be valid. */
- if (!xfs_verify_fileoff(mp, offset)) {
- ASSERT(xfs_verify_fileoff(mp, offset));
+ if (!xfs_verify_fileoff(offset)) {
+ ASSERT(xfs_verify_fileoff(offset));
return -EFSCORRUPTED;
}
dq->q_fileoffset = offset;
@@ -248,10 +248,7 @@ xrep_quota_item(
dq->q_flags |= XFS_DQFLAG_DIRTY;
xfs_trans_dqjoin(sc->tp, dq);
- if (dq->q_id) {
- xfs_qm_adjust_dqlimits(dq);
- xfs_qm_adjust_dqtimers(dq);
- }
+ xfs_qm_adjust_dqenforcement(dq);
xfs_trans_log_dquot(sc->tp, dq);
return xfs_trans_roll(&sc->tp);
diff --git a/fs/xfs/scrub/quotacheck_repair.c b/fs/xfs/scrub/quotacheck_repair.c
index dbb522e1513b..b8334edf380c 100644
--- a/fs/xfs/scrub/quotacheck_repair.c
+++ b/fs/xfs/scrub/quotacheck_repair.c
@@ -39,6 +39,54 @@
* dquot is locked.
*/
+static bool
+xqcheck_dqres_force_dirty(
+ const struct xfs_dquot_res *res,
+ const struct xfs_quota_limits *qlim)
+{
+ /* zero limits mean that we should set the default limits */
+ if (res->softlimit == 0 && qlim->soft != 0)
+ return true;
+ if (res->hardlimit == 0 && qlim->hard != 0)
+ return true;
+
+ /* do we need to adjust the timer setting? */
+ if ((res->softlimit && res->count > res->softlimit) ||
+ (res->hardlimit && res->count > res->hardlimit)) {
+ if (!res->timer)
+ return true;
+ } else {
+ if (res->timer)
+ return true;
+ }
+
+ return false;
+}
+
+/* Decide if we need to adjust the dquot limits or timers */
+static bool
+xqcheck_dquot_force_dirty(
+ const struct xfs_dquot *dq)
+{
+ struct xfs_quotainfo *qi = dq->q_mount->m_quotainfo;
+ struct xfs_def_quota *defq;
+
+ /* root dquot does not enforce limits */
+ if (dq->q_id == 0)
+ return false;
+
+ defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
+
+ if (xqcheck_dqres_force_dirty(&dq->q_blk, &defq->blk))
+ return true;
+ if (xqcheck_dqres_force_dirty(&dq->q_ino, &defq->ino))
+ return true;
+ if (xqcheck_dqres_force_dirty(&dq->q_rtb, &defq->rtb))
+ return true;
+
+ return false;
+}
+
/* Commit new counters to a dquot. */
static int
xqcheck_commit_dquot(
@@ -91,6 +139,9 @@ xqcheck_commit_dquot(
dirty = true;
}
+ if (!dirty && xqcheck_dquot_force_dirty(dq))
+ dirty = true;
+
xcdq.flags |= (XQCHECK_DQUOT_REPAIR_SCANNED | XQCHECK_DQUOT_WRITTEN);
error = xfarray_store(counts, dq->q_id, &xcdq);
if (error == -EFBIG) {
@@ -110,8 +161,7 @@ xqcheck_commit_dquot(
/* Commit the dirty dquot to disk. */
dq->q_flags |= XFS_DQFLAG_DIRTY;
- if (dq->q_id)
- xfs_qm_adjust_dqtimers(dq);
+ xfs_qm_adjust_dqenforcement(dq);
xfs_trans_log_dquot(xqc->sc->tp, dq);
return xrep_trans_commit(xqc->sc);
diff --git a/fs/xfs/scrub/rtrefcount_repair.c b/fs/xfs/scrub/rtrefcount_repair.c
index 2b939960c7dd..c78a6d2990c5 100644
--- a/fs/xfs/scrub/rtrefcount_repair.c
+++ b/fs/xfs/scrub/rtrefcount_repair.c
@@ -596,8 +596,7 @@ xrep_rtrefc_iroot_size(
unsigned int nr_this_level,
void *priv)
{
- return xfs_rtrefcount_broot_space_calc(cur->bc_mp, level,
- nr_this_level);
+ return xfs_rtrefcount_broot_space_calc(level, nr_this_level);
}
/*
diff --git a/fs/xfs/scrub/rtrmap_repair.c b/fs/xfs/scrub/rtrmap_repair.c
index a2b72e61edf5..5cfa4470c57c 100644
--- a/fs/xfs/scrub/rtrmap_repair.c
+++ b/fs/xfs/scrub/rtrmap_repair.c
@@ -693,7 +693,7 @@ xrep_rtrmap_iroot_size(
unsigned int nr_this_level,
void *priv)
{
- return xfs_rtrmap_broot_space_calc(cur->bc_mp, level, nr_this_level);
+ return xfs_rtrmap_broot_space_calc(level, nr_this_level);
}
/*
diff --git a/fs/xfs/scrub/xfarray.c b/fs/xfs/scrub/xfarray.c
index 2ce24bfe4c0f..c94f35560779 100644
--- a/fs/xfs/scrub/xfarray.c
+++ b/fs/xfs/scrub/xfarray.c
@@ -140,55 +140,23 @@ xfarray_load(
xfarray_pos(array, idx));
}
-/* Is this array element potentially unset? */
-static inline bool
-xfarray_is_unset(
- struct xfarray *array,
- loff_t pos)
-{
- void *temp = xfarray_scratch(array);
- int error;
-
- if (array->unset_slots == 0)
- return false;
-
- error = xfile_load(array->xfile, temp, array->obj_size, pos);
- if (!error && xfarray_element_is_null(array, temp))
- return true;
-
- return false;
-}
-
-/*
- * Unset an array element. If @idx is the last element in the array, the
- * array will be truncated. Otherwise, the entry will be zeroed.
- */
+/* Remove the elements at the end of an array. */
int
-xfarray_unset(
- struct xfarray *array,
- xfarray_idx_t idx)
+xfarray_trim(
+ struct xfarray *array,
+ unsigned long long nr)
{
- void *temp = xfarray_scratch(array);
- loff_t pos = xfarray_pos(array, idx);
- int error;
+ loff_t new_eof;
- if (idx >= array->nr)
+ if (nr > array->nr)
return -ENODATA;
- if (idx == array->nr - 1) {
- array->nr--;
- return 0;
- }
-
- if (xfarray_is_unset(array, pos))
- return 0;
-
- memset(temp, 0, array->obj_size);
- error = xfile_store(array->xfile, temp, array->obj_size, pos);
- if (error)
- return error;
+ array->nr -= nr;
+ if (!array->nr)
+ array->possibly_sparse = false;
- array->unset_slots++;
+ new_eof = xfarray_pos(array, array->nr);
+ xfile_discard(array->xfile, new_eof, MAX_LFS_FILESIZE - new_eof);
return 0;
}
@@ -214,6 +182,8 @@ xfarray_store(
if (ret)
return ret;
+ if (idx > array->nr)
+ array->possibly_sparse = true;
array->nr = max(array->nr, idx + 1);
return 0;
}
@@ -227,43 +197,6 @@ xfarray_element_is_null(
return !memchr_inv(ptr, 0, array->obj_size);
}
-/*
- * Store an element anywhere in the array that is unset. If there are no
- * unset slots, append the element to the array.
- */
-int
-xfarray_store_anywhere(
- struct xfarray *array,
- const void *ptr)
-{
- void *temp = xfarray_scratch(array);
- loff_t endpos = xfarray_pos(array, array->nr);
- loff_t pos;
- int error;
-
- /* Find an unset slot to put it in. */
- for (pos = 0;
- pos < endpos && array->unset_slots > 0;
- pos += array->obj_size) {
- error = xfile_load(array->xfile, temp, array->obj_size,
- pos);
- if (error || !xfarray_element_is_null(array, temp))
- continue;
-
- error = xfile_store(array->xfile, ptr, array->obj_size,
- pos);
- if (error)
- return error;
-
- array->unset_slots--;
- return 0;
- }
-
- /* No unset slots found; attach it on the end. */
- array->unset_slots = 0;
- return xfarray_append(array, ptr);
-}
-
/* Return length of array. */
uint64_t
xfarray_length(
@@ -677,26 +610,10 @@ xfarray_qsort_pivot(
/* Load the selected xfarray records into the pivot array. */
for (i = 0; i < XFARRAY_QSORT_PIVOT_NR; i++) {
- xfarray_idx_t idx;
-
recp = xfarray_pivot_array_rec(parray, pivot_rec_sz, i);
idxp = xfarray_pivot_array_idx(parray, pivot_rec_sz, i);
- /* No unset records; load directly into the array. */
- if (likely(si->array->unset_slots == 0)) {
- error = xfarray_sort_load(si, *idxp, recp);
- if (error)
- return error;
- continue;
- }
-
- /*
- * Load non-null records into the scratchpad without changing
- * the xfarray_idx_t in the pivot array.
- */
- idx = *idxp;
- xfarray_sort_bump_loads(si);
- error = xfarray_load_next(si->array, &idx, recp);
+ error = xfarray_sort_load(si, *idxp, recp);
if (error)
return error;
}
@@ -765,6 +682,18 @@ xfarray_qsort_push(
return -EFSCORRUPTED;
}
+ /*
+ * Avoid the integer underflow below in (lo - 1). This shouldn't
+ * be possible because the pivot is the median of nine distinct
+ * filesystem metadata records, so at least four records will be less
+ * than the pivot, which means the pivot will not be in the low end of
+ * the range by the time we get here.
+ */
+ if (lo == 0) {
+ ASSERT(lo != 0);
+ return -EFSCORRUPTED;
+ }
+
si->max_stack_used = max_t(uint8_t, si->max_stack_used,
si->stack_depth + 2);
@@ -794,6 +723,46 @@ xfarray_sort_scan_done(
si->folio = NULL;
}
+static int
+xfarray_sort_load_folio(
+ struct xfarray_sortinfo *si,
+ xfarray_idx_t idx,
+ loff_t idx_pos)
+{
+ struct folio *folio;
+ loff_t next_pos;
+
+ folio = xfile_get_folio(si->array->xfile, idx_pos, si->array->obj_size,
+ XFILE_ALLOC);
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
+ si->folio = folio;
+
+ /* No folio? Get the caller to read into the scratchpad. */
+ if (!si->folio)
+ return 0;
+
+ si->first_folio_idx = xfarray_idx(si->array,
+ folio_pos(si->folio) + si->array->obj_size - 1);
+
+ next_pos = folio_next_pos(si->folio);
+ si->last_folio_idx = xfarray_idx(si->array, next_pos - 1);
+ if (xfarray_pos(si->array, si->last_folio_idx + 1) > next_pos)
+ si->last_folio_idx--;
+
+ /*
+ * If this folio still doesn't cover the desired element, it must cross
+ * a folio boundary. Get the caller to read into the scratchpad.
+ */
+ if (idx < si->first_folio_idx || idx > si->last_folio_idx) {
+ xfarray_sort_scan_done(si);
+ return 0;
+ }
+
+ trace_xfarray_sort_scan(si, idx);
+ return 0;
+}
+
/*
* Cache the folio backing the start of the given array element. If the array
* element is contained entirely within the folio, return a pointer to the
@@ -819,33 +788,18 @@ xfarray_sort_scan(
(idx < si->first_folio_idx || idx > si->last_folio_idx))
xfarray_sort_scan_done(si);
- /* Grab the first folio that backs this array element. */
+ /* Grab the folio that backs this array element. */
if (!si->folio) {
- struct folio *folio;
- loff_t next_pos;
-
- folio = xfile_get_folio(si->array->xfile, idx_pos,
- si->array->obj_size, XFILE_ALLOC);
- if (IS_ERR(folio))
- return PTR_ERR(folio);
- si->folio = folio;
-
- si->first_folio_idx = xfarray_idx(si->array,
- folio_pos(si->folio) + si->array->obj_size - 1);
-
- next_pos = folio_next_pos(si->folio);
- si->last_folio_idx = xfarray_idx(si->array, next_pos - 1);
- if (xfarray_pos(si->array, si->last_folio_idx + 1) > next_pos)
- si->last_folio_idx--;
-
- trace_xfarray_sort_scan(si, idx);
+ error = xfarray_sort_load_folio(si, idx, idx_pos);
+ if (error)
+ return error;
}
/*
- * If this folio still doesn't cover the desired element, it must cross
- * a folio boundary. Read into the scratchpad and we're done.
+ * If we don't have a folio mapping the entire array element, read into
+ * the scratchpad and we're done.
*/
- if (idx < si->first_folio_idx || idx > si->last_folio_idx) {
+ if (!si->folio) {
void *temp = xfarray_scratch(si->array);
error = xfile_load(si->array->xfile, temp, si->array->obj_size,
@@ -916,6 +870,14 @@ xfarray_sort(
return 0;
if (array->nr >= QSORT_MAX_RECS)
return -E2BIG;
+ if (array->possibly_sparse) {
+ /*
+ * What does it mean to sort an array with holes in it?
+ * Currently none of the users need this ability.
+ */
+ ASSERT(!array->possibly_sparse);
+ return -EINVAL;
+ }
error = xfarray_sortinfo_alloc(array, cmp_fn, flags, &si);
if (error)
@@ -1069,4 +1031,5 @@ xfarray_truncate(
{
xfile_discard(array->xfile, 0, MAX_LFS_FILESIZE);
array->nr = 0;
+ array->possibly_sparse = false;
}
diff --git a/fs/xfs/scrub/xfarray.h b/fs/xfs/scrub/xfarray.h
index 5eeeeed13ae2..05ff65b09fcf 100644
--- a/fs/xfs/scrub/xfarray.h
+++ b/fs/xfs/scrub/xfarray.h
@@ -27,23 +27,22 @@ struct xfarray {
/* Maximum possible array size. */
xfarray_idx_t max_nr;
- /* Number of unset slots in the array below @nr. */
- uint64_t unset_slots;
-
/* Size of an array element. */
size_t obj_size;
/* log2 of array element size, if possible. */
int obj_size_log;
+
+ /* Might there be sparse holes in this array? */
+ bool possibly_sparse;
};
int xfarray_create(const char *descr, unsigned long long required_capacity,
size_t obj_size, struct xfarray **arrayp);
void xfarray_destroy(struct xfarray *array);
int xfarray_load(struct xfarray *array, xfarray_idx_t idx, void *ptr);
-int xfarray_unset(struct xfarray *array, xfarray_idx_t idx);
+int xfarray_trim(struct xfarray *array, unsigned long long nr);
int xfarray_store(struct xfarray *array, xfarray_idx_t idx, const void *ptr);
-int xfarray_store_anywhere(struct xfarray *array, const void *ptr);
bool xfarray_element_is_null(struct xfarray *array, const void *ptr);
void xfarray_truncate(struct xfarray *array);
unsigned long long xfarray_bytes(struct xfarray *array);
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index fdfca6fc75b6..20d87b52c4fc 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -243,7 +243,7 @@ xfs_acl_set_mode(
}
int
-xfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+xfs_set_acl(const struct mnt_idmap *idmap, struct dentry *dentry,
struct posix_acl *acl, int type)
{
umode_t mode;
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index bf7f960997d3..183526bec32c 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -11,7 +11,7 @@ struct posix_acl;
#ifdef CONFIG_XFS_POSIX_ACL
extern struct posix_acl *xfs_get_acl(struct inode *inode, int type, bool rcu);
-extern int xfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+extern int xfs_set_acl(const struct mnt_idmap *idmap, struct dentry *dentry,
struct posix_acl *acl, int type);
extern int __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
void xfs_forget_acl(struct inode *inode, const char *name);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 8b6119776fb3..c30e688cfc9f 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -23,7 +23,6 @@
#include "xfs_ioend.h"
#include "xfs_zone_alloc.h"
#include "xfs_rtgroup.h"
-#include <linux/bio-integrity.h>
struct xfs_writepage_ctx {
struct iomap_writepage_ctx ctx;
@@ -498,8 +497,7 @@ xfs_zoned_writeback_submit(
bio_endio(&ioend->io_bio);
return error;
}
- if (wpc->iomap.flags & IOMAP_F_INTEGRITY)
- fs_bio_integrity_generate(&ioend->io_bio);
+
xfs_zone_alloc_and_submit(ioend, &XFS_ZWPC(wpc)->open_zone);
return 0;
}
@@ -585,11 +583,10 @@ xfs_bio_submit_read(
const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx)
{
- struct bio *bio = ctx->read_ctx;
-
- /* defer read completions to the ioend workqueue */
- iomap_init_ioend(iter->inode, bio, ctx->read_ctx_file_offset, 0);
- iomap_bio_submit_read_endio(iter, ctx, xfs_end_bio);
+ xfs_ioend_submit_read(iter->inode, ctx->read_ctx,
+ ctx->read_ctx_file_offset,
+ iomap_ioend_flags(&iter->iomap));
+ ctx->read_ctx = NULL;
}
static const struct iomap_read_ops xfs_iomap_read_ops = {
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index aa5b41629747..62be62342fea 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -442,7 +442,7 @@ xfs_bui_validate(
if (!xfs_verify_ino(mp, map->me_owner))
return false;
- if (!xfs_verify_fileext(mp, map->me_startoff, map->me_len))
+ if (!xfs_verify_fileext(map->me_startoff, map->me_len))
return false;
if (map->me_flags & XFS_BMAP_EXTENT_REALTIME)
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 8256c1d13ce2..6c93b4f5629c 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -5,6 +5,7 @@
*/
#include "xfs_platform.h"
#include <linux/backing-dev.h>
+#include <linux/blk-integrity.h>
#include <linux/dax.h>
#include "xfs_shared.h"
@@ -1694,6 +1695,7 @@ xfs_configure_buftarg(
struct xfs_mount *mp = btp->bt_mount;
if (btp->bt_bdev) {
+ struct blk_integrity *bi = bdev_get_integrity(btp->bt_bdev);
int error;
error = bdev_validate_blocksize(btp->bt_bdev, sectorsize);
@@ -1706,6 +1708,15 @@ xfs_configure_buftarg(
if (bdev_can_atomic_write(btp->bt_bdev))
xfs_configure_buftarg_atomic_writes(btp);
+
+ if (!bi)
+ ;
+ else if (btp->bt_bdev == btp->bt_mount->m_super->s_bdev)
+ xfs_info(mp, "using %s integrity profile",
+ blk_integrity_profile_name(bi));
+ else
+ xfs_info(mp, "using %s integrity profile for %pg",
+ blk_integrity_profile_name(bi), btp->bt_bdev);
}
btp->bt_meta_sectorsize = sectorsize;
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index e696ee36c2e8..6d22ead562da 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -115,18 +115,15 @@ xfs_qm_dqdestroy(
* We overwrite the dquot limits only if they are zero and this
* is not the root dquot.
*/
-void
+static void
xfs_qm_adjust_dqlimits(
struct xfs_dquot *dq)
{
struct xfs_mount *mp = dq->q_mount;
struct xfs_quotainfo *q = mp->m_quotainfo;
- struct xfs_def_quota *defq;
+ struct xfs_def_quota *defq = xfs_get_defquota(q, xfs_dquot_type(dq));
int prealloc = 0;
- ASSERT(dq->q_id);
- defq = xfs_get_defquota(q, xfs_dquot_type(dq));
-
if (!dq->q_blk.softlimit) {
dq->q_blk.softlimit = defq->blk.soft;
prealloc = 1;
@@ -223,6 +220,19 @@ xfs_qm_adjust_dqtimers(
xfs_qm_adjust_res_timer(dq->q_mount, &dq->q_rtb, &defq->rtb);
}
+/* Adjust enforcement limits and timers after a change in usage. */
+void
+xfs_qm_adjust_dqenforcement(
+ struct xfs_dquot *dq)
+{
+ if (dq->q_id == 0)
+ return;
+
+ xfs_qm_adjust_dqlimits(dq);
+ xfs_qm_adjust_dqtimers(dq);
+ dq->q_flags |= XFS_DQFLAG_DIRTY;
+}
+
/*
* initialize a buffer full of dquots and log the whole thing
*/
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index bbb824adca82..28c09704acc2 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -205,7 +205,7 @@ void xfs_qm_dqdestroy(struct xfs_dquot *dqp);
int xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf *bp);
void xfs_qm_dqunpin_wait(struct xfs_dquot *dqp);
void xfs_qm_adjust_dqtimers(struct xfs_dquot *d);
-void xfs_qm_adjust_dqlimits(struct xfs_dquot *d);
+void xfs_qm_adjust_dqenforcement(struct xfs_dquot *d);
xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip,
xfs_dqtype_t type);
int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
diff --git a/fs/xfs/xfs_exchmaps_item.c b/fs/xfs/xfs_exchmaps_item.c
index dd5d92ca1010..dd104bf778ba 100644
--- a/fs/xfs/xfs_exchmaps_item.c
+++ b/fs/xfs/xfs_exchmaps_item.c
@@ -341,10 +341,10 @@ xfs_xmi_validate(
!xfs_verify_ino(mp, xlf->xmi_inode2))
return false;
- if (!xfs_verify_fileext(mp, xlf->xmi_startoff1, xlf->xmi_blockcount))
+ if (!xfs_verify_fileext(xlf->xmi_startoff1, xlf->xmi_blockcount))
return false;
- if (!xfs_verify_fileext(mp, xlf->xmi_startoff2, xlf->xmi_blockcount))
+ if (!xfs_verify_fileext(xlf->xmi_startoff2, xlf->xmi_blockcount))
return false;
if (xlf->xmi_flags & XFS_EXCHMAPS_SET_SIZES) {
diff --git a/fs/xfs/xfs_exchrange.c b/fs/xfs/xfs_exchrange.c
index fafb4e3f065c..a1001315d4a7 100644
--- a/fs/xfs/xfs_exchrange.c
+++ b/fs/xfs/xfs_exchrange.c
@@ -238,7 +238,7 @@ retry:
trace_xfs_exchrange_before(ip2, 2);
trace_xfs_exchrange_before(ip1, 1);
- error = xfs_exchmaps_check_forks(mp, &req);
+ error = xfs_exchmaps_check_forks(&req);
if (error)
goto out_trans_cancel;
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index d8202da15aca..d164de6ff98b 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -37,6 +37,7 @@
#include <linux/fadvise.h>
#include <linux/mount.h>
#include <linux/filelock.h>
+#include <linux/bio-integrity.h>
static const struct vm_operations_struct xfs_file_vm_ops;
@@ -222,9 +223,8 @@ xfs_dio_read_bounce_submit_io(
struct bio *bio,
loff_t file_offset)
{
- iomap_init_ioend(iter->inode, bio, file_offset, IOMAP_IOEND_DIRECT);
- bio->bi_end_io = xfs_end_bio;
- submit_bio(bio);
+ xfs_ioend_submit_read(iter->inode, bio, file_offset,
+ iomap_ioend_flags(&iter->iomap) | IOMAP_IOEND_DIRECT);
}
static const struct iomap_dio_ops xfs_dio_read_bounce_ops = {
@@ -252,8 +252,7 @@ xfs_file_dio_read(
return ret;
if (mapping_stable_writes(iocb->ki_filp->f_mapping)) {
ret = iomap_dio_rw(iocb, to, &xfs_read_iomap_ops,
- &xfs_dio_read_bounce_ops, IOMAP_DIO_BOUNCE,
- NULL, 0);
+ &xfs_dio_read_bounce_ops, 0, NULL, 0);
} else {
ret = iomap_dio_read_simple(iocb, to, xfs_read_iomap_begin);
if (ret == -ENOTBLK)
@@ -713,7 +712,7 @@ xfs_dio_zoned_submit_io(
bio->bi_end_io = xfs_end_bio;
ioend = iomap_init_ioend(iter->inode, bio, file_offset,
- IOMAP_IOEND_DIRECT);
+ iomap_ioend_flags(&iter->iomap) | IOMAP_IOEND_DIRECT);
xfs_zone_alloc_and_submit(ioend, &ac->open_zone);
}
@@ -1872,17 +1871,21 @@ xfs_file_release(
return 0;
/*
- * If we can't get the iolock just skip truncating the blocks past EOF
- * because we could deadlock with the mmap_lock otherwise. We'll get
- * another chance to drop them once the last reference to the inode is
- * dropped, so we'll never leak blocks permanently.
+ * If we can't get the iolock or if the filesystem is frozen, just skip
+ * truncating the blocks past EOF because we could deadlock with the
+ * mmap_lock or hang the close() call. We'll get another chance to drop
+ * them once the last reference to the inode is dropped, so we'll never
+ * leak blocks permanently.
*/
if (!xfs_iflags_test(ip, XFS_EOFBLOCKS_RELEASED) &&
- xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
- if (xfs_can_free_eofblocks(ip) &&
- !xfs_iflags_test_and_set(ip, XFS_EOFBLOCKS_RELEASED))
- xfs_free_eofblocks(ip);
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+ sb_start_write_trylock(mp->m_super)) {
+ if (xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
+ if (xfs_can_free_eofblocks(ip) &&
+ !xfs_iflags_test_and_set(ip, XFS_EOFBLOCKS_RELEASED))
+ xfs_free_eofblocks(ip);
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+ }
+ sb_end_write(mp->m_super);
}
return 0;
diff --git a/fs/xfs/xfs_handle.c b/fs/xfs/xfs_handle.c
index 0689cade8f74..4924e676ae91 100644
--- a/fs/xfs/xfs_handle.c
+++ b/fs/xfs/xfs_handle.c
@@ -272,11 +272,11 @@ xfs_open_by_handle(
path.mnt = mntget(parfilp->f_path.mnt);
FD_PREPARE(fdf, 0, dentry_open(&path, hreq->oflags, cred));
- if (fdf.err)
- return fdf.err;
+ if (fdf->fd < 0)
+ return fdf->fd;
if (S_ISREG(inode->i_mode)) {
- struct file *filp = fd_prepare_file(fdf);
+ struct file *filp = fdf->file;
filp->f_flags |= O_NOATIME;
filp->f_mode |= FMODE_NOCMTIME;
@@ -409,7 +409,7 @@ xfs_ioc_attr_list(
void *buffer;
int error;
- if (bufsize < sizeof(struct xfs_attrlist) ||
+ if (bufsize < struct_size(alist, al_offset, 1) ||
bufsize > XFS_XATTR_LIST_MAX)
return -EINVAL;
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 621513d7215e..05a14da28031 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -755,7 +755,7 @@ xfs_create(
*ipp = du.ip;
xfs_iunlock(du.ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
return 0;
out_trans_cancel:
@@ -772,7 +772,7 @@ xfs_create(
xfs_irele(du.ip);
}
out_parent:
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
out_release_dquots:
xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp);
@@ -972,7 +972,7 @@ xfs_link(
error = xfs_trans_commit(tp);
xfs_iunlock(tdp, XFS_ILOCK_EXCL);
xfs_iunlock(sip, XFS_ILOCK_EXCL);
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
return error;
error_return:
@@ -980,7 +980,7 @@ xfs_link(
xfs_iunlock(tdp, XFS_ILOCK_EXCL);
xfs_iunlock(sip, XFS_ILOCK_EXCL);
out_parent:
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
std_return:
if (error == -ENOSPC && nospace_error)
error = nospace_error;
@@ -1064,7 +1064,7 @@ xfs_itruncate_extents_flags(
* the page cache can't scale that far.
*/
first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
- if (!xfs_verify_fileoff(mp, first_unmap_block)) {
+ if (!xfs_verify_fileoff(first_unmap_block)) {
WARN_ON_ONCE(first_unmap_block > XFS_MAX_FILEOFF);
return 0;
}
@@ -1985,7 +1985,7 @@ xfs_remove(
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
return 0;
out_trans_cancel:
@@ -1994,7 +1994,7 @@ xfs_remove(
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
out_parent:
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
std_return:
return error;
}
@@ -2084,7 +2084,7 @@ xfs_sort_inodes(
*/
static int
xfs_rename_alloc_whiteout(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct xfs_name *src_name,
struct xfs_inode *dp,
struct xfs_inode **wip)
@@ -2130,7 +2130,7 @@ xfs_rename_alloc_whiteout(
*/
int
xfs_rename(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct xfs_inode *src_dp,
struct xfs_name *src_name,
struct xfs_inode *src_ip,
@@ -2357,11 +2357,11 @@ out_trans_cancel:
out_unlock:
xfs_iunlock_rename(inodes, num_inodes);
out_tgt_ppargs:
- xfs_parent_finish(mp, du_tgt.ppargs);
+ xfs_parent_finish(du_tgt.ppargs);
out_wip_ppargs:
- xfs_parent_finish(mp, du_wip.ppargs);
+ xfs_parent_finish(du_wip.ppargs);
out_src_ppargs:
- xfs_parent_finish(mp, du_src.ppargs);
+ xfs_parent_finish(du_src.ppargs);
out_release_wip:
if (du_wip.ip)
xfs_irele(du_wip.ip);
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 1602027cd0aa..ca96ba096359 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -568,7 +568,7 @@ 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 mnt_idmap *idmap,
+int xfs_rename(const struct mnt_idmap *idmap,
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,
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 96ca3e480cb9..f81b6e52ac40 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -748,7 +748,7 @@ xfs_ioctl_setattr_check_projid(
int
xfs_fileattr_set(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct dentry *dentry,
struct file_kattr *fa)
{
@@ -962,10 +962,10 @@ out_free_buf:
}
int
-xfs_ioc_swapext(
- xfs_swapext_t *sxp)
+xfs_swapext(
+ struct xfs_swapext *sxp)
{
- xfs_inode_t *ip, *tip;
+ struct xfs_inode *ip, *tip;
/* Pull information for the target fd */
CLASS(fd, f)((int)sxp->sx_fdtarget);
@@ -1035,6 +1035,46 @@ xfs_ioc_getlabel(
return 0;
}
+/*
+ * Same behavior as xfs_sync_sb, except that it is always synchronous and it
+ * also writes the superblock buffer to disk sector 0 immediately.
+ */
+static int
+xfs_sync_sb_buf(
+ struct xfs_mount *mp,
+ bool update_rtsb)
+{
+ struct xfs_trans *tp;
+ int error;
+
+ error = xfs_trans_alloc(mp, &M_RES(mp)->tr_sb, 0, 0, 0, &tp);
+ if (error)
+ return error;
+
+ xfs_log_sb(tp);
+ if (update_rtsb)
+ xfs_log_rtsb(tp, xfs_trans_getsb(tp));
+ xfs_trans_set_sync(tp);
+ error = xfs_trans_commit(tp);
+ if (error)
+ return error;
+
+ /* Re-acquire and write the sb and rtsb to disk. */
+ xfs_buf_lock(mp->m_sb_bp);
+ error = xfs_bwrite(mp->m_sb_bp);
+ xfs_buf_unlock(mp->m_sb_bp);
+ if (error)
+ return error;
+
+ if (update_rtsb && mp->m_rtsb_bp) {
+ xfs_buf_lock(mp->m_rtsb_bp);
+ error = xfs_bwrite(mp->m_rtsb_bp);
+ xfs_buf_unlock(mp->m_rtsb_bp);
+ }
+
+ return error;
+}
+
static int
xfs_ioc_setlabel(
struct file *filp,
@@ -1144,7 +1184,7 @@ xfs_fs_eofblocks_from_user(
}
static int
-xfs_ioctl_getset_resblocks(
+xfs_ioc_getset_resblocks(
struct file *filp,
unsigned int cmd,
void __user *arg)
@@ -1183,7 +1223,7 @@ xfs_ioctl_getset_resblocks(
}
static int
-xfs_ioctl_fs_counts(
+xfs_ioc_fs_counts(
struct xfs_mount *mp,
struct xfs_fsop_counts __user *uarg)
{
@@ -1200,6 +1240,202 @@ xfs_ioctl_fs_counts(
return 0;
}
+static int
+xfs_ioc_dioinfo(
+ struct file *file,
+ void __user *arg)
+{
+ struct kstat st;
+ struct dioattr da;
+ int error;
+
+ error = vfs_getattr(&file->f_path, &st, STATX_DIOALIGN, 0);
+ if (error)
+ return error;
+
+ /*
+ * Some userspace directly feeds the return value to posix_memalign,
+ * which fails for values that are smaller than the pointer size.
+ * Round up the value to not break userspace.
+ */
+ da.d_mem = roundup(st.dio_mem_align, sizeof(void *));
+ da.d_miniosz = st.dio_offset_align;
+ da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
+ if (copy_to_user(arg, &da, sizeof(da)))
+ return -EFAULT;
+ return 0;
+}
+
+static int
+xfs_ioc_find_handle(
+ unsigned int cmd,
+ void __user *arg)
+{
+ struct xfs_fsop_handlereq hreq;
+
+ if (copy_from_user(&hreq, arg, sizeof(hreq)))
+ return -EFAULT;
+ return xfs_find_handle(cmd, &hreq);
+}
+
+static int
+xfs_ioc_open_by_handle(
+ struct file *file,
+ void __user *arg)
+{
+ struct xfs_fsop_handlereq hreq;
+
+ if (copy_from_user(&hreq, arg, sizeof(hreq)))
+ return -EFAULT;
+ return xfs_open_by_handle(file, &hreq);
+}
+
+static int
+xfs_ioc_readlink_by_handle(
+ struct file *file,
+ void __user *arg)
+{
+ struct xfs_fsop_handlereq hreq;
+
+ if (copy_from_user(&hreq, arg, sizeof(hreq)))
+ return -EFAULT;
+ return xfs_readlink_by_handle(file, &hreq);
+}
+
+static int
+xfs_ioc_swapext(
+ struct file *file,
+ void __user *arg)
+{
+ struct xfs_swapext sxp;
+ int error;
+
+ if (copy_from_user(&sxp, arg, sizeof(sxp)))
+ return -EFAULT;
+
+ error = mnt_want_write_file(file);
+ if (error)
+ return error;
+ error = xfs_swapext(&sxp);
+ mnt_drop_write_file(file);
+ return error;
+}
+
+static int
+xfs_ioc_growfs_data(
+ struct file *file,
+ struct xfs_mount *mp,
+ void __user *arg)
+{
+ struct xfs_growfs_data in;
+ int error;
+
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return -EFAULT;
+
+ error = mnt_want_write_file(file);
+ if (error)
+ return error;
+ error = xfs_growfs_data(mp, &in);
+ mnt_drop_write_file(file);
+ return error;
+}
+
+static int
+xfs_ioc_growfs_log(
+ struct file *file,
+ struct xfs_mount *mp,
+ void __user *arg)
+{
+ struct xfs_growfs_log in;
+ int error;
+
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return -EFAULT;
+
+ error = mnt_want_write_file(file);
+ if (error)
+ return error;
+ error = xfs_growfs_log(mp, &in);
+ mnt_drop_write_file(file);
+ return error;
+}
+
+static int
+xfs_ioc_growfs_rt(
+ struct file *file,
+ struct xfs_mount *mp,
+ void __user *arg)
+{
+ struct xfs_growfs_rt in;
+ int error;
+
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return -EFAULT;
+
+ error = mnt_want_write_file(file);
+ if (error)
+ return error;
+ error = xfs_growfs_rt(mp, &in);
+ mnt_drop_write_file(file);
+ return error;
+}
+
+static int
+xfs_ioc_goingdown(
+ struct xfs_mount *mp,
+ uint32_t __user *arg)
+{
+ uint32_t in;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (get_user(in, arg))
+ return -EFAULT;
+ return xfs_fs_goingdown(mp, in);
+}
+
+static int
+xfs_ioc_error_injection(
+ struct xfs_mount *mp,
+ struct xfs_error_injection __user *arg)
+{
+ struct xfs_error_injection in;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return -EFAULT;
+ return xfs_errortag_add(mp, in.errtag);
+}
+
+static int
+xfs_ioc_free_eofblocks(
+ struct xfs_mount *mp,
+ struct xfs_fs_eofblocks __user *arg)
+{
+ struct xfs_fs_eofblocks eofb;
+ struct xfs_icwalk icw;
+ int error;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (xfs_is_readonly(mp))
+ return -EROFS;
+
+ if (copy_from_user(&eofb, arg, sizeof(eofb)))
+ return -EFAULT;
+
+ error = xfs_fs_eofblocks_from_user(&eofb, &icw);
+ if (error)
+ return error;
+
+ trace_xfs_ioc_free_eofblocks(mp, &icw, _RET_IP_);
+
+ guard(super_write)(mp->m_super);
+ return xfs_blockgc_free_space(mp, &icw);
+}
+
/*
* These long-unused ioctls were removed from the official ioctl API in 5.17,
* but retain these definitions so that we can log warnings about them.
@@ -1209,12 +1445,6 @@ xfs_ioctl_fs_counts(
#define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
#define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
-/*
- * Note: some of the ioctl's return positive numbers as a
- * byte count indicating success, such as readlink_by_handle.
- * So we don't "sign flip" like most other routines. This means
- * true errors need to be returned as a negative value.
- */
long
xfs_file_ioctl(
struct file *filp,
@@ -1225,7 +1455,6 @@ xfs_file_ioctl(
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
void __user *arg = (void __user *)p;
- int error;
trace_xfs_file_ioctl(ip);
@@ -1244,26 +1473,9 @@ xfs_file_ioctl(
"%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",
current->comm);
return -ENOTTY;
- case XFS_IOC_DIOINFO: {
- struct kstat st;
- struct dioattr da;
- error = vfs_getattr(&filp->f_path, &st, STATX_DIOALIGN, 0);
- if (error)
- return error;
-
- /*
- * Some userspace directly feeds the return value to
- * posix_memalign, which fails for values that are smaller than
- * the pointer size. Round up the value to not break userspace.
- */
- da.d_mem = roundup(st.dio_mem_align, sizeof(void *));
- da.d_miniosz = st.dio_offset_align;
- da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
- if (copy_to_user(arg, &da, sizeof(da)))
- return -EFAULT;
- return 0;
- }
+ case XFS_IOC_DIOINFO:
+ return xfs_ioc_dioinfo(filp, arg);
case XFS_IOC_FSBULKSTAT_SINGLE:
case XFS_IOC_FSBULKSTAT:
@@ -1311,148 +1523,45 @@ xfs_file_ioctl(
case XFS_IOC_FD_TO_HANDLE:
case XFS_IOC_PATH_TO_HANDLE:
- case XFS_IOC_PATH_TO_FSHANDLE: {
- xfs_fsop_handlereq_t hreq;
-
- if (copy_from_user(&hreq, arg, sizeof(hreq)))
- return -EFAULT;
- return xfs_find_handle(cmd, &hreq);
- }
- case XFS_IOC_OPEN_BY_HANDLE: {
- xfs_fsop_handlereq_t hreq;
-
- if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
- return -EFAULT;
- return xfs_open_by_handle(filp, &hreq);
- }
-
- case XFS_IOC_READLINK_BY_HANDLE: {
- xfs_fsop_handlereq_t hreq;
-
- if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
- return -EFAULT;
- return xfs_readlink_by_handle(filp, &hreq);
- }
+ case XFS_IOC_PATH_TO_FSHANDLE:
+ return xfs_ioc_find_handle(cmd, arg);
+ case XFS_IOC_OPEN_BY_HANDLE:
+ return xfs_ioc_open_by_handle(filp, arg);
+ case XFS_IOC_READLINK_BY_HANDLE:
+ return xfs_ioc_readlink_by_handle(filp, arg);
case XFS_IOC_ATTRLIST_BY_HANDLE:
return xfs_attrlist_by_handle(filp, arg);
-
case XFS_IOC_ATTRMULTI_BY_HANDLE:
return xfs_attrmulti_by_handle(filp, arg);
- case XFS_IOC_SWAPEXT: {
- struct xfs_swapext sxp;
-
- if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t)))
- return -EFAULT;
- error = mnt_want_write_file(filp);
- if (error)
- return error;
- error = xfs_ioc_swapext(&sxp);
- mnt_drop_write_file(filp);
- return error;
- }
+ case XFS_IOC_SWAPEXT:
+ return xfs_ioc_swapext(filp, arg);
case XFS_IOC_FSCOUNTS:
- return xfs_ioctl_fs_counts(mp, arg);
+ return xfs_ioc_fs_counts(mp, arg);
case XFS_IOC_SET_RESBLKS:
case XFS_IOC_GET_RESBLKS:
- return xfs_ioctl_getset_resblocks(filp, cmd, arg);
-
- case XFS_IOC_FSGROWFSDATA: {
- struct xfs_growfs_data in;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return -EFAULT;
-
- error = mnt_want_write_file(filp);
- if (error)
- return error;
- error = xfs_growfs_data(mp, &in);
- mnt_drop_write_file(filp);
- return error;
- }
-
- case XFS_IOC_FSGROWFSLOG: {
- struct xfs_growfs_log in;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return -EFAULT;
-
- error = mnt_want_write_file(filp);
- if (error)
- return error;
- error = xfs_growfs_log(mp, &in);
- mnt_drop_write_file(filp);
- return error;
- }
-
- case XFS_IOC_FSGROWFSRT: {
- xfs_growfs_rt_t in;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return -EFAULT;
-
- error = mnt_want_write_file(filp);
- if (error)
- return error;
- error = xfs_growfs_rt(mp, &in);
- mnt_drop_write_file(filp);
- return error;
- }
-
- case XFS_IOC_GOINGDOWN: {
- uint32_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (get_user(in, (uint32_t __user *)arg))
- return -EFAULT;
-
- return xfs_fs_goingdown(mp, in);
- }
-
- case XFS_IOC_ERROR_INJECTION: {
- xfs_error_injection_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return -EFAULT;
-
- return xfs_errortag_add(mp, in.errtag);
- }
-
+ return xfs_ioc_getset_resblocks(filp, cmd, arg);
+
+ case XFS_IOC_FSGROWFSDATA:
+ return xfs_ioc_growfs_data(filp, mp, arg);
+ case XFS_IOC_FSGROWFSLOG:
+ return xfs_ioc_growfs_log(filp, mp, arg);
+ case XFS_IOC_FSGROWFSRT:
+ return xfs_ioc_growfs_rt(filp, mp, arg);
+
+ case XFS_IOC_GOINGDOWN:
+ return xfs_ioc_goingdown(mp, arg);
+ case XFS_IOC_ERROR_INJECTION:
+ return xfs_ioc_error_injection(mp, arg);
case XFS_IOC_ERROR_CLEARALL:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
-
return xfs_errortag_clearall(mp);
- case XFS_IOC_FREE_EOFBLOCKS: {
- struct xfs_fs_eofblocks eofb;
- struct xfs_icwalk icw;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (xfs_is_readonly(mp))
- return -EROFS;
-
- if (copy_from_user(&eofb, arg, sizeof(eofb)))
- return -EFAULT;
-
- error = xfs_fs_eofblocks_from_user(&eofb, &icw);
- if (error)
- return error;
-
- trace_xfs_ioc_free_eofblocks(mp, &icw, _RET_IP_);
-
- guard(super_write)(mp->m_super);
- return xfs_blockgc_free_space(mp, &icw);
- }
+ case XFS_IOC_FREE_EOFBLOCKS:
+ return xfs_ioc_free_eofblocks(mp, arg);
case XFS_IOC_EXCHANGE_RANGE:
return xfs_ioc_exchange_range(filp, arg);
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index f5ed5cf9d3df..6e55cc847654 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -10,9 +10,7 @@ struct xfs_bstat;
struct xfs_ibulk;
struct xfs_inogrp;
-int
-xfs_ioc_swapext(
- xfs_swapext_t *sxp);
+int xfs_swapext(struct xfs_swapext *sxp);
extern int
xfs_fileattr_get(
@@ -21,7 +19,7 @@ xfs_fileattr_get(
extern int
xfs_fileattr_set(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct dentry *dentry,
struct file_kattr *fa);
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index c66e192448a8..f6875a2cc706 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -44,26 +44,46 @@ xfs_compat_ioc_fsgeometry_v1(
return 0;
}
-STATIC int
-xfs_compat_growfs_data_copyin(
- struct xfs_growfs_data *in,
- compat_xfs_growfs_data_t __user *arg32)
+static int
+xfs_compat_ioc_growfs_data(
+ struct file *file,
+ struct xfs_mount *mp,
+ struct compat_xfs_growfs_data __user *arg32)
{
- if (get_user(in->newblocks, &arg32->newblocks) ||
- get_user(in->imaxpct, &arg32->imaxpct))
+ struct xfs_growfs_data in = { };
+ int error;
+
+ if (get_user(in.newblocks, &arg32->newblocks) ||
+ get_user(in.imaxpct, &arg32->imaxpct))
return -EFAULT;
- return 0;
+
+ error = mnt_want_write_file(file);
+ if (error)
+ return error;
+ error = xfs_growfs_data(mp, &in);
+ mnt_drop_write_file(file);
+ return error;
}
-STATIC int
-xfs_compat_growfs_rt_copyin(
- struct xfs_growfs_rt *in,
- compat_xfs_growfs_rt_t __user *arg32)
+static int
+xfs_compat_ioc_growfs_rt(
+ struct file *file,
+ struct xfs_mount *mp,
+ struct compat_xfs_growfs_rt __user *arg32)
{
- if (get_user(in->newblocks, &arg32->newblocks) ||
- get_user(in->extsize, &arg32->extsize))
+ struct xfs_growfs_rt in = {};
+ int error;
+
+ if (get_user(in.newblocks, &arg32->newblocks) ||
+ get_user(in.extsize, &arg32->extsize))
return -EFAULT;
- return 0;
+
+ error = mnt_want_write_file(file);
+ if (error)
+ return error;
+ error = xfs_growfs_rt(mp, &in);
+ mnt_drop_write_file(file);
+ return error;
}
STATIC int
@@ -138,6 +158,27 @@ xfs_ioctl32_bstat_copyin(
return 0;
}
+static int
+xfs_compat_ioc_swapext(
+ struct file *file,
+ struct compat_xfs_swapext __user *sxu)
+{
+ struct xfs_swapext sxp;
+ int error;
+
+ /* Bulk copy in up to the sx_stat field, then copy bstat */
+ if (copy_from_user(&sxp, sxu, offsetof(struct xfs_swapext, sx_stat)) ||
+ xfs_ioctl32_bstat_copyin(&sxp.sx_stat, &sxu->sx_stat))
+ return -EFAULT;
+
+ error = mnt_want_write_file(file);
+ if (error)
+ return error;
+ error = xfs_swapext(&sxp);
+ mnt_drop_write_file(file);
+ return error;
+}
+
/* XFS_IOC_FSBULKSTAT and friends */
STATIC int
@@ -338,6 +379,43 @@ xfs_compat_handlereq_to_dentry(
compat_ptr(hreq->ihandle), hreq->ihandlen);
}
+static int
+xfs_compat_ioc_find_handle(
+ unsigned int cmd,
+ void __user *arg)
+{
+ struct xfs_fsop_handlereq hreq;
+
+ if (xfs_compat_handlereq_copyin(&hreq, arg))
+ return -EFAULT;
+ return xfs_find_handle(_NATIVE_IOC(cmd, struct xfs_fsop_handlereq),
+ &hreq);
+}
+
+static int
+xfs_compat_ioc_open_by_handle(
+ struct file *file,
+ void __user *arg)
+{
+ struct xfs_fsop_handlereq hreq;
+
+ if (xfs_compat_handlereq_copyin(&hreq, arg))
+ return -EFAULT;
+ return xfs_open_by_handle(file, &hreq);
+}
+
+static int
+xfs_compat_ioc_readlink_by_handle(
+ struct file *file,
+ void __user *arg)
+{
+ struct xfs_fsop_handlereq hreq;
+
+ if (xfs_compat_handlereq_copyin(&hreq, arg))
+ return -EFAULT;
+ return xfs_readlink_by_handle(file, &hreq);
+}
+
STATIC int
xfs_compat_attrlist_by_handle(
struct file *parfilp,
@@ -426,7 +504,6 @@ xfs_file_compat_ioctl(
struct inode *inode = file_inode(filp);
struct xfs_inode *ip = XFS_I(inode);
void __user *arg = compat_ptr(p);
- int error;
trace_xfs_file_compat_ioctl(ip);
@@ -434,85 +511,34 @@ xfs_file_compat_ioctl(
#if defined(BROKEN_X86_ALIGNMENT)
case XFS_IOC_FSGEOMETRY_V1_32:
return xfs_compat_ioc_fsgeometry_v1(ip->i_mount, arg);
- case XFS_IOC_FSGROWFSDATA_32: {
- struct xfs_growfs_data in;
-
- if (xfs_compat_growfs_data_copyin(&in, arg))
- return -EFAULT;
- error = mnt_want_write_file(filp);
- if (error)
- return error;
- error = xfs_growfs_data(ip->i_mount, &in);
- mnt_drop_write_file(filp);
- return error;
- }
- case XFS_IOC_FSGROWFSRT_32: {
- struct xfs_growfs_rt in;
-
- if (xfs_compat_growfs_rt_copyin(&in, arg))
- return -EFAULT;
- error = mnt_want_write_file(filp);
- if (error)
- return error;
- error = xfs_growfs_rt(ip->i_mount, &in);
- mnt_drop_write_file(filp);
- return error;
- }
+ case XFS_IOC_FSGROWFSDATA_32:
+ return xfs_compat_ioc_growfs_data(filp, ip->i_mount, arg);
+ case XFS_IOC_FSGROWFSRT_32:
+ return xfs_compat_ioc_growfs_rt(filp, ip->i_mount, arg);
#endif
- /* long changes size, but xfs only copiese out 32 bits */
case XFS_IOC_GETVERSION_32:
- cmd = _NATIVE_IOC(cmd, long);
- return xfs_file_ioctl(filp, cmd, p);
- case XFS_IOC_SWAPEXT_32: {
- struct xfs_swapext sxp;
- struct compat_xfs_swapext __user *sxu = arg;
-
- /* Bulk copy in up to the sx_stat field, then copy bstat */
- if (copy_from_user(&sxp, sxu,
- offsetof(struct xfs_swapext, sx_stat)) ||
- xfs_ioctl32_bstat_copyin(&sxp.sx_stat, &sxu->sx_stat))
- return -EFAULT;
- error = mnt_want_write_file(filp);
- if (error)
- return error;
- error = xfs_ioc_swapext(&sxp);
- mnt_drop_write_file(filp);
- return error;
- }
+ /* long changes size, but xfs only copies out 32 bits */
+ return xfs_file_ioctl(filp, _NATIVE_IOC(cmd, long), p);
+ case XFS_IOC_SWAPEXT_32:
+ return xfs_compat_ioc_swapext(filp, arg);
case XFS_IOC_FSBULKSTAT_32:
case XFS_IOC_FSBULKSTAT_SINGLE_32:
case XFS_IOC_FSINUMBERS_32:
return xfs_compat_ioc_fsbulkstat(filp, cmd, arg);
case XFS_IOC_FD_TO_HANDLE_32:
case XFS_IOC_PATH_TO_HANDLE_32:
- case XFS_IOC_PATH_TO_FSHANDLE_32: {
- struct xfs_fsop_handlereq hreq;
-
- if (xfs_compat_handlereq_copyin(&hreq, arg))
- return -EFAULT;
- cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq);
- return xfs_find_handle(cmd, &hreq);
- }
- case XFS_IOC_OPEN_BY_HANDLE_32: {
- struct xfs_fsop_handlereq hreq;
-
- if (xfs_compat_handlereq_copyin(&hreq, arg))
- return -EFAULT;
- return xfs_open_by_handle(filp, &hreq);
- }
- case XFS_IOC_READLINK_BY_HANDLE_32: {
- struct xfs_fsop_handlereq hreq;
-
- if (xfs_compat_handlereq_copyin(&hreq, arg))
- return -EFAULT;
- return xfs_readlink_by_handle(filp, &hreq);
- }
+ case XFS_IOC_PATH_TO_FSHANDLE_32:
+ return xfs_compat_ioc_find_handle(cmd, arg);
+ case XFS_IOC_OPEN_BY_HANDLE_32:
+ return xfs_compat_ioc_open_by_handle(filp, arg);
+ case XFS_IOC_READLINK_BY_HANDLE_32:
+ return xfs_compat_ioc_readlink_by_handle(filp, arg);
case XFS_IOC_ATTRLIST_BY_HANDLE_32:
return xfs_compat_attrlist_by_handle(filp, arg);
case XFS_IOC_ATTRMULTI_BY_HANDLE_32:
return xfs_compat_attrmulti_by_handle(filp, arg);
default:
/* try the native version */
- return xfs_file_ioctl(filp, cmd, (unsigned long)arg);
+ return xfs_file_ioctl(filp, cmd, p);
}
}
diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
index 40695d18dac0..e70be5b86f0b 100644
--- a/fs/xfs/xfs_ioend.c
+++ b/fs/xfs/xfs_ioend.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2016-2025 Christoph Hellwig.
+ * Copyright (c) 2016-2026 Christoph Hellwig.
* All Rights Reserved.
*/
#include "xfs_platform.h"
@@ -16,6 +16,135 @@
#include "xfs_reflink.h"
#include "xfs_zone_alloc.h"
#include "xfs_ioend.h"
+#include "xfs_error.h"
+#include "xfs_errortag.h"
+#include <linux/bio-integrity.h>
+
+static void
+xfs_dio_bounce_end_io(
+ struct bio *bio)
+{
+ struct iomap_ioend *ioend = iomap_ioend_from_bio(bio);
+ int error = blk_status_to_errno(bio->bi_status);
+ struct bio *orig_bio = bio->bi_private;
+
+ if ((ioend->io_flags & IOMAP_IOEND_INTEGRITY) && !bio->bi_status)
+ error = iomap_ioend_integrity_verify(ioend);
+ iomap_bounce_read_end_io(ioend, orig_bio, error);
+}
+
+static void
+xfs_bounce_submit_ioend(
+ struct iomap_ioend *ioend)
+{
+ if (ioend->io_flags & IOMAP_IOEND_INTEGRITY)
+ fs_bio_integrity_alloc(&ioend->io_bio);
+ ioend->io_bio.bi_end_io = xfs_dio_bounce_end_io;
+ bio_set_flag(&ioend->io_bio, BIO_COMPLETE_IN_TASK);
+ submit_bio(&ioend->io_bio);
+}
+
+static void
+xfs_end_bio_bounced(
+ struct bio *bio)
+{
+ /*
+ * Just complete the original ioends as all verification is done by the
+ * end_io handlers for the clone bio(s).
+ */
+ iomap_finish_ioends(iomap_ioend_from_bio(bio),
+ blk_status_to_errno(bio->bi_status));
+}
+
+static void
+xfs_read_bounce_and_resubmit(
+ struct iomap_ioend *ioend)
+{
+ struct bio *bio = &ioend->io_bio;
+ struct xfs_inode *ip = XFS_I(ioend->io_inode);
+ unsigned int nofs_flag = memalloc_nofs_save();
+
+ trace_xfs_bounce_reread(ip, ioend->io_offset, ioend->io_size);
+
+ /*
+ * Free the bio integrity data for the original bio, as we'll allocate
+ * a new one for each sub-I/O, which could deadlock if we keep the
+ * integrity data for the original bio around.
+ */
+ if (bio_integrity(bio))
+ fs_bio_integrity_free(bio);
+
+ /*
+ * Resubmit the bio through the iomap bounce machinery. The original
+ * bio itself is not resubmitted to the block layer, but just used to
+ * track I/O completion of the cloned bios.
+ */
+ bio_prepare_reissue(bio, xfs_inode_buftarg(ip)->bt_bdev);
+ bio->bi_iter = (struct bvec_iter) {
+ .bi_sector = ioend->io_sector,
+ .bi_size = ioend->io_size,
+ .bi_offset = ioend->io_bvec_offset,
+ };
+ bio->bi_end_io = xfs_end_bio_bounced;
+ iomap_bounce_read(ioend, bdev_logical_block_size(bio->bi_bdev),
+ xfs_bounce_submit_ioend);
+ memalloc_nofs_restore(nofs_flag);
+}
+
+static void
+xfs_end_io_read(
+ struct bio *bio)
+{
+ struct iomap_ioend *ioend = iomap_ioend_from_bio(bio);
+ struct xfs_inode *ip = XFS_I(ioend->io_inode);
+ struct xfs_mount *mp = ip->i_mount;
+ int error = blk_status_to_errno(bio->bi_status);
+
+ if (!error && (ioend->io_flags & IOMAP_IOEND_INTEGRITY)) {
+ error = iomap_ioend_integrity_verify(ioend);
+ if ((ioend->io_flags & IOMAP_IOEND_DIRECT) &&
+ READ_ONCE(mp->m_read_bounce) == XFS_READ_BOUNCE_LAZY) {
+ /*
+ * We only really need to retry for guard tag errors,
+ * but right now we can't distinguish them from other
+ * (i.e, reftag) errors.
+ */
+ if (error ||
+ XFS_TEST_ERROR(mp, XFS_ERRTAG_BOUNCE_REREAD)) {
+ xfs_read_bounce_and_resubmit(ioend);
+ return;
+ }
+ }
+ }
+
+ iomap_finish_ioends(ioend, error);
+}
+
+void
+xfs_ioend_submit_read(
+ struct inode *inode,
+ struct bio *bio,
+ loff_t file_offset,
+ u16 ioend_flags)
+{
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ struct iomap_ioend *ioend;
+
+ ioend = iomap_init_ioend(inode, bio, file_offset, ioend_flags);
+ if ((ioend_flags & IOMAP_IOEND_DIRECT) &&
+ READ_ONCE(mp->m_read_bounce) == XFS_READ_BOUNCE_ALWAYS) {
+ iomap_bounce_read(ioend, bdev_logical_block_size(bio->bi_bdev),
+ xfs_bounce_submit_ioend);
+ return;
+ }
+
+ if (ioend_flags & IOMAP_IOEND_INTEGRITY)
+ fs_bio_integrity_alloc(bio);
+ bio->bi_end_io = xfs_end_io_read;
+ bio_set_flag(bio, BIO_COMPLETE_IN_TASK);
+ submit_bio(bio);
+}
static void
xfs_ioend_put_open_zones(
@@ -148,11 +277,7 @@ xfs_end_io(
io_list))) {
list_del_init(&ioend->io_list);
iomap_ioend_try_merge(ioend, &tmp);
- if (bio_op(&ioend->io_bio) == REQ_OP_READ)
- iomap_finish_ioends(ioend,
- blk_status_to_errno(ioend->io_bio.bi_status));
- else
- xfs_end_ioend_write(ioend);
+ xfs_end_ioend_write(ioend);
cond_resched();
}
}
diff --git a/fs/xfs/xfs_ioend.h b/fs/xfs/xfs_ioend.h
index 525865767fca..7c2a1ea3e6ed 100644
--- a/fs/xfs/xfs_ioend.h
+++ b/fs/xfs/xfs_ioend.h
@@ -12,5 +12,7 @@ static inline bool xfs_ioend_is_append(struct iomap_ioend *ioend)
}
void xfs_end_bio(struct bio *bio);
+void xfs_ioend_submit_read(struct inode *inode, struct bio *bio,
+ loff_t file_offset, u16 ioend_flags);
#endif /* __XFS_IOEND_H */
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index d1306e723899..f67a541ef35a 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -169,7 +169,7 @@ xfs_create_need_xattr(
STATIC int
xfs_generic_create(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
umode_t mode,
@@ -279,7 +279,7 @@ xfs_generic_create(
STATIC int
xfs_vn_mknod(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
umode_t mode,
@@ -290,7 +290,7 @@ xfs_vn_mknod(
STATIC int
xfs_vn_create(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
umode_t mode)
@@ -300,7 +300,7 @@ xfs_vn_create(
STATIC struct dentry *
xfs_vn_mkdir(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
umode_t mode)
@@ -425,7 +425,7 @@ xfs_vn_unlink(
STATIC int
xfs_vn_symlink(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct inode *dir,
struct dentry *dentry,
const char *symname)
@@ -466,7 +466,7 @@ xfs_vn_symlink(
STATIC int
xfs_vn_rename(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct inode *odir,
struct dentry *odentry,
struct inode *ndir,
@@ -679,7 +679,7 @@ xfs_report_atomic_write(
STATIC int
xfs_vn_getattr(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
const struct path *path,
struct kstat *stat,
u32 request_mask,
@@ -754,7 +754,7 @@ xfs_vn_getattr(
static int
xfs_vn_change_ok(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct dentry *dentry,
struct iattr *iattr)
{
@@ -777,7 +777,7 @@ xfs_vn_change_ok(
*/
static int
xfs_setattr_nonsize(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct dentry *dentry,
struct xfs_inode *ip,
struct iattr *iattr)
@@ -903,7 +903,7 @@ out_dqrele:
*/
int
xfs_vn_setattr_size(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct dentry *dentry,
struct iattr *iattr)
{
@@ -1130,7 +1130,7 @@ out_trans_cancel:
STATIC int
xfs_vn_setattr(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct dentry *dentry,
struct iattr *iattr)
{
@@ -1250,7 +1250,7 @@ xfs_vn_fiemap(
STATIC int
xfs_vn_tmpfile(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct inode *dir,
struct file *file,
umode_t mode)
diff --git a/fs/xfs/xfs_iops.h b/fs/xfs/xfs_iops.h
index 0896f6b8b3b8..328305bba19d 100644
--- a/fs/xfs/xfs_iops.h
+++ b/fs/xfs/xfs_iops.h
@@ -10,7 +10,7 @@ struct xfs_inode;
extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
-int xfs_vn_setattr_size(struct mnt_idmap *idmap,
+int xfs_vn_setattr_size(const struct mnt_idmap *idmap,
struct dentry *dentry, struct iattr *vap);
int xfs_inode_init_security(struct inode *inode, struct inode *dir,
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 159295c63e8f..a4cf1effa5e6 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -63,7 +63,7 @@ want_metadir_file(
STATIC int
xfs_bulkstat_one_int(
struct xfs_mount *mp,
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct xfs_trans *tp,
xfs_ino_t ino,
struct xfs_bstat_chunk *bc)
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 2d0612f14d6e..c0567bfc30fb 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -8,7 +8,7 @@
/* In-memory representation of a userspace request for batch inode data. */
struct xfs_ibulk {
struct xfs_mount *mp;
- struct mnt_idmap *idmap;
+ const struct mnt_idmap *idmap;
void __user *ubuffer; /* user output buffer */
xfs_ino_t startino; /* start with this inode */
unsigned int icount; /* number of elements in ubuffer */
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 216a38a354e7..894ff2f4ecbd 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -142,6 +142,12 @@ struct xfs_freecounter {
uint64_t res_saved;
};
+enum xfs_read_bounce {
+ XFS_READ_BOUNCE_NEVER,
+ XFS_READ_BOUNCE_ALWAYS,
+ XFS_READ_BOUNCE_LAZY,
+};
+
/*
* The struct xfsmount layout is optimised to separate read-mostly variables
* from variables that are frequently modified. We put the read-mostly variables
@@ -177,6 +183,7 @@ typedef struct xfs_mount {
struct workqueue_struct *m_sync_workqueue;
struct workqueue_struct *m_blockgc_wq;
struct workqueue_struct *m_inodegc_wq;
+ enum xfs_read_bounce m_read_bounce;
int m_bsize; /* fs logical block size */
uint8_t m_blkbit_log; /* blocklog + NBBY */
@@ -291,6 +298,7 @@ typedef struct xfs_mount {
struct xfs_zone_info *m_zone_info; /* zone allocator information */
struct dentry *m_debugfs; /* debugfs parent */
struct xfs_kobj m_kobj;
+ struct xfs_kobj m_csum_kobj;
struct xfs_kobj m_error_kobj;
struct xfs_kobj m_error_meta_kobj;
struct xfs_error_cfg m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX];
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 54d00d543b51..008fed8624be 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1294,11 +1294,7 @@ xfs_qm_quotacheck_dqadjust(
*
* There are no timers for the default values set in the root dquot.
*/
- if (dqp->q_id) {
- xfs_qm_adjust_dqlimits(dqp);
- xfs_qm_adjust_dqtimers(dqp);
- }
-
+ xfs_qm_adjust_dqenforcement(dqp);
dqp->q_flags |= XFS_DQFLAG_DIRTY;
out_unlock:
mutex_unlock(&dqp->q_qlock);
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index 000cff1ce324..be2d5d6fe863 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -494,7 +494,7 @@ xfs_rui_validate_map(
!xfs_verify_ino(mp, map->me_owner))
return false;
- if (!xfs_verify_fileext(mp, map->me_startoff, map->me_len))
+ if (!xfs_verify_fileext(map->me_startoff, map->me_len))
return false;
if (isrt)
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 78a690b489ed..1d5108861acd 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -46,10 +46,34 @@ int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp);
int xfs_growfs_check_rtgeom(const struct xfs_mount *mp, xfs_rfsblock_t dblocks,
xfs_rfsblock_t rblocks, xfs_agblock_t rextsize);
#else
-# define xfs_growfs_rt(mp,in) (-ENOSYS)
-# define xfs_rtalloc_reinit_frextents(m) (0)
-# define xfs_rtmount_readsb(mp) (0)
-# define xfs_rtmount_freesb(mp) ((void)0)
+static inline int
+xfs_growfs_rt(
+ struct xfs_mount *mp,
+ struct xfs_growfs_rt *in)
+{
+ return -ENOSYS;
+}
+
+static inline int
+xfs_rtalloc_reinit_frextents(
+ struct xfs_mount *mp)
+{
+ return 0;
+}
+
+static inline int
+xfs_rtmount_readsb(
+ struct xfs_mount *mp)
+{
+ return 0;
+}
+
+static inline void
+xfs_rtmount_freesb(
+ struct xfs_mount *mp)
+{
+}
+
static inline int /* error */
xfs_rtmount_init(
xfs_mount_t *mp) /* file system mount structure */
@@ -60,8 +84,21 @@ xfs_rtmount_init(
xfs_warn(mp, "Not built with CONFIG_XFS_RT");
return -ENOSYS;
}
-# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (-ENOSYS))
-# define xfs_rtunmount_inodes(m)
+
+static inline int
+xfs_rtmount_inodes(
+ struct xfs_mount *mp)
+{
+ if (mp->m_sb.sb_rblocks)
+ return -ENOSYS;
+ return 0;
+}
+
+static inline void
+xfs_rtunmount_inodes(
+ struct xfs_mount *mp)
+{
+}
static inline int
xfs_growfs_check_rtgeom(const struct xfs_mount *mp,
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index b24db75eaedc..5a06132aa384 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1889,7 +1889,7 @@ xfs_fs_fill_super(
* Avoid integer overflow by comparing the maximum bmbt offset to the
* maximum pagecache offset in units of fs blocks.
*/
- if (!xfs_verify_fileoff(mp, XFS_B_TO_FSBT(mp, MAX_LFS_FILESIZE))) {
+ if (!xfs_verify_fileoff(XFS_B_TO_FSBT(mp, MAX_LFS_FILESIZE))) {
xfs_warn(mp,
"MAX_LFS_FILESIZE block offset (%llu) exceeds extent map maximum (%llu)!",
XFS_B_TO_FSBT(mp, MAX_LFS_FILESIZE),
@@ -2317,6 +2317,7 @@ xfs_init_fs_context(
mp->m_logbufs = -1;
mp->m_logbsize = -1;
mp->m_allocsize_log = 16; /* 64k */
+ mp->m_read_bounce = XFS_READ_BOUNCE_LAZY;
xfs_hooks_init(&mp->m_dir_update_hooks);
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index 5585ac7f4d16..709cd22248f8 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -82,7 +82,7 @@ xfs_readlink(
int
xfs_symlink(
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
struct xfs_inode *dp,
struct xfs_name *link_name,
const char *target_path,
@@ -219,7 +219,7 @@ xfs_symlink(
*ipp = du.ip;
xfs_iunlock(du.ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
return 0;
out_trans_cancel:
@@ -236,7 +236,7 @@ out_release_inode:
xfs_irele(du.ip);
}
out_parent:
- xfs_parent_finish(mp, du.ppargs);
+ xfs_parent_finish(du.ppargs);
out_release_dquots:
xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp);
diff --git a/fs/xfs/xfs_symlink.h b/fs/xfs/xfs_symlink.h
index 0d29a50e66fd..3c5a969f9fc5 100644
--- a/fs/xfs/xfs_symlink.h
+++ b/fs/xfs/xfs_symlink.h
@@ -7,7 +7,7 @@
/* Kernel only symlink definitions */
-int xfs_symlink(struct mnt_idmap *idmap, struct xfs_inode *dp,
+int xfs_symlink(const struct mnt_idmap *idmap, struct xfs_inode *dp,
struct xfs_name *link_name, const char *target_path,
umode_t mode, struct xfs_inode **ipp);
int xfs_readlink(struct xfs_inode *ip, char *link);
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c
index b62712187324..e77917ac179d 100644
--- a/fs/xfs/xfs_sysfs.c
+++ b/fs/xfs/xfs_sysfs.c
@@ -392,6 +392,71 @@ const struct kobj_type xfs_stats_ktype = {
.default_groups = xfs_stats_groups,
};
+static inline struct xfs_mount *csum_to_mp(struct kobject *kobj)
+{
+ return container_of(to_kobj(kobj), struct xfs_mount, m_csum_kobj);
+}
+
+static bool
+xfs_has_read_bounce(
+ struct xfs_mount *mp)
+{
+ if (bdev_has_integrity_csum(mp->m_ddev_targp->bt_bdev))
+ return true;
+ if (mp->m_rtdev_targp &&
+ bdev_has_integrity_csum(mp->m_rtdev_targp->bt_bdev))
+ return true;
+ return false;
+}
+
+static const char * const bounce_modes[] = {
+ [XFS_READ_BOUNCE_NEVER] = "never",
+ [XFS_READ_BOUNCE_ALWAYS] = "always",
+ [XFS_READ_BOUNCE_LAZY] = "lazy",
+};
+
+static ssize_t
+read_bounce_show(
+ struct kobject *kobj,
+ char *buf)
+{
+ struct xfs_mount *mp = csum_to_mp(kobj);
+
+ return sysfs_emit(buf, "%s\n",
+ bounce_modes[READ_ONCE(mp->m_read_bounce)]);
+}
+
+static ssize_t
+read_bounce_store(
+ struct kobject *kobj,
+ const char *buf,
+ size_t count)
+{
+ struct xfs_mount *mp = csum_to_mp(kobj);
+ int ret;
+
+ if (!xfs_has_read_bounce(mp))
+ return -EINVAL;
+ ret = sysfs_match_string(bounce_modes, buf);
+ if (ret < 0)
+ return ret;
+ WRITE_ONCE(mp->m_read_bounce, ret);
+ return count;
+}
+XFS_SYSFS_ATTR_RW(read_bounce);
+
+static struct attribute *xfs_csum_attrs[] = {
+ ATTR_LIST(read_bounce),
+ NULL,
+};
+ATTRIBUTE_GROUPS(xfs_csum);
+
+static const struct kobj_type xfs_csum_ktype = {
+ .release = xfs_sysfs_release,
+ .sysfs_ops = &xfs_sysfs_ops,
+ .default_groups = xfs_csum_groups,
+};
+
/* xlog */
static inline struct xlog *
@@ -817,11 +882,17 @@ xfs_mount_sysfs_init(
if (error)
goto out_remove_fsdir;
+ /* .../xfs/<dev>/csum/ */
+ error = xfs_sysfs_init(&mp->m_csum_kobj, &xfs_csum_ktype, &mp->m_kobj,
+ "csum");
+ if (error)
+ goto out_remove_stats_dir;
+
/* .../xfs/<dev>/error/ */
error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
&mp->m_kobj, "error");
if (error)
- goto out_remove_stats_dir;
+ goto out_remove_csum_dir;
/* .../xfs/<dev>/error/fail_at_unmount */
error = sysfs_create_file(&mp->m_error_kobj.kobject,
@@ -835,12 +906,14 @@ xfs_mount_sysfs_init(
"metadata", &mp->m_error_meta_kobj,
xfs_error_meta_init);
if (error)
- goto out_remove_error_dir;
+ goto out_remove_csum_dir;
return 0;
out_remove_error_dir:
xfs_sysfs_del(&mp->m_error_kobj);
+out_remove_csum_dir:
+ xfs_sysfs_del(&mp->m_csum_kobj);
out_remove_stats_dir:
xfs_sysfs_del(&mp->m_stats.xs_kobj);
out_remove_fsdir:
@@ -864,6 +937,7 @@ xfs_mount_sysfs_del(
}
xfs_sysfs_del(&mp->m_error_meta_kobj);
xfs_sysfs_del(&mp->m_error_kobj);
+ xfs_sysfs_del(&mp->m_csum_kobj);
xfs_sysfs_del(&mp->m_stats.xs_kobj);
xfs_sysfs_del(&mp->m_kobj);
}
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 6aa379c2cf0c..28d49f158b22 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -1896,6 +1896,7 @@ DEFINE_SIMPLE_IO_EVENT(xfs_zero_eof);
DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write);
DEFINE_SIMPLE_IO_EVENT(xfs_file_splice_read);
DEFINE_SIMPLE_IO_EVENT(xfs_zoned_map_blocks);
+DEFINE_SIMPLE_IO_EVENT(xfs_bounce_reread);
DECLARE_EVENT_CLASS(xfs_itrunc_class,
TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size),
@@ -6030,32 +6031,54 @@ DEFINE_HEALTHMON_EVENT(xfs_healthmon_detach);
DEFINE_HEALTHMON_EVENT(xfs_healthmon_report_unmount);
#define XFS_HEALTHMON_TYPE_STRINGS \
+ { XFS_HEALTHMON_RUNNING, "run" }, \
{ XFS_HEALTHMON_LOST, "lost" }, \
{ XFS_HEALTHMON_UNMOUNT, "unmount" }, \
+ { XFS_HEALTHMON_SHUTDOWN, "shutdown" }, \
{ XFS_HEALTHMON_SICK, "sick" }, \
{ XFS_HEALTHMON_CORRUPT, "corrupt" }, \
{ XFS_HEALTHMON_HEALTHY, "healthy" }, \
- { XFS_HEALTHMON_SHUTDOWN, "shutdown" }
+ { XFS_HEALTHMON_MEDIA_ERROR, "media" }, \
+ { XFS_HEALTHMON_BUFREAD, "bufread" }, \
+ { XFS_HEALTHMON_BUFWRITE, "bufwrite" }, \
+ { XFS_HEALTHMON_DIOREAD, "dioread" }, \
+ { XFS_HEALTHMON_DIOWRITE, "diowrite" }, \
+ { XFS_HEALTHMON_DATALOST, "datalost" }
#define XFS_HEALTHMON_DOMAIN_STRINGS \
{ XFS_HEALTHMON_MOUNT, "mount" }, \
{ XFS_HEALTHMON_FS, "fs" }, \
{ XFS_HEALTHMON_AG, "ag" }, \
{ XFS_HEALTHMON_INODE, "inode" }, \
- { XFS_HEALTHMON_RTGROUP, "rtgroup" }
+ { XFS_HEALTHMON_RTGROUP, "rtgroup" }, \
+ { XFS_HEALTHMON_DATADEV, "datadev" }, \
+ { XFS_HEALTHMON_RTDEV, "rtdev" }, \
+ { XFS_HEALTHMON_LOGDEV, "logdev" }, \
+ { XFS_HEALTHMON_FILERANGE, "filerange" }
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_RUNNING);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_LOST);
-TRACE_DEFINE_ENUM(XFS_HEALTHMON_SHUTDOWN);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_UNMOUNT);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_SHUTDOWN);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_SICK);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_CORRUPT);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_HEALTHY);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_MEDIA_ERROR);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_BUFREAD);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_BUFWRITE);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_DIOREAD);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_DIOWRITE);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_DATALOST);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_MOUNT);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_FS);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_AG);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_INODE);
TRACE_DEFINE_ENUM(XFS_HEALTHMON_RTGROUP);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_DATADEV);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_RTDEV);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_LOGDEV);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_FILERANGE);
DECLARE_EVENT_CLASS(xfs_healthmon_event_class,
TP_PROTO(const struct xfs_healthmon *hm,
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 1606c614f205..93ec876792cc 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -566,11 +566,7 @@ xfs_trans_apply_dquot_deltas(
* Get any default limits in use.
* Start/reset the timer(s) if needed.
*/
- if (dqp->q_id) {
- xfs_qm_adjust_dqlimits(dqp);
- xfs_qm_adjust_dqtimers(dqp);
- }
-
+ xfs_qm_adjust_dqenforcement(dqp);
dqp->q_flags |= XFS_DQFLAG_DIRTY;
/*
* add this to the list of items to get logged
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 1efe6c8139b2..b059a9714d11 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -169,7 +169,7 @@ xfs_xattr_flags_to_op(
static int
xfs_xattr_set(const struct xattr_handler *handler,
- struct mnt_idmap *idmap, struct dentry *unused,
+ const struct mnt_idmap *idmap, struct dentry *unused,
struct inode *inode, const char *name, const void *value,
size_t size, int flags)
{
diff --git a/fs/xfs/xfs_zone_alloc.c b/fs/xfs/xfs_zone_alloc.c
index b75cf3bfe33c..5f0af0c2c5e5 100644
--- a/fs/xfs/xfs_zone_alloc.c
+++ b/fs/xfs/xfs_zone_alloc.c
@@ -26,6 +26,7 @@
#include "xfs_zones.h"
#include "xfs_trace.h"
#include "xfs_mru_cache.h"
+#include <linux/bio-integrity.h>
static void
xfs_open_zone_free_rcu(
@@ -911,6 +912,9 @@ xfs_zone_alloc_and_submit(
if (xfs_is_shutdown(mp))
goto out_error;
+ if (ioend->io_flags & IOMAP_IOEND_INTEGRITY)
+ fs_bio_integrity_generate(&ioend->io_bio);
+
/*
* If we don't have a locally cached zone in this write context, see if
* the inode is still associated with a zone and use that if so.