[PATCH 7/8] xfsprogs: clean up errors in libxfs_mount() consistently

Alex Elder
2011-11-10T20:35:44Z

Until the perag structures for the filesystem have been set up,
initialization of the mount point only assigns computed values and
has no other side-effects (such as allocating additional
structures). So up to that point, returning a null pointer to
signal an error is adequate. Once the perag initialization is done
there needs to be some teardown in case of an error.

Here the handling of errors is inconsistent. If early perag
initialization fails, the code currently just exits. Then, if
getting a reference to the root inode results in an error, a null
pointer is returned but without first cleaning up the perag
structures. Next, if rtmount_inodes() returns an error, the
reference to the root inode (if any) is released, but again the
perag structures are not cleaned up. Finally, when the perag data
is read in, if an error occurs, a null pointer is returned but the
root inode pointer reference is not released and the perag
structures are not cleaned up.

Remedy all of that by having each of these error cases jump to error
handling code at the end of the function. That code needs to
release the reference to the root inode and release all of the perag
structures. This (plus a few other things that will be no-ops at
this point in the mount process) is exactly what libxfs_umount(), so
just use that function to implement this cleanup activity.

Signed-off-by: Alex Elder <aelder@sgi.com>
---
libxfs/init.c | 18 ++++++++++--------
1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index d34fd8c..9dad5b7 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -757,7 +757,7 @@ libxfs_mount(
if (error) {
fprintf(stderr, _("%s: perag init failed\n"),
progname);
- exit(1);
+ goto out_err;
}

/*
@@ -770,15 +770,12 @@ libxfs_mount(
fprintf(stderr, _("%s: cannot read root inode (%d)\n"),
progname, error);
if (!(flags & LIBXFS_MOUNT_DEBUGGER))
- return NULL;
+ goto out_err;
}
ASSERT(mp->m_rootip != NULL);
}
- if ((flags & LIBXFS_MOUNT_ROOTINOS) && rtmount_inodes(mp)) {
- if (mp->m_rootip)
- libxfs_iput(mp->m_rootip, 0);
- return NULL;
- }
+ if ((flags & LIBXFS_MOUNT_ROOTINOS) && rtmount_inodes(mp))
+ goto out_err;

/*
* mkfs calls mount before the AGF/AGI structures are written.
@@ -789,11 +786,16 @@ libxfs_mount(
if (error) {
fprintf(stderr, _("%s: cannot init perag data (%d)\n"),
progname, error);
- return NULL;
+ goto out_err;
}
}

return mp;
+
+out_err:
+ libxfs_umount(mp); /* clean up first */
+
+ return NULL;
}

void
--
1.7.6.4