Merge tag 'v3.10.99' into update
This is the 3.10.99 stable release
This commit is contained in:
@@ -2441,6 +2441,7 @@ int open_ctree(struct super_block *sb,
|
||||
"unsupported option features (%Lx).\n",
|
||||
(unsigned long long)features);
|
||||
err = -EINVAL;
|
||||
brelse(bh);
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
|
||||
+18
-3
@@ -7477,15 +7477,28 @@ int btrfs_readpage(struct file *file, struct page *page)
|
||||
static int btrfs_writepage(struct page *page, struct writeback_control *wbc)
|
||||
{
|
||||
struct extent_io_tree *tree;
|
||||
|
||||
struct inode *inode = page->mapping->host;
|
||||
int ret;
|
||||
|
||||
if (current->flags & PF_MEMALLOC) {
|
||||
redirty_page_for_writepage(wbc, page);
|
||||
unlock_page(page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are under memory pressure we will call this directly from the
|
||||
* VM, we need to make sure we have the inode referenced for the ordered
|
||||
* extent. If not just return like we didn't do anything.
|
||||
*/
|
||||
if (!igrab(inode)) {
|
||||
redirty_page_for_writepage(wbc, page);
|
||||
return AOP_WRITEPAGE_ACTIVATE;
|
||||
}
|
||||
tree = &BTRFS_I(page->mapping->host)->io_tree;
|
||||
return extent_write_full_page(tree, page, btrfs_get_extent, wbc);
|
||||
ret = extent_write_full_page(tree, page, btrfs_get_extent, wbc);
|
||||
btrfs_add_delayed_iput(inode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btrfs_writepages(struct address_space *mapping,
|
||||
@@ -8474,9 +8487,11 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
||||
/*
|
||||
* 2 items for inode item and ref
|
||||
* 2 items for dir items
|
||||
* 1 item for updating parent inode item
|
||||
* 1 item for the inline extent item
|
||||
* 1 item for xattr if selinux is on
|
||||
*/
|
||||
trans = btrfs_start_transaction(root, 5);
|
||||
trans = btrfs_start_transaction(root, 7);
|
||||
if (IS_ERR(trans))
|
||||
return PTR_ERR(trans);
|
||||
|
||||
|
||||
+15
-1
@@ -1338,7 +1338,21 @@ static int read_symlink(struct send_ctx *sctx,
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
BUG_ON(ret);
|
||||
if (ret) {
|
||||
/*
|
||||
* An empty symlink inode. Can happen in rare error paths when
|
||||
* creating a symlink (transaction committed before the inode
|
||||
* eviction handler removed the symlink inode items and a crash
|
||||
* happened in between or the subvol was snapshoted in between).
|
||||
* Print an informative message to dmesg/syslog so that the user
|
||||
* can delete the symlink.
|
||||
*/
|
||||
btrfs_err(root->fs_info,
|
||||
"Found empty symlink inode %llu at root %llu",
|
||||
ino, root->root_key.objectid);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
|
||||
struct btrfs_file_extent_item);
|
||||
|
||||
@@ -720,15 +720,13 @@ static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
|
||||
init_special_inode(inode, mode, dev);
|
||||
err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
|
||||
if (!err)
|
||||
if (err)
|
||||
goto out_free;
|
||||
|
||||
err = read_name(inode, name);
|
||||
__putname(name);
|
||||
if (err)
|
||||
goto out_put;
|
||||
if (err)
|
||||
goto out_put;
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
return 0;
|
||||
|
||||
+4
-3
@@ -116,7 +116,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
|
||||
atomic_inc(&nsm->sm_count);
|
||||
else {
|
||||
host = NULL;
|
||||
nsm = nsm_get_handle(ni->sap, ni->salen,
|
||||
nsm = nsm_get_handle(ni->net, ni->sap, ni->salen,
|
||||
ni->hostname, ni->hostname_len);
|
||||
if (unlikely(nsm == NULL)) {
|
||||
dprintk("lockd: %s failed; no nsm handle\n",
|
||||
@@ -534,17 +534,18 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
|
||||
|
||||
/**
|
||||
* nlm_host_rebooted - Release all resources held by rebooted host
|
||||
* @net: network namespace
|
||||
* @info: pointer to decoded results of NLM_SM_NOTIFY call
|
||||
*
|
||||
* We were notified that the specified host has rebooted. Release
|
||||
* all resources held by that peer.
|
||||
*/
|
||||
void nlm_host_rebooted(const struct nlm_reboot *info)
|
||||
void nlm_host_rebooted(const struct net *net, const struct nlm_reboot *info)
|
||||
{
|
||||
struct nsm_handle *nsm;
|
||||
struct nlm_host *host;
|
||||
|
||||
nsm = nsm_reboot_lookup(info);
|
||||
nsm = nsm_reboot_lookup(net, info);
|
||||
if (unlikely(nsm == NULL))
|
||||
return;
|
||||
|
||||
|
||||
+22
-14
@@ -51,7 +51,6 @@ struct nsm_res {
|
||||
};
|
||||
|
||||
static const struct rpc_program nsm_program;
|
||||
static LIST_HEAD(nsm_handles);
|
||||
static DEFINE_SPINLOCK(nsm_lock);
|
||||
|
||||
/*
|
||||
@@ -259,33 +258,35 @@ void nsm_unmonitor(const struct nlm_host *host)
|
||||
}
|
||||
}
|
||||
|
||||
static struct nsm_handle *nsm_lookup_hostname(const char *hostname,
|
||||
const size_t len)
|
||||
static struct nsm_handle *nsm_lookup_hostname(const struct list_head *nsm_handles,
|
||||
const char *hostname, const size_t len)
|
||||
{
|
||||
struct nsm_handle *nsm;
|
||||
|
||||
list_for_each_entry(nsm, &nsm_handles, sm_link)
|
||||
list_for_each_entry(nsm, nsm_handles, sm_link)
|
||||
if (strlen(nsm->sm_name) == len &&
|
||||
memcmp(nsm->sm_name, hostname, len) == 0)
|
||||
return nsm;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct nsm_handle *nsm_lookup_addr(const struct sockaddr *sap)
|
||||
static struct nsm_handle *nsm_lookup_addr(const struct list_head *nsm_handles,
|
||||
const struct sockaddr *sap)
|
||||
{
|
||||
struct nsm_handle *nsm;
|
||||
|
||||
list_for_each_entry(nsm, &nsm_handles, sm_link)
|
||||
list_for_each_entry(nsm, nsm_handles, sm_link)
|
||||
if (rpc_cmp_addr(nsm_addr(nsm), sap))
|
||||
return nsm;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv)
|
||||
static struct nsm_handle *nsm_lookup_priv(const struct list_head *nsm_handles,
|
||||
const struct nsm_private *priv)
|
||||
{
|
||||
struct nsm_handle *nsm;
|
||||
|
||||
list_for_each_entry(nsm, &nsm_handles, sm_link)
|
||||
list_for_each_entry(nsm, nsm_handles, sm_link)
|
||||
if (memcmp(nsm->sm_priv.data, priv->data,
|
||||
sizeof(priv->data)) == 0)
|
||||
return nsm;
|
||||
@@ -350,6 +351,7 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
|
||||
|
||||
/**
|
||||
* nsm_get_handle - Find or create a cached nsm_handle
|
||||
* @net: network namespace
|
||||
* @sap: pointer to socket address of handle to find
|
||||
* @salen: length of socket address
|
||||
* @hostname: pointer to C string containing hostname to find
|
||||
@@ -362,11 +364,13 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
|
||||
* @hostname cannot be found in the handle cache. Returns NULL if
|
||||
* an error occurs.
|
||||
*/
|
||||
struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
|
||||
struct nsm_handle *nsm_get_handle(const struct net *net,
|
||||
const struct sockaddr *sap,
|
||||
const size_t salen, const char *hostname,
|
||||
const size_t hostname_len)
|
||||
{
|
||||
struct nsm_handle *cached, *new = NULL;
|
||||
struct lockd_net *ln = net_generic(net, lockd_net_id);
|
||||
|
||||
if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
|
||||
if (printk_ratelimit()) {
|
||||
@@ -381,9 +385,10 @@ retry:
|
||||
spin_lock(&nsm_lock);
|
||||
|
||||
if (nsm_use_hostnames && hostname != NULL)
|
||||
cached = nsm_lookup_hostname(hostname, hostname_len);
|
||||
cached = nsm_lookup_hostname(&ln->nsm_handles,
|
||||
hostname, hostname_len);
|
||||
else
|
||||
cached = nsm_lookup_addr(sap);
|
||||
cached = nsm_lookup_addr(&ln->nsm_handles, sap);
|
||||
|
||||
if (cached != NULL) {
|
||||
atomic_inc(&cached->sm_count);
|
||||
@@ -397,7 +402,7 @@ retry:
|
||||
}
|
||||
|
||||
if (new != NULL) {
|
||||
list_add(&new->sm_link, &nsm_handles);
|
||||
list_add(&new->sm_link, &ln->nsm_handles);
|
||||
spin_unlock(&nsm_lock);
|
||||
dprintk("lockd: created nsm_handle for %s (%s)\n",
|
||||
new->sm_name, new->sm_addrbuf);
|
||||
@@ -414,19 +419,22 @@ retry:
|
||||
|
||||
/**
|
||||
* nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle
|
||||
* @net: network namespace
|
||||
* @info: pointer to NLMPROC_SM_NOTIFY arguments
|
||||
*
|
||||
* Returns a matching nsm_handle if found in the nsm cache. The returned
|
||||
* nsm_handle's reference count is bumped. Otherwise returns NULL if some
|
||||
* error occurred.
|
||||
*/
|
||||
struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
|
||||
struct nsm_handle *nsm_reboot_lookup(const struct net *net,
|
||||
const struct nlm_reboot *info)
|
||||
{
|
||||
struct nsm_handle *cached;
|
||||
struct lockd_net *ln = net_generic(net, lockd_net_id);
|
||||
|
||||
spin_lock(&nsm_lock);
|
||||
|
||||
cached = nsm_lookup_priv(&info->priv);
|
||||
cached = nsm_lookup_priv(&ln->nsm_handles, &info->priv);
|
||||
if (unlikely(cached == NULL)) {
|
||||
spin_unlock(&nsm_lock);
|
||||
dprintk("lockd: never saw rebooted peer '%.*s' before\n",
|
||||
|
||||
@@ -16,6 +16,7 @@ struct lockd_net {
|
||||
spinlock_t nsm_clnt_lock;
|
||||
unsigned int nsm_users;
|
||||
struct rpc_clnt *nsm_clnt;
|
||||
struct list_head nsm_handles;
|
||||
};
|
||||
|
||||
extern int lockd_net_id;
|
||||
|
||||
@@ -583,6 +583,7 @@ static int lockd_init_net(struct net *net)
|
||||
INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
|
||||
INIT_LIST_HEAD(&ln->grace_list);
|
||||
spin_lock_init(&ln->nsm_clnt_lock);
|
||||
INIT_LIST_HEAD(&ln->nsm_handles);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -421,7 +421,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
|
||||
return rpc_system_err;
|
||||
}
|
||||
|
||||
nlm_host_rebooted(argp);
|
||||
nlm_host_rebooted(SVC_NET(rqstp), argp);
|
||||
return rpc_success;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -464,7 +464,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
|
||||
return rpc_system_err;
|
||||
}
|
||||
|
||||
nlm_host_rebooted(argp);
|
||||
nlm_host_rebooted(SVC_NET(rqstp), argp);
|
||||
return rpc_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -2917,6 +2917,10 @@ opened:
|
||||
goto exit_fput;
|
||||
}
|
||||
out:
|
||||
if (unlikely(error > 0)) {
|
||||
WARN_ON(1);
|
||||
error = -EINVAL;
|
||||
}
|
||||
if (got_write)
|
||||
mnt_drop_write(nd->path.mnt);
|
||||
path_put(&save_parent);
|
||||
|
||||
+1
-1
@@ -1452,7 +1452,7 @@ restart:
|
||||
}
|
||||
spin_unlock(&state->state_lock);
|
||||
nfs4_put_open_state(state);
|
||||
clear_bit(NFS4CLNT_RECLAIM_NOGRACE,
|
||||
clear_bit(NFS_STATE_RECLAIM_NOGRACE,
|
||||
&state->flags);
|
||||
spin_lock(&sp->so_lock);
|
||||
goto restart;
|
||||
|
||||
+2
-2
@@ -220,7 +220,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
|
||||
if (!priv->task)
|
||||
return ERR_PTR(-ESRCH);
|
||||
|
||||
mm = mm_access(priv->task, PTRACE_MODE_READ);
|
||||
mm = mm_access(priv->task, PTRACE_MODE_READ_FSCREDS);
|
||||
if (!mm || IS_ERR(mm))
|
||||
return mm;
|
||||
down_read(&mm->mmap_sem);
|
||||
@@ -1138,7 +1138,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
|
||||
if (!pm.buffer)
|
||||
goto out_task;
|
||||
|
||||
mm = mm_access(task, PTRACE_MODE_READ);
|
||||
mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
|
||||
ret = PTR_ERR(mm);
|
||||
if (!mm || IS_ERR(mm))
|
||||
goto out_free;
|
||||
|
||||
@@ -223,7 +223,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
|
||||
if (!priv->task)
|
||||
return ERR_PTR(-ESRCH);
|
||||
|
||||
mm = mm_access(priv->task, PTRACE_MODE_READ);
|
||||
mm = mm_access(priv->task, PTRACE_MODE_READ_FSCREDS);
|
||||
if (!mm || IS_ERR(mm)) {
|
||||
put_task_struct(priv->task);
|
||||
priv->task = NULL;
|
||||
|
||||
+12
-1
@@ -949,6 +949,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
|
||||
|
||||
splice_from_pipe_begin(sd);
|
||||
do {
|
||||
cond_resched();
|
||||
ret = splice_from_pipe_next(pipe, sd);
|
||||
if (ret > 0)
|
||||
ret = splice_from_pipe_feed(pipe, sd, actor);
|
||||
@@ -1189,7 +1190,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
|
||||
long ret, bytes;
|
||||
umode_t i_mode;
|
||||
size_t len;
|
||||
int i, flags;
|
||||
int i, flags, more;
|
||||
|
||||
/*
|
||||
* We require the input being a regular file, as we don't want to
|
||||
@@ -1232,6 +1233,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
|
||||
* Don't block on output, we have to drain the direct pipe.
|
||||
*/
|
||||
sd->flags &= ~SPLICE_F_NONBLOCK;
|
||||
more = sd->flags & SPLICE_F_MORE;
|
||||
|
||||
while (len) {
|
||||
size_t read_len;
|
||||
@@ -1244,6 +1246,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
|
||||
read_len = ret;
|
||||
sd->total_len = read_len;
|
||||
|
||||
/*
|
||||
* If more data is pending, set SPLICE_F_MORE
|
||||
* If this is the last data and SPLICE_F_MORE was not set
|
||||
* initially, clears it.
|
||||
*/
|
||||
if (read_len < len)
|
||||
sd->flags |= SPLICE_F_MORE;
|
||||
else if (!more)
|
||||
sd->flags &= ~SPLICE_F_MORE;
|
||||
/*
|
||||
* NOTE: nonblocking mode only applies to the input. We
|
||||
* must not do the output in nonblocking mode as then we
|
||||
|
||||
Reference in New Issue
Block a user