diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-02-08 08:48:36 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-02-08 08:48:36 +0000 |
commit | e427fb773837953c01ebe8dfaf8f8679c7895fc2 (patch) | |
tree | 5008c15a3a2ebf8e7fee043ae9880a8a7cd7568c | |
parent | 223adf17682765f9e72d3436348700085d823a6e (diff) | |
download | cmogstored-e427fb773837953c01ebe8dfaf8f8679c7895fc2.tar.gz |
This centralizes the mountpoint suitability logic in one place. In the future, it may also allow us to parallelize the work of scanning filesystems.
-rw-r--r-- | mnt.c | 35 | ||||
-rw-r--r-- | mnt.h | 2 | ||||
-rw-r--r-- | mnt_usable.c | 44 |
3 files changed, 44 insertions, 37 deletions
@@ -62,24 +62,11 @@ static Hash_table * mnt_new(size_t n) return rv; } -static bool resolve_symlink(char **orig) -{ - char *p = canonicalize_filename_mode(*orig, CAN_EXISTING); - - if (p) { - free(*orig); - *orig = p; - return true; - } - return false; -} - /* populates a hash table starting with the mount list */ static void mnt_populate(Hash_table *tbl) { struct mount_entry *head = read_file_system_list(false); struct mount_entry *next; - struct stat sb; union { const void *ptr; struct mount_entry *old_me; @@ -98,29 +85,9 @@ static void mnt_populate(Hash_table *tbl) } head->me_type = NULL; - if (head->me_dummy) - goto skip; - if (!mog_mnt_usable(head->me_mountdir)) + if (!mog_mnt_usable(head)) goto skip; - /* the device number may not have been populated, do it */ - if (head->me_dev == (dev_t)-1) { - if (stat(head->me_mountdir, &sb) != 0) - goto skip; - head->me_dev = sb.st_dev; - } - - /* - * resolve symlinks for things that look like paths - * and skip dead symlinks - */ - if (head->me_devname[0] == '/') { - if (lstat(head->me_devname, &sb) == 0 && - S_ISLNK(sb.st_mode) && - ! resolve_symlink(&head->me_devname)) - goto skip; - } - /* mark the device as something we _might_ track util for */ mog_iou_active(head->me_dev); @@ -9,4 +9,4 @@ void mog_mnt_update_util(struct mog_iostat *); char *mog_mnt_fetch_util(dev_t st_dev, char dst[MOG_IOUTIL_LEN]); /* mnt_usable.c */ -bool mog_mnt_usable(const char *path); +bool mog_mnt_usable(struct mount_entry *me); diff --git a/mnt_usable.c b/mnt_usable.c index 1d590b1..9ba52e4 100644 --- a/mnt_usable.c +++ b/mnt_usable.c @@ -16,18 +16,58 @@ #define MY_STATFS statvfs #endif +static bool resolve_symlink(char **orig) +{ + char *p = canonicalize_filename_mode(*orig, CAN_EXISTING); + + if (p) { + free(*orig); + *orig = p; + return true; + } + return false; +} + +static bool stat_harder(struct mount_entry *me) +{ + struct stat sb; + + /* the device number may not have been populated, do it */ + if (me->me_dev == (dev_t)-1) { + if (stat(me->me_mountdir, &sb) != 0) + return false; + me->me_dev = sb.st_dev; + } + + /* + * resolve symlinks for things that look like paths + * and skip dead symlinks + */ + if (me->me_devname[0] == '/') { + if (lstat(me->me_devname, &sb) == 0 + && S_ISLNK(sb.st_mode) + && ! resolve_symlink(&me->me_devname)) + return false; + } + return true; +} + /* * prevents us from using filesystems of unknown size, since those could * be stalled/dead network mounts */ -bool mog_mnt_usable(const char *path) +bool mog_mnt_usable(struct mount_entry *me) { struct MY_STATFS buf; + const char *path = me->me_mountdir; + + if (me->me_dummy) + return false; retry: errno = 0; if (MY_STATFS(path, &buf) == 0) - return (buf.f_blocks > 0); + return (buf.f_blocks > 0) ? stat_harder(me) : false; /* unknown */ assert(errno != EFAULT && "BUG: EFAULT from statfs/statvfs"); |