summaryrefslogtreecommitdiffstats
path: root/libmount/src/fs.c
diff options
context:
space:
mode:
authorKarel Zak2013-08-21 12:31:43 +0200
committerKarel Zak2013-08-21 12:48:42 +0200
commit26d0c0aefde9a94f29d9850514fcbcf638eb8728 (patch)
treecfe01b73d0d399baeeb5bdf1ffb8e6cdd6a38708 /libmount/src/fs.c
parentpylibmount: remove Context_get_table() (diff)
downloadkernel-qcow2-util-linux-26d0c0aefde9a94f29d9850514fcbcf638eb8728.tar.gz
kernel-qcow2-util-linux-26d0c0aefde9a94f29d9850514fcbcf638eb8728.tar.xz
kernel-qcow2-util-linux-26d0c0aefde9a94f29d9850514fcbcf638eb8728.zip
libmount: add reference counting to libmount_fs
* mnt_new_fs() returns object with refcount=1 * mnt_free_fs() does not care about reference counter * new functions mnt_ref_fs() and mnt_unref_fs() * mnt_table_add_fs() and mnt_table_rem_fs() uses reference counter * libmmnt_context uses reference counter for internal FS (as it could be shared outside the context) * backwardly incompatible change: - FS could be deallocated after mnt_table_remove_fs() * it's recommended to use mnt_unref_fs() after mnt_table_add_fs() Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src/fs.c')
-rw-r--r--libmount/src/fs.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/libmount/src/fs.c b/libmount/src/fs.c
index 97c606211..690428cda 100644
--- a/libmount/src/fs.c
+++ b/libmount/src/fs.c
@@ -21,6 +21,9 @@
/**
* mnt_new_fs:
*
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the filesystem.
+ *
* Returns: newly allocated struct libmnt_fs.
*/
struct libmnt_fs *mnt_new_fs(void)
@@ -29,7 +32,7 @@ struct libmnt_fs *mnt_new_fs(void)
if (!fs)
return NULL;
- /*DBG(FS, mnt_debug_h(fs, "alloc"));*/
+ fs->refcount = 1;
INIT_LIST_HEAD(&fs->ents);
return fs;
}
@@ -38,7 +41,10 @@ struct libmnt_fs *mnt_new_fs(void)
* mnt_free_fs:
* @fs: fs pointer
*
- * Deallocates the fs.
+ * Deallocates the fs. This function does not care about reference count. Don't
+ * use this function directly -- it's better to use use mnt_unref_fs().
+ *
+ * The reference counting is supported since util-linux v2.24.
*/
void mnt_free_fs(struct libmnt_fs *fs)
{
@@ -47,6 +53,7 @@ void mnt_free_fs(struct libmnt_fs *fs)
list_del(&fs->ents);
/*DBG(FS, mnt_debug_h(fs, "free"));*/
+ WARN_REFCOUNT(FS, fs, fs->refcount);
free(fs->source);
free(fs->bindsrc);
@@ -75,8 +82,45 @@ void mnt_free_fs(struct libmnt_fs *fs)
*/
void mnt_reset_fs(struct libmnt_fs *fs)
{
- if (fs)
- memset(fs, 0, sizeof(*fs));
+ int ref;
+
+ if (!fs)
+ return;
+
+ ref = fs->refcount;
+ memset(fs, 0, sizeof(*fs));
+ fs->refcount = ref;
+}
+
+/**
+ * mnt_ref_fs:
+ * @fs: fs pointer
+ *
+ * Increments reference counter.
+ */
+void mnt_ref_fs(struct libmnt_fs *fs)
+{
+ if (fs) {
+ fs->refcount++;
+ /*DBG(FS, mnt_debug_h(fs, "ref=%d", fs->refcount));*/
+ }
+}
+
+/**
+ * mnt_unref_fs:
+ * @fs: fs pointer
+ *
+ * De-increments reference counter, on zero the FS is automatically
+ * deallocated by mnt_free_fs().
+ */
+void mnt_unref_fs(struct libmnt_fs *fs)
+{
+ if (fs) {
+ fs->refcount--;
+ /*DBG(FS, mnt_debug_h(fs, "unref=%d", fs->refcount));*/
+ if (fs->refcount <= 0)
+ mnt_free_fs(fs);
+ }
}
static inline int update_str(char **dest, const char *src)