From: Andi Kleen <andi@firstfloor.org>
To: viro@zeniv.linux.org.uk
Cc: hch@infradead.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org, Andi Kleen <ak@linux.intel.com>
Subject: [PATCH 2/5] VFS: Use f_lock for SEEK_SET
Date: Thu, 16 Jun 2011 14:07:19 -0700 [thread overview]
Message-ID: <1308258442-19804-2-git-send-email-andi@firstfloor.org> (raw)
In-Reply-To: <1308258442-19804-1-git-send-email-andi@firstfloor.org>
From: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
fs/read_write.c | 44 ++++++++++++++++++++++++++++++--------------
include/linux/fs.h | 3 ++-
2 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/fs/read_write.c b/fs/read_write.c
index 9bd5d23..0b1d4ca 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -35,6 +35,20 @@ static inline int unsigned_offsets(struct file *file)
return file->f_mode & FMODE_UNSIGNED_OFFSET;
}
+static loff_t lseek_execute(struct file *file, struct inode *inode, loff_t offset)
+{
+ if (offset < 0 && !unsigned_offsets(file))
+ return -EINVAL;
+ if (offset > inode->i_sb->s_maxbytes)
+ return -EINVAL;
+
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ file->f_version = 0;
+ }
+ return offset;
+}
+
/**
* generic_file_llseek - generic llseek implementation for regular files
* @file: file structure to seek on
@@ -44,6 +58,12 @@ static inline int unsigned_offsets(struct file *file)
* This is a generic implemenation of ->llseek useable for all normal local
* filesystems. It just updates the file offset to the value specified by
* @offset and @origin under i_mutex.
+ *
+ * Synchronization:
+ * SEEK_SET is unsynchronized (but atomic on 64bit platforms)
+ * SEEK_CUR is synchronized against other SEEK_CURs, but not read/writes.
+ * read/writes behave like SEEK_SET against seeks.
+ * SEEK_END
*/
loff_t
generic_file_llseek(struct file *file, loff_t offset, int origin)
@@ -63,22 +83,18 @@ generic_file_llseek(struct file *file, loff_t offset, int origin)
*/
if (offset == 0)
return file->f_pos;
- offset += file->f_pos;
- break;
- }
-
- if (offset < 0 && !unsigned_offsets(file))
- return -EINVAL;
- if (offset > inode->i_sb->s_maxbytes)
- return -EINVAL;
-
- /* Special lock needed here? */
- if (offset != file->f_pos) {
- file->f_pos = offset;
- file->f_version = 0;
+ /*
+ * f_lock protects against read/modify/write race with other
+ * SEEK_CURs. Note that parallel writes and reads behave
+ * like SEEK_SET.
+ */
+ spin_lock(&file->f_lock);
+ offset = lseek_execute(file, inode, offset + file->f_pos);
+ spin_unlock(&file->f_lock);
+ return offset;
}
- return offset;
+ return lseek_execute(file, inode, offset);
}
EXPORT_SYMBOL(generic_file_llseek);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index deec2cd..a19d164 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -946,7 +946,8 @@ struct file {
#define f_dentry f_path.dentry
#define f_vfsmnt f_path.mnt
const struct file_operations *f_op;
- spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */
+ spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ,
+ SEEK_SET */
#ifdef CONFIG_SMP
int f_sb_list_cpu;
#endif
--
1.7.4.4
next prev parent reply other threads:[~2011-06-16 21:09 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-16 21:07 [PATCH 1/5] VFS: Do (nearly) lockless generic_file_llseek Andi Kleen
2011-06-16 21:07 ` Andi Kleen [this message]
2011-06-16 21:07 ` [PATCH 3/5] VFS: Add generic_file_llseek_size Andi Kleen
2011-06-16 21:07 ` [PATCH 4/5] EXT4: Replace cut'n'pasted llseek code with generic_file_llseek_size Andi Kleen
2011-06-16 21:07 ` [PATCH 5/5] NFS: Drop unnecessary locking in llseek Andi Kleen
2011-06-17 12:40 ` [PATCH 1/5] VFS: Do (nearly) lockless generic_file_llseek Arnd Bergmann
2011-06-17 17:42 ` Andi Kleen
2011-06-17 21:18 ` Arnd Bergmann
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=1308258442-19804-2-git-send-email-andi@firstfloor.org \
--to=andi@firstfloor.org \
--cc=ak@linux.intel.com \
--cc=hch@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--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).