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:
commit
aa263c43fe
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue