Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions src/smoothfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,34 +130,6 @@ static char *smoothfs_rel_path_from_dentry(struct dentry *dentry)
return rel;
}

static int smoothfs_resolve_rel_path_on_tier(struct smoothfs_sb_info *sbi,
u8 tier, const char *rel_path,
struct path *out)
{
char *buf, *rendered, *full = NULL;
int err;

buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!buf)
return -ENOMEM;
rendered = d_path(&sbi->tiers[tier].lower_path, buf, PATH_MAX);
if (IS_ERR(rendered)) {
err = PTR_ERR(rendered);
kfree(buf);
return err;
}
if (rel_path && *rel_path)
full = kasprintf(GFP_KERNEL, "%s/%s", rendered, rel_path);
else
full = kstrdup(rendered, GFP_KERNEL);
kfree(buf);
if (!full)
return -ENOMEM;
err = kern_path(full, LOOKUP_FOLLOW, out);
kfree(full);
return err;
}

static int smoothfs_collect_one_dir(struct smoothfs_dir_cache *cache,
struct path *dir_path,
const struct cred *cred)
Expand Down
28 changes: 0 additions & 28 deletions src/smoothfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,34 +49,6 @@ static char *smoothfs_rel_path_from_dentry(struct dentry *dentry)
return rel;
}

static int smoothfs_resolve_rel_path_on_tier(struct smoothfs_sb_info *sbi,
u8 tier, const char *rel_path,
struct path *out)
{
char *buf, *rendered, *full = NULL;
int err;

buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!buf)
return -ENOMEM;
rendered = d_path(&sbi->tiers[tier].lower_path, buf, PATH_MAX);
if (IS_ERR(rendered)) {
err = PTR_ERR(rendered);
kfree(buf);
return err;
}
if (rel_path && *rel_path)
full = kasprintf(GFP_KERNEL, "%s/%s", rendered, rel_path);
else
full = kstrdup(rendered, GFP_KERNEL);
kfree(buf);
if (!full)
return -ENOMEM;
err = kern_path(full, LOOKUP_FOLLOW, out);
kfree(full);
return err;
}

static bool smoothfs_tier_near_enospc(struct smoothfs_sb_info *sbi, u8 tier)
{
struct kstatfs st;
Expand Down
26 changes: 26 additions & 0 deletions src/smoothfs/smoothfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,32 @@ struct smoothfs_sb_info {
void *sysfs_pool;
};

/*
* Resolve a pool-relative path from the lower mount that smoothfs pinned at
* mount time. Never render that path and feed it back to kern_path():
* kern_path() starts in the calling task's mount namespace, where containers
* need not expose the backing-tier mountpoints at all.
*/
static inline int
smoothfs_resolve_rel_path_on_tier(struct smoothfs_sb_info *sbi, u8 tier,
const char *rel_path, struct path *out)
{
struct path root;

if (tier >= sbi->ntiers)
return -EINVAL;

root = sbi->tiers[tier].lower_path;
if (!rel_path || !*rel_path) {
*out = root;
path_get(out);
return 0;
}

return vfs_path_lookup(root.dentry, root.mnt, rel_path,
LOOKUP_FOLLOW, out);
}

static inline u8 smoothfs_tier_of(struct smoothfs_sb_info *sbi,
struct vfsmount *mnt)
{
Expand Down
31 changes: 0 additions & 31 deletions src/smoothfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -697,37 +697,6 @@ static void smoothfs_write_staging_set_reason(struct smoothfs_sb_info *sbi,
spin_unlock(&sbi->write_staging_lock);
}

static int smoothfs_resolve_rel_path_on_tier(struct smoothfs_sb_info *sbi,
u8 tier, const char *rel_path,
struct path *out)
{
char *buf, *rendered, *full = NULL;
int err;

if (tier >= sbi->ntiers)
return -EINVAL;

buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!buf)
return -ENOMEM;
rendered = d_path(&sbi->tiers[tier].lower_path, buf, PATH_MAX);
if (IS_ERR(rendered)) {
err = PTR_ERR(rendered);
kfree(buf);
return err;
}
if (rel_path && *rel_path)
full = kasprintf(GFP_KERNEL, "%s/%s", rendered, rel_path);
else
full = kstrdup(rendered, GFP_KERNEL);
kfree(buf);
if (!full)
return -ENOMEM;
err = kern_path(full, LOOKUP_FOLLOW, out);
kfree(full);
return err;
}

/*
* Drop the replay pin on the separately-tracked smoothfs inode that shadows a
* spill/replica copy we just removed from `tier`.
Expand Down
1 change: 1 addition & 0 deletions src/smoothfs/test/run_runtime_harnesses.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ core_tests=(
tier_spill_nested_parent.sh
tier_spill_union_readdir.sh
tier_spill_negative_dentry_revalidate.sh
tier_spill_mount_namespace_lookup.sh
tier_spill_unlink_finds_right_tier.sh
tier_spill_rmdir_placement.sh
tier_spill_forget_lower_reclaim.sh
Expand Down
42 changes: 42 additions & 0 deletions src/smoothfs/test/tier_spill_mount_namespace_lookup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
# Regression: lower-tier resolution must not depend on the calling task's
# mount namespace. Containers see the merged bind mount but intentionally do
# not see SmoothNAS's backing-tier mountpoints.

set -u

SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
export SPILL_ROOT=${SPILL_ROOT:-/tmp/smoothfs-mount-namespace-lookup}
. "$SCRIPT_DIR/tier_spill_lib.sh"

trap spill_cleanup EXIT

echo "=== laying down 2-tier XFS smoothfs ==="
spill_setup_pool nslookup 00000000-0000-0000-0000-00000000f10f

mkdir -p "$SPILL_ROOT/slow/library"
printf 'namespace-independent\n' > "$SPILL_ROOT/slow/library/episode.mkv"
sync

echo "=== hide lower mountpoints from a container-like mount namespace ==="
VIEW="$SPILL_ROOT/container-view"
mkdir -p "$VIEW"
if unshare --mount bash -eu -c '
mount --bind "$1/server" "$2"
umount -l "$1/server"
umount -l "$1/fast"
umount -l "$1/slow"

# The caller can no longer resolve the host backing path by name.
test ! -e "$1/slow/library/episode.mkv"
# Smoothfs must still resolve through its pinned lower struct path.
test -f "$2/library/episode.mkv"
test "$(cat "$2/library/episode.mkv")" = namespace-independent
ls "$2/library" | grep -qx episode.mkv
' _ "$SPILL_ROOT" "$VIEW"; then
spill_assert true
else
spill_assert false "merged lookup failed outside the host mount namespace"
fi

spill_finish "tier_spill_mount_namespace_lookup"