From: Karel Zak Date: Tue, 9 Mar 2010 14:48:11 +0000 (+0100) Subject: libmount: add support for userdata and work with VFS tree X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26b4f9e4551ca97334dd06114bf0f97a75c4ce81;p=util-linux libmount: add support for userdata and work with VFS tree Signed-off-by: Karel Zak --- diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c index fef61b0d..ae97b654 100644 --- a/shlibs/mount/src/fs.c +++ b/shlibs/mount/src/fs.c @@ -57,6 +57,33 @@ void mnt_free_fs(mnt_fs *fs) free(fs); } +/** + * mnt_fs_get_userdata: + * @fs: mnt_file instance + * + * Returns private data set by mnt_fs_set_userdata() or NULL. + */ +void *mnt_fs_get_userdata(mnt_fs *fs) +{ + return fs ? fs->userdata : NULL; +} + +/** + * mnt_fs_set_userdata: + * @fs: mnt_file instance + * + * The "userdata" are library independent data. + * + * Returns 0 or -1 in case of error (if @fs is NULL). + */ +int mnt_fs_set_userdata(mnt_fs *fs, void *data) +{ + if (!fs) + return -1; + fs->userdata = data; + return 0; +} + /** * mnt_fs_get_srcpath: * @fs: mnt_file (fstab/mtab/mountinfo) fs diff --git a/shlibs/mount/src/mount.h.in b/shlibs/mount/src/mount.h.in index 585b9fca..4e918b83 100644 --- a/shlibs/mount/src/mount.h.in +++ b/shlibs/mount/src/mount.h.in @@ -212,6 +212,8 @@ extern int mnt_lock_file(mnt_lock *ml); /* fs.c */ extern mnt_fs *mnt_new_fs(void); extern void mnt_free_fs(mnt_fs *ent); +extern void *mnt_fs_get_userdata(mnt_fs *fs); +extern int mnt_fs_set_userdata(mnt_fs *fs, void *data); extern const char *mnt_fs_get_source(mnt_fs *ent); extern int mnt_fs_set_source(mnt_fs *ent, const char *source); extern const char *mnt_fs_get_srcpath(mnt_fs *ent); @@ -271,6 +273,9 @@ extern const char *mnt_tab_get_name(mnt_tab *tb); extern int mnt_tab_add_fs(mnt_tab *tb, mnt_fs *fs); extern int mnt_tab_remove_fs(mnt_tab *tb, mnt_fs *fs); extern int mnt_tab_next_fs(mnt_tab *tb, mnt_iter *itr, mnt_fs **fs); +extern int mnt_tab_next_child_fs(mnt_tab *tb, mnt_iter *itr, + mnt_fs *parent, mnt_fs **chld); +extern int mnt_tab_get_root_fs(mnt_tab *tb, mnt_fs **root); extern int mnt_tab_set_iter(mnt_tab *tb, mnt_iter *itr, mnt_fs *fs); extern mnt_fs *mnt_tab_find_target(mnt_tab *tb, const char *path, int direction); diff --git a/shlibs/mount/src/mount.sym b/shlibs/mount/src/mount.sym index 6740bbcd..5df37796 100644 --- a/shlibs/mount/src/mount.sym +++ b/shlibs/mount/src/mount.sym @@ -31,6 +31,7 @@ global: mnt_fs_get_srcpath; mnt_fs_get_tag; mnt_fs_get_target; + mnt_fs_get_userdata; mnt_fs_match_fstype; mnt_fs_match_options; mnt_fs_match_source; @@ -42,6 +43,7 @@ global: mnt_fs_set_passno; mnt_fs_set_source; mnt_fs_set_target; + mnt_fs_set_userdata; mnt_fstype_is_netfs; mnt_fstype_is_pseudofs; mnt_get_builtin_optmap; @@ -116,6 +118,8 @@ global: mnt_tab_get_name; mnt_tab_get_nents; mnt_tab_get_nerrs; + mnt_tab_get_root_fs; + mnt_tab_next_child_fs; mnt_tab_next_fs; mnt_tab_parse_file; mnt_tab_remove_fs; diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h index e92ba701..4b4e5b5b 100644 --- a/shlibs/mount/src/mountP.h +++ b/shlibs/mount/src/mountP.h @@ -155,6 +155,8 @@ struct _mnt_fs { int flags; /* MNT_FS_* flags */ int lineno; /* line number in the parental file */ + + void *userdata; /* library independent data */ }; /* diff --git a/shlibs/mount/src/tab.c b/shlibs/mount/src/tab.c index 2ae694b5..98c56602 100644 --- a/shlibs/mount/src/tab.c +++ b/shlibs/mount/src/tab.c @@ -209,6 +209,97 @@ int mnt_tab_remove_fs(mnt_tab *tb, mnt_fs *fs) return 0; } +/** + * mnt_tab_get_root_fs: + * @tb: mountinfo file (/proc/self/mountinfo) + * @root: returns pointer to the root filesystem (/) + * + * Returns: 0 on success or -1 case of error. + */ +int mnt_tab_get_root_fs(mnt_tab *tb, mnt_fs **root) +{ + mnt_iter itr; + mnt_fs *fs; + int root_id = 0; + + assert(tb); + assert(root); + + if (!tb || !root) + return -1; + + mnt_reset_iter(&itr, MNT_ITER_FORWARD); + while(mnt_tab_next_fs(tb, &itr, &fs) == 0) { + int id = mnt_fs_get_parent_id(fs); + if (!id) + break; /* @tab is not mountinfo file? */ + + if (!*root || id < root_id) { + *root = fs; + root_id = id; + } + } + + return root_id ? 0 : -1; +} + +/** + * mnt_tab_next_child_fs: + * @tb: mountinfo file (/proc/self/mountinfo) + * @parent: parental FS + * @chld: returns the next child filesystem + * + * Note that filesystems are returned in the order how was mounted (according to + * IDs in /proc/self/mountinfo). + * + * Returns 0 on success, -1 in case of error or 1 at end of list. + */ +int mnt_tab_next_child_fs(mnt_tab *tb, mnt_iter *itr, + mnt_fs *parent, mnt_fs **chld) +{ + mnt_fs *fs; + int parent_id, lastchld_id = 0, chld_id = 0; + + if (!tb || !itr || !parent) + return -1; + + parent_id = mnt_fs_get_id(parent); + if (!parent_id) + return -1; + + /* get ID of the previously returned child */ + if (itr->head && itr->p != itr->head) { + MNT_ITER_ITERATE(itr, fs, struct _mnt_fs, ents); + lastchld_id = mnt_fs_get_id(fs); + } + + *chld = NULL; + + mnt_reset_iter(itr, MNT_ITER_FORWARD); + while(mnt_tab_next_fs(tb, itr, &fs) == 0) { + int id; + + if (mnt_fs_get_parent_id(fs) != parent_id) + continue; + + id = mnt_fs_get_id(fs); + + if ((!lastchld_id || id > lastchld_id) && + (!*chld || id < chld_id)) { + *chld = fs; + chld_id = id; + } + } + + if (!chld_id) + return 1; /* end of iterator */ + + /* set the iterator to the @chld for the next call */ + mnt_tab_set_iter(tb, itr, *chld); + + return 0; +} + /** * mnt_tab_next_fs: * @tb: tab pointer @@ -290,6 +381,7 @@ int mnt_tab_find_next_fs(mnt_tab *tb, mnt_iter *itr, return 0; } while(1); + *fs = NULL; return 1; }