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 /mnt_usable.c | |
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.
Diffstat (limited to 'mnt_usable.c')
-rw-r--r-- | mnt_usable.c | 44 |
1 files changed, 42 insertions, 2 deletions
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"); |