diff options
author | Karel Zak | 2014-03-03 10:36:15 +0100 |
---|---|---|
committer | Karel Zak | 2014-03-03 10:36:15 +0100 |
commit | 6a52473ecd877227f6f7da2b95da0b51593ffec1 (patch) | |
tree | 6dd6778cf47560258450468de30c6e49c4adc169 /libmount/src/mountP.h | |
parent | docs: refresh TODO (diff) | |
download | kernel-qcow2-util-linux-6a52473ecd877227f6f7da2b95da0b51593ffec1.tar.gz kernel-qcow2-util-linux-6a52473ecd877227f6f7da2b95da0b51593ffec1.tar.xz kernel-qcow2-util-linux-6a52473ecd877227f6f7da2b95da0b51593ffec1.zip |
umount: don't use mountinfo if possible
The umount(8) always parses /proc/self/mountinfo to get fstype and to
merge kernel mount options with userspace mount options from
/run/mount/utab. This behavior is overkill in many cases and it's
pretty expensive as kernel has to always compose *whole* mountinfo.
This performance disadvantage is visible for crazy use-cases with huge
number of mountpoints and frequently called umount(8).
It seems that we can bypass /proc/self/mountinfo by statfs() to get
filesystem type (statfs.f_type magic) and analyze /run/mount/utab
before we parse mountinfo.
This optimization is not used when:
* umount(8) executed by non-root (as user= in utab is expected)
* umount --lazy / --force (target is probably unreachable NFS, then
use statfs() is pretty bad idea)
* target is not a directory (e.g. umount /dev/sda1)
* there is (deprecated) writeable mtab
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src/mountP.h')
-rw-r--r-- | libmount/src/mountP.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index adc245af4..a580ae438 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -15,6 +15,7 @@ #include <string.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/vfs.h> #include <unistd.h> #include "c.h" @@ -142,6 +143,7 @@ extern char *stripoff_last_component(char *path); extern int mnt_valid_tagname(const char *tagname); extern int append_string(char **a, const char *b); +extern const char *mnt_statfs_get_fstype(struct statfs *vfs); extern int is_file_empty(const char *name); extern int mkdir_p(const char *path, mode_t mode); @@ -178,6 +180,11 @@ extern struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb, struct libmnt_fs *fs, unsigned long mountflags, char **fsroot); +extern int __mnt_table_parse_mtab(struct libmnt_table *tb, + const char *filename, + struct libmnt_table *u_tb); + + /* * Generic iterator */ @@ -327,6 +334,7 @@ struct libmnt_context struct libmnt_table *fstab; /* fstab (or mtab for some remounts) entries */ struct libmnt_table *mtab; /* mtab entries */ + struct libmnt_table *utab; /* rarely used by umount only */ int (*table_errcb)(struct libmnt_table *tb, /* callback for libmnt_table structs */ const char *filename, int line); |