aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-04 14:54:22 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-03-10 11:44:42 -0400
commitbd2a31d522344b3ac2fb680bd2366e77a9bd8209 (patch)
treed08be6aea75b2f41bebf516bfc33187d0673bfce
parent00e188ef6a7e7bf2883bcffc30d89e98a0bb76b3 (diff)
get rid of fget_light()
instead of returning the flags by reference, we can just have the low-level primitive return those in lower bits of unsigned long, with struct file * derived from the rest. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/file.c56
-rw-r--r--fs/read_write.c16
-rw-r--r--include/linux/file.h21
-rw-r--r--include/linux/fs.h2
4 files changed, 56 insertions, 39 deletions
diff --git a/fs/file.c b/fs/file.c
index db25c2bdfe46..60a45e9f5323 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -683,35 +683,65 @@ EXPORT_SYMBOL(fget_raw);
683 * The fput_needed flag returned by fget_light should be passed to the 683 * The fput_needed flag returned by fget_light should be passed to the
684 * corresponding fput_light. 684 * corresponding fput_light.
685 */ 685 */
686struct file *__fget_light(unsigned int fd, fmode_t mask, int *fput_needed) 686static unsigned long __fget_light(unsigned int fd, fmode_t mask)
687{ 687{
688 struct files_struct *files = current->files; 688 struct files_struct *files = current->files;
689 struct file *file; 689 struct file *file;
690 690
691 *fput_needed = 0;
692 if (atomic_read(&files->count) == 1) { 691 if (atomic_read(&files->count) == 1) {
693 file = __fcheck_files(files, fd); 692 file = __fcheck_files(files, fd);
694 if (file && (file->f_mode & mask)) 693 if (!file || unlikely(file->f_mode & mask))
695 file = NULL; 694 return 0;
695 return (unsigned long)file;
696 } else { 696 } else {
697 file = __fget(fd, mask); 697 file = __fget(fd, mask);
698 if (file) 698 if (!file)
699 *fput_needed = 1; 699 return 0;
700 return FDPUT_FPUT | (unsigned long)file;
700 } 701 }
701
702 return file;
703} 702}
704struct file *fget_light(unsigned int fd, int *fput_needed) 703unsigned long __fdget(unsigned int fd)
705{ 704{
706 return __fget_light(fd, FMODE_PATH, fput_needed); 705 return __fget_light(fd, FMODE_PATH);
707} 706}
708EXPORT_SYMBOL(fget_light); 707EXPORT_SYMBOL(__fdget);
709 708
710struct file *fget_raw_light(unsigned int fd, int *fput_needed) 709unsigned long __fdget_raw(unsigned int fd)
711{ 710{
712 return __fget_light(fd, 0, fput_needed); 711 return __fget_light(fd, 0);
712}
713
714unsigned long __fdget_pos(unsigned int fd)
715{
716 struct files_struct *files = current->files;
717 struct file *file;
718 unsigned long v;
719
720 if (atomic_read(&files->count) == 1) {
721 file = __fcheck_files(files, fd);
722 v = 0;
723 } else {
724 file = __fget(fd, 0);
725 v = FDPUT_FPUT;
726 }
727 if (!file)
728 return 0;
729
730 if (file->f_mode & FMODE_ATOMIC_POS) {
731 if (file_count(file) > 1) {
732 v |= FDPUT_POS_UNLOCK;
733 mutex_lock(&file->f_pos_lock);
734 }
735 }
736 return v | (unsigned long)file;
713} 737}
714 738
739/*
740 * We only lock f_pos if we have threads or if the file might be
741 * shared with another process. In both cases we'll have an elevated
742 * file count (done either by fdget() or by fork()).
743 */
744
715void set_close_on_exec(unsigned int fd, int flag) 745void set_close_on_exec(unsigned int fd, int flag)
716{ 746{
717 struct files_struct *files = current->files; 747 struct files_struct *files = current->files;
diff --git a/fs/read_write.c b/fs/read_write.c
index 932bb3414a96..54e19b9392dc 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -264,23 +264,9 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
264} 264}
265EXPORT_SYMBOL(vfs_llseek); 265EXPORT_SYMBOL(vfs_llseek);
266 266
267/*
268 * We only lock f_pos if we have threads or if the file might be
269 * shared with another process. In both cases we'll have an elevated
270 * file count (done either by fdget() or by fork()).
271 */
272static inline struct fd fdget_pos(int fd) 267static inline struct fd fdget_pos(int fd)
273{ 268{
274 struct fd f = fdget(fd); 269 return __to_fd(__fdget_pos(fd));
275 struct file *file = f.file;
276
277 if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
278 if (file_count(file) > 1) {
279 f.flags |= FDPUT_POS_UNLOCK;
280 mutex_lock(&file->f_pos_lock);
281 }
282 }
283 return f;
284} 270}
285 271
286static inline void fdput_pos(struct fd f) 272static inline void fdput_pos(struct fd f)
diff --git a/include/linux/file.h b/include/linux/file.h
index f2517fa2d610..4d69123377a2 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -40,23 +40,24 @@ static inline void fdput(struct fd fd)
40} 40}
41 41
42extern struct file *fget(unsigned int fd); 42extern struct file *fget(unsigned int fd);
43extern struct file *fget_light(unsigned int fd, int *fput_needed); 43extern struct file *fget_raw(unsigned int fd);
44extern unsigned long __fdget(unsigned int fd);
45extern unsigned long __fdget_raw(unsigned int fd);
46extern unsigned long __fdget_pos(unsigned int fd);
44 47
45static inline struct fd fdget(unsigned int fd) 48static inline struct fd __to_fd(unsigned long v)
46{ 49{
47 int b; 50 return (struct fd){(struct file *)(v & ~3),v & 3};
48 struct file *f = fget_light(fd, &b);
49 return (struct fd){f,b};
50} 51}
51 52
52extern struct file *fget_raw(unsigned int fd); 53static inline struct fd fdget(unsigned int fd)
53extern struct file *fget_raw_light(unsigned int fd, int *fput_needed); 54{
55 return __to_fd(__fdget(fd));
56}
54 57
55static inline struct fd fdget_raw(unsigned int fd) 58static inline struct fd fdget_raw(unsigned int fd)
56{ 59{
57 int b; 60 return __to_fd(__fdget_raw(fd));
58 struct file *f = fget_raw_light(fd, &b);
59 return (struct fd){f,b};
60} 61}
61 62
62extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); 63extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ebfde04bca06..23b2a35d712e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -812,7 +812,7 @@ struct file {
812#ifdef CONFIG_DEBUG_WRITECOUNT 812#ifdef CONFIG_DEBUG_WRITECOUNT
813 unsigned long f_mnt_write_state; 813 unsigned long f_mnt_write_state;
814#endif 814#endif
815}; 815} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
816 816
817struct file_handle { 817struct file_handle {
818 __u32 handle_bytes; 818 __u32 handle_bytes;