Fixes: #4920
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
filepath path(relpath);
Inode *in;
bool created = false;
- int r = path_walk(path, &in);
+ /* O_CREATE with O_EXCL enforces O_NOFOLLOW. */
+ bool followsym = !((flags & O_NOFOLLOW) || ((flags & O_CREAT) && (flags & O_EXCL)));
+ int r = path_walk(path, &in, followsym);
+
if (r == 0 && (flags & O_CREAT) && (flags & O_EXCL))
return -EEXIST;
+
+ if (r == 0 && in->is_symlink() && (flags & O_NOFOLLOW))
+ return -ELOOP;
+
if (r == -ENOENT && (flags & O_CREAT)) {
filepath dirpath = path;
string dname = dirpath.last_dentry();
ASSERT_EQ(ceph_symlink(cmount, test_file, test_symlink), 0);
+ // test the O_NOFOLLOW case
+ fd = ceph_open(cmount, test_symlink, O_NOFOLLOW, 0);
+ ASSERT_EQ(fd, -ELOOP);
+
// stat the original file
struct stat stbuf_orig;
ASSERT_EQ(ceph_stat(cmount, test_file, &stbuf_orig), 0);