aboutsummaryrefslogtreecommitdiffstats
path: root/fs/read_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/read_write.c')
-rw-r--r--fs/read_write.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/read_write.c b/fs/read_write.c
index 969a6d9c020b..5cc6924eb158 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -50,6 +50,14 @@ generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
50 offset += inode->i_size; 50 offset += inode->i_size;
51 break; 51 break;
52 case SEEK_CUR: 52 case SEEK_CUR:
53 /*
54 * Here we special-case the lseek(fd, 0, SEEK_CUR)
55 * position-querying operation. Avoid rewriting the "same"
56 * f_pos value back to the file because a concurrent read(),
57 * write() or lseek() might have altered it
58 */
59 if (offset == 0)
60 return file->f_pos;
53 offset += file->f_pos; 61 offset += file->f_pos;
54 break; 62 break;
55 } 63 }
@@ -105,6 +113,10 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
105 offset += i_size_read(file->f_path.dentry->d_inode); 113 offset += i_size_read(file->f_path.dentry->d_inode);
106 break; 114 break;
107 case SEEK_CUR: 115 case SEEK_CUR:
116 if (offset == 0) {
117 retval = file->f_pos;
118 goto out;
119 }
108 offset += file->f_pos; 120 offset += file->f_pos;
109 } 121 }
110 retval = -EINVAL; 122 retval = -EINVAL;
@@ -115,6 +127,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
115 } 127 }
116 retval = offset; 128 retval = offset;
117 } 129 }
130out:
118 unlock_kernel(); 131 unlock_kernel();
119 return retval; 132 return retval;
120} 133}