xref: /openbmc/linux/fs/xfs/xfs_iunlink_item.c (revision 9b2e5a23)
1784eb7d8SDave Chinner // SPDX-License-Identifier: GPL-2.0
2784eb7d8SDave Chinner /*
3784eb7d8SDave Chinner  * Copyright (c) 2020-2022, Red Hat, Inc.
4784eb7d8SDave Chinner  * All Rights Reserved.
5784eb7d8SDave Chinner  */
6784eb7d8SDave Chinner #include "xfs.h"
7784eb7d8SDave Chinner #include "xfs_fs.h"
8784eb7d8SDave Chinner #include "xfs_shared.h"
9784eb7d8SDave Chinner #include "xfs_format.h"
10784eb7d8SDave Chinner #include "xfs_log_format.h"
11784eb7d8SDave Chinner #include "xfs_trans_resv.h"
12784eb7d8SDave Chinner #include "xfs_mount.h"
13784eb7d8SDave Chinner #include "xfs_inode.h"
14784eb7d8SDave Chinner #include "xfs_trans.h"
15784eb7d8SDave Chinner #include "xfs_trans_priv.h"
16784eb7d8SDave Chinner #include "xfs_ag.h"
17784eb7d8SDave Chinner #include "xfs_iunlink_item.h"
18784eb7d8SDave Chinner #include "xfs_trace.h"
19784eb7d8SDave Chinner #include "xfs_error.h"
20784eb7d8SDave Chinner 
21784eb7d8SDave Chinner struct kmem_cache	*xfs_iunlink_cache;
22784eb7d8SDave Chinner 
IUL_ITEM(struct xfs_log_item * lip)23784eb7d8SDave Chinner static inline struct xfs_iunlink_item *IUL_ITEM(struct xfs_log_item *lip)
24784eb7d8SDave Chinner {
25784eb7d8SDave Chinner 	return container_of(lip, struct xfs_iunlink_item, item);
26784eb7d8SDave Chinner }
27784eb7d8SDave Chinner 
28784eb7d8SDave Chinner static void
xfs_iunlink_item_release(struct xfs_log_item * lip)29784eb7d8SDave Chinner xfs_iunlink_item_release(
30784eb7d8SDave Chinner 	struct xfs_log_item	*lip)
31784eb7d8SDave Chinner {
32784eb7d8SDave Chinner 	struct xfs_iunlink_item	*iup = IUL_ITEM(lip);
33784eb7d8SDave Chinner 
34784eb7d8SDave Chinner 	xfs_perag_put(iup->pag);
35784eb7d8SDave Chinner 	kmem_cache_free(xfs_iunlink_cache, IUL_ITEM(lip));
36784eb7d8SDave Chinner }
37784eb7d8SDave Chinner 
38784eb7d8SDave Chinner 
39784eb7d8SDave Chinner static uint64_t
xfs_iunlink_item_sort(struct xfs_log_item * lip)40784eb7d8SDave Chinner xfs_iunlink_item_sort(
41784eb7d8SDave Chinner 	struct xfs_log_item	*lip)
42784eb7d8SDave Chinner {
43784eb7d8SDave Chinner 	return IUL_ITEM(lip)->ip->i_ino;
44784eb7d8SDave Chinner }
45784eb7d8SDave Chinner 
46784eb7d8SDave Chinner /*
47784eb7d8SDave Chinner  * Look up the inode cluster buffer and log the on-disk unlinked inode change
48784eb7d8SDave Chinner  * we need to make.
49784eb7d8SDave Chinner  */
50784eb7d8SDave Chinner static int
xfs_iunlink_log_dinode(struct xfs_trans * tp,struct xfs_iunlink_item * iup)51784eb7d8SDave Chinner xfs_iunlink_log_dinode(
52784eb7d8SDave Chinner 	struct xfs_trans	*tp,
53784eb7d8SDave Chinner 	struct xfs_iunlink_item	*iup)
54784eb7d8SDave Chinner {
55784eb7d8SDave Chinner 	struct xfs_mount	*mp = tp->t_mountp;
56784eb7d8SDave Chinner 	struct xfs_inode	*ip = iup->ip;
57784eb7d8SDave Chinner 	struct xfs_dinode	*dip;
58784eb7d8SDave Chinner 	struct xfs_buf		*ibp;
59784eb7d8SDave Chinner 	int			offset;
60784eb7d8SDave Chinner 	int			error;
61784eb7d8SDave Chinner 
62784eb7d8SDave Chinner 	error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &ibp);
63784eb7d8SDave Chinner 	if (error)
64784eb7d8SDave Chinner 		return error;
65784eb7d8SDave Chinner 	/*
66784eb7d8SDave Chinner 	 * Don't log the unlinked field on stale buffers as this may be the
67784eb7d8SDave Chinner 	 * transaction that frees the inode cluster and relogging the buffer
68784eb7d8SDave Chinner 	 * here will incorrectly remove the stale state.
69784eb7d8SDave Chinner 	 */
70784eb7d8SDave Chinner 	if (ibp->b_flags & XBF_STALE)
71784eb7d8SDave Chinner 		goto out;
72784eb7d8SDave Chinner 
73784eb7d8SDave Chinner 	dip = xfs_buf_offset(ibp, ip->i_imap.im_boffset);
74784eb7d8SDave Chinner 
75784eb7d8SDave Chinner 	/* Make sure the old pointer isn't garbage. */
76784eb7d8SDave Chinner 	if (be32_to_cpu(dip->di_next_unlinked) != iup->old_agino) {
77784eb7d8SDave Chinner 		xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
78784eb7d8SDave Chinner 				sizeof(*dip), __this_address);
79784eb7d8SDave Chinner 		error = -EFSCORRUPTED;
80784eb7d8SDave Chinner 		goto out;
81784eb7d8SDave Chinner 	}
82784eb7d8SDave Chinner 
83784eb7d8SDave Chinner 	trace_xfs_iunlink_update_dinode(mp, iup->pag->pag_agno,
84784eb7d8SDave Chinner 			XFS_INO_TO_AGINO(mp, ip->i_ino),
85784eb7d8SDave Chinner 			be32_to_cpu(dip->di_next_unlinked), iup->next_agino);
86784eb7d8SDave Chinner 
87784eb7d8SDave Chinner 	dip->di_next_unlinked = cpu_to_be32(iup->next_agino);
88784eb7d8SDave Chinner 	offset = ip->i_imap.im_boffset +
89784eb7d8SDave Chinner 			offsetof(struct xfs_dinode, di_next_unlinked);
90784eb7d8SDave Chinner 
91784eb7d8SDave Chinner 	xfs_dinode_calc_crc(mp, dip);
92784eb7d8SDave Chinner 	xfs_trans_inode_buf(tp, ibp);
93784eb7d8SDave Chinner 	xfs_trans_log_buf(tp, ibp, offset, offset + sizeof(xfs_agino_t) - 1);
94784eb7d8SDave Chinner 	return 0;
95784eb7d8SDave Chinner out:
96784eb7d8SDave Chinner 	xfs_trans_brelse(tp, ibp);
97784eb7d8SDave Chinner 	return error;
98784eb7d8SDave Chinner }
99784eb7d8SDave Chinner 
100784eb7d8SDave Chinner /*
101784eb7d8SDave Chinner  * On precommit, we grab the inode cluster buffer for the inode number we were
102784eb7d8SDave Chinner  * passed, then update the next unlinked field for that inode in the buffer and
103784eb7d8SDave Chinner  * log the buffer. This ensures that the inode cluster buffer was logged in the
104784eb7d8SDave Chinner  * correct order w.r.t. other inode cluster buffers. We can then remove the
105784eb7d8SDave Chinner  * iunlink item from the transaction and release it as it is has now served it's
106784eb7d8SDave Chinner  * purpose.
107784eb7d8SDave Chinner  */
108784eb7d8SDave Chinner static int
xfs_iunlink_item_precommit(struct xfs_trans * tp,struct xfs_log_item * lip)109784eb7d8SDave Chinner xfs_iunlink_item_precommit(
110784eb7d8SDave Chinner 	struct xfs_trans	*tp,
111784eb7d8SDave Chinner 	struct xfs_log_item	*lip)
112784eb7d8SDave Chinner {
113784eb7d8SDave Chinner 	struct xfs_iunlink_item	*iup = IUL_ITEM(lip);
114784eb7d8SDave Chinner 	int			error;
115784eb7d8SDave Chinner 
116784eb7d8SDave Chinner 	error = xfs_iunlink_log_dinode(tp, iup);
117784eb7d8SDave Chinner 	list_del(&lip->li_trans);
118784eb7d8SDave Chinner 	xfs_iunlink_item_release(lip);
119784eb7d8SDave Chinner 	return error;
120784eb7d8SDave Chinner }
121784eb7d8SDave Chinner 
122784eb7d8SDave Chinner static const struct xfs_item_ops xfs_iunlink_item_ops = {
123784eb7d8SDave Chinner 	.iop_release	= xfs_iunlink_item_release,
124784eb7d8SDave Chinner 	.iop_sort	= xfs_iunlink_item_sort,
125784eb7d8SDave Chinner 	.iop_precommit	= xfs_iunlink_item_precommit,
126784eb7d8SDave Chinner };
127784eb7d8SDave Chinner 
128784eb7d8SDave Chinner 
129784eb7d8SDave Chinner /*
130784eb7d8SDave Chinner  * Initialize the inode log item for a newly allocated (in-core) inode.
131784eb7d8SDave Chinner  *
132784eb7d8SDave Chinner  * Inode extents can only reside within an AG. Hence specify the starting
133784eb7d8SDave Chinner  * block for the inode chunk by offset within an AG as well as the
134784eb7d8SDave Chinner  * length of the allocated extent.
135784eb7d8SDave Chinner  *
136784eb7d8SDave Chinner  * This joins the item to the transaction and marks it dirty so
137784eb7d8SDave Chinner  * that we don't need a separate call to do this, nor does the
138784eb7d8SDave Chinner  * caller need to know anything about the iunlink item.
139784eb7d8SDave Chinner  */
140784eb7d8SDave Chinner int
xfs_iunlink_log_inode(struct xfs_trans * tp,struct xfs_inode * ip,struct xfs_perag * pag,xfs_agino_t next_agino)141784eb7d8SDave Chinner xfs_iunlink_log_inode(
142784eb7d8SDave Chinner 	struct xfs_trans	*tp,
143784eb7d8SDave Chinner 	struct xfs_inode	*ip,
144784eb7d8SDave Chinner 	struct xfs_perag	*pag,
145784eb7d8SDave Chinner 	xfs_agino_t		next_agino)
146784eb7d8SDave Chinner {
147784eb7d8SDave Chinner 	struct xfs_mount	*mp = tp->t_mountp;
148784eb7d8SDave Chinner 	struct xfs_iunlink_item	*iup;
149784eb7d8SDave Chinner 
150784eb7d8SDave Chinner 	ASSERT(xfs_verify_agino_or_null(pag, next_agino));
151784eb7d8SDave Chinner 	ASSERT(xfs_verify_agino_or_null(pag, ip->i_next_unlinked));
152784eb7d8SDave Chinner 
153784eb7d8SDave Chinner 	/*
154784eb7d8SDave Chinner 	 * Since we're updating a linked list, we should never find that the
155784eb7d8SDave Chinner 	 * current pointer is the same as the new value, unless we're
156784eb7d8SDave Chinner 	 * terminating the list.
157784eb7d8SDave Chinner 	 */
158784eb7d8SDave Chinner 	if (ip->i_next_unlinked == next_agino) {
159784eb7d8SDave Chinner 		if (next_agino != NULLAGINO)
160784eb7d8SDave Chinner 			return -EFSCORRUPTED;
161784eb7d8SDave Chinner 		return 0;
162784eb7d8SDave Chinner 	}
163784eb7d8SDave Chinner 
164784eb7d8SDave Chinner 	iup = kmem_cache_zalloc(xfs_iunlink_cache, GFP_KERNEL | __GFP_NOFAIL);
165784eb7d8SDave Chinner 	xfs_log_item_init(mp, &iup->item, XFS_LI_IUNLINK,
166784eb7d8SDave Chinner 			  &xfs_iunlink_item_ops);
167784eb7d8SDave Chinner 
168784eb7d8SDave Chinner 	iup->ip = ip;
169784eb7d8SDave Chinner 	iup->next_agino = next_agino;
170784eb7d8SDave Chinner 	iup->old_agino = ip->i_next_unlinked;
171*9b2e5a23SDarrick J. Wong 	iup->pag = xfs_perag_hold(pag);
172784eb7d8SDave Chinner 
173784eb7d8SDave Chinner 	xfs_trans_add_item(tp, &iup->item);
174784eb7d8SDave Chinner 	tp->t_flags |= XFS_TRANS_DIRTY;
175784eb7d8SDave Chinner 	set_bit(XFS_LI_DIRTY, &iup->item.li_flags);
176784eb7d8SDave Chinner 	return 0;
177784eb7d8SDave Chinner }
178784eb7d8SDave Chinner 
179