dlmfs_file_write(): fix the bogosity in handling non-zero *ppos
'count' is how much you want written, not the final position. Moreover, it can legitimately be less than the current position... Cc: stable@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
8f3d9f3542
commit
3815f1be54
|
@ -275,7 +275,6 @@ static ssize_t dlmfs_file_write(struct file *filp,
|
||||||
loff_t *ppos)
|
loff_t *ppos)
|
||||||
{
|
{
|
||||||
int bytes_left;
|
int bytes_left;
|
||||||
ssize_t writelen;
|
|
||||||
char *lvb_buf;
|
char *lvb_buf;
|
||||||
struct inode *inode = file_inode(filp);
|
struct inode *inode = file_inode(filp);
|
||||||
|
|
||||||
|
@ -285,32 +284,30 @@ static ssize_t dlmfs_file_write(struct file *filp,
|
||||||
if (*ppos >= i_size_read(inode))
|
if (*ppos >= i_size_read(inode))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
|
/* don't write past the lvb */
|
||||||
|
if (count > i_size_read(inode) - *ppos)
|
||||||
|
count = i_size_read(inode) - *ppos;
|
||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!access_ok(buf, count))
|
if (!access_ok(buf, count))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
/* don't write past the lvb */
|
lvb_buf = kmalloc(count, GFP_NOFS);
|
||||||
if ((count + *ppos) > i_size_read(inode))
|
|
||||||
writelen = i_size_read(inode) - *ppos;
|
|
||||||
else
|
|
||||||
writelen = count - *ppos;
|
|
||||||
|
|
||||||
lvb_buf = kmalloc(writelen, GFP_NOFS);
|
|
||||||
if (!lvb_buf)
|
if (!lvb_buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
bytes_left = copy_from_user(lvb_buf, buf, writelen);
|
bytes_left = copy_from_user(lvb_buf, buf, count);
|
||||||
writelen -= bytes_left;
|
count -= bytes_left;
|
||||||
if (writelen)
|
if (count)
|
||||||
user_dlm_write_lvb(inode, lvb_buf, writelen);
|
user_dlm_write_lvb(inode, lvb_buf, count);
|
||||||
|
|
||||||
kfree(lvb_buf);
|
kfree(lvb_buf);
|
||||||
|
|
||||||
*ppos = *ppos + writelen;
|
*ppos = *ppos + count;
|
||||||
mlog(0, "wrote %zd bytes\n", writelen);
|
mlog(0, "wrote %zu bytes\n", count);
|
||||||
return writelen;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dlmfs_init_once(void *foo)
|
static void dlmfs_init_once(void *foo)
|
||||||
|
|
Loading…
Reference in New Issue