xref: /openbmc/linux/fs/xfs/xfs_attr_inactive.c (revision aeb64ff3)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4  * Copyright (c) 2013 Red Hat, Inc.
5  * All Rights Reserved.
6  */
7 #include "xfs.h"
8 #include "xfs_fs.h"
9 #include "xfs_shared.h"
10 #include "xfs_format.h"
11 #include "xfs_log_format.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_bit.h"
14 #include "xfs_mount.h"
15 #include "xfs_da_format.h"
16 #include "xfs_da_btree.h"
17 #include "xfs_inode.h"
18 #include "xfs_attr_remote.h"
19 #include "xfs_trans.h"
20 #include "xfs_bmap.h"
21 #include "xfs_attr.h"
22 #include "xfs_attr_leaf.h"
23 #include "xfs_quota.h"
24 #include "xfs_dir2.h"
25 #include "xfs_error.h"
26 
27 /*
28  * Look at all the extents for this logical region,
29  * invalidate any buffers that are incore/in transactions.
30  */
31 STATIC int
32 xfs_attr3_leaf_freextent(
33 	struct xfs_trans	**trans,
34 	struct xfs_inode	*dp,
35 	xfs_dablk_t		blkno,
36 	int			blkcnt)
37 {
38 	struct xfs_bmbt_irec	map;
39 	struct xfs_buf		*bp;
40 	xfs_dablk_t		tblkno;
41 	xfs_daddr_t		dblkno;
42 	int			tblkcnt;
43 	int			dblkcnt;
44 	int			nmap;
45 	int			error;
46 
47 	/*
48 	 * Roll through the "value", invalidating the attribute value's
49 	 * blocks.
50 	 */
51 	tblkno = blkno;
52 	tblkcnt = blkcnt;
53 	while (tblkcnt > 0) {
54 		/*
55 		 * Try to remember where we decided to put the value.
56 		 */
57 		nmap = 1;
58 		error = xfs_bmapi_read(dp, (xfs_fileoff_t)tblkno, tblkcnt,
59 				       &map, &nmap, XFS_BMAPI_ATTRFORK);
60 		if (error) {
61 			return error;
62 		}
63 		ASSERT(nmap == 1);
64 		ASSERT(map.br_startblock != DELAYSTARTBLOCK);
65 
66 		/*
67 		 * If it's a hole, these are already unmapped
68 		 * so there's nothing to invalidate.
69 		 */
70 		if (map.br_startblock != HOLESTARTBLOCK) {
71 
72 			dblkno = XFS_FSB_TO_DADDR(dp->i_mount,
73 						  map.br_startblock);
74 			dblkcnt = XFS_FSB_TO_BB(dp->i_mount,
75 						map.br_blockcount);
76 			bp = xfs_trans_get_buf(*trans,
77 					dp->i_mount->m_ddev_targp,
78 					dblkno, dblkcnt, 0);
79 			if (!bp)
80 				return -ENOMEM;
81 			xfs_trans_binval(*trans, bp);
82 			/*
83 			 * Roll to next transaction.
84 			 */
85 			error = xfs_trans_roll_inode(trans, dp);
86 			if (error)
87 				return error;
88 		}
89 
90 		tblkno += map.br_blockcount;
91 		tblkcnt -= map.br_blockcount;
92 	}
93 
94 	return 0;
95 }
96 
97 /*
98  * Invalidate all of the "remote" value regions pointed to by a particular
99  * leaf block.
100  * Note that we must release the lock on the buffer so that we are not
101  * caught holding something that the logging code wants to flush to disk.
102  */
103 STATIC int
104 xfs_attr3_leaf_inactive(
105 	struct xfs_trans	**trans,
106 	struct xfs_inode	*dp,
107 	struct xfs_buf		*bp)
108 {
109 	struct xfs_attr_leafblock *leaf;
110 	struct xfs_attr3_icleaf_hdr ichdr;
111 	struct xfs_attr_leaf_entry *entry;
112 	struct xfs_attr_leaf_name_remote *name_rmt;
113 	struct xfs_attr_inactive_list *list;
114 	struct xfs_attr_inactive_list *lp;
115 	int			error;
116 	int			count;
117 	int			size;
118 	int			tmp;
119 	int			i;
120 	struct xfs_mount	*mp = bp->b_mount;
121 
122 	leaf = bp->b_addr;
123 	xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
124 
125 	/*
126 	 * Count the number of "remote" value extents.
127 	 */
128 	count = 0;
129 	entry = xfs_attr3_leaf_entryp(leaf);
130 	for (i = 0; i < ichdr.count; entry++, i++) {
131 		if (be16_to_cpu(entry->nameidx) &&
132 		    ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
133 			name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
134 			if (name_rmt->valueblk)
135 				count++;
136 		}
137 	}
138 
139 	/*
140 	 * If there are no "remote" values, we're done.
141 	 */
142 	if (count == 0) {
143 		xfs_trans_brelse(*trans, bp);
144 		return 0;
145 	}
146 
147 	/*
148 	 * Allocate storage for a list of all the "remote" value extents.
149 	 */
150 	size = count * sizeof(xfs_attr_inactive_list_t);
151 	list = kmem_alloc(size, 0);
152 
153 	/*
154 	 * Identify each of the "remote" value extents.
155 	 */
156 	lp = list;
157 	entry = xfs_attr3_leaf_entryp(leaf);
158 	for (i = 0; i < ichdr.count; entry++, i++) {
159 		if (be16_to_cpu(entry->nameidx) &&
160 		    ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
161 			name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
162 			if (name_rmt->valueblk) {
163 				lp->valueblk = be32_to_cpu(name_rmt->valueblk);
164 				lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
165 						    be32_to_cpu(name_rmt->valuelen));
166 				lp++;
167 			}
168 		}
169 	}
170 	xfs_trans_brelse(*trans, bp);	/* unlock for trans. in freextent() */
171 
172 	/*
173 	 * Invalidate each of the "remote" value extents.
174 	 */
175 	error = 0;
176 	for (lp = list, i = 0; i < count; i++, lp++) {
177 		tmp = xfs_attr3_leaf_freextent(trans, dp,
178 				lp->valueblk, lp->valuelen);
179 
180 		if (error == 0)
181 			error = tmp;	/* save only the 1st errno */
182 	}
183 
184 	kmem_free(list);
185 	return error;
186 }
187 
188 /*
189  * Recurse (gasp!) through the attribute nodes until we find leaves.
190  * We're doing a depth-first traversal in order to invalidate everything.
191  */
192 STATIC int
193 xfs_attr3_node_inactive(
194 	struct xfs_trans	**trans,
195 	struct xfs_inode	*dp,
196 	struct xfs_buf		*bp,
197 	int			level)
198 {
199 	struct xfs_mount	*mp = dp->i_mount;
200 	struct xfs_da_blkinfo	*info;
201 	xfs_dablk_t		child_fsb;
202 	xfs_daddr_t		parent_blkno, child_blkno;
203 	struct xfs_buf		*child_bp;
204 	struct xfs_da3_icnode_hdr ichdr;
205 	int			error, i;
206 
207 	/*
208 	 * Since this code is recursive (gasp!) we must protect ourselves.
209 	 */
210 	if (level > XFS_DA_NODE_MAXDEPTH) {
211 		xfs_trans_brelse(*trans, bp);	/* no locks for later trans */
212 		xfs_buf_corruption_error(bp);
213 		return -EFSCORRUPTED;
214 	}
215 
216 	xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, bp->b_addr);
217 	parent_blkno = bp->b_bn;
218 	if (!ichdr.count) {
219 		xfs_trans_brelse(*trans, bp);
220 		return 0;
221 	}
222 	child_fsb = be32_to_cpu(ichdr.btree[0].before);
223 	xfs_trans_brelse(*trans, bp);	/* no locks for later trans */
224 
225 	/*
226 	 * If this is the node level just above the leaves, simply loop
227 	 * over the leaves removing all of them.  If this is higher up
228 	 * in the tree, recurse downward.
229 	 */
230 	for (i = 0; i < ichdr.count; i++) {
231 		/*
232 		 * Read the subsidiary block to see what we have to work with.
233 		 * Don't do this in a transaction.  This is a depth-first
234 		 * traversal of the tree so we may deal with many blocks
235 		 * before we come back to this one.
236 		 */
237 		error = xfs_da3_node_read(*trans, dp, child_fsb, &child_bp,
238 					  XFS_ATTR_FORK);
239 		if (error)
240 			return error;
241 
242 		/* save for re-read later */
243 		child_blkno = XFS_BUF_ADDR(child_bp);
244 
245 		/*
246 		 * Invalidate the subtree, however we have to.
247 		 */
248 		info = child_bp->b_addr;
249 		switch (info->magic) {
250 		case cpu_to_be16(XFS_DA_NODE_MAGIC):
251 		case cpu_to_be16(XFS_DA3_NODE_MAGIC):
252 			error = xfs_attr3_node_inactive(trans, dp, child_bp,
253 							level + 1);
254 			break;
255 		case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
256 		case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
257 			error = xfs_attr3_leaf_inactive(trans, dp, child_bp);
258 			break;
259 		default:
260 			xfs_buf_corruption_error(child_bp);
261 			xfs_trans_brelse(*trans, child_bp);
262 			error = -EFSCORRUPTED;
263 			break;
264 		}
265 		if (error)
266 			return error;
267 
268 		/*
269 		 * Remove the subsidiary block from the cache and from the log.
270 		 */
271 		child_bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
272 				child_blkno,
273 				XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0);
274 		if (!child_bp)
275 			return -EIO;
276 		error = bp->b_error;
277 		if (error) {
278 			xfs_trans_brelse(*trans, child_bp);
279 			return error;
280 		}
281 		xfs_trans_binval(*trans, child_bp);
282 
283 		/*
284 		 * If we're not done, re-read the parent to get the next
285 		 * child block number.
286 		 */
287 		if (i + 1 < ichdr.count) {
288 			struct xfs_da3_icnode_hdr phdr;
289 
290 			error = xfs_da3_node_read_mapped(*trans, dp,
291 					parent_blkno, &bp, XFS_ATTR_FORK);
292 			if (error)
293 				return error;
294 			xfs_da3_node_hdr_from_disk(dp->i_mount, &phdr,
295 						  bp->b_addr);
296 			child_fsb = be32_to_cpu(phdr.btree[i + 1].before);
297 			xfs_trans_brelse(*trans, bp);
298 		}
299 		/*
300 		 * Atomically commit the whole invalidate stuff.
301 		 */
302 		error = xfs_trans_roll_inode(trans, dp);
303 		if (error)
304 			return  error;
305 	}
306 
307 	return 0;
308 }
309 
310 /*
311  * Indiscriminately delete the entire attribute fork
312  *
313  * Recurse (gasp!) through the attribute nodes until we find leaves.
314  * We're doing a depth-first traversal in order to invalidate everything.
315  */
316 static int
317 xfs_attr3_root_inactive(
318 	struct xfs_trans	**trans,
319 	struct xfs_inode	*dp)
320 {
321 	struct xfs_mount	*mp = dp->i_mount;
322 	struct xfs_da_blkinfo	*info;
323 	struct xfs_buf		*bp;
324 	xfs_daddr_t		blkno;
325 	int			error;
326 
327 	/*
328 	 * Read block 0 to see what we have to work with.
329 	 * We only get here if we have extents, since we remove
330 	 * the extents in reverse order the extent containing
331 	 * block 0 must still be there.
332 	 */
333 	error = xfs_da3_node_read(*trans, dp, 0, &bp, XFS_ATTR_FORK);
334 	if (error)
335 		return error;
336 	blkno = bp->b_bn;
337 
338 	/*
339 	 * Invalidate the tree, even if the "tree" is only a single leaf block.
340 	 * This is a depth-first traversal!
341 	 */
342 	info = bp->b_addr;
343 	switch (info->magic) {
344 	case cpu_to_be16(XFS_DA_NODE_MAGIC):
345 	case cpu_to_be16(XFS_DA3_NODE_MAGIC):
346 		error = xfs_attr3_node_inactive(trans, dp, bp, 1);
347 		break;
348 	case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
349 	case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
350 		error = xfs_attr3_leaf_inactive(trans, dp, bp);
351 		break;
352 	default:
353 		error = -EFSCORRUPTED;
354 		xfs_buf_corruption_error(bp);
355 		xfs_trans_brelse(*trans, bp);
356 		break;
357 	}
358 	if (error)
359 		return error;
360 
361 	/*
362 	 * Invalidate the incore copy of the root block.
363 	 */
364 	bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno,
365 			XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0);
366 	if (!bp)
367 		return -EIO;
368 	error = bp->b_error;
369 	if (error) {
370 		xfs_trans_brelse(*trans, bp);
371 		return error;
372 	}
373 	xfs_trans_binval(*trans, bp);	/* remove from cache */
374 	/*
375 	 * Commit the invalidate and start the next transaction.
376 	 */
377 	error = xfs_trans_roll_inode(trans, dp);
378 
379 	return error;
380 }
381 
382 /*
383  * xfs_attr_inactive kills all traces of an attribute fork on an inode. It
384  * removes both the on-disk and in-memory inode fork. Note that this also has to
385  * handle the condition of inodes without attributes but with an attribute fork
386  * configured, so we can't use xfs_inode_hasattr() here.
387  *
388  * The in-memory attribute fork is removed even on error.
389  */
390 int
391 xfs_attr_inactive(
392 	struct xfs_inode	*dp)
393 {
394 	struct xfs_trans	*trans;
395 	struct xfs_mount	*mp;
396 	int			lock_mode = XFS_ILOCK_SHARED;
397 	int			error = 0;
398 
399 	mp = dp->i_mount;
400 	ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
401 
402 	xfs_ilock(dp, lock_mode);
403 	if (!XFS_IFORK_Q(dp))
404 		goto out_destroy_fork;
405 	xfs_iunlock(dp, lock_mode);
406 
407 	lock_mode = 0;
408 
409 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrinval, 0, 0, 0, &trans);
410 	if (error)
411 		goto out_destroy_fork;
412 
413 	lock_mode = XFS_ILOCK_EXCL;
414 	xfs_ilock(dp, lock_mode);
415 
416 	if (!XFS_IFORK_Q(dp))
417 		goto out_cancel;
418 
419 	/*
420 	 * No need to make quota reservations here. We expect to release some
421 	 * blocks, not allocate, in the common case.
422 	 */
423 	xfs_trans_ijoin(trans, dp, 0);
424 
425 	/*
426 	 * Invalidate and truncate the attribute fork extents. Make sure the
427 	 * fork actually has attributes as otherwise the invalidation has no
428 	 * blocks to read and returns an error. In this case, just do the fork
429 	 * removal below.
430 	 */
431 	if (xfs_inode_hasattr(dp) &&
432 	    dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) {
433 		error = xfs_attr3_root_inactive(&trans, dp);
434 		if (error)
435 			goto out_cancel;
436 
437 		error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
438 		if (error)
439 			goto out_cancel;
440 	}
441 
442 	/* Reset the attribute fork - this also destroys the in-core fork */
443 	xfs_attr_fork_remove(dp, trans);
444 
445 	error = xfs_trans_commit(trans);
446 	xfs_iunlock(dp, lock_mode);
447 	return error;
448 
449 out_cancel:
450 	xfs_trans_cancel(trans);
451 out_destroy_fork:
452 	/* kill the in-core attr fork before we drop the inode lock */
453 	if (dp->i_afp)
454 		xfs_idestroy_fork(dp, XFS_ATTR_FORK);
455 	if (lock_mode)
456 		xfs_iunlock(dp, lock_mode);
457 	return error;
458 }
459