linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: Al Viro <viro@zeniv.linux.org.uk>
Cc: George Spelvin <linux@horizon.com>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: Update of file offset on write() etc. is non-atomic with I/O
Date: Mon, 3 Mar 2014 14:17:55 -0800	[thread overview]
Message-ID: <CA+55aFyRJqb1HkVESdZDOcQ+20t-s-JWxZa15SHJpGU+k=6www@mail.gmail.com> (raw)
In-Reply-To: <20140303220106.GL18016@ZenIV.linux.org.uk>

[-- Attachment #1: Type: text/plain, Size: 680 bytes --]

On Mon, Mar 3, 2014 at 2:01 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> The thing is, the callers in there do *not* keep struct file * at all -
> they keep struct socket * and use sock->file to get struct file * back
> when they need it.

Not a problem. Just make sockfd_lookup_light() use the broken
inefficient calling convention.

So then the networking code can continue to use the old bad interface,
without it impacting the normal users.

Something like the attached untested patch. This gets rid of
"fget_light()", and instead makes "fdget()" the native interface (same
for the "raw" version).

Totally untested patch (on top of my previous one)

               Linus

[-- Attachment #2: patch.diff --]
[-- Type: text/plain, Size: 3673 bytes --]

 fs/file.c            | 30 +++++++++++++++---------------
 include/linux/file.h | 24 ++----------------------
 net/socket.c         | 17 ++++++++++++-----
 3 files changed, 29 insertions(+), 42 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index db25c2bdfe46..cd0c1c329baf 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -683,33 +683,33 @@ EXPORT_SYMBOL(fget_raw);
  * The fput_needed flag returned by fget_light should be passed to the
  * corresponding fput_light.
  */
-struct file *__fget_light(unsigned int fd, fmode_t mask, int *fput_needed)
+static struct fd __fdget(unsigned int fd, fmode_t mask)
 {
 	struct files_struct *files = current->files;
-	struct file *file;
+	struct fd f = { NULL, };
 
-	*fput_needed = 0;
 	if (atomic_read(&files->count) == 1) {
-		file = __fcheck_files(files, fd);
-		if (file && (file->f_mode & mask))
-			file = NULL;
+		f.file = __fcheck_files(files, fd);
+		if (f.file && (f.file->f_mode & mask))
+			f.file = NULL;
 	} else {
-		file = __fget(fd, mask);
-		if (file)
-			*fput_needed = 1;
+		f.file = __fget(fd, mask);
+		if (f.file)
+			f.need_put = 1;
 	}
 
-	return file;
+	return f;
 }
-struct file *fget_light(unsigned int fd, int *fput_needed)
+
+struct fd fdget(unsigned int fd)
 {
-	return __fget_light(fd, FMODE_PATH, fput_needed);
+	return __fdget(fd, FMODE_PATH);
 }
-EXPORT_SYMBOL(fget_light);
+EXPORT_SYMBOL(fdget);
 
-struct file *fget_raw_light(unsigned int fd, int *fput_needed)
+struct fd fdget_raw(unsigned int fd)
 {
-	return __fget_light(fd, 0, fput_needed);
+	return __fdget(fd, 0);
 }
 
 void set_close_on_exec(unsigned int fd, int flag)
diff --git a/include/linux/file.h b/include/linux/file.h
index 636634a09c92..253402e6f3da 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -20,12 +20,6 @@ struct path;
 extern struct file *alloc_file(struct path *, fmode_t mode,
 	const struct file_operations *fop);
 
-static inline void fput_light(struct file *file, int fput_needed)
-{
-	if (fput_needed)
-		fput(file);
-}
-
 struct fd {
 	struct file *file;
 	unsigned need_put:1, need_pos_unlock:1;
@@ -38,24 +32,10 @@ static inline void fdput(struct fd fd)
 }
 
 extern struct file *fget(unsigned int fd);
-extern struct file *fget_light(unsigned int fd, int *fput_needed);
-
-static inline struct fd fdget(unsigned int fd)
-{
-	int b;
-	struct file *f = fget_light(fd, &b);
-	return (struct fd){f,b,0};
-}
-
 extern struct file *fget_raw(unsigned int fd);
-extern struct file *fget_raw_light(unsigned int fd, int *fput_needed);
 
-static inline struct fd fdget_raw(unsigned int fd)
-{
-	int b;
-	struct file *f = fget_raw_light(fd, &b);
-	return (struct fd){f,b,0};
-}
+extern struct fd fdget(unsigned int fd);
+extern struct fd fdget_raw(unsigned 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);
diff --git a/net/socket.c b/net/socket.c
index 879933aaed4c..4c9dc05f3b4b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -448,18 +448,25 @@ struct socket *sockfd_lookup(int fd, int *err)
 }
 EXPORT_SYMBOL(sockfd_lookup);
 
+static void fput_light(struct file *file, int fput_needed)
+{
+	struct fd f = { file, fput_needed, 0};
+	fdput(f);
+}
+
 static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
 {
-	struct file *file;
+	struct fd f;
 	struct socket *sock;
 
 	*err = -EBADF;
-	file = fget_light(fd, fput_needed);
-	if (file) {
-		sock = sock_from_file(file, err);
+	f = fdget(fd);
+	*fput_needed = f.need_put;
+	if (f.file) {
+		sock = sock_from_file(f.file, err);
 		if (sock)
 			return sock;
-		fput_light(file, *fput_needed);
+		fdput(f);
 	}
 	return NULL;
 }

  reply	other threads:[~2014-03-03 22:17 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-03 21:03 Update of file offset on write() etc. is non-atomic with I/O George Spelvin
2014-03-03 21:26 ` Al Viro
2014-03-03 21:52   ` Linus Torvalds
2014-03-03 22:01     ` Al Viro
2014-03-03 22:17       ` Linus Torvalds [this message]
2014-03-03 23:28         ` Al Viro
2014-03-03 23:34           ` Linus Torvalds
2014-03-03 23:42             ` Al Viro
2014-03-03 23:59               ` Linus Torvalds
2014-03-04  0:23                 ` Al Viro
2014-03-04  0:42                   ` Linus Torvalds
2014-03-04  1:05                     ` Al Viro
2014-03-04 20:00                       ` Al Viro
2014-03-04 21:17                         ` Linus Torvalds
2014-03-05  0:04                           ` Al Viro
2014-03-10 15:55                             ` Al Viro
2014-03-03 22:55     ` Linus Torvalds
2014-03-03 23:23       ` Linus Torvalds
2014-03-03 23:39         ` Al Viro
2014-03-03 23:54           ` Linus Torvalds
2014-03-03 23:54           ` Al Viro
2014-03-04 20:11           ` Cedric Blancher
2014-03-04  0:07     ` George Spelvin
2014-05-04  7:04 ` Michael Kerrisk
     [not found] <a8df285f-de7f-4a3a-9a19-e0ad07ab3a5c@blur>
2014-02-20 18:15 ` Zuckerman, Boris
2014-02-20 18:29   ` Al Viro
2014-02-21  6:01     ` Michael Kerrisk (man-pages)
2014-02-23  1:18       ` Kevin Easton
2014-02-23  7:38         ` Michael Kerrisk (man-pages)
  -- strict thread matches above, loose matches on Subject: below --
2014-02-17 15:41 Michael Kerrisk (man-pages)
2014-02-18 13:00 ` Michael Kerrisk
2014-02-20 17:14 ` Linus Torvalds
2014-03-03 17:36   ` Linus Torvalds
2014-03-03 21:45     ` Al Viro
2014-03-03 21:56       ` Linus Torvalds
2014-03-03 22:09         ` Al Viro
2014-03-03 22:20           ` Linus Torvalds
2014-03-03 22:01       ` Linus Torvalds
2014-03-03 22:10         ` Al Viro
2014-03-03 22:22           ` Linus Torvalds
2014-03-06 15:03     ` Michael Kerrisk (man-pages)
2014-03-07  3:38       ` Yongzhi Pan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CA+55aFyRJqb1HkVESdZDOcQ+20t-s-JWxZa15SHJpGU+k=6www@mail.gmail.com' \
    --to=torvalds@linux-foundation.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@horizon.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).