Skip to content

Commit

Permalink
Merge tag 'nfs-for-4.1-1' of git://git.linux-nfs.org/projects/trondmy…
Browse files Browse the repository at this point in the history
…/linux-nfs

Pull NFS client updates from Trond Myklebust:
 "Another set of mainly bugfixes and a couple of cleanups.  No new
  functionality in this round.

  Highlights include:

  Stable patches:
   - Fix a regression in /proc/self/mountstats
   - Fix the pNFS flexfiles O_DIRECT support
   - Fix high load average due to callback thread sleeping

  Bugfixes:
   - Various patches to fix the pNFS layoutcommit support
   - Do not cache pNFS deviceids unless server notifications are enabled
   - Fix a SUNRPC transport reconnection regression
   - make debugfs file creation failure non-fatal in SUNRPC
   - Another fix for circular directory warnings on NFSv4 "junctioned"
     mountpoints
   - Fix locking around NFSv4.2 fallocate() support
   - Truncating NFSv4 file opens should also sync O_DIRECT writes
   - Prevent infinite loop in rpcrdma_ep_create()

  Features:
   - Various improvements to the RDMA transport code's handling of
     memory registration
   - Various code cleanups"

* tag 'nfs-for-4.1-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (55 commits)
  fs/nfs: fix new compiler warning about boolean in switch
  nfs: Remove unneeded casts in nfs
  NFS: Don't attempt to decode missing directory entries
  Revert "nfs: replace nfs_add_stats with nfs_inc_stats when add one"
  NFS: Rename idmap.c to nfs4idmap.c
  NFS: Move nfs_idmap.h into fs/nfs/
  NFS: Remove CONFIG_NFS_V4 checks from nfs_idmap.h
  NFS: Add a stub for GETDEVICELIST
  nfs: remove WARN_ON_ONCE from nfs_direct_good_bytes
  nfs: fix DIO good bytes calculation
  nfs: Fetch MOUNTED_ON_FILEID when updating an inode
  sunrpc: make debugfs file creation failure non-fatal
  nfs: fix high load average due to callback thread sleeping
  NFS: Reduce time spent holding the i_mutex during fallocate()
  NFS: Don't zap caches on fallocate()
  xprtrdma: Make rpcrdma_{un}map_one() into inline functions
  xprtrdma: Handle non-SEND completions via a callout
  xprtrdma: Add "open" memreg op
  xprtrdma: Add "destroy MRs" memreg op
  xprtrdma: Add "reset MRs" memreg op
  ...
  • Loading branch information
torvalds committed Apr 27, 2015
2 parents 9ec3a64 + f139b6c commit 59953fb
Show file tree
Hide file tree
Showing 49 changed files with 1,150 additions and 914 deletions.
2 changes: 1 addition & 1 deletion fs/nfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
obj-$(CONFIG_NFS_V4) += nfsv4.o
CFLAGS_nfs4trace.o += -I$(src)
nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
delegation.o nfs4idmap.o callback.o callback_xdr.o callback_proc.o \
nfs4namespace.o nfs4getroot.o nfs4client.o nfs4session.o \
dns_resolve.o nfs4trace.o
nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o
Expand Down
1 change: 1 addition & 0 deletions fs/nfs/blocklayout/blocklayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,7 @@ static struct pnfs_layoutdriver_type blocklayout_type = {
.free_deviceid_node = bl_free_deviceid_node,
.pg_read_ops = &bl_pg_read_ops,
.pg_write_ops = &bl_pg_write_ops,
.sync = pnfs_generic_sync,
};

static int __init nfs4blocklayout_init(void)
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/blocklayout/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ bl_free_deviceid_node(struct nfs4_deviceid_node *d)
container_of(d, struct pnfs_block_dev, node);

bl_free_device(dev);
kfree(dev);
kfree_rcu(dev, node.rcu);
}

static int
Expand Down
6 changes: 3 additions & 3 deletions fs/nfs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ nfs41_callback_svc(void *vrqstp)
if (try_to_freeze())
continue;

prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_UNINTERRUPTIBLE);
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
spin_lock_bh(&serv->sv_cb_lock);
if (!list_empty(&serv->sv_cb_list)) {
req = list_first_entry(&serv->sv_cb_list,
Expand All @@ -142,10 +142,10 @@ nfs41_callback_svc(void *vrqstp)
error);
} else {
spin_unlock_bh(&serv->sv_cb_lock);
/* schedule_timeout to game the hung task watchdog */
schedule_timeout(60 * HZ);
schedule();
finish_wait(&serv->sv_cb_waitq, &wq);
}
flush_signals(current);
}
return 0;
}
Expand Down
1 change: 0 additions & 1 deletion fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include <linux/lockd/bind.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/nfs_idmap.h>
#include <linux/vfs.h>
#include <linux/inet.h>
#include <linux/in6.h>
Expand Down
4 changes: 2 additions & 2 deletions fs/nfs/delegation.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
if (freeme == NULL)
goto out;
}
list_add_rcu(&delegation->super_list, &server->delegations);
list_add_tail_rcu(&delegation->super_list, &server->delegations);
rcu_assign_pointer(nfsi->delegation, delegation);
delegation = NULL;

Expand Down Expand Up @@ -514,7 +514,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode)

delegation = nfs_inode_detach_delegation(inode);
if (delegation != NULL)
nfs_do_return_delegation(inode, delegation, 0);
nfs_do_return_delegation(inode, delegation, 1);
}

/**
Expand Down
4 changes: 4 additions & 0 deletions fs/nfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,9 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
if (scratch == NULL)
return -ENOMEM;

if (buflen == 0)
goto out_nopages;

xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);

Expand All @@ -564,6 +567,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
break;
} while (!entry->eof);

out_nopages:
if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
array = nfs_readdir_get_array(page);
if (!IS_ERR(array)) {
Expand Down
39 changes: 18 additions & 21 deletions fs/nfs/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,22 +129,25 @@ nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr)
int i;
ssize_t count;

WARN_ON_ONCE(hdr->pgio_mirror_idx >= dreq->mirror_count);

count = dreq->mirrors[hdr->pgio_mirror_idx].count;
if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) {
count = hdr->io_start + hdr->good_bytes - dreq->io_start;
dreq->mirrors[hdr->pgio_mirror_idx].count = count;
}

/* update the dreq->count by finding the minimum agreed count from all
* mirrors */
count = dreq->mirrors[0].count;
if (dreq->mirror_count == 1) {
dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes;
dreq->count += hdr->good_bytes;
} else {
/* mirrored writes */
count = dreq->mirrors[hdr->pgio_mirror_idx].count;
if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) {
count = hdr->io_start + hdr->good_bytes - dreq->io_start;
dreq->mirrors[hdr->pgio_mirror_idx].count = count;
}
/* update the dreq->count by finding the minimum agreed count from all
* mirrors */
count = dreq->mirrors[0].count;

for (i = 1; i < dreq->mirror_count; i++)
count = min(count, dreq->mirrors[i].count);
for (i = 1; i < dreq->mirror_count; i++)
count = min(count, dreq->mirrors[i].count);

dreq->count = count;
dreq->count = count;
}
}

/*
Expand Down Expand Up @@ -258,18 +261,11 @@ ssize_t nfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
if (!IS_SWAPFILE(inode))
return 0;

#ifndef CONFIG_NFS_SWAP
dprintk("NFS: nfs_direct_IO (%pD) off/no(%Ld/%lu) EINVAL\n",
iocb->ki_filp, (long long) pos, iter->nr_segs);

return -EINVAL;
#else
VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE);

if (iov_iter_rw(iter) == READ)
return nfs_file_direct_read(iocb, iter, pos);
return nfs_file_direct_write(iocb, iter);
#endif /* CONFIG_NFS_SWAP */
}

static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
Expand Down Expand Up @@ -1030,6 +1026,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
if (i_size_read(inode) < iocb->ki_pos)
i_size_write(inode, iocb->ki_pos);
spin_unlock(&inode->i_lock);
generic_write_sync(file, pos, result);
}
}
nfs_direct_req_release(dreq);
Expand Down
3 changes: 2 additions & 1 deletion fs/nfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)

trace_nfs_fsync_enter(inode);

nfs_inode_dio_wait(inode);
do {
ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (ret != 0)
Expand Down Expand Up @@ -782,7 +783,7 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
* Flush all pending writes before doing anything
* with locks..
*/
nfs_sync_mapping(filp->f_mapping);
vfs_fsync(filp, 0);

l_ctx = nfs_get_lock_context(nfs_file_open_context(filp));
if (!IS_ERR(l_ctx)) {
Expand Down
10 changes: 6 additions & 4 deletions fs/nfs/filelayout/filelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ filelayout_set_layoutcommit(struct nfs_pgio_header *hdr)
hdr->res.verf->committed != NFS_DATA_SYNC)
return;

pnfs_set_layoutcommit(hdr);
pnfs_set_layoutcommit(hdr->inode, hdr->lseg,
hdr->mds_offset + hdr->res.count);
dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
(unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
}
Expand Down Expand Up @@ -373,7 +374,7 @@ static int filelayout_commit_done_cb(struct rpc_task *task,
}

if (data->verf.committed == NFS_UNSTABLE)
pnfs_commit_set_layoutcommit(data);
pnfs_set_layoutcommit(data->inode, data->lseg, data->lwb);

return 0;
}
Expand Down Expand Up @@ -1086,7 +1087,7 @@ filelayout_alloc_deviceid_node(struct nfs_server *server,
}

static void
filelayout_free_deveiceid_node(struct nfs4_deviceid_node *d)
filelayout_free_deviceid_node(struct nfs4_deviceid_node *d)
{
nfs4_fl_free_deviceid(container_of(d, struct nfs4_file_layout_dsaddr, id_node));
}
Expand Down Expand Up @@ -1137,7 +1138,8 @@ static struct pnfs_layoutdriver_type filelayout_type = {
.read_pagelist = filelayout_read_pagelist,
.write_pagelist = filelayout_write_pagelist,
.alloc_deviceid_node = filelayout_alloc_deviceid_node,
.free_deviceid_node = filelayout_free_deveiceid_node,
.free_deviceid_node = filelayout_free_deviceid_node,
.sync = pnfs_nfs_generic_sync,
};

static int __init nfs4filelayout_init(void)
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/filelayout/filelayoutdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
nfs4_pnfs_ds_put(ds);
}
kfree(dsaddr->stripe_indices);
kfree(dsaddr);
kfree_rcu(dsaddr, id_node.rcu);
}

/* Decode opaque device data and return the result */
Expand Down
12 changes: 7 additions & 5 deletions fs/nfs/flexfilelayout/flexfilelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include <linux/module.h>

#include <linux/sunrpc/metrics.h>
#include <linux/nfs_idmap.h>

#include "flexfilelayout.h"
#include "../nfs4session.h"
#include "../nfs4idmap.h"
#include "../internal.h"
#include "../delegation.h"
#include "../nfs4trace.h"
Expand Down Expand Up @@ -891,7 +891,8 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
static void
ff_layout_set_layoutcommit(struct nfs_pgio_header *hdr)
{
pnfs_set_layoutcommit(hdr);
pnfs_set_layoutcommit(hdr->inode, hdr->lseg,
hdr->mds_offset + hdr->res.count);
dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
(unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
}
Expand Down Expand Up @@ -1074,7 +1075,7 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
}

if (data->verf.committed == NFS_UNSTABLE)
pnfs_commit_set_layoutcommit(data);
pnfs_set_layoutcommit(data->inode, data->lseg, data->lwb);

return 0;
}
Expand Down Expand Up @@ -1414,7 +1415,7 @@ ff_layout_get_ds_info(struct inode *inode)
}

static void
ff_layout_free_deveiceid_node(struct nfs4_deviceid_node *d)
ff_layout_free_deviceid_node(struct nfs4_deviceid_node *d)
{
nfs4_ff_layout_free_deviceid(container_of(d, struct nfs4_ff_layout_ds,
id_node));
Expand Down Expand Up @@ -1498,7 +1499,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = {
.pg_read_ops = &ff_layout_pg_read_ops,
.pg_write_ops = &ff_layout_pg_write_ops,
.get_ds_info = ff_layout_get_ds_info,
.free_deviceid_node = ff_layout_free_deveiceid_node,
.free_deviceid_node = ff_layout_free_deviceid_node,
.mark_request_commit = pnfs_layout_mark_request_commit,
.clear_request_commit = pnfs_generic_clear_request_commit,
.scan_commit_lists = pnfs_generic_scan_commit_lists,
Expand All @@ -1508,6 +1509,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = {
.write_pagelist = ff_layout_write_pagelist,
.alloc_deviceid_node = ff_layout_alloc_deviceid_node,
.encode_layoutreturn = ff_layout_encode_layoutreturn,
.sync = pnfs_nfs_generic_sync,
};

static int __init nfs4flexfilelayout_init(void)
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/flexfilelayout/flexfilelayoutdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds)
{
nfs4_print_deviceid(&mirror_ds->id_node.deviceid);
nfs4_pnfs_ds_put(mirror_ds->ds);
kfree(mirror_ds);
kfree_rcu(mirror_ds, id_node.rcu);
}

/* Decode opaque device data and construct new_ds using it */
Expand Down
36 changes: 27 additions & 9 deletions fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ void nfs_evict_inode(struct inode *inode)
nfs_clear_inode(inode);
}

int nfs_sync_inode(struct inode *inode)
{
nfs_inode_dio_wait(inode);
return nfs_wb_all(inode);
}
EXPORT_SYMBOL_GPL(nfs_sync_inode);

/**
* nfs_sync_mapping - helper to flush all mmapped dirty data to disk
*/
Expand Down Expand Up @@ -192,7 +199,6 @@ void nfs_zap_caches(struct inode *inode)
nfs_zap_caches_locked(inode);
spin_unlock(&inode->i_lock);
}
EXPORT_SYMBOL_GPL(nfs_zap_caches);

void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
{
Expand Down Expand Up @@ -525,10 +531,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
trace_nfs_setattr_enter(inode);

/* Write all dirty data */
if (S_ISREG(inode->i_mode)) {
nfs_inode_dio_wait(inode);
nfs_wb_all(inode);
}
if (S_ISREG(inode->i_mode))
nfs_sync_inode(inode);

fattr = nfs_alloc_fattr();
if (fattr == NULL)
Expand Down Expand Up @@ -644,8 +648,9 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
trace_nfs_getattr_enter(inode);
/* Flush out writes to the server in order to update c/mtime. */
if (S_ISREG(inode->i_mode)) {
nfs_inode_dio_wait(inode);
err = filemap_write_and_wait(inode->i_mapping);
mutex_lock(&inode->i_mutex);
err = nfs_sync_inode(inode);
mutex_unlock(&inode->i_mutex);
if (err)
goto out;
}
Expand Down Expand Up @@ -1588,6 +1593,19 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
}
EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);


static inline bool nfs_fileid_valid(struct nfs_inode *nfsi,
struct nfs_fattr *fattr)
{
bool ret1 = true, ret2 = true;

if (fattr->valid & NFS_ATTR_FATTR_FILEID)
ret1 = (nfsi->fileid == fattr->fileid);
if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
ret2 = (nfsi->fileid == fattr->mounted_on_fileid);
return ret1 || ret2;
}

/*
* Many nfs protocol calls return the new file attributes after
* an operation. Here we update the inode to reflect the state
Expand All @@ -1614,7 +1632,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
nfs_display_fhandle_hash(NFS_FH(inode)),
atomic_read(&inode->i_count), fattr->valid);

if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) {
if (!nfs_fileid_valid(nfsi, fattr)) {
printk(KERN_ERR "NFS: server %s error: fileid changed\n"
"fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
NFS_SERVER(inode)->nfs_client->cl_hostname,
Expand Down Expand Up @@ -1819,7 +1837,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
struct inode *nfs_alloc_inode(struct super_block *sb)
{
struct nfs_inode *nfsi;
nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL);
nfsi = kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL);
if (!nfsi)
return NULL;
nfsi->flags = 0UL;
Expand Down
Loading

0 comments on commit 59953fb

Please sign in to comment.