diff options
author | Vikas Gorur <vikas@gluster.com> | 2010-01-28 06:55:05 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-02-07 23:27:52 -0800 |
commit | 03f487c9419fca50d378ce514b014450e46af113 (patch) | |
tree | c8ca27607c609ed168e9f398f7cafa3ef6b3342c | |
parent | 58b29b62980299bc70196703f36b7c7c30b72ba1 (diff) |
storage/posix: Fix device number handling.
There are two fixes in this patch:
1) If the device number has changed, do a fresh stat on the export
directory and if it matches the device number of the file,
assume a remount happened and remember the new device number
as official (this helps automounted export volumes).
2) Don't log the "device number changed" message if it is due
to a stat on ".." (in posix_readdirp), as it could be because
".." leads us out of the exported volume.
Signed-off-by: Vikas Gorur <vikas@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 576 (crossing device (2056) + fuse LOOKUP error)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=576
-rw-r--r-- | xlators/storage/posix/src/posix.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index ae47dffef6f..8374f408cc2 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -199,19 +199,33 @@ posix_scale_st_ino (struct posix_private *priv, struct stat *buf) int i = 0; int ret = -1; ino_t temp_ino = 0; - + int r; + struct stat export_buf; + for (i = 0; i < priv->num_devices_to_span; i++) { - if (buf->st_dev == priv->st_device[i]) + if (buf->st_dev == priv->st_device[i]) { break; + } if (priv->st_device[i] == 0) { priv->st_device[i] = buf->st_dev; break; } } - if (i == priv->num_devices_to_span) - goto out; - + if (i == priv->num_devices_to_span) { + r = lstat (priv->base_path, &export_buf); + if ((r != 0) || (buf->st_dev != export_buf.st_dev)) { + goto out; + } + + gf_log (THIS->name, GF_LOG_WARNING, + "device number for exported volume %s has changed " + "since init --- assuming done by automount", + priv->base_path); + + priv->st_device[0] = export_buf.st_dev; + } + temp_ino = (buf->st_ino * priv->num_devices_to_span) + i; buf->st_ino = temp_ino; @@ -239,7 +253,10 @@ posix_lstat_with_gen (xlator_t *this, const char *path, struct stat *stbuf_p) return -1; ret = posix_scale_st_ino (priv, &stbuf); - if (ret == -1) { + if ((ret == -1) && !strcmp (path, "..")) { + /* stat on ../ might land us outside the export directory, + so don't panic */ + gf_log (this->name, GF_LOG_WARNING, "Access to %s (on dev %lld) is crossing device (%lld)", path, (unsigned long long) stbuf.st_dev, |