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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.