-
Notifications
You must be signed in to change notification settings - Fork 0
fdget_pos
Donald Buczek edited this page Jun 13, 2020
·
2 revisions
https://elixir.bootlin.com/linux/v5.7/source/include/linux/file.h#L72
static inline struct fd fdget_pos(int fd)
{
return __to_fd(__fdget_pos(fd));
}
https://elixir.bootlin.com/linux/v5.7/source/fs/file.c#L818
unsigned long __fdget_pos(unsigned int fd)
{
unsigned long v = __fdget(fd);
struct file *file = (struct file *)(v & ~3);
if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
if (file_count(file) > 1) {
v |= FDPUT_POS_UNLOCK;
mutex_lock(&file->f_pos_lock);
}
}
return v;
}
https://elixir.bootlin.com/linux/v5.7/source/fs/file.c#L807
unsigned long __fdget(unsigned int fd)
{
return __fget_light(fd, FMODE_PATH);
}
https://elixir.bootlin.com/linux/v5.7/source/fs/file.c#L774
/*
* Lightweight file lookup - no refcnt increment if fd table isn't shared.
*
* You can use this instead of fget if you satisfy all of the following
* conditions:
* 1) You must call fput_light before exiting the syscall and returning control
* to userspace (i.e. you cannot remember the returned struct file * after
* returning to userspace).
* 2) You must not call filp_close on the returned struct file * in between
* calls to fget_light and fput_light.
* 3) You must not clone the current task in between the calls to fget_light
* and fput_light.
*
* The fput_needed flag returned by fget_light should be passed to the
* corresponding fput_light.
*/
static unsigned long __fget_light(unsigned int fd, fmode_t mask)
{
struct files_struct *files = current->files;
struct file *file;
if (atomic_read(&files->count) == 1) {
file = __fcheck_files(files, fd);
if (!file || unlikely(file->f_mode & mask))
return 0;
return (unsigned long)file;
} else {
file = __fget(fd, mask, 1);
if (!file)
return 0;
return FDPUT_FPUT | (unsigned long)file;
}
}