Skip to content

Commit

Permalink
introduce "fd_pos" class, convert fdget_pos() users to it.
Browse files Browse the repository at this point in the history
fdget_pos() for constructor, fdput_pos() for cleanup, all users of
fd..._pos() converted trivially.

Reviewed-by: Christian Brauner <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed Nov 3, 2024
1 parent 0481819 commit d7a9616
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 42 deletions.
5 changes: 2 additions & 3 deletions arch/alpha/kernel/osf_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
long __user *, basep)
{
int error;
struct fd arg = fdget_pos(fd);
CLASS(fd_pos, arg)(fd);
struct osf_dirent_callback buf = {
.ctx.actor = osf_filldir,
.dirent = dirent,
.basep = basep,
.count = count
};

if (!fd_file(arg))
if (fd_empty(arg))
return -EBADF;

error = iterate_dir(fd_file(arg), &buf.ctx);
Expand All @@ -169,7 +169,6 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
if (count != buf.count)
error = count - buf.count;

fdput_pos(arg);
return error;
}

Expand Down
34 changes: 13 additions & 21 deletions fs/read_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,8 @@ EXPORT_SYMBOL(vfs_llseek);
static off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence)
{
off_t retval;
struct fd f = fdget_pos(fd);
if (!fd_file(f))
CLASS(fd_pos, f)(fd);
if (fd_empty(f))
return -EBADF;

retval = -EINVAL;
Expand All @@ -397,7 +397,6 @@ static off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence)
if (res != (loff_t)retval)
retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
}
fdput_pos(f);
return retval;
}

Expand All @@ -420,15 +419,14 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
unsigned int, whence)
{
int retval;
struct fd f = fdget_pos(fd);
CLASS(fd_pos, f)(fd);
loff_t offset;

if (!fd_file(f))
if (fd_empty(f))
return -EBADF;

retval = -EINVAL;
if (whence > SEEK_MAX)
goto out_putf;
return -EINVAL;

offset = vfs_llseek(fd_file(f), ((loff_t) offset_high << 32) | offset_low,
whence);
Expand All @@ -439,8 +437,6 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
if (!copy_to_user(result, &offset, sizeof(offset)))
retval = 0;
}
out_putf:
fdput_pos(f);
return retval;
}
#endif
Expand Down Expand Up @@ -700,10 +696,10 @@ static inline loff_t *file_ppos(struct file *file)

ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
{
struct fd f = fdget_pos(fd);
CLASS(fd_pos, f)(fd);
ssize_t ret = -EBADF;

if (fd_file(f)) {
if (!fd_empty(f)) {
loff_t pos, *ppos = file_ppos(fd_file(f));
if (ppos) {
pos = *ppos;
Expand All @@ -712,7 +708,6 @@ ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
ret = vfs_read(fd_file(f), buf, count, ppos);
if (ret >= 0 && ppos)
fd_file(f)->f_pos = pos;
fdput_pos(f);
}
return ret;
}
Expand All @@ -724,10 +719,10 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)

ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count)
{
struct fd f = fdget_pos(fd);
CLASS(fd_pos, f)(fd);
ssize_t ret = -EBADF;

if (fd_file(f)) {
if (!fd_empty(f)) {
loff_t pos, *ppos = file_ppos(fd_file(f));
if (ppos) {
pos = *ppos;
Expand All @@ -736,7 +731,6 @@ ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count)
ret = vfs_write(fd_file(f), buf, count, ppos);
if (ret >= 0 && ppos)
fd_file(f)->f_pos = pos;
fdput_pos(f);
}

return ret;
Expand Down Expand Up @@ -1075,10 +1069,10 @@ static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec,
unsigned long vlen, rwf_t flags)
{
struct fd f = fdget_pos(fd);
CLASS(fd_pos, f)(fd);
ssize_t ret = -EBADF;

if (fd_file(f)) {
if (!fd_empty(f)) {
loff_t pos, *ppos = file_ppos(fd_file(f));
if (ppos) {
pos = *ppos;
Expand All @@ -1087,7 +1081,6 @@ static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec,
ret = vfs_readv(fd_file(f), vec, vlen, ppos, flags);
if (ret >= 0 && ppos)
fd_file(f)->f_pos = pos;
fdput_pos(f);
}

if (ret > 0)
Expand All @@ -1099,10 +1092,10 @@ static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec,
static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec,
unsigned long vlen, rwf_t flags)
{
struct fd f = fdget_pos(fd);
CLASS(fd_pos, f)(fd);
ssize_t ret = -EBADF;

if (fd_file(f)) {
if (!fd_empty(f)) {
loff_t pos, *ppos = file_ppos(fd_file(f));
if (ppos) {
pos = *ppos;
Expand All @@ -1111,7 +1104,6 @@ static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec,
ret = vfs_writev(fd_file(f), vec, vlen, ppos, flags);
if (ret >= 0 && ppos)
fd_file(f)->f_pos = pos;
fdput_pos(f);
}

if (ret > 0)
Expand Down
28 changes: 10 additions & 18 deletions fs/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,19 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
struct old_linux_dirent __user *, dirent, unsigned int, count)
{
int error;
struct fd f = fdget_pos(fd);
CLASS(fd_pos, f)(fd);
struct readdir_callback buf = {
.ctx.actor = fillonedir,
.dirent = dirent
};

if (!fd_file(f))
if (fd_empty(f))
return -EBADF;

error = iterate_dir(fd_file(f), &buf.ctx);
if (buf.result)
error = buf.result;

fdput_pos(f);
return error;
}

Expand Down Expand Up @@ -309,16 +308,15 @@ static bool filldir(struct dir_context *ctx, const char *name, int namlen,
SYSCALL_DEFINE3(getdents, unsigned int, fd,
struct linux_dirent __user *, dirent, unsigned int, count)
{
struct fd f;
CLASS(fd_pos, f)(fd);
struct getdents_callback buf = {
.ctx.actor = filldir,
.count = count,
.current_dir = dirent
};
int error;

f = fdget_pos(fd);
if (!fd_file(f))
if (fd_empty(f))
return -EBADF;

error = iterate_dir(fd_file(f), &buf.ctx);
Expand All @@ -333,7 +331,6 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
else
error = count - buf.count;
}
fdput_pos(f);
return error;
}

Expand Down Expand Up @@ -392,16 +389,15 @@ static bool filldir64(struct dir_context *ctx, const char *name, int namlen,
SYSCALL_DEFINE3(getdents64, unsigned int, fd,
struct linux_dirent64 __user *, dirent, unsigned int, count)
{
struct fd f;
CLASS(fd_pos, f)(fd);
struct getdents_callback64 buf = {
.ctx.actor = filldir64,
.count = count,
.current_dir = dirent
};
int error;

f = fdget_pos(fd);
if (!fd_file(f))
if (fd_empty(f))
return -EBADF;

error = iterate_dir(fd_file(f), &buf.ctx);
Expand All @@ -417,7 +413,6 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
else
error = count - buf.count;
}
fdput_pos(f);
return error;
}

Expand Down Expand Up @@ -477,20 +472,19 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
struct compat_old_linux_dirent __user *, dirent, unsigned int, count)
{
int error;
struct fd f = fdget_pos(fd);
CLASS(fd_pos, f)(fd);
struct compat_readdir_callback buf = {
.ctx.actor = compat_fillonedir,
.dirent = dirent
};

if (!fd_file(f))
if (fd_empty(f))
return -EBADF;

error = iterate_dir(fd_file(f), &buf.ctx);
if (buf.result)
error = buf.result;

fdput_pos(f);
return error;
}

Expand Down Expand Up @@ -560,16 +554,15 @@ static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen
COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
struct compat_linux_dirent __user *, dirent, unsigned int, count)
{
struct fd f;
CLASS(fd_pos, f)(fd);
struct compat_getdents_callback buf = {
.ctx.actor = compat_filldir,
.current_dir = dirent,
.count = count
};
int error;

f = fdget_pos(fd);
if (!fd_file(f))
if (fd_empty(f))
return -EBADF;

error = iterate_dir(fd_file(f), &buf.ctx);
Expand All @@ -584,7 +577,6 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
else
error = count - buf.count;
}
fdput_pos(f);
return error;
}
#endif
1 change: 1 addition & 0 deletions include/linux/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ static inline void fdput_pos(struct fd f)

DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd)
DEFINE_CLASS(fd_raw, struct fd, fdput(_T), fdget_raw(fd), int fd)
DEFINE_CLASS(fd_pos, struct fd, fdput_pos(_T), fdget_pos(fd), int fd)

extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
extern int replace_fd(unsigned fd, struct file *file, unsigned flags);
Expand Down

0 comments on commit d7a9616

Please sign in to comment.