Skip to content

Commit de12c33

Browse files
author
Al Viro
committed
add struct fd constructors, get rid of __to_fd()
Make __fdget() et.al. return struct fd directly. New helpers: BORROWED_FD(file) and CLONED_FD(file), for borrowed and cloned file references resp. NOTE: this might need tuning; in particular, inline on __fget_light() is there to keep the code generation same as before - we probably want to keep it inlined in fdget() et.al. (especially so in fdget_pos()), but that needs profiling. Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 88a2f64 commit de12c33

File tree

2 files changed

+24
-35
lines changed

2 files changed

+24
-35
lines changed

fs/file.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ EXPORT_SYMBOL(task_lookup_next_fdget_rcu);
11281128
* The fput_needed flag returned by fget_light should be passed to the
11291129
* corresponding fput_light.
11301130
*/
1131-
static unsigned long __fget_light(unsigned int fd, fmode_t mask)
1131+
static inline struct fd __fget_light(unsigned int fd, fmode_t mask)
11321132
{
11331133
struct files_struct *files = current->files;
11341134
struct file *file;
@@ -1145,22 +1145,22 @@ static unsigned long __fget_light(unsigned int fd, fmode_t mask)
11451145
if (likely(atomic_read_acquire(&files->count) == 1)) {
11461146
file = files_lookup_fd_raw(files, fd);
11471147
if (!file || unlikely(file->f_mode & mask))
1148-
return 0;
1149-
return (unsigned long)file;
1148+
return EMPTY_FD;
1149+
return BORROWED_FD(file);
11501150
} else {
11511151
file = __fget_files(files, fd, mask);
11521152
if (!file)
1153-
return 0;
1154-
return FDPUT_FPUT | (unsigned long)file;
1153+
return EMPTY_FD;
1154+
return CLONED_FD(file);
11551155
}
11561156
}
1157-
unsigned long __fdget(unsigned int fd)
1157+
struct fd fdget(unsigned int fd)
11581158
{
11591159
return __fget_light(fd, FMODE_PATH);
11601160
}
1161-
EXPORT_SYMBOL(__fdget);
1161+
EXPORT_SYMBOL(fdget);
11621162

1163-
unsigned long __fdget_raw(unsigned int fd)
1163+
struct fd fdget_raw(unsigned int fd)
11641164
{
11651165
return __fget_light(fd, 0);
11661166
}
@@ -1181,16 +1181,16 @@ static inline bool file_needs_f_pos_lock(struct file *file)
11811181
(file_count(file) > 1 || file->f_op->iterate_shared);
11821182
}
11831183

1184-
unsigned long __fdget_pos(unsigned int fd)
1184+
struct fd fdget_pos(unsigned int fd)
11851185
{
1186-
unsigned long v = __fdget(fd);
1187-
struct file *file = (struct file *)(v & ~3);
1186+
struct fd f = fdget(fd);
1187+
struct file *file = fd_file(f);
11881188

11891189
if (file && file_needs_f_pos_lock(file)) {
1190-
v |= FDPUT_POS_UNLOCK;
1190+
f.word |= FDPUT_POS_UNLOCK;
11911191
mutex_lock(&file->f_pos_lock);
11921192
}
1193-
return v;
1193+
return f;
11941194
}
11951195

11961196
void __f_unlock_pos(struct file *f)

include/linux/file.h

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ static inline bool fd_empty(struct fd f)
5353
}
5454

5555
#define EMPTY_FD (struct fd){0}
56+
static inline struct fd BORROWED_FD(struct file *f)
57+
{
58+
return (struct fd){(unsigned long)f};
59+
}
60+
static inline struct fd CLONED_FD(struct file *f)
61+
{
62+
return (struct fd){(unsigned long)f | FDPUT_FPUT};
63+
}
5664

5765
static inline void fdput(struct fd fd)
5866
{
@@ -63,30 +71,11 @@ static inline void fdput(struct fd fd)
6371
extern struct file *fget(unsigned int fd);
6472
extern struct file *fget_raw(unsigned int fd);
6573
extern struct file *fget_task(struct task_struct *task, unsigned int fd);
66-
extern unsigned long __fdget(unsigned int fd);
67-
extern unsigned long __fdget_raw(unsigned int fd);
68-
extern unsigned long __fdget_pos(unsigned int fd);
6974
extern void __f_unlock_pos(struct file *);
7075

71-
static inline struct fd __to_fd(unsigned long v)
72-
{
73-
return (struct fd){v};
74-
}
75-
76-
static inline struct fd fdget(unsigned int fd)
77-
{
78-
return __to_fd(__fdget(fd));
79-
}
80-
81-
static inline struct fd fdget_raw(unsigned int fd)
82-
{
83-
return __to_fd(__fdget_raw(fd));
84-
}
85-
86-
static inline struct fd fdget_pos(int fd)
87-
{
88-
return __to_fd(__fdget_pos(fd));
89-
}
76+
struct fd fdget(unsigned int fd);
77+
struct fd fdget_raw(unsigned int fd);
78+
struct fd fdget_pos(unsigned int fd);
9079

9180
static inline void fdput_pos(struct fd f)
9281
{

0 commit comments

Comments
 (0)