brintos

brintos / linux-shallow public Read only

0
0
Text · 20.6 KiB · cc38e1c Raw
750 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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_t28xfs_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_t70xfs_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_t88xfs_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_t137xfs_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 void148xfs_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 size196	 * 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 both198	 * rtinherit and extszinherit flags set.  If the misaligned hint is199	 * propagated from a directory into a new realtime file, new file200	 * allocations will fail due to math errors in the rt allocator and/or201	 * trip the verifiers.  Validate the hint settings in the new file so202	 * 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 void215xfs_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 228	/* Don't let invalid cowextsize hints propagate. */229	failaddr = xfs_inode_validate_cowextsize(ip->i_mount, ip->i_cowextsize,230			VFS_I(ip)->i_mode, ip->i_diflags, ip->i_diflags2);231	if (failaddr) {232		ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE;233		ip->i_cowextsize = 0;234	}235}236 237/*238 * If we need to create attributes immediately after allocating the inode,239 * initialise an empty attribute fork right now. We use the default fork offset240 * for attributes here as we don't know exactly what size or how many241 * attributes we might be adding. We can do this safely here because we know242 * the data fork is completely empty and this saves us from needing to run a243 * separate transaction to set the fork offset in the immediate future.244 *245 * If we have parent pointers and the caller hasn't told us that the file will246 * never be linked into a directory tree, we /must/ create the attr fork.247 */248static inline bool249xfs_icreate_want_attrfork(250	struct xfs_mount		*mp,251	const struct xfs_icreate_args	*args)252{253	if (args->flags & XFS_ICREATE_INIT_XATTRS)254		return true;255 256	if (!(args->flags & XFS_ICREATE_UNLINKABLE) && xfs_has_parent(mp))257		return true;258 259	return false;260}261 262/* Initialise an inode's attributes. */263void264xfs_inode_init(265	struct xfs_trans	*tp,266	const struct xfs_icreate_args *args,267	struct xfs_inode	*ip)268{269	struct xfs_inode	*pip = args->pip;270	struct inode		*dir = pip ? VFS_I(pip) : NULL;271	struct xfs_mount	*mp = tp->t_mountp;272	struct inode		*inode = VFS_I(ip);273	unsigned int		flags;274	int			times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG |275					XFS_ICHGTIME_ACCESS;276 277	if (args->flags & XFS_ICREATE_TMPFILE)278		set_nlink(inode, 0);279	else if (S_ISDIR(args->mode))280		set_nlink(inode, 2);281	else282		set_nlink(inode, 1);283	inode->i_rdev = args->rdev;284 285	if (!args->idmap || pip == NULL) {286		/* creating a tree root, sb rooted, or detached file */287		inode->i_uid = GLOBAL_ROOT_UID;288		inode->i_gid = GLOBAL_ROOT_GID;289		ip->i_projid = 0;290		inode->i_mode = args->mode;291	} else {292		/* creating a child in the directory tree */293		if (dir && !(dir->i_mode & S_ISGID) && xfs_has_grpid(mp)) {294			inode_fsuid_set(inode, args->idmap);295			inode->i_gid = dir->i_gid;296			inode->i_mode = args->mode;297		} else {298			inode_init_owner(args->idmap, inode, dir, args->mode);299		}300 301		/*302		 * If the group ID of the new file does not match the effective303		 * group ID or one of the supplementary group IDs, the S_ISGID304		 * bit is cleared (and only if the irix_sgid_inherit305		 * compatibility variable is set).306		 */307		if (irix_sgid_inherit && (inode->i_mode & S_ISGID) &&308		    !vfsgid_in_group_p(i_gid_into_vfsgid(args->idmap, inode)))309			inode->i_mode &= ~S_ISGID;310 311		ip->i_projid = xfs_get_initial_prid(pip);312	}313 314	ip->i_disk_size = 0;315	ip->i_df.if_nextents = 0;316	ASSERT(ip->i_nblocks == 0);317 318	ip->i_extsize = 0;319	ip->i_diflags = 0;320 321	if (xfs_has_v3inodes(mp)) {322		inode_set_iversion(inode, 1);323		ip->i_cowextsize = 0;324		times |= XFS_ICHGTIME_CREATE;325	}326 327	xfs_trans_ichgtime(tp, ip, times);328 329	flags = XFS_ILOG_CORE;330	switch (args->mode & S_IFMT) {331	case S_IFIFO:332	case S_IFCHR:333	case S_IFBLK:334	case S_IFSOCK:335		ip->i_df.if_format = XFS_DINODE_FMT_DEV;336		flags |= XFS_ILOG_DEV;337		break;338	case S_IFREG:339	case S_IFDIR:340		if (pip && (pip->i_diflags & XFS_DIFLAG_ANY))341			xfs_inode_inherit_flags(ip, pip);342		if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY))343			xfs_inode_inherit_flags2(ip, pip);344		fallthrough;345	case S_IFLNK:346		ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;347		ip->i_df.if_bytes = 0;348		ip->i_df.if_data = NULL;349		break;350	default:351		ASSERT(0);352	}353 354	if (xfs_icreate_want_attrfork(mp, args)) {355		ip->i_forkoff = xfs_default_attroffset(ip) >> 3;356		xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0);357 358		if (!xfs_has_attr(mp)) {359			spin_lock(&mp->m_sb_lock);360			xfs_add_attr(mp);361			spin_unlock(&mp->m_sb_lock);362			xfs_log_sb(tp);363		}364	}365 366	xfs_trans_log_inode(tp, ip, flags);367}368 369/*370 * In-Core Unlinked List Lookups371 * =============================372 *373 * Every inode is supposed to be reachable from some other piece of metadata374 * with the exception of the root directory.  Inodes with a connection to a375 * file descriptor but not linked from anywhere in the on-disk directory tree376 * are collectively known as unlinked inodes, though the filesystem itself377 * maintains links to these inodes so that on-disk metadata are consistent.378 *379 * XFS implements a per-AG on-disk hash table of unlinked inodes.  The AGI380 * header contains a number of buckets that point to an inode, and each inode381 * record has a pointer to the next inode in the hash chain.  This382 * singly-linked list causes scaling problems in the iunlink remove function383 * because we must walk that list to find the inode that points to the inode384 * being removed from the unlinked hash bucket list.385 *386 * Hence we keep an in-memory double linked list to link each inode on an387 * unlinked list. Because there are 64 unlinked lists per AGI, keeping pointer388 * based lists would require having 64 list heads in the perag, one for each389 * list. This is expensive in terms of memory (think millions of AGs) and cache390 * misses on lookups. Instead, use the fact that inodes on the unlinked list391 * must be referenced at the VFS level to keep them on the list and hence we392 * have an existence guarantee for inodes on the unlinked list.393 *394 * Given we have an existence guarantee, we can use lockless inode cache lookups395 * to resolve aginos to xfs inodes. This means we only need 8 bytes per inode396 * for the double linked unlinked list, and we don't need any extra locking to397 * keep the list safe as all manipulations are done under the AGI buffer lock.398 * Keeping the list up to date does not require memory allocation, just finding399 * the XFS inode and updating the next/prev unlinked list aginos.400 */401 402/*403 * Update the prev pointer of the next agino.  Returns -ENOLINK if the inode404 * is not in cache.405 */406static int407xfs_iunlink_update_backref(408	struct xfs_perag	*pag,409	xfs_agino_t		prev_agino,410	xfs_agino_t		next_agino)411{412	struct xfs_inode	*ip;413 414	/* No update necessary if we are at the end of the list. */415	if (next_agino == NULLAGINO)416		return 0;417 418	ip = xfs_iunlink_lookup(pag, next_agino);419	if (!ip)420		return -ENOLINK;421 422	ip->i_prev_unlinked = prev_agino;423	return 0;424}425 426/*427 * Point the AGI unlinked bucket at an inode and log the results.  The caller428 * is responsible for validating the old value.429 */430STATIC int431xfs_iunlink_update_bucket(432	struct xfs_trans	*tp,433	struct xfs_perag	*pag,434	struct xfs_buf		*agibp,435	unsigned int		bucket_index,436	xfs_agino_t		new_agino)437{438	struct xfs_agi		*agi = agibp->b_addr;439	xfs_agino_t		old_value;440	int			offset;441 442	ASSERT(xfs_verify_agino_or_null(pag, new_agino));443 444	old_value = be32_to_cpu(agi->agi_unlinked[bucket_index]);445	trace_xfs_iunlink_update_bucket(tp->t_mountp, pag->pag_agno, bucket_index,446			old_value, new_agino);447 448	/*449	 * We should never find the head of the list already set to the value450	 * passed in because either we're adding or removing ourselves from the451	 * head of the list.452	 */453	if (old_value == new_agino) {454		xfs_buf_mark_corrupt(agibp);455		xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);456		return -EFSCORRUPTED;457	}458 459	agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino);460	offset = offsetof(struct xfs_agi, agi_unlinked) +461			(sizeof(xfs_agino_t) * bucket_index);462	xfs_trans_log_buf(tp, agibp, offset, offset + sizeof(xfs_agino_t) - 1);463	return 0;464}465 466static int467xfs_iunlink_insert_inode(468	struct xfs_trans	*tp,469	struct xfs_perag	*pag,470	struct xfs_buf		*agibp,471	struct xfs_inode	*ip)472{473	struct xfs_mount	*mp = tp->t_mountp;474	struct xfs_agi		*agi = agibp->b_addr;475	xfs_agino_t		next_agino;476	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ip->i_ino);477	short			bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;478	int			error;479 480	/*481	 * Get the index into the agi hash table for the list this inode will482	 * go on.  Make sure the pointer isn't garbage and that this inode483	 * isn't already on the list.484	 */485	next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);486	if (next_agino == agino ||487	    !xfs_verify_agino_or_null(pag, next_agino)) {488		xfs_buf_mark_corrupt(agibp);489		xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);490		return -EFSCORRUPTED;491	}492 493	/*494	 * Update the prev pointer in the next inode to point back to this495	 * inode.496	 */497	error = xfs_iunlink_update_backref(pag, agino, next_agino);498	if (error == -ENOLINK)499		error = xfs_iunlink_reload_next(tp, agibp, agino, next_agino);500	if (error)501		return error;502 503	if (next_agino != NULLAGINO) {504		/*505		 * There is already another inode in the bucket, so point this506		 * inode to the current head of the list.507		 */508		error = xfs_iunlink_log_inode(tp, ip, pag, next_agino);509		if (error)510			return error;511		ip->i_next_unlinked = next_agino;512	}513 514	/* Point the head of the list to point to this inode. */515	ip->i_prev_unlinked = NULLAGINO;516	return xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, agino);517}518 519/*520 * This is called when the inode's link count has gone to 0 or we are creating521 * a tmpfile via O_TMPFILE.  The inode @ip must have nlink == 0.522 *523 * We place the on-disk inode on a list in the AGI.  It will be pulled from this524 * list when the inode is freed.525 */526int527xfs_iunlink(528	struct xfs_trans	*tp,529	struct xfs_inode	*ip)530{531	struct xfs_mount	*mp = tp->t_mountp;532	struct xfs_perag	*pag;533	struct xfs_buf		*agibp;534	int			error;535 536	ASSERT(VFS_I(ip)->i_nlink == 0);537	ASSERT(VFS_I(ip)->i_mode != 0);538	trace_xfs_iunlink(ip);539 540	pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));541 542	/* Get the agi buffer first.  It ensures lock ordering on the list. */543	error = xfs_read_agi(pag, tp, 0, &agibp);544	if (error)545		goto out;546 547	error = xfs_iunlink_insert_inode(tp, pag, agibp, ip);548out:549	xfs_perag_put(pag);550	return error;551}552 553static int554xfs_iunlink_remove_inode(555	struct xfs_trans	*tp,556	struct xfs_perag	*pag,557	struct xfs_buf		*agibp,558	struct xfs_inode	*ip)559{560	struct xfs_mount	*mp = tp->t_mountp;561	struct xfs_agi		*agi = agibp->b_addr;562	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ip->i_ino);563	xfs_agino_t		head_agino;564	short			bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;565	int			error;566 567	trace_xfs_iunlink_remove(ip);568 569	/*570	 * Get the index into the agi hash table for the list this inode will571	 * go on.  Make sure the head pointer isn't garbage.572	 */573	head_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);574	if (!xfs_verify_agino(pag, head_agino)) {575		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,576				agi, sizeof(*agi));577		xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);578		return -EFSCORRUPTED;579	}580 581	/*582	 * Set our inode's next_unlinked pointer to NULL and then return583	 * the old pointer value so that we can update whatever was previous584	 * to us in the list to point to whatever was next in the list.585	 */586	error = xfs_iunlink_log_inode(tp, ip, pag, NULLAGINO);587	if (error)588		return error;589 590	/*591	 * Update the prev pointer in the next inode to point back to previous592	 * inode in the chain.593	 */594	error = xfs_iunlink_update_backref(pag, ip->i_prev_unlinked,595			ip->i_next_unlinked);596	if (error == -ENOLINK)597		error = xfs_iunlink_reload_next(tp, agibp, ip->i_prev_unlinked,598				ip->i_next_unlinked);599	if (error)600		return error;601 602	if (head_agino != agino) {603		struct xfs_inode	*prev_ip;604 605		prev_ip = xfs_iunlink_lookup(pag, ip->i_prev_unlinked);606		if (!prev_ip) {607			xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);608			return -EFSCORRUPTED;609		}610 611		error = xfs_iunlink_log_inode(tp, prev_ip, pag,612				ip->i_next_unlinked);613		prev_ip->i_next_unlinked = ip->i_next_unlinked;614	} else {615		/* Point the head of the list to the next unlinked inode. */616		error = xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index,617				ip->i_next_unlinked);618	}619 620	ip->i_next_unlinked = NULLAGINO;621	ip->i_prev_unlinked = 0;622	return error;623}624 625/*626 * Pull the on-disk inode from the AGI unlinked list.627 */628int629xfs_iunlink_remove(630	struct xfs_trans	*tp,631	struct xfs_perag	*pag,632	struct xfs_inode	*ip)633{634	struct xfs_buf		*agibp;635	int			error;636 637	trace_xfs_iunlink_remove(ip);638 639	/* Get the agi buffer first.  It ensures lock ordering on the list. */640	error = xfs_read_agi(pag, tp, 0, &agibp);641	if (error)642		return error;643 644	return xfs_iunlink_remove_inode(tp, pag, agibp, ip);645}646 647/*648 * Decrement the link count on an inode & log the change.  If this causes the649 * link count to go to zero, move the inode to AGI unlinked list so that it can650 * be freed when the last active reference goes away via xfs_inactive().651 */652int653xfs_droplink(654	struct xfs_trans	*tp,655	struct xfs_inode	*ip)656{657	struct inode		*inode = VFS_I(ip);658 659	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);660 661	if (inode->i_nlink == 0) {662		xfs_info_ratelimited(tp->t_mountp,663 "Inode 0x%llx link count dropped below zero.  Pinning link count.",664				ip->i_ino);665		set_nlink(inode, XFS_NLINK_PINNED);666	}667	if (inode->i_nlink != XFS_NLINK_PINNED)668		drop_nlink(inode);669 670	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);671 672	if (inode->i_nlink)673		return 0;674 675	return xfs_iunlink(tp, ip);676}677 678/*679 * Increment the link count on an inode & log the change.680 */681void682xfs_bumplink(683	struct xfs_trans	*tp,684	struct xfs_inode	*ip)685{686	struct inode		*inode = VFS_I(ip);687 688	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);689 690	if (inode->i_nlink == XFS_NLINK_PINNED - 1)691		xfs_info_ratelimited(tp->t_mountp,692 "Inode 0x%llx link count exceeded maximum.  Pinning link count.",693				ip->i_ino);694	if (inode->i_nlink != XFS_NLINK_PINNED)695		inc_nlink(inode);696 697	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);698}699 700/* Free an inode in the ondisk index and zero it out. */701int702xfs_inode_uninit(703	struct xfs_trans	*tp,704	struct xfs_perag	*pag,705	struct xfs_inode	*ip,706	struct xfs_icluster	*xic)707{708	struct xfs_mount	*mp = ip->i_mount;709	int			error;710 711	/*712	 * Free the inode first so that we guarantee that the AGI lock is going713	 * to be taken before we remove the inode from the unlinked list. This714	 * makes the AGI lock -> unlinked list modification order the same as715	 * used in O_TMPFILE creation.716	 */717	error = xfs_difree(tp, pag, ip->i_ino, xic);718	if (error)719		return error;720 721	error = xfs_iunlink_remove(tp, pag, ip);722	if (error)723		return error;724 725	/*726	 * Free any local-format data sitting around before we reset the727	 * data fork to extents format.  Note that the attr fork data has728	 * already been freed by xfs_attr_inactive.729	 */730	if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {731		kfree(ip->i_df.if_data);732		ip->i_df.if_data = NULL;733		ip->i_df.if_bytes = 0;734	}735 736	VFS_I(ip)->i_mode = 0;		/* mark incore inode as free */737	ip->i_diflags = 0;738	ip->i_diflags2 = mp->m_ino_geo.new_diflags2;739	ip->i_forkoff = 0;		/* mark the attr fork not in use */740	ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;741 742	/*743	 * Bump the generation count so no one will be confused744	 * by reincarnations of this inode.745	 */746	VFS_I(ip)->i_generation++;747	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);748	return 0;749}750