Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63b6df14 authored by Al Viro's avatar Al Viro
Browse files

give readdir(2)/getdents(2)/etc. uniform exclusion with lseek()



same as read() on regular files has, and for the same reason.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 9902af79
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
		long __user *, basep)
{
	int error;
	struct fd arg = fdget(fd);
	struct fd arg = fdget_pos(fd);
	struct osf_dirent_callback buf = {
		.ctx.actor = osf_filldir,
		.dirent = dirent,
@@ -164,7 +164,7 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
	if (count != buf.count)
		error = count - buf.count;

	fdput(arg);
	fdput_pos(arg);
	return error;
}

+6 −6
Original line number Diff line number Diff line
@@ -884,7 +884,7 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
		struct compat_old_linux_dirent __user *, dirent, unsigned int, count)
{
	int error;
	struct fd f = fdget(fd);
	struct fd f = fdget_pos(fd);
	struct compat_readdir_callback buf = {
		.ctx.actor = compat_fillonedir,
		.dirent = dirent
@@ -897,7 +897,7 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
	if (buf.result)
		error = buf.result;

	fdput(f);
	fdput_pos(f);
	return error;
}

@@ -975,7 +975,7 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
	if (!access_ok(VERIFY_WRITE, dirent, count))
		return -EFAULT;

	f = fdget(fd);
	f = fdget_pos(fd);
	if (!f.file)
		return -EBADF;

@@ -989,7 +989,7 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
		else
			error = count - buf.count;
	}
	fdput(f);
	fdput_pos(f);
	return error;
}

@@ -1062,7 +1062,7 @@ COMPAT_SYSCALL_DEFINE3(getdents64, unsigned int, fd,
	if (!access_ok(VERIFY_WRITE, dirent, count))
		return -EFAULT;

	f = fdget(fd);
	f = fdget_pos(fd);
	if (!f.file)
		return -EBADF;

@@ -1077,7 +1077,7 @@ COMPAT_SYSCALL_DEFINE3(getdents64, unsigned int, fd,
		else
			error = count - buf.count;
	}
	fdput(f);
	fdput_pos(f);
	return error;
}
#endif /* __ARCH_WANT_COMPAT_SYS_GETDENTS64 */
+5 −0
Original line number Diff line number Diff line
@@ -784,6 +784,11 @@ unsigned long __fdget_pos(unsigned int fd)
	return v;
}

void __f_unlock_pos(struct file *f)
{
	mutex_unlock(&f->f_pos_lock);
}

/*
 * We only lock f_pos if we have threads or if the file might be
 * shared with another process. In both cases we'll have an elevated
+1 −1
Original line number Diff line number Diff line
@@ -713,7 +713,7 @@ static int do_dentry_open(struct file *f,
	}

	/* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */
	if (S_ISREG(inode->i_mode))
	if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))
		f->f_mode |= FMODE_ATOMIC_POS;

	f->f_op = fops_get(inode->i_fop);
+0 −12
Original line number Diff line number Diff line
@@ -302,18 +302,6 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
}
EXPORT_SYMBOL(vfs_llseek);

static inline struct fd fdget_pos(int fd)
{
	return __to_fd(__fdget_pos(fd));
}

static inline void fdput_pos(struct fd f)
{
	if (f.flags & FDPUT_POS_UNLOCK)
		mutex_unlock(&f.file->f_pos_lock);
	fdput(f);
}

SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence)
{
	off_t retval;
Loading