From: Darrick J. Wong <djwong@xxxxxxxxxx> Port the xfs_bumplink function from the kernel and use it to replace raw calls to inc_nlink. The next patch will need this common function to prevent integer overflows in the link count. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- include/xfs_inode.h | 2 ++ libxfs/util.c | 17 +++++++++++++++++ mkfs/proto.c | 4 ++-- repair/phase6.c | 10 +++++----- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 302df4c6f7e..47959314811 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -348,6 +348,8 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *); +void libxfs_bumplink(struct xfs_trans *tp, struct xfs_inode *ip); + /* Inode Cache Interfaces */ extern int libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, uint, struct xfs_inode **); diff --git a/libxfs/util.c b/libxfs/util.c index c1ddaf92c8a..11978529ed6 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -240,6 +240,23 @@ xfs_inode_propagate_flags( ip->i_diflags |= di_flags; } +/* + * Increment the link count on an inode & log the change. + */ +void +libxfs_bumplink( + struct xfs_trans *tp, + struct xfs_inode *ip) +{ + struct inode *inode = VFS_I(ip); + + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); + + inc_nlink(inode); + + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); +} + /* * Initialise a newly allocated inode and return the in-core inode to the * caller locked exclusively. diff --git a/mkfs/proto.c b/mkfs/proto.c index 0f2facbc32e..457899ac178 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -590,7 +590,7 @@ parseproto( &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); - inc_nlink(VFS_I(ip)); /* account for . */ + libxfs_bumplink(tp, ip); /* account for . */ if (!pip) { pip = ip; mp->m_sb.sb_rootino = ip->i_ino; @@ -600,7 +600,7 @@ parseproto( libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_DIR; newdirent(mp, tp, pip, &xname, ip->i_ino); - inc_nlink(VFS_I(pip)); + libxfs_bumplink(tp, pip); libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); } newdirectory(mp, tp, ip, pip); diff --git a/repair/phase6.c b/repair/phase6.c index ac037cf80ad..75391378291 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -944,7 +944,7 @@ mk_orphanage(xfs_mount_t *mp) do_error(_("%s inode allocation failed %d\n"), ORPHANAGE, error); } - inc_nlink(VFS_I(ip)); /* account for . */ + libxfs_bumplink(tp, ip); /* account for . */ ino = ip->i_ino; irec = find_inode_rec(mp, @@ -996,7 +996,7 @@ mk_orphanage(xfs_mount_t *mp) * for .. in the new directory, and update the irec copy of the * on-disk nlink so we don't fail the link count check later. */ - inc_nlink(VFS_I(pip)); + libxfs_bumplink(tp, pip); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); add_inode_ref(irec, 0); @@ -1090,7 +1090,7 @@ mv_orphanage( if (irec) add_inode_ref(irec, ino_offset); else - inc_nlink(VFS_I(orphanage_ip)); + libxfs_bumplink(tp, orphanage_ip); libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE); err = -libxfs_dir_createname(tp, ino_p, &xfs_name_dotdot, @@ -1099,7 +1099,7 @@ mv_orphanage( do_error( _("creation of .. entry failed (%d)\n"), err); - inc_nlink(VFS_I(ino_p)); + libxfs_bumplink(tp, ino_p); libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE); err = -libxfs_trans_commit(tp); if (err) @@ -1124,7 +1124,7 @@ mv_orphanage( if (irec) add_inode_ref(irec, ino_offset); else - inc_nlink(VFS_I(orphanage_ip)); + libxfs_bumplink(tp, orphanage_ip); libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE); /*