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