]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: move on-disk inode allocation out of xfs_ialloc()
authorDave Chinner <dchinner@redhat.com>
Thu, 7 Jan 2021 20:59:17 +0000 (15:59 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Thu, 7 Jan 2021 20:59:17 +0000 (15:59 -0500)
Source kernel commit: 1abcf261016e12246e1f0d2dada9c5c851a9ceb7

So xfs_ialloc() will only address in-core inode allocation then,
Also, rename xfs_ialloc() to xfs_dir_ialloc_init() in order to
keep everything in xfs_inode.c under the same namespace.

[sandeen: make equivalent change in xfsprogs]

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/util.c

index a79b650ae400e5df62a9915fae948d6eff466655..64c7da4ad329958a67c19703e8a54886ec6d58cd 100644 (file)
@@ -239,44 +239,24 @@ xfs_inode_propagate_flags(
 }
 
 /*
- * Allocate an inode on disk and return a copy of its in-core version.
- * Set mode, nlink, and rdev appropriately within the inode.
- * The uid and gid for the inode are set according to the contents of
- * the given cred structure.
- *
- * This was once shared with the kernel, but has diverged to the point
- * where it's no longer worth the hassle of maintaining common code.
+ * Initialise a newly allocated inode and return the in-core inode to the
+ * caller locked exclusively.
  */
 static int
-libxfs_ialloc(
-       xfs_trans_t     *tp,
-       xfs_inode_t     *pip,
-       mode_t          mode,
-       nlink_t         nlink,
-       xfs_dev_t       rdev,
-       struct cred     *cr,
-       struct fsxattr  *fsx,
-       xfs_buf_t       **ialloc_context,
-       xfs_inode_t     **ipp)
+libxfs_init_new_inode(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *pip,
+       xfs_ino_t               ino,
+       umode_t                 mode,
+       xfs_nlink_t             nlink,
+       dev_t                   rdev,
+       struct cred             *cr,
+       struct fsxattr          *fsx,
+       struct xfs_inode        **ipp)
 {
-       xfs_ino_t       ino;
-       xfs_inode_t     *ip;
-       uint            flags;
-       int             error;
-
-       /*
-        * Call the space management code to pick
-        * the on-disk inode to be allocated.
-        */
-       error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode,
-                           ialloc_context, &ino);
-       if (error != 0)
-               return error;
-       if (*ialloc_context || ino == NULLFSINO) {
-               *ipp = NULL;
-               return 0;
-       }
-       ASSERT(*ialloc_context == NULL);
+       struct xfs_inode        *ip;
+       unsigned int            flags;
+       int                     error;
 
        error = libxfs_iget(tp->t_mountp, tp, ino, 0, &ip);
        if (error != 0)
@@ -532,54 +512,58 @@ error0:   /* Cancel bmap, cancel trans */
  */
 int
 libxfs_dir_ialloc(
-       xfs_trans_t     **tpp,
-       xfs_inode_t     *dp,
-       mode_t          mode,
-       nlink_t         nlink,
-       xfs_dev_t       rdev,
-       struct cred     *cr,
-       struct fsxattr  *fsx,
-       xfs_inode_t     **ipp)
+       struct xfs_trans        **tpp,
+       struct xfs_inode        *dp,
+       mode_t                  mode,
+       nlink_t                 nlink,
+       xfs_dev_t               rdev,
+       struct cred             *cr,
+       struct fsxattr          *fsx,
+       struct xfs_inode        **ipp)
 {
-       xfs_trans_t     *tp;
-       xfs_inode_t     *ip;
-       xfs_buf_t       *ialloc_context = NULL;
-       int             code;
-
-       tp = *tpp;
+       struct xfs_buf          *ialloc_context = NULL;
+       xfs_ino_t               parent_ino = dp ? dp->i_ino : 0;
+       xfs_ino_t               ino;
+       int                     error;
 
-       code = libxfs_ialloc(tp, dp, mode, nlink, rdev, cr, fsx,
-                          &ialloc_context, &ip);
-       if (code) {
-               *ipp = NULL;
-               return code;
-       }
-       if (!ialloc_context && !ip) {
-               *ipp = NULL;
-               return -ENOSPC;
-       }
+       /*
+        * Call the space management code to pick the on-disk inode to be
+        * allocated.
+        */
+       error = xfs_dialloc(*tpp, parent_ino, mode, &ialloc_context, &ino);
+       if (error)
+               return error;
 
+       /*
+        * If the AGI buffer is non-NULL, then we were unable to get an
+        * inode in one operation.  We need to commit the current
+        * transaction and call xfs_dialloc() again.  It is guaranteed
+        * to succeed the second time.
+        */
        if (ialloc_context) {
-               code = xfs_dialloc_roll(&tp, ialloc_context);
-               if (code) {
+               error = xfs_dialloc_roll(tpp, ialloc_context);
+               if (error) {
                        fprintf(stderr, _("%s: cannot duplicate transaction: %s\n"),
-                               progname, strerror(code));
+                               progname, strerror(error));
                        exit(1);
                }
-               code = libxfs_ialloc(tp, dp, mode, nlink, rdev, cr,
-                                  fsx, &ialloc_context, &ip);
-               if (!ip)
-                       code = -ENOSPC;
-               if (code) {
-                       *tpp = tp;
-                       *ipp = NULL;
-                       return code;
-               }
+               /*
+                * Call dialloc again. Since we've locked out all other
+                * allocations in this allocation group, this call should
+                * always succeed.
+                */
+               error = xfs_dialloc(*tpp, parent_ino, mode, &ialloc_context,
+                               &ino);
+               if (error)
+                       return error;
+               ASSERT(!ialloc_context);
        }
 
-       *ipp = ip;
-       *tpp = tp;
-       return code;
+       if (ino == NULLFSINO)
+               return -ENOSPC;
+
+       return libxfs_init_new_inode(*tpp, dp, ino, mode, nlink, rdev, cr,
+                               fsx, ipp);
 }
 
 void