X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;ds=sidebyside;f=fs%2Fread_write.c;h=5520f8ad550446d095c6483e67acc0ca5522ff91;hb=5b45b69c0573b802a50ccad30e154b93d3b36ff8;hp=5d431bacbea967e7a66755bf9320f20d9f464902;hpb=d78c68efa84ff312f3663dbf921b1e3485232205;p=mv-sheeva.git diff --git a/fs/read_write.c b/fs/read_write.c index 5d431bacbea..5520f8ad550 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -30,18 +30,9 @@ const struct file_operations generic_ro_fops = { EXPORT_SYMBOL(generic_ro_fops); -static int -__negative_fpos_check(struct file *file, loff_t pos, size_t count) +static inline int unsigned_offsets(struct file *file) { - /* - * pos or pos+count is negative here, check overflow. - * too big "count" will be caught in rw_verify_area(). - */ - if ((pos < 0) && (pos + count < pos)) - return -EOVERFLOW; - if (file->f_mode & FMODE_UNSIGNED_OFFSET) - return 0; - return -EINVAL; + return file->f_mode & FMODE_UNSIGNED_OFFSET; } /** @@ -75,7 +66,7 @@ generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin) break; } - if (offset < 0 && __negative_fpos_check(file, offset, 0)) + if (offset < 0 && !unsigned_offsets(file)) return -EINVAL; if (offset > inode->i_sb->s_maxbytes) return -EINVAL; @@ -152,7 +143,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin) offset += file->f_pos; } retval = -EINVAL; - if (offset >= 0 || !__negative_fpos_check(file, offset, 0)) { + if (offset >= 0 || unsigned_offsets(file)) { if (offset != file->f_pos) { file->f_pos = offset; file->f_version = 0; @@ -252,9 +243,13 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count if (unlikely((ssize_t) count < 0)) return retval; pos = *ppos; - if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) { - retval = __negative_fpos_check(file, pos, count); - if (retval) + if (unlikely(pos < 0)) { + if (!unsigned_offsets(file)) + return retval; + if (count >= -pos) /* both values are in 0..LLONG_MAX */ + return -EOVERFLOW; + } else if (unlikely((loff_t) (pos + count) < 0)) { + if (!unsigned_offsets(file)) return retval; }