diff options
Diffstat (limited to 'libmount/src/fs.c')
| -rw-r--r-- | libmount/src/fs.c | 222 |
1 files changed, 176 insertions, 46 deletions
diff --git a/libmount/src/fs.c b/libmount/src/fs.c index c95cdc7e7..3ab614503 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,8 +32,9 @@ 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); + /*DBG(FS, mnt_debug_h(fs, "alloc"));*/ return fs; } @@ -38,7 +42,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 +54,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); @@ -62,6 +70,7 @@ void mnt_free_fs(struct libmnt_fs *fs) free(fs->user_optstr); free(fs->attrs); free(fs->opt_fields); + free(fs->comment); free(fs); } @@ -74,8 +83,46 @@ 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)); + INIT_LIST_HEAD(&fs->ents); + 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) @@ -106,7 +153,7 @@ static inline int cpy_str_at_offset(void *new, const void *old, size_t offset) char **n = (char **) (new + offset); if (*n) - return 0; /* already set, not overwrite */ + return 0; /* already set, don't overwrite */ return update_str(n, *o); } @@ -117,7 +164,7 @@ static inline int cpy_str_at_offset(void *new, const void *old, size_t offset) * @src: source FS * * If @dest is NULL, then a new FS is allocated, if any @dest field is already - * set then the field is NOT overwrited. + * set, then the field is NOT overwritten. * * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is * not linked with any existing mnt_tab. @@ -250,7 +297,12 @@ err: void *mnt_fs_get_userdata(struct libmnt_fs *fs) { assert(fs); - return fs ? fs->userdata : NULL; + + if (!fs) + return NULL; + + /*DBG(FS, mnt_debug_h(fs, "get userdata [%p]", fs->userdata));*/ + return fs->userdata; } /** @@ -267,6 +319,8 @@ int mnt_fs_set_userdata(struct libmnt_fs *fs, void *data) assert(fs); if (!fs) return -EINVAL; + + /*DBG(FS, mnt_debug_h(fs, "set userdata [%p]", fs->userdata));*/ fs->userdata = data; return 0; } @@ -310,7 +364,7 @@ const char *mnt_fs_get_source(struct libmnt_fs *fs) } /* - * Used by parser ONLY (@source has to be freed on error) + * Used by the parser ONLY (@source has to be freed on error) */ int __mnt_fs_set_source_ptr(struct libmnt_fs *fs, char *source) { @@ -318,9 +372,12 @@ int __mnt_fs_set_source_ptr(struct libmnt_fs *fs, char *source) assert(fs); - if (source && *source != '/' && strchr(source, '=')) { - if (blkid_parse_tag_string(source, &t, &v) != 0) - return -1; + if (source && blkid_parse_tag_string(source, &t, &v) == 0 && + !mnt_valid_tagname(t)) { + /* parsable but unknown tag -- ignore */ + free(t); + free(v); + t = v = NULL; } if (fs->source != source) @@ -370,7 +427,7 @@ int mnt_fs_set_source(struct libmnt_fs *fs, const char *source) * @fs: fs * @path: source path * - * Compares @fs source path with @path. The tailing slash is ignored. + * Compares @fs source path with @path. The trailing slash is ignored. * See also mnt_fs_match_source(). * * Returns: 1 if @fs source path equal to @path, otherwise 0. @@ -399,7 +456,7 @@ int mnt_fs_streq_srcpath(struct libmnt_fs *fs, const char *path) * @fs: fs * @path: mount point * - * Compares @fs target path with @path. The tailing slash is ignored. + * Compares @fs target path with @path. The trailing slash is ignored. * See also mnt_fs_match_target(). * * Returns: 1 if @fs target path equal to @path, otherwise 0. @@ -418,8 +475,8 @@ int mnt_fs_streq_target(struct libmnt_fs *fs, const char *path) * * "TAG" is NAME=VALUE (e.g. LABEL=foo) * - * The TAG is the first column in the fstab file. The TAG or "srcpath" has to - * be always set for all entries. + * The TAG is the first column in the fstab file. The TAG or "srcpath" always has + * to be set for all entries. * * See also mnt_fs_get_source(). * @@ -441,7 +498,7 @@ int mnt_fs_streq_target(struct libmnt_fs *fs, const char *path) * </programlisting> * </informalexample> * - * Returns: 0 on success or negative number in case that a TAG is not defined. + * Returns: 0 on success or negative number in case a TAG is not defined. */ int mnt_fs_get_tag(struct libmnt_fs *fs, const char **name, const char **value) { @@ -502,10 +559,10 @@ static int mnt_fs_get_flags(struct libmnt_fs *fs) /** * mnt_fs_get_propagation: * @fs: mountinfo entry - * @flags: returns propagation MS_* flags as present in mountinfo file + * @flags: returns propagation MS_* flags as present in the mountinfo file * - * Note that this function set @flags to zero if not found any propagation flag - * in mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored + * Note that this function sets @flags to zero if no propagation flags are found + * in the mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored * in the mountinfo file. * * Returns: 0 on success or negative number in case of error. @@ -594,7 +651,7 @@ const char *mnt_fs_get_fstype(struct libmnt_fs *fs) return fs ? fs->fstype : NULL; } -/* Used by struct libmnt_file parser only */ +/* Used by the struct libmnt_file parser only */ int __mnt_fs_set_fstype_ptr(struct libmnt_fs *fs, char *fstype) { assert(fs); @@ -670,7 +727,7 @@ static char *merge_optstr(const char *vfs, const char *fs) if (!strcmp(vfs, fs)) return strdup(vfs); /* e.g. "aaa" and "aaa" */ - /* leave space for leading "r[ow],", "," and trailing zero */ + /* leave space for the leading "r[ow],", "," and the trailing zero */ sz = strlen(vfs) + strlen(fs) + 5; res = malloc(sz); if (!res) @@ -701,7 +758,7 @@ static char *merge_optstr(const char *vfs, const char *fs) * mnt_fs_strdup_options: * @fs: fstab/mtab/mountinfo entry pointer * - * Merges all mount options (VFS, FS and userspace) to the one options string + * Merges all mount options (VFS, FS and userspace) to one options string * and returns the result. This function does not modigy @fs. * * Returns: pointer to string (can be freed by free(3)) or NULL in case of error. @@ -757,10 +814,10 @@ const char *mnt_fs_get_optional_fields(struct libmnt_fs *fs) * @fs: fstab/mtab/mountinfo entry pointer * @optstr: options string * - * Splits @optstr to VFS, FS and userspace mount options and update relevat + * Splits @optstr to VFS, FS and userspace mount options and updates relevant * parts of @fs. * - * Returns: 0 on success, or negative number icase of error. + * Returns: 0 on success, or negative number in case of error. */ int mnt_fs_set_options(struct libmnt_fs *fs, const char *optstr) { @@ -774,8 +831,12 @@ int mnt_fs_set_options(struct libmnt_fs *fs, const char *optstr) if (rc) return rc; n = strdup(optstr); - if (!n) + if (!n) { + free(u); + free(v); + free(f); return -ENOMEM; + } } free(fs->fs_optstr); @@ -799,7 +860,7 @@ int mnt_fs_set_options(struct libmnt_fs *fs, const char *optstr) * Parses (splits) @optstr and appends results to VFS, FS and userspace lists * of options. * - * If @optstr is NULL then @fs is not modified and 0 is returned. + * If @optstr is NULL, then @fs is not modified and 0 is returned. * * Returns: 0 on success or negative number in case of error. */ @@ -815,6 +876,9 @@ int mnt_fs_append_options(struct libmnt_fs *fs, const char *optstr) return 0; rc = mnt_split_optstr((char *) optstr, &u, &v, &f, 0, 0); + if (rc) + return rc; + if (!rc && v) rc = mnt_optstr_append_option(&fs->vfs_optstr, v, NULL); if (!rc && f) @@ -836,10 +900,10 @@ int mnt_fs_append_options(struct libmnt_fs *fs, const char *optstr) * @fs: fstab/mtab/mountinfo entry * @optstr: mount options * - * Parses (splits) @optstr and prepands results to VFS, FS and userspace lists + * Parses (splits) @optstr and prepends the results to VFS, FS and userspace lists * of options. * - * If @optstr is NULL then @fs is not modified and 0 is returned. + * If @optstr is NULL, then @fs is not modified and 0 is returned. * * Returns: 0 on success or negative number in case of error. */ @@ -855,6 +919,9 @@ int mnt_fs_prepend_options(struct libmnt_fs *fs, const char *optstr) return 0; rc = mnt_split_optstr((char *) optstr, &u, &v, &f, 0, 0); + if (rc) + return rc; + if (!rc && v) rc = mnt_optstr_prepend_option(&fs->vfs_optstr, v, NULL); if (!rc && f) @@ -925,10 +992,10 @@ const char *mnt_fs_get_attributes(struct libmnt_fs *fs) * @optstr: options string * * Sets mount attributes. The attributes are mount(2) and mount(8) independent - * options, these options are not send to kernel and are not interpreted by + * options, these options are not sent to the kernel and are not interpreted by * libmount. The attributes are stored in /run/mount/utab only. * - * The atrtributes are managed by libmount in userspace only. It's possible + * The attributes are managed by libmount in userspace only. It's possible * that information stored in userspace will not be available for libmount * after CLONE_FS unshare. Be careful, and don't use attributes if possible. * @@ -1221,7 +1288,7 @@ dev_t mnt_fs_get_devno(struct libmnt_fs *fs) * mnt_fs_get_tid: * @fs: /proc/tid/mountinfo entry * - * Returns: TID (task ID) for filesystems read from mountinfo file + * Returns: TID (task ID) for filesystems read from the mountinfo file */ pid_t mnt_fs_get_tid(struct libmnt_fs *fs) { @@ -1233,10 +1300,10 @@ pid_t mnt_fs_get_tid(struct libmnt_fs *fs) * mnt_fs_get_option: * @fs: fstab/mtab/mountinfo entry pointer * @name: option name - * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL + * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL * @valsz: returns size of options value or 0 * - * Returns: 0 on success, 1 when not found the @name or negative number in case of error. + * Returns: 0 on success, 1 when @name not found or negative number in case of error. */ int mnt_fs_get_option(struct libmnt_fs *fs, const char *name, char **value, size_t *valsz) @@ -1259,10 +1326,10 @@ int mnt_fs_get_option(struct libmnt_fs *fs, const char *name, * mnt_fs_get_attribute: * @fs: fstab/mtab/mountinfo entry pointer * @name: option name - * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL + * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL * @valsz: returns size of options value or 0 * - * Returns: 0 on success, 1 when not found the @name or negative number in case of error. + * Returns: 0 on success, 1 when @name not found or negative number in case of error. */ int mnt_fs_get_attribute(struct libmnt_fs *fs, const char *name, char **value, size_t *valsz) @@ -1278,6 +1345,67 @@ int mnt_fs_get_attribute(struct libmnt_fs *fs, const char *name, } /** + * mnt_fs_get_comment: + * @fs: fstab/mtab/mountinfo entry pointer + * + * Returns: 0 on success, 1 when not found the @name or negative number in case of error. + */ +const char *mnt_fs_get_comment(struct libmnt_fs *fs) +{ + assert(fs); + if (!fs) + return NULL; + return fs->comment; +} + +/** + * mnt_fs_set_comment: + * @fs: fstab entry pointer + * @comm: comment string + * + * Note that the comment has to be terminated by '\n' (new line), otherwise + * the whole filesystem entry will be written as a comment to the tabfile (e.g. + * fstab). + * + * Returns: 0 on success or <0 in case of error. + */ +int mnt_fs_set_comment(struct libmnt_fs *fs, const char *comm) +{ + char *p = NULL; + + assert(fs); + if (!fs) + return -EINVAL; + if (comm) { + p = strdup(comm); + if (!p) + return -ENOMEM; + } + + free(fs->comment); + fs->comment = p; + return 0; +} + +/** + * mnt_fs_append_comment: + * @fs: fstab entry pointer + * @comm: comment string + * + * See also mnt_fs_set_comment(). + * + * Returns: 0 on success or <0 in case of error. + */ +int mnt_fs_append_comment(struct libmnt_fs *fs, const char *comm) +{ + assert(fs); + if (!fs) + return -EINVAL; + + return append_string(&fs->comment, comm); +} + +/** * mnt_fs_match_target: * @fs: filesystem * @target: mountpoint path @@ -1291,7 +1419,7 @@ int mnt_fs_get_attribute(struct libmnt_fs *fs, const char *name, * * The 2nd and 3rd attempts are not performed when @cache is NULL. * - * Returns: 1 if @fs target is equal to @target else 0. + * Returns: 1 if @fs target is equal to @target, else 0. */ int mnt_fs_match_target(struct libmnt_fs *fs, const char *target, struct libmnt_cache *cache) @@ -1326,7 +1454,7 @@ int mnt_fs_match_target(struct libmnt_fs *fs, const char *target, * @source: tag or path (device or so) or NULL * @cache: tags/paths cache or NULL * - * Possible are four attempts: + * Four attempts are possible: * 1) compare @source with @fs->source * 2) compare realpath(@source) with @fs->source * 3) compare realpath(@source) with realpath(@fs->source) @@ -1335,7 +1463,7 @@ int mnt_fs_match_target(struct libmnt_fs *fs, const char *target, * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The * 2nd and 3rd attempts are not performed if @fs->source is tag. * - * Returns: 1 if @fs source is equal to @source else 0. + * Returns: 1 if @fs source is equal to @source, else 0. */ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, struct libmnt_cache *cache) @@ -1379,14 +1507,14 @@ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, return 1; } if (src || mnt_fs_get_tag(fs, &t, &v)) - /* src path does not match and tag is not defined */ + /* src path does not match and the tag is not defined */ return 0; /* read @source's tags to the cache */ if (mnt_cache_read_tags(cache, cn) < 0) { if (errno == EACCES) { /* we don't have permissions to read TAGs from - * @source, but can translate @fs tag to devname. + * @source, but can translate the @fs tag to devname. * * (because libblkid uses udev symlinks and this is * accessible for non-root uses) @@ -1398,7 +1526,7 @@ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, return 0; } - /* 4) has the @source a tag that matches with tag from @fs ? */ + /* 4) has the @source a tag that matches with the tag from @fs ? */ if (mnt_cache_device_has_tag(cache, cn, t, v)) return 1; @@ -1412,7 +1540,7 @@ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, * * For more details see mnt_match_fstype(). * - * Returns: 1 if @fs type is matching to @types else 0. The function returns + * Returns: 1 if @fs type is matching to @types, else 0. The function returns * 0 when types is NULL. */ int mnt_fs_match_fstype(struct libmnt_fs *fs, const char *types) @@ -1428,7 +1556,7 @@ int mnt_fs_match_fstype(struct libmnt_fs *fs, const char *types) * * For more details see mnt_match_options(). * - * Returns: 1 if @fs type is matching to @options else 0. The function returns + * Returns: 1 if @fs type is matching to @options, else 0. The function returns * 0 when types is NULL. */ int mnt_fs_match_options(struct libmnt_fs *fs, const char *options) @@ -1493,6 +1621,8 @@ int mnt_fs_print_debug(struct libmnt_fs *fs, FILE *file) minor(mnt_fs_get_devno(fs))); if (mnt_fs_get_tid(fs)) fprintf(file, "tid: %d\n", mnt_fs_get_tid(fs)); + if (mnt_fs_get_comment(fs)) + fprintf(file, "comment: '%s'\n", mnt_fs_get_comment(fs)); return 0; } @@ -1501,7 +1631,7 @@ int mnt_fs_print_debug(struct libmnt_fs *fs, FILE *file) * mnt_free_mntent: * @mnt: mount entry * - * Deallocates "mntent.h" mount entry. + * Deallocates the "mntent.h" mount entry. */ void mnt_free_mntent(struct mntent *mnt) { @@ -1519,11 +1649,11 @@ void mnt_free_mntent(struct mntent *mnt) * @fs: filesystem * @mnt: mount description (as described in mntent.h) * - * Copies information from @fs to struct mntent @mnt. If @mnt is already set + * Copies the information from @fs to struct mntent @mnt. If @mnt is already set, * then the struct mntent items are reallocated and updated. See also * mnt_free_mntent(). * - * Returns: 0 on success and negative number in case of error. + * Returns: 0 on success and a negative number in case of error. */ int mnt_fs_to_mntent(struct libmnt_fs *fs, struct mntent **mnt) { |
