Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fixes from Al Viro:
 "Assorted fixes - xattr one from this cycle, the rest - stable fodder"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fs/pnode.c: treat zero mnt_group_id-s as unequal
  affs_do_readpage_ofs(): just use kmap_atomic() around memcpy()
  xattr handlers: plug a lock leak in simple_xattr_list
  fs: allow no_seek_end_llseek to actually seek
This commit is contained in:
Linus Torvalds 2016-02-24 14:00:26 -08:00
commit aa263c43fe
4 changed files with 14 additions and 9 deletions

View File

@ -511,8 +511,6 @@ affs_do_readpage_ofs(struct page *page, unsigned to)
pr_debug("%s(%lu, %ld, 0, %d)\n", __func__, inode->i_ino, pr_debug("%s(%lu, %ld, 0, %d)\n", __func__, inode->i_ino,
page->index, to); page->index, to);
BUG_ON(to > PAGE_CACHE_SIZE); BUG_ON(to > PAGE_CACHE_SIZE);
kmap(page);
data = page_address(page);
bsize = AFFS_SB(sb)->s_data_blksize; bsize = AFFS_SB(sb)->s_data_blksize;
tmp = page->index << PAGE_CACHE_SHIFT; tmp = page->index << PAGE_CACHE_SHIFT;
bidx = tmp / bsize; bidx = tmp / bsize;
@ -524,14 +522,15 @@ affs_do_readpage_ofs(struct page *page, unsigned to)
return PTR_ERR(bh); return PTR_ERR(bh);
tmp = min(bsize - boff, to - pos); tmp = min(bsize - boff, to - pos);
BUG_ON(pos + tmp > to || tmp > bsize); BUG_ON(pos + tmp > to || tmp > bsize);
data = kmap_atomic(page);
memcpy(data + pos, AFFS_DATA(bh) + boff, tmp); memcpy(data + pos, AFFS_DATA(bh) + boff, tmp);
kunmap_atomic(data);
affs_brelse(bh); affs_brelse(bh);
bidx++; bidx++;
pos += tmp; pos += tmp;
boff = 0; boff = 0;
} }
flush_dcache_page(page); flush_dcache_page(page);
kunmap(page);
return 0; return 0;
} }

View File

@ -202,6 +202,11 @@ static struct mount *last_dest, *last_source, *dest_master;
static struct mountpoint *mp; static struct mountpoint *mp;
static struct hlist_head *list; static struct hlist_head *list;
static inline bool peers(struct mount *m1, struct mount *m2)
{
return m1->mnt_group_id == m2->mnt_group_id && m1->mnt_group_id;
}
static int propagate_one(struct mount *m) static int propagate_one(struct mount *m)
{ {
struct mount *child; struct mount *child;
@ -212,7 +217,7 @@ static int propagate_one(struct mount *m)
/* skip if mountpoint isn't covered by it */ /* skip if mountpoint isn't covered by it */
if (!is_subdir(mp->m_dentry, m->mnt.mnt_root)) if (!is_subdir(mp->m_dentry, m->mnt.mnt_root))
return 0; return 0;
if (m->mnt_group_id == last_dest->mnt_group_id) { if (peers(m, last_dest)) {
type = CL_MAKE_SHARED; type = CL_MAKE_SHARED;
} else { } else {
struct mount *n, *p; struct mount *n, *p;
@ -223,7 +228,7 @@ static int propagate_one(struct mount *m)
last_source = last_source->mnt_master; last_source = last_source->mnt_master;
last_dest = last_source->mnt_parent; last_dest = last_source->mnt_parent;
} }
if (n->mnt_group_id != last_dest->mnt_group_id) { if (!peers(n, last_dest)) {
last_source = last_source->mnt_master; last_source = last_source->mnt_master;
last_dest = last_source->mnt_parent; last_dest = last_source->mnt_parent;
} }

View File

@ -17,6 +17,7 @@
#include <linux/splice.h> #include <linux/splice.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/fs.h>
#include "internal.h" #include "internal.h"
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -183,7 +184,7 @@ loff_t no_seek_end_llseek(struct file *file, loff_t offset, int whence)
switch (whence) { switch (whence) {
case SEEK_SET: case SEEK_CUR: case SEEK_SET: case SEEK_CUR:
return generic_file_llseek_size(file, offset, whence, return generic_file_llseek_size(file, offset, whence,
~0ULL, 0); OFFSET_MAX, 0);
default: default:
return -EINVAL; return -EINVAL;
} }

View File

@ -940,7 +940,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
bool trusted = capable(CAP_SYS_ADMIN); bool trusted = capable(CAP_SYS_ADMIN);
struct simple_xattr *xattr; struct simple_xattr *xattr;
ssize_t remaining_size = size; ssize_t remaining_size = size;
int err; int err = 0;
#ifdef CONFIG_FS_POSIX_ACL #ifdef CONFIG_FS_POSIX_ACL
if (inode->i_acl) { if (inode->i_acl) {
@ -965,11 +965,11 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
err = xattr_list_one(&buffer, &remaining_size, xattr->name); err = xattr_list_one(&buffer, &remaining_size, xattr->name);
if (err) if (err)
return err; break;
} }
spin_unlock(&xattrs->lock); spin_unlock(&xattrs->lock);
return size - remaining_size; return err ? err : size - remaining_size;
} }
/* /*