Skip to content

Commit

Permalink
fs: split off vfs_getdents function of getdents64 syscall
Browse files Browse the repository at this point in the history
This splits off the vfs_getdents function from the getdents64 system
call. This allows io_uring to call the function.

Signed-off-by: Stefan Roesch <shr@fb.com>
  • Loading branch information
Stefan Roesch authored and intel-lab-lkp committed Nov 25, 2021
1 parent db41839 commit 018019b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
8 changes: 8 additions & 0 deletions fs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,11 @@ long splice_file_to_pipe(struct file *in,
struct pipe_inode_info *opipe,
loff_t *offset,
size_t len, unsigned int flags);

/*
* fs/readdir.c
*/
struct linux_dirent64;

int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
unsigned int count, s64 pos);
36 changes: 28 additions & 8 deletions fs/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,22 +368,26 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
return -EFAULT;
}

SYSCALL_DEFINE3(getdents64, unsigned int, fd,
struct linux_dirent64 __user *, dirent, unsigned int, count)
/**
* vfs_getdents - getdents without fdget
* @file : pointer to file struct of directory
* @dirent : pointer to user directory structure
* @count : size of buffer
* @ctx_pos : if file pos is used, pass -1,
* if ctx pos is used, pass ctx pos
*/
int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
unsigned int count, s64 ctx_pos)
{
struct fd f;
struct getdents_callback64 buf = {
.ctx.actor = filldir64,
.ctx.pos = ctx_pos,
.count = count,
.current_dir = dirent
};
int error;

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

error = iterate_dir(f.file, &buf.ctx);
error = do_iterate_dir(file, &buf.ctx, ctx_pos < 0);
if (error >= 0)
error = buf.error;
if (buf.prev_reclen) {
Expand All @@ -396,6 +400,22 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
else
error = count - buf.count;
}

return error;
}

SYSCALL_DEFINE3(getdents64, unsigned int, fd,
struct linux_dirent64 __user *, dirent, unsigned int, count)
{
struct fd f;
int error;

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

error = vfs_getdents(f.file, dirent, count, -1);

fdput_pos(f);
return error;
}
Expand Down

0 comments on commit 018019b

Please sign in to comment.