mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-14 08:13:56 +08:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro. The most notable fix here is probably the fix for a splice regression ("fix a fencepost error in pipe_advance()") noticed by Alan Wylie. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fix a fencepost error in pipe_advance() coredump: Ensure proper size of sparse core files aio: fix lock dep warning tmpfs: clear S_ISGID when setting posix ACLs
This commit is contained in:
commit
f4d3935e4f
6
fs/aio.c
6
fs/aio.c
@ -1085,7 +1085,8 @@ static void aio_complete(struct kiocb *kiocb, long res, long res2)
|
|||||||
* Tell lockdep we inherited freeze protection from submission
|
* Tell lockdep we inherited freeze protection from submission
|
||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
__sb_writers_acquired(file_inode(file)->i_sb, SB_FREEZE_WRITE);
|
if (S_ISREG(file_inode(file)->i_mode))
|
||||||
|
__sb_writers_acquired(file_inode(file)->i_sb, SB_FREEZE_WRITE);
|
||||||
file_end_write(file);
|
file_end_write(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1525,7 +1526,8 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored,
|
|||||||
* by telling it the lock got released so that it doesn't
|
* by telling it the lock got released so that it doesn't
|
||||||
* complain about held lock when we return to userspace.
|
* complain about held lock when we return to userspace.
|
||||||
*/
|
*/
|
||||||
__sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE);
|
if (S_ISREG(file_inode(file)->i_mode))
|
||||||
|
__sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE);
|
||||||
}
|
}
|
||||||
kfree(iovec);
|
kfree(iovec);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2298,6 +2298,7 @@ static int elf_core_dump(struct coredump_params *cprm)
|
|||||||
goto end_coredump;
|
goto end_coredump;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dump_truncate(cprm);
|
||||||
|
|
||||||
if (!elf_core_write_extra_data(cprm))
|
if (!elf_core_write_extra_data(cprm))
|
||||||
goto end_coredump;
|
goto end_coredump;
|
||||||
|
@ -833,3 +833,21 @@ int dump_align(struct coredump_params *cprm, int align)
|
|||||||
return mod ? dump_skip(cprm, align - mod) : 1;
|
return mod ? dump_skip(cprm, align - mod) : 1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dump_align);
|
EXPORT_SYMBOL(dump_align);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensures that file size is big enough to contain the current file
|
||||||
|
* postion. This prevents gdb from complaining about a truncated file
|
||||||
|
* if the last "write" to the file was dump_skip.
|
||||||
|
*/
|
||||||
|
void dump_truncate(struct coredump_params *cprm)
|
||||||
|
{
|
||||||
|
struct file *file = cprm->file;
|
||||||
|
loff_t offset;
|
||||||
|
|
||||||
|
if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
|
||||||
|
offset = file->f_op->llseek(file, 0, SEEK_CUR);
|
||||||
|
if (i_size_read(file->f_mapping->host) < offset)
|
||||||
|
do_truncate(file->f_path.dentry, offset, 0, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dump_truncate);
|
||||||
|
@ -922,11 +922,10 @@ int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (type == ACL_TYPE_ACCESS) {
|
if (type == ACL_TYPE_ACCESS) {
|
||||||
error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
error = posix_acl_update_mode(inode,
|
||||||
if (error < 0)
|
&inode->i_mode, &acl);
|
||||||
return 0;
|
if (error)
|
||||||
if (error == 0)
|
return error;
|
||||||
acl = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inode->i_ctime = current_time(inode);
|
inode->i_ctime = current_time(inode);
|
||||||
|
@ -14,6 +14,7 @@ struct coredump_params;
|
|||||||
extern int dump_skip(struct coredump_params *cprm, size_t nr);
|
extern int dump_skip(struct coredump_params *cprm, size_t nr);
|
||||||
extern int dump_emit(struct coredump_params *cprm, const void *addr, int nr);
|
extern int dump_emit(struct coredump_params *cprm, const void *addr, int nr);
|
||||||
extern int dump_align(struct coredump_params *cprm, int align);
|
extern int dump_align(struct coredump_params *cprm, int align);
|
||||||
|
extern void dump_truncate(struct coredump_params *cprm);
|
||||||
#ifdef CONFIG_COREDUMP
|
#ifdef CONFIG_COREDUMP
|
||||||
extern void do_coredump(const siginfo_t *siginfo);
|
extern void do_coredump(const siginfo_t *siginfo);
|
||||||
#else
|
#else
|
||||||
|
@ -730,43 +730,50 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
|
EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
|
||||||
|
|
||||||
static void pipe_advance(struct iov_iter *i, size_t size)
|
static inline void pipe_truncate(struct iov_iter *i)
|
||||||
{
|
{
|
||||||
struct pipe_inode_info *pipe = i->pipe;
|
struct pipe_inode_info *pipe = i->pipe;
|
||||||
struct pipe_buffer *buf;
|
|
||||||
int idx = i->idx;
|
|
||||||
size_t off = i->iov_offset, orig_sz;
|
|
||||||
|
|
||||||
if (unlikely(i->count < size))
|
|
||||||
size = i->count;
|
|
||||||
orig_sz = size;
|
|
||||||
|
|
||||||
if (size) {
|
|
||||||
if (off) /* make it relative to the beginning of buffer */
|
|
||||||
size += off - pipe->bufs[idx].offset;
|
|
||||||
while (1) {
|
|
||||||
buf = &pipe->bufs[idx];
|
|
||||||
if (size <= buf->len)
|
|
||||||
break;
|
|
||||||
size -= buf->len;
|
|
||||||
idx = next_idx(idx, pipe);
|
|
||||||
}
|
|
||||||
buf->len = size;
|
|
||||||
i->idx = idx;
|
|
||||||
off = i->iov_offset = buf->offset + size;
|
|
||||||
}
|
|
||||||
if (off)
|
|
||||||
idx = next_idx(idx, pipe);
|
|
||||||
if (pipe->nrbufs) {
|
if (pipe->nrbufs) {
|
||||||
int unused = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
|
size_t off = i->iov_offset;
|
||||||
/* [curbuf,unused) is in use. Free [idx,unused) */
|
int idx = i->idx;
|
||||||
while (idx != unused) {
|
int nrbufs = (idx - pipe->curbuf) & (pipe->buffers - 1);
|
||||||
|
if (off) {
|
||||||
|
pipe->bufs[idx].len = off - pipe->bufs[idx].offset;
|
||||||
|
idx = next_idx(idx, pipe);
|
||||||
|
nrbufs++;
|
||||||
|
}
|
||||||
|
while (pipe->nrbufs > nrbufs) {
|
||||||
pipe_buf_release(pipe, &pipe->bufs[idx]);
|
pipe_buf_release(pipe, &pipe->bufs[idx]);
|
||||||
idx = next_idx(idx, pipe);
|
idx = next_idx(idx, pipe);
|
||||||
pipe->nrbufs--;
|
pipe->nrbufs--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i->count -= orig_sz;
|
}
|
||||||
|
|
||||||
|
static void pipe_advance(struct iov_iter *i, size_t size)
|
||||||
|
{
|
||||||
|
struct pipe_inode_info *pipe = i->pipe;
|
||||||
|
if (unlikely(i->count < size))
|
||||||
|
size = i->count;
|
||||||
|
if (size) {
|
||||||
|
struct pipe_buffer *buf;
|
||||||
|
size_t off = i->iov_offset, left = size;
|
||||||
|
int idx = i->idx;
|
||||||
|
if (off) /* make it relative to the beginning of buffer */
|
||||||
|
left += off - pipe->bufs[idx].offset;
|
||||||
|
while (1) {
|
||||||
|
buf = &pipe->bufs[idx];
|
||||||
|
if (left <= buf->len)
|
||||||
|
break;
|
||||||
|
left -= buf->len;
|
||||||
|
idx = next_idx(idx, pipe);
|
||||||
|
}
|
||||||
|
i->idx = idx;
|
||||||
|
i->iov_offset = buf->offset + left;
|
||||||
|
}
|
||||||
|
i->count -= size;
|
||||||
|
/* ... and discard everything past that point */
|
||||||
|
pipe_truncate(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iov_iter_advance(struct iov_iter *i, size_t size)
|
void iov_iter_advance(struct iov_iter *i, size_t size)
|
||||||
@ -826,6 +833,7 @@ void iov_iter_pipe(struct iov_iter *i, int direction,
|
|||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
BUG_ON(direction != ITER_PIPE);
|
BUG_ON(direction != ITER_PIPE);
|
||||||
|
WARN_ON(pipe->nrbufs == pipe->buffers);
|
||||||
i->type = direction;
|
i->type = direction;
|
||||||
i->pipe = pipe;
|
i->pipe = pipe;
|
||||||
i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
|
i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user