]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: hoist xfs_{bump,drop}link to libxfs
authorDarrick J. Wong <djwong@kernel.org>
Wed, 3 Jul 2024 21:21:35 +0000 (14:21 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 31 Jul 2024 01:46:42 +0000 (18:46 -0700)
Move xfs_bumplink and xfs_droplink to libxfs.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
db/namei.c
include/xfs_inode.h
libxfs/inode.c
libxfs/libxfs_api_defs.h
libxfs/libxfs_priv.h
libxfs/xfs_inode_util.c
libxfs/xfs_inode_util.h

index d57ead4f165d809b466c8c5fb67274d3b13dee26..8c7f4932fce4a3d86aabbcad6e295c36bd885717 100644 (file)
@@ -1142,21 +1142,6 @@ unlink_help(void)
        ));
 }
 
-static void
-droplink(
-       struct xfs_trans        *tp,
-       struct xfs_inode        *ip)
-{
-       struct inode            *inode = VFS_I(ip);
-
-       libxfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
-
-       if (inode->i_nlink != XFS_NLINK_PINNED)
-               drop_nlink(VFS_I(ip));
-
-       libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-}
-
 static int
 remove_child(
        struct xfs_mount        *mp,
@@ -1206,13 +1191,17 @@ remove_child(
 
        if (S_ISDIR(VFS_I(ip)->i_mode)) {
                /* drop ip's dotdot link to dp */
-               droplink(tp, dp);
+               error = -libxfs_droplink(tp, dp);
+               if (error)
+                       goto out_trans;
        } else {
                libxfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
        }
 
        /* drop dp's link to ip */
-       droplink(tp, ip);
+       error = -libxfs_droplink(tp, ip);
+       if (error)
+               goto out_trans;
 
        error = -libxfs_dir_removename(tp, dp, &xname, ip->i_ino, resblks);
        if (error)
index 737e0551ba2c14c88230262515086c7463b7ac31..4fe2826f9bdfcb89c1542c0e885a2e40404ef2ae 100644 (file)
@@ -407,8 +407,6 @@ 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);
-
 int libxfs_icreate(struct xfs_trans *tp, xfs_ino_t ino,
                const struct xfs_icreate_args *args, struct xfs_inode **ipp);
 
index 20b9c483a5ea768d69f439e52758c5f8a3f19d6e..2062ecf54486cffcbd84818b0faeee53f26500b4 100644 (file)
 #include "xfs_da_btree.h"
 #include "xfs_dir2_priv.h"
 
-/*
- * 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);
-
-       if (inode->i_nlink != XFS_NLINK_PINNED)
-               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.
index 384e812f21283c98b560275b9e900acedb19333c..6a057eba1e38b84e3d09b45bd1836f29c0ecb636 100644 (file)
 #define xfs_buf_relse                  libxfs_buf_relse
 #define xfs_buf_unlock                 libxfs_buf_unlock
 #define xfs_buftarg_drain              libxfs_buftarg_drain
+#define xfs_bumplink                   libxfs_bumplink
 #define xfs_bunmapi                    libxfs_bunmapi
 #define xfs_bwrite                     libxfs_bwrite
 #define xfs_calc_dquots_per_chunk      libxfs_calc_dquots_per_chunk
index 577739ff2f590b0890b8d70d30b108d31f9f05ce..17adaa1d68bf6f28d992a4f8defd961e4e07dccc 100644 (file)
@@ -135,6 +135,7 @@ extern void cmn_err(int, char *, ...);
 enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
 
 #define xfs_info(mp,fmt,args...)       cmn_err(CE_CONT, _(fmt), ## args)
+#define xfs_info_ratelimited(mp,fmt,args...) cmn_err(CE_CONT, _(fmt), ## args)
 #define xfs_notice(mp,fmt,args...)     cmn_err(CE_NOTE, _(fmt), ## args)
 #define xfs_warn(mp,fmt,args...)       cmn_err((mp) ? CE_WARN : CE_WARN, _(fmt), ## args)
 #define xfs_err(mp,fmt,args...)                cmn_err(CE_ALERT, _(fmt), ## args)
index 2d7e970d72f26a5907e968f073a37420b16e0f20..62af002b2140dc59784e6faa32e6add256ef83fa 100644 (file)
@@ -624,3 +624,56 @@ xfs_iunlink_remove(
 
        return xfs_iunlink_remove_inode(tp, pag, agibp, ip);
 }
+
+/*
+ * Decrement the link count on an inode & log the change.  If this causes the
+ * link count to go to zero, move the inode to AGI unlinked list so that it can
+ * be freed when the last active reference goes away via xfs_inactive().
+ */
+int
+xfs_droplink(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip)
+{
+       struct inode            *inode = VFS_I(ip);
+
+       xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
+
+       if (inode->i_nlink == 0) {
+               xfs_info_ratelimited(tp->t_mountp,
+ "Inode 0x%llx link count dropped below zero.  Pinning link count.",
+                               ip->i_ino);
+               set_nlink(inode, XFS_NLINK_PINNED);
+       }
+       if (inode->i_nlink != XFS_NLINK_PINNED)
+               drop_nlink(inode);
+
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
+       if (inode->i_nlink)
+               return 0;
+
+       return xfs_iunlink(tp, ip);
+}
+
+/*
+ * Increment the link count on an inode & log the change.
+ */
+void
+xfs_bumplink(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip)
+{
+       struct inode            *inode = VFS_I(ip);
+
+       xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
+
+       if (inode->i_nlink == XFS_NLINK_PINNED - 1)
+               xfs_info_ratelimited(tp->t_mountp,
+ "Inode 0x%llx link count exceeded maximum.  Pinning link count.",
+                               ip->i_ino);
+       if (inode->i_nlink != XFS_NLINK_PINNED)
+               inc_nlink(inode);
+
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+}
index 42a032afe3cacebe52acc7ce774f38e76ea915b2..50c14ba6ca5a2c7b7988a4ea00726f208f9f87df 100644 (file)
@@ -50,5 +50,7 @@ void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args,
 int xfs_iunlink(struct xfs_trans *tp, struct xfs_inode *ip);
 int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag,
                struct xfs_inode *ip);
+int xfs_droplink(struct xfs_trans *tp, struct xfs_inode *ip);
+void xfs_bumplink(struct xfs_trans *tp, struct xfs_inode *ip);
 
 #endif /* __XFS_INODE_UTIL_H__ */