diff options
Diffstat (limited to 'libmount/src/lock.c')
-rw-r--r-- | libmount/src/lock.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/libmount/src/lock.c b/libmount/src/lock.c index 4835406..8aca8a7 100644 --- a/libmount/src/lock.c +++ b/libmount/src/lock.c @@ -36,6 +36,7 @@ * lock handler */ struct libmnt_lock { + int refcount; /* reference counter */ char *lockfile; /* path to lock file (e.g. /etc/mtab~) */ int lockfile_fd; /* lock file descriptor */ @@ -73,6 +74,7 @@ struct libmnt_lock *mnt_new_lock(const char *datafile, pid_t id __attribute__((_ if (!ml) goto err; + ml->refcount = 1; ml->lockfile_fd = -1; ml->lockfile = lo; @@ -89,18 +91,57 @@ err: * mnt_free_lock: * @ml: struct libmnt_lock handler * - * Deallocates mnt_lock. + * Deallocates libmnt_lock. This function does not care about reference count. Don't + * use this function directly -- it's better to use mnt_unref_lock(). + * + * The reference counting is supported since util-linux v2.40. */ void mnt_free_lock(struct libmnt_lock *ml) { if (!ml) return; - DBG(LOCKS, ul_debugobj(ml, "free%s", ml->locked ? " !!! LOCKED !!!" : "")); + + DBG(LOCKS, ul_debugobj(ml, "free%s [refcount=%d]", + ml->locked ? " !!! LOCKED !!!" : "", + ml->refcount)); free(ml->lockfile); free(ml); } /** + * mnt_ref_lock: + * @ml: lock pointer + * + * Increments reference counter. + * + * Since: 2.40 + */ +void mnt_ref_lock(struct libmnt_lock *ml) +{ + if (ml) { + ml->refcount++; + /*DBG(FS, ul_debugobj(fs, "ref=%d", ml->refcount));*/ + } +} + +/** + * mnt_unref_lock: + * @ml: lock pointer + * + * De-increments reference counter, on zero the @ml is automatically + * deallocated by mnt_free_lock). + */ +void mnt_unref_lock(struct libmnt_lock *ml) +{ + if (ml) { + ml->refcount--; + /*DBG(FS, ul_debugobj(fs, "unref=%d", ml->refcount));*/ + if (ml->refcount <= 0) + mnt_free_lock(ml); + } +} + +/** * mnt_lock_block_signals: * @ml: struct libmnt_lock handler * @enable: TRUE/FALSE @@ -146,7 +187,7 @@ static int lock_simplelock(struct libmnt_lock *ml) const char *lfile; int rc; struct stat sb; - const mode_t lock_mask = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; + const mode_t lock_mask = S_IRUSR|S_IWUSR; assert(ml); @@ -161,8 +202,7 @@ static int lock_simplelock(struct libmnt_lock *ml) sigprocmask(SIG_BLOCK, &sigs, &ml->oldsigmask); } - ml->lockfile_fd = open(lfile, O_RDONLY|O_CREAT|O_CLOEXEC, - S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH); + ml->lockfile_fd = open(lfile, O_RDONLY|O_CREAT|O_CLOEXEC, lock_mask); if (ml->lockfile_fd < 0) { rc = -errno; goto err; @@ -287,7 +327,7 @@ static void clean_lock(void) if (!lock) return; mnt_unlock_file(lock); - mnt_free_lock(lock); + mnt_unref_lock(lock); } static void __attribute__((__noreturn__)) sig_handler(int sig) @@ -295,7 +335,8 @@ static void __attribute__((__noreturn__)) sig_handler(int sig) errx(EXIT_FAILURE, "\n%d: catch signal: %s\n", getpid(), strsignal(sig)); } -static int test_lock(struct libmnt_test *ts, int argc, char *argv[]) +static int test_lock(struct libmnt_test *ts __attribute__((unused)), + int argc, char *argv[]) { time_t synctime = 0; unsigned int usecs; @@ -367,7 +408,7 @@ static int test_lock(struct libmnt_test *ts, int argc, char *argv[]) increment_data(datafile, verbose, l); mnt_unlock_file(lock); - mnt_free_lock(lock); + mnt_unref_lock(lock); lock = NULL; /* The mount command usually finishes after a mtab update. We |