Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1466b77a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull second set of NFS client updates from Trond Myklebust:
 "This mainly contains some small readdir optimisations that had
  dependencies on Al Viro's readdir rewrite.  There is also a fix for a
  nasty deadlock which surfaced earlier in this merge window.

  Highlights include:
   - Fix an_rpc pipefs regression that causes a deadlock on mount
   - Readdir optimisations by Scott Mayhew and Jeff Layton
   - clean up the rpc_pipefs dentry operation setup"

* tag 'nfs-for-3.11-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  SUNRPC: Fix a deadlock in rpc_client_register()
  rpc_pipe: rpc_dir_inode_operations can be static
  NFS: Allow nfs_updatepage to extend a write under additional circumstances
  NFS: Make nfs_readdir revalidate less often
  NFS: Make nfs_attribute_cache_expired() non-static
  rpc_pipe: set dentry operations at d_alloc time
  nfs: set verifier on existing dentries in nfs_prime_dcache
parents 19d2f8e0 eeee2452
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -450,6 +450,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
	dentry = d_lookup(parent, &filename);
	if (dentry != NULL) {
		if (nfs_same_file(dentry, entry)) {
			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
			status = nfs_refresh_inode(dentry->d_inode, entry->fattr);
			if (!status)
				nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label);
@@ -817,7 +818,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
	nfs_readdir_descriptor_t my_desc,
			*desc = &my_desc;
	struct nfs_open_dir_context *dir_ctx = file->private_data;
	int res;
	int res = 0;

	dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
			dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -839,6 +840,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
	desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0;

	nfs_block_sillyrename(dentry);
	if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
		res = nfs_revalidate_mapping(inode, file->f_mapping);
	if (res < 0)
		goto out;
+1 −1
Original line number Diff line number Diff line
@@ -936,7 +936,7 @@ int nfs_attribute_timeout(struct inode *inode)
	return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}

static int nfs_attribute_cache_expired(struct inode *inode)
int nfs_attribute_cache_expired(struct inode *inode)
{
	if (nfs_have_delegated_attributes(inode))
		return 0;
+23 −8
Original line number Diff line number Diff line
@@ -888,6 +888,28 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode)
	return PageUptodate(page) != 0;
}

/* If we know the page is up to date, and we're not using byte range locks (or
 * if we have the whole file locked for writing), it may be more efficient to
 * extend the write to cover the entire page in order to avoid fragmentation
 * inefficiencies.
 *
 * If the file is opened for synchronous writes or if we have a write delegation
 * from the server then we can just skip the rest of the checks.
 */
static int nfs_can_extend_write(struct file *file, struct page *page, struct inode *inode)
{
	if (file->f_flags & O_DSYNC)
		return 0;
	if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
		return 1;
	if (nfs_write_pageuptodate(page, inode) && (inode->i_flock == NULL ||
			(inode->i_flock->fl_start == 0 &&
			inode->i_flock->fl_end == OFFSET_MAX &&
			inode->i_flock->fl_type != F_RDLCK)))
		return 1;
	return 0;
}

/*
 * Update and possibly write a cached page of an NFS file.
 *
@@ -908,14 +930,7 @@ int nfs_updatepage(struct file *file, struct page *page,
		file->f_path.dentry->d_name.name, count,
		(long long)(page_file_offset(page) + offset));

	/* If we're not using byte range locks, and we know the page
	 * is up to date, it may be more efficient to extend the write
	 * to cover the entire page in order to avoid fragmentation
	 * inefficiencies.
	 */
	if (nfs_write_pageuptodate(page, inode) &&
			inode->i_flock == NULL &&
			!(file->f_flags & O_DSYNC)) {
	if (nfs_can_extend_write(file, page, inode)) {
		count = max(count + offset, nfs_page_length(page));
		offset = 0;
	}
+1 −0
Original line number Diff line number Diff line
@@ -348,6 +348,7 @@ extern int nfs_permission(struct inode *, int);
extern int nfs_open(struct inode *, struct file *);
extern int nfs_release(struct inode *, struct file *);
extern int nfs_attribute_timeout(struct inode *inode);
extern int nfs_attribute_cache_expired(struct inode *inode);
extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
+9 −7
Original line number Diff line number Diff line
@@ -290,7 +290,7 @@ static int rpc_client_register(const struct rpc_create_args *args,
	struct rpc_auth *auth;
	struct net *net = rpc_net_ns(clnt);
	struct super_block *pipefs_sb;
	int err = 0;
	int err;

	pipefs_sb = rpc_get_sb_net(net);
	if (pipefs_sb) {
@@ -299,6 +299,10 @@ static int rpc_client_register(const struct rpc_create_args *args,
			goto out;
	}

	rpc_register_client(clnt);
	if (pipefs_sb)
		rpc_put_sb_net(net);

	auth = rpcauth_create(args->authflavor, clnt);
	if (IS_ERR(auth)) {
		dprintk("RPC:       Couldn't create auth handle (flavor %u)\n",
@@ -306,16 +310,14 @@ static int rpc_client_register(const struct rpc_create_args *args,
		err = PTR_ERR(auth);
		goto err_auth;
	}

	rpc_register_client(clnt);
	return 0;
err_auth:
	pipefs_sb = rpc_get_sb_net(net);
	__rpc_clnt_remove_pipedir(clnt);
out:
	if (pipefs_sb)
		rpc_put_sb_net(net);
	return err;

err_auth:
	__rpc_clnt_remove_pipedir(clnt);
	goto out;
}

static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
Loading