File Index
Files and directories
Sign in
FILE

xfs_inode_util.c

File preview with syntax highlighting.

linux-6.19.14/fs/xfs/libxfs/xfs_inode_util.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  4 * All Rights Reserved.
  5 */
  6#include <linux/iversion.h>
  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_sb.h"
 14#include "xfs_mount.h"
 15#include "xfs_inode.h"
 16#include "xfs_inode_util.h"
 17#include "xfs_trans.h"
 18#include "xfs_ialloc.h"
 19#include "xfs_health.h"
 20#include "xfs_bmap.h"
 21#include "xfs_error.h"
 22#include "xfs_trace.h"
 23#include "xfs_ag.h"
 24#include "xfs_iunlink_item.h"
 25#include "xfs_inode_item.h"
 26
 27uint16_t
 28xfs_flags2diflags(
 29	struct xfs_inode	*ip,
 30	unsigned int		xflags)
 31{
 32	/* can't set PREALLOC this way, just preserve it */
 33	uint16_t		di_flags =
 34		(ip->i_diflags & XFS_DIFLAG_PREALLOC);
 35
 36	if (xflags & FS_XFLAG_IMMUTABLE)
 37		di_flags |= XFS_DIFLAG_IMMUTABLE;
 38	if (xflags & FS_XFLAG_APPEND)
 39		di_flags |= XFS_DIFLAG_APPEND;
 40	if (xflags & FS_XFLAG_SYNC)
 41		di_flags |= XFS_DIFLAG_SYNC;
 42	if (xflags & FS_XFLAG_NOATIME)
 43		di_flags |= XFS_DIFLAG_NOATIME;
 44	if (xflags & FS_XFLAG_NODUMP)
 45		di_flags |= XFS_DIFLAG_NODUMP;
 46	if (xflags & FS_XFLAG_NODEFRAG)
 47		di_flags |= XFS_DIFLAG_NODEFRAG;
 48	if (xflags & FS_XFLAG_FILESTREAM)
 49		di_flags |= XFS_DIFLAG_FILESTREAM;
 50	if (S_ISDIR(VFS_I(ip)->i_mode)) {
 51		if (xflags & FS_XFLAG_RTINHERIT)
 52			di_flags |= XFS_DIFLAG_RTINHERIT;
 53		if (xflags & FS_XFLAG_NOSYMLINKS)
 54			di_flags |= XFS_DIFLAG_NOSYMLINKS;
 55		if (xflags & FS_XFLAG_EXTSZINHERIT)
 56			di_flags |= XFS_DIFLAG_EXTSZINHERIT;
 57		if (xflags & FS_XFLAG_PROJINHERIT)
 58			di_flags |= XFS_DIFLAG_PROJINHERIT;
 59	} else if (S_ISREG(VFS_I(ip)->i_mode)) {
 60		if (xflags & FS_XFLAG_REALTIME)
 61			di_flags |= XFS_DIFLAG_REALTIME;
 62		if (xflags & FS_XFLAG_EXTSIZE)
 63			di_flags |= XFS_DIFLAG_EXTSIZE;
 64	}
 65
 66	return di_flags;
 67}
 68
 69uint64_t
 70xfs_flags2diflags2(
 71	struct xfs_inode	*ip,
 72	unsigned int		xflags)
 73{
 74	uint64_t		di_flags2 =
 75		(ip->i_diflags2 & (XFS_DIFLAG2_REFLINK |
 76				   XFS_DIFLAG2_BIGTIME |
 77				   XFS_DIFLAG2_NREXT64));
 78
 79	if (xflags & FS_XFLAG_DAX)
 80		di_flags2 |= XFS_DIFLAG2_DAX;
 81	if (xflags & FS_XFLAG_COWEXTSIZE)
 82		di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
 83
 84	return di_flags2;
 85}
 86
 87uint32_t
 88xfs_ip2xflags(
 89	struct xfs_inode	*ip)
 90{
 91	uint32_t		flags = 0;
 92
 93	if (ip->i_diflags & XFS_DIFLAG_ANY) {
 94		if (ip->i_diflags & XFS_DIFLAG_REALTIME)
 95			flags |= FS_XFLAG_REALTIME;
 96		if (ip->i_diflags & XFS_DIFLAG_PREALLOC)
 97			flags |= FS_XFLAG_PREALLOC;
 98		if (ip->i_diflags & XFS_DIFLAG_IMMUTABLE)
 99			flags |= FS_XFLAG_IMMUTABLE;
100		if (ip->i_diflags & XFS_DIFLAG_APPEND)
101			flags |= FS_XFLAG_APPEND;
102		if (ip->i_diflags & XFS_DIFLAG_SYNC)
103			flags |= FS_XFLAG_SYNC;
104		if (ip->i_diflags & XFS_DIFLAG_NOATIME)
105			flags |= FS_XFLAG_NOATIME;
106		if (ip->i_diflags & XFS_DIFLAG_NODUMP)
107			flags |= FS_XFLAG_NODUMP;
108		if (ip->i_diflags & XFS_DIFLAG_RTINHERIT)
109			flags |= FS_XFLAG_RTINHERIT;
110		if (ip->i_diflags & XFS_DIFLAG_PROJINHERIT)
111			flags |= FS_XFLAG_PROJINHERIT;
112		if (ip->i_diflags & XFS_DIFLAG_NOSYMLINKS)
113			flags |= FS_XFLAG_NOSYMLINKS;
114		if (ip->i_diflags & XFS_DIFLAG_EXTSIZE)
115			flags |= FS_XFLAG_EXTSIZE;
116		if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT)
117			flags |= FS_XFLAG_EXTSZINHERIT;
118		if (ip->i_diflags & XFS_DIFLAG_NODEFRAG)
119			flags |= FS_XFLAG_NODEFRAG;
120		if (ip->i_diflags & XFS_DIFLAG_FILESTREAM)
121			flags |= FS_XFLAG_FILESTREAM;
122	}
123
124	if (ip->i_diflags2 & XFS_DIFLAG2_ANY) {
125		if (ip->i_diflags2 & XFS_DIFLAG2_DAX)
126			flags |= FS_XFLAG_DAX;
127		if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
128			flags |= FS_XFLAG_COWEXTSIZE;
129	}
130
131	if (xfs_inode_has_attr_fork(ip))
132		flags |= FS_XFLAG_HASATTR;
133	return flags;
134}
135
136prid_t
137xfs_get_initial_prid(struct xfs_inode *dp)
138{
139	if (dp->i_diflags & XFS_DIFLAG_PROJINHERIT)
140		return dp->i_projid;
141
142	/* Assign to the root project by default. */
143	return 0;
144}
145
146/* Propagate di_flags from a parent inode to a child inode. */
147static inline void
148xfs_inode_inherit_flags(
149	struct xfs_inode	*ip,
150	const struct xfs_inode	*pip)
151{
152	unsigned int		di_flags = 0;
153	xfs_failaddr_t		failaddr;
154	umode_t			mode = VFS_I(ip)->i_mode;
155
156	if (S_ISDIR(mode)) {
157		if (pip->i_diflags & XFS_DIFLAG_RTINHERIT)
158			di_flags |= XFS_DIFLAG_RTINHERIT;
159		if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
160			di_flags |= XFS_DIFLAG_EXTSZINHERIT;
161			ip->i_extsize = pip->i_extsize;
162		}
163		if (pip->i_diflags & XFS_DIFLAG_PROJINHERIT)
164			di_flags |= XFS_DIFLAG_PROJINHERIT;
165	} else if (S_ISREG(mode)) {
166		if ((pip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
167		    xfs_has_realtime(ip->i_mount))
168			di_flags |= XFS_DIFLAG_REALTIME;
169		if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
170			di_flags |= XFS_DIFLAG_EXTSIZE;
171			ip->i_extsize = pip->i_extsize;
172		}
173	}
174	if ((pip->i_diflags & XFS_DIFLAG_NOATIME) &&
175	    xfs_inherit_noatime)
176		di_flags |= XFS_DIFLAG_NOATIME;
177	if ((pip->i_diflags & XFS_DIFLAG_NODUMP) &&
178	    xfs_inherit_nodump)
179		di_flags |= XFS_DIFLAG_NODUMP;
180	if ((pip->i_diflags & XFS_DIFLAG_SYNC) &&
181	    xfs_inherit_sync)
182		di_flags |= XFS_DIFLAG_SYNC;
183	if ((pip->i_diflags & XFS_DIFLAG_NOSYMLINKS) &&
184	    xfs_inherit_nosymlinks)
185		di_flags |= XFS_DIFLAG_NOSYMLINKS;
186	if ((pip->i_diflags & XFS_DIFLAG_NODEFRAG) &&
187	    xfs_inherit_nodefrag)
188		di_flags |= XFS_DIFLAG_NODEFRAG;
189	if (pip->i_diflags & XFS_DIFLAG_FILESTREAM)
190		di_flags |= XFS_DIFLAG_FILESTREAM;
191
192	ip->i_diflags |= di_flags;
193
194	/*
195	 * Inode verifiers on older kernels only check that the extent size
196	 * hint is an integer multiple of the rt extent size on realtime files.
197	 * They did not check the hint alignment on a directory with both
198	 * rtinherit and extszinherit flags set.  If the misaligned hint is
199	 * propagated from a directory into a new realtime file, new file
200	 * allocations will fail due to math errors in the rt allocator and/or
201	 * trip the verifiers.  Validate the hint settings in the new file so
202	 * that we don't let broken hints propagate.
203	 */
204	failaddr = xfs_inode_validate_extsize(ip->i_mount, ip->i_extsize,
205			VFS_I(ip)->i_mode, ip->i_diflags);
206	if (failaddr) {
207		ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
208				   XFS_DIFLAG_EXTSZINHERIT);
209		ip->i_extsize = 0;
210	}
211}
212
213/* Propagate di_flags2 from a parent inode to a child inode. */
214static inline void
215xfs_inode_inherit_flags2(
216	struct xfs_inode	*ip,
217	const struct xfs_inode	*pip)
218{
219	xfs_failaddr_t		failaddr;
220
221	if (pip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) {
222		ip->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE;
223		ip->i_cowextsize = pip->i_cowextsize;
224	}
225	if (pip->i_diflags2 & XFS_DIFLAG2_DAX)
226		ip->i_diflags2 |= XFS_DIFLAG2_DAX;
227	if (xfs_is_metadir_inode(pip))
228		ip->i_diflags2 |= XFS_DIFLAG2_METADATA;
229
230	/* Don't let invalid cowextsize hints propagate. */
231	failaddr = xfs_inode_validate_cowextsize(ip->i_mount, ip->i_cowextsize,
232			VFS_I(ip)->i_mode, ip->i_diflags, ip->i_diflags2);
233	if (failaddr) {
234		ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
235		ip->i_cowextsize = 0;
236	}
237}
238
239/*
240 * If we need to create attributes immediately after allocating the inode,
241 * initialise an empty attribute fork right now. We use the default fork offset
242 * for attributes here as we don't know exactly what size or how many
243 * attributes we might be adding. We can do this safely here because we know
244 * the data fork is completely empty and this saves us from needing to run a
245 * separate transaction to set the fork offset in the immediate future.
246 *
247 * If we have parent pointers and the caller hasn't told us that the file will
248 * never be linked into a directory tree, we /must/ create the attr fork.
249 */
250static inline bool
251xfs_icreate_want_attrfork(
252	struct xfs_mount		*mp,
253	const struct xfs_icreate_args	*args)
254{
255	if (args->flags & XFS_ICREATE_INIT_XATTRS)
256		return true;
257
258	if (!(args->flags & XFS_ICREATE_UNLINKABLE) && xfs_has_parent(mp))
259		return true;
260
261	return false;
262}
263
264/* Initialise an inode's attributes. */
265void
266xfs_inode_init(
267	struct xfs_trans	*tp,
268	const struct xfs_icreate_args *args,
269	struct xfs_inode	*ip)
270{
271	struct xfs_inode	*pip = args->pip;
272	struct inode		*dir = pip ? VFS_I(pip) : NULL;
273	struct xfs_mount	*mp = tp->t_mountp;
274	struct inode		*inode = VFS_I(ip);
275	unsigned int		flags;
276	int			times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG |
277					XFS_ICHGTIME_ACCESS;
278
279	if (args->flags & XFS_ICREATE_TMPFILE)
280		set_nlink(inode, 0);
281	else if (S_ISDIR(args->mode))
282		set_nlink(inode, 2);
283	else
284		set_nlink(inode, 1);
285	inode->i_rdev = args->rdev;
286
287	if (!args->idmap || pip == NULL) {
288		/* creating a tree root, sb rooted, or detached file */
289		inode->i_uid = GLOBAL_ROOT_UID;
290		inode->i_gid = GLOBAL_ROOT_GID;
291		ip->i_projid = 0;
292		inode->i_mode = args->mode;
293	} else {
294		/* creating a child in the directory tree */
295		if (dir && !(dir->i_mode & S_ISGID) && xfs_has_grpid(mp)) {
296			inode_fsuid_set(inode, args->idmap);
297			inode->i_gid = dir->i_gid;
298			inode->i_mode = args->mode;
299		} else {
300			inode_init_owner(args->idmap, inode, dir, args->mode);
301		}
302		ip->i_projid = xfs_get_initial_prid(pip);
303	}
304
305	ip->i_disk_size = 0;
306	ip->i_df.if_nextents = 0;
307	ASSERT(ip->i_nblocks == 0);
308
309	ip->i_extsize = 0;
310	ip->i_diflags = 0;
311
312	if (xfs_has_v3inodes(mp)) {
313		inode_set_iversion(inode, 1);
314		/* also covers the di_used_blocks union arm: */
315		ip->i_cowextsize = 0;
316		times |= XFS_ICHGTIME_CREATE;
317	}
318
319	xfs_trans_ichgtime(tp, ip, times);
320
321	flags = XFS_ILOG_CORE;
322	switch (args->mode & S_IFMT) {
323	case S_IFIFO:
324	case S_IFCHR:
325	case S_IFBLK:
326	case S_IFSOCK:
327		ip->i_df.if_format = XFS_DINODE_FMT_DEV;
328		flags |= XFS_ILOG_DEV;
329		break;
330	case S_IFREG:
331	case S_IFDIR:
332		if (pip && (pip->i_diflags & XFS_DIFLAG_ANY))
333			xfs_inode_inherit_flags(ip, pip);
334		if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY))
335			xfs_inode_inherit_flags2(ip, pip);
336		fallthrough;
337	case S_IFLNK:
338		ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
339		ip->i_df.if_bytes = 0;
340		ip->i_df.if_data = NULL;
341		break;
342	default:
343		ASSERT(0);
344	}
345
346	if (xfs_icreate_want_attrfork(mp, args)) {
347		ip->i_forkoff = xfs_default_attroffset(ip) >> 3;
348		xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0);
349
350		if (!xfs_has_attr(mp)) {
351			spin_lock(&mp->m_sb_lock);
352			xfs_add_attr(mp);
353			spin_unlock(&mp->m_sb_lock);
354			xfs_log_sb(tp);
355		}
356	}
357
358	xfs_trans_log_inode(tp, ip, flags);
359}
360
361/*
362 * In-Core Unlinked List Lookups
363 * =============================
364 *
365 * Every inode is supposed to be reachable from some other piece of metadata
366 * with the exception of the root directory.  Inodes with a connection to a
367 * file descriptor but not linked from anywhere in the on-disk directory tree
368 * are collectively known as unlinked inodes, though the filesystem itself
369 * maintains links to these inodes so that on-disk metadata are consistent.
370 *
371 * XFS implements a per-AG on-disk hash table of unlinked inodes.  The AGI
372 * header contains a number of buckets that point to an inode, and each inode
373 * record has a pointer to the next inode in the hash chain.  This
374 * singly-linked list causes scaling problems in the iunlink remove function
375 * because we must walk that list to find the inode that points to the inode
376 * being removed from the unlinked hash bucket list.
377 *
378 * Hence we keep an in-memory double linked list to link each inode on an
379 * unlinked list. Because there are 64 unlinked lists per AGI, keeping pointer
380 * based lists would require having 64 list heads in the perag, one for each
381 * list. This is expensive in terms of memory (think millions of AGs) and cache
382 * misses on lookups. Instead, use the fact that inodes on the unlinked list
383 * must be referenced at the VFS level to keep them on the list and hence we
384 * have an existence guarantee for inodes on the unlinked list.
385 *
386 * Given we have an existence guarantee, we can use lockless inode cache lookups
387 * to resolve aginos to xfs inodes. This means we only need 8 bytes per inode
388 * for the double linked unlinked list, and we don't need any extra locking to
389 * keep the list safe as all manipulations are done under the AGI buffer lock.
390 * Keeping the list up to date does not require memory allocation, just finding
391 * the XFS inode and updating the next/prev unlinked list aginos.
392 */
393
394/*
395 * Update the prev pointer of the next agino.  Returns -ENOLINK if the inode
396 * is not in cache.
397 */
398static int
399xfs_iunlink_update_backref(
400	struct xfs_perag	*pag,
401	xfs_agino_t		prev_agino,
402	xfs_agino_t		next_agino)
403{
404	struct xfs_inode	*ip;
405
406	/* No update necessary if we are at the end of the list. */
407	if (next_agino == NULLAGINO)
408		return 0;
409
410	ip = xfs_iunlink_lookup(pag, next_agino);
411	if (!ip)
412		return -ENOLINK;
413
414	ip->i_prev_unlinked = prev_agino;
415	return 0;
416}
417
418/*
419 * Point the AGI unlinked bucket at an inode and log the results.  The caller
420 * is responsible for validating the old value.
421 */
422STATIC int
423xfs_iunlink_update_bucket(
424	struct xfs_trans	*tp,
425	struct xfs_perag	*pag,
426	struct xfs_buf		*agibp,
427	unsigned int		bucket_index,
428	xfs_agino_t		new_agino)
429{
430	struct xfs_agi		*agi = agibp->b_addr;
431	xfs_agino_t		old_value;
432	int			offset;
433
434	ASSERT(xfs_verify_agino_or_null(pag, new_agino));
435
436	old_value = be32_to_cpu(agi->agi_unlinked[bucket_index]);
437	trace_xfs_iunlink_update_bucket(pag, bucket_index, old_value,
438			new_agino);
439
440	/*
441	 * We should never find the head of the list already set to the value
442	 * passed in because either we're adding or removing ourselves from the
443	 * head of the list.
444	 */
445	if (old_value == new_agino) {
446		xfs_buf_mark_corrupt(agibp);
447		xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
448		return -EFSCORRUPTED;
449	}
450
451	agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino);
452	offset = offsetof(struct xfs_agi, agi_unlinked) +
453			(sizeof(xfs_agino_t) * bucket_index);
454	xfs_trans_log_buf(tp, agibp, offset, offset + sizeof(xfs_agino_t) - 1);
455	return 0;
456}
457
458static int
459xfs_iunlink_insert_inode(
460	struct xfs_trans	*tp,
461	struct xfs_perag	*pag,
462	struct xfs_buf		*agibp,
463	struct xfs_inode	*ip)
464{
465	struct xfs_mount	*mp = tp->t_mountp;
466	struct xfs_agi		*agi = agibp->b_addr;
467	xfs_agino_t		next_agino;
468	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
469	short			bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
470	int			error;
471
472	/*
473	 * Get the index into the agi hash table for the list this inode will
474	 * go on.  Make sure the pointer isn't garbage and that this inode
475	 * isn't already on the list.
476	 */
477	next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
478	if (next_agino == agino ||
479	    !xfs_verify_agino_or_null(pag, next_agino)) {
480		xfs_buf_mark_corrupt(agibp);
481		xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
482		return -EFSCORRUPTED;
483	}
484
485	/*
486	 * Update the prev pointer in the next inode to point back to this
487	 * inode.
488	 */
489	error = xfs_iunlink_update_backref(pag, agino, next_agino);
490	if (error == -ENOLINK)
491		error = xfs_iunlink_reload_next(tp, agibp, agino, next_agino);
492	if (error)
493		return error;
494
495	if (next_agino != NULLAGINO) {
496		/*
497		 * There is already another inode in the bucket, so point this
498		 * inode to the current head of the list.
499		 */
500		error = xfs_iunlink_log_inode(tp, ip, pag, next_agino);
501		if (error)
502			return error;
503		ip->i_next_unlinked = next_agino;
504	}
505
506	/* Point the head of the list to point to this inode. */
507	ip->i_prev_unlinked = NULLAGINO;
508	return xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, agino);
509}
510
511/*
512 * This is called when the inode's link count has gone to 0 or we are creating
513 * a tmpfile via O_TMPFILE.  The inode @ip must have nlink == 0.
514 *
515 * We place the on-disk inode on a list in the AGI.  It will be pulled from this
516 * list when the inode is freed.
517 */
518int
519xfs_iunlink(
520	struct xfs_trans	*tp,
521	struct xfs_inode	*ip)
522{
523	struct xfs_mount	*mp = tp->t_mountp;
524	struct xfs_perag	*pag;
525	struct xfs_buf		*agibp;
526	int			error;
527
528	ASSERT(VFS_I(ip)->i_nlink == 0);
529	ASSERT(VFS_I(ip)->i_mode != 0);
530	trace_xfs_iunlink(ip);
531
532	pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
533
534	/* Get the agi buffer first.  It ensures lock ordering on the list. */
535	error = xfs_read_agi(pag, tp, 0, &agibp);
536	if (error)
537		goto out;
538
539	error = xfs_iunlink_insert_inode(tp, pag, agibp, ip);
540out:
541	xfs_perag_put(pag);
542	return error;
543}
544
545static int
546xfs_iunlink_remove_inode(
547	struct xfs_trans	*tp,
548	struct xfs_perag	*pag,
549	struct xfs_buf		*agibp,
550	struct xfs_inode	*ip)
551{
552	struct xfs_mount	*mp = tp->t_mountp;
553	struct xfs_agi		*agi = agibp->b_addr;
554	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
555	xfs_agino_t		head_agino;
556	short			bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
557	int			error;
558
559	trace_xfs_iunlink_remove(ip);
560
561	/*
562	 * Get the index into the agi hash table for the list this inode will
563	 * go on.  Make sure the head pointer isn't garbage.
564	 */
565	head_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
566	if (!xfs_verify_agino(pag, head_agino)) {
567		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
568				agi, sizeof(*agi));
569		xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
570		return -EFSCORRUPTED;
571	}
572
573	/*
574	 * Set our inode's next_unlinked pointer to NULL and then return
575	 * the old pointer value so that we can update whatever was previous
576	 * to us in the list to point to whatever was next in the list.
577	 */
578	error = xfs_iunlink_log_inode(tp, ip, pag, NULLAGINO);
579	if (error)
580		return error;
581
582	/*
583	 * Update the prev pointer in the next inode to point back to previous
584	 * inode in the chain.
585	 */
586	error = xfs_iunlink_update_backref(pag, ip->i_prev_unlinked,
587			ip->i_next_unlinked);
588	if (error == -ENOLINK)
589		error = xfs_iunlink_reload_next(tp, agibp, ip->i_prev_unlinked,
590				ip->i_next_unlinked);
591	if (error)
592		return error;
593
594	if (head_agino != agino) {
595		struct xfs_inode	*prev_ip;
596
597		prev_ip = xfs_iunlink_lookup(pag, ip->i_prev_unlinked);
598		if (!prev_ip) {
599			xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
600			return -EFSCORRUPTED;
601		}
602
603		error = xfs_iunlink_log_inode(tp, prev_ip, pag,
604				ip->i_next_unlinked);
605		prev_ip->i_next_unlinked = ip->i_next_unlinked;
606	} else {
607		/* Point the head of the list to the next unlinked inode. */
608		error = xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index,
609				ip->i_next_unlinked);
610	}
611
612	ip->i_next_unlinked = NULLAGINO;
613	ip->i_prev_unlinked = 0;
614	return error;
615}
616
617/*
618 * Pull the on-disk inode from the AGI unlinked list.
619 */
620int
621xfs_iunlink_remove(
622	struct xfs_trans	*tp,
623	struct xfs_perag	*pag,
624	struct xfs_inode	*ip)
625{
626	struct xfs_buf		*agibp;
627	int			error;
628
629	trace_xfs_iunlink_remove(ip);
630
631	/* Get the agi buffer first.  It ensures lock ordering on the list. */
632	error = xfs_read_agi(pag, tp, 0, &agibp);
633	if (error)
634		return error;
635
636	return xfs_iunlink_remove_inode(tp, pag, agibp, ip);
637}
638
639/*
640 * Decrement the link count on an inode & log the change.  If this causes the
641 * link count to go to zero, move the inode to AGI unlinked list so that it can
642 * be freed when the last active reference goes away via xfs_inactive().
643 */
644int
645xfs_droplink(
646	struct xfs_trans	*tp,
647	struct xfs_inode	*ip)
648{
649	struct inode		*inode = VFS_I(ip);
650
651	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
652
653	if (inode->i_nlink == 0) {
654		xfs_info_ratelimited(tp->t_mountp,
655 "Inode 0x%llx link count dropped below zero.  Pinning link count.",
656				ip->i_ino);
657		set_nlink(inode, XFS_NLINK_PINNED);
658	}
659	if (inode->i_nlink != XFS_NLINK_PINNED)
660		drop_nlink(inode);
661
662	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
663
664	if (inode->i_nlink)
665		return 0;
666
667	return xfs_iunlink(tp, ip);
668}
669
670/*
671 * Increment the link count on an inode & log the change.
672 */
673void
674xfs_bumplink(
675	struct xfs_trans	*tp,
676	struct xfs_inode	*ip)
677{
678	struct inode		*inode = VFS_I(ip);
679
680	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
681
682	if (inode->i_nlink == XFS_NLINK_PINNED - 1)
683		xfs_info_ratelimited(tp->t_mountp,
684 "Inode 0x%llx link count exceeded maximum.  Pinning link count.",
685				ip->i_ino);
686	if (inode->i_nlink != XFS_NLINK_PINNED)
687		inc_nlink(inode);
688
689	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
690}
691
692/* Free an inode in the ondisk index and zero it out. */
693int
694xfs_inode_uninit(
695	struct xfs_trans	*tp,
696	struct xfs_perag	*pag,
697	struct xfs_inode	*ip,
698	struct xfs_icluster	*xic)
699{
700	struct xfs_mount	*mp = ip->i_mount;
701	int			error;
702
703	/*
704	 * Free the inode first so that we guarantee that the AGI lock is going
705	 * to be taken before we remove the inode from the unlinked list. This
706	 * makes the AGI lock -> unlinked list modification order the same as
707	 * used in O_TMPFILE creation.
708	 */
709	error = xfs_difree(tp, pag, ip->i_ino, xic);
710	if (error)
711		return error;
712
713	error = xfs_iunlink_remove(tp, pag, ip);
714	if (error)
715		return error;
716
717	/*
718	 * Free any local-format data sitting around before we reset the
719	 * data fork to extents format.  Note that the attr fork data has
720	 * already been freed by xfs_attr_inactive.
721	 */
722	if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
723		kfree(ip->i_df.if_data);
724		ip->i_df.if_data = NULL;
725		ip->i_df.if_bytes = 0;
726	}
727
728	VFS_I(ip)->i_mode = 0;		/* mark incore inode as free */
729	ip->i_diflags = 0;
730	ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
731	ip->i_forkoff = 0;		/* mark the attr fork not in use */
732	ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
733
734	/*
735	 * Bump the generation count so no one will be confused
736	 * by reincarnations of this inode.
737	 */
738	VFS_I(ip)->i_generation++;
739	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
740	return 0;
741}
~/ Read-only file preview.