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

Commit b04cde34 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.linux-nfs.org/pub/linux/nfs-2.6:
  NFSv4: Fix an rpc_cred reference leakage in fs/nfs/delegation.c
  NFSv4: Ensure that we wait for the CLOSE request to complete
  NFS: Fix a race in sillyrename
  NFS: Fix a writeback race...
parents 4800be29 603c83da
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -168,7 +168,8 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
	spin_unlock(&inode->i_lock);

	spin_unlock(&clp->cl_lock);
	kfree(delegation);
	if (delegation != NULL)
		nfs_free_delegation(delegation);
	return status;
}

+11 −3
Original line number Diff line number Diff line
@@ -562,6 +562,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
	nfs_fattr_init(&fattr);
	desc->entry = &my_entry;

	nfs_block_sillyrename(dentry);
	while(!desc->entry->eof) {
		res = readdir_search_pagecache(desc);

@@ -592,6 +593,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
			break;
		}
	}
	nfs_unblock_sillyrename(dentry);
	unlock_kernel();
	if (res > 0)
		res = 0;
@@ -866,6 +868,7 @@ struct dentry_operations nfs_dentry_operations = {
static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{
	struct dentry *res;
	struct dentry *parent;
	struct inode *inode = NULL;
	int error;
	struct nfs_fh fhandle;
@@ -894,26 +897,31 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
		goto out_unlock;
	}

	parent = dentry->d_parent;
	/* Protect against concurrent sillydeletes */
	nfs_block_sillyrename(parent);
	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
	if (error == -ENOENT)
		goto no_entry;
	if (error < 0) {
		res = ERR_PTR(error);
		goto out_unlock;
		goto out_unblock_sillyrename;
	}
	inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
	res = (struct dentry *)inode;
	if (IS_ERR(res))
		goto out_unlock;
		goto out_unblock_sillyrename;

no_entry:
	res = d_materialise_unique(dentry, inode);
	if (res != NULL) {
		if (IS_ERR(res))
			goto out_unlock;
			goto out_unblock_sillyrename;
		dentry = res;
	}
	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out_unblock_sillyrename:
	nfs_unblock_sillyrename(parent);
out_unlock:
	unlock_kernel();
out:
+1 −1
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
{
	/* Ensure that dirty pages are flushed out with the right creds */
	if (filp->f_mode & FMODE_WRITE)
		filemap_fdatawrite(filp->f_mapping);
		nfs_wb_all(filp->f_path.dentry->d_inode);
	nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
	return NFS_PROTO(inode)->file_release(inode, filp);
}
+21 −4
Original line number Diff line number Diff line
@@ -514,7 +514,7 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
	return ctx;
}

void put_nfs_open_context(struct nfs_open_context *ctx)
static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait)
{
	struct inode *inode = ctx->path.dentry->d_inode;

@@ -522,8 +522,12 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
		return;
	list_del(&ctx->list);
	spin_unlock(&inode->i_lock);
	if (ctx->state != NULL)
	if (ctx->state != NULL) {
		if (wait)
			nfs4_close_sync(&ctx->path, ctx->state, ctx->mode);
		else
			nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
	}
	if (ctx->cred != NULL)
		put_rpccred(ctx->cred);
	dput(ctx->path.dentry);
@@ -531,6 +535,16 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
	kfree(ctx);
}

void put_nfs_open_context(struct nfs_open_context *ctx)
{
	__put_nfs_open_context(ctx, 0);
}

static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
{
	__put_nfs_open_context(ctx, 1);
}

/*
 * Ensure that mmap has a recent RPC credential for use when writing out
 * shared pages
@@ -577,7 +591,7 @@ static void nfs_file_clear_open_context(struct file *filp)
		spin_lock(&inode->i_lock);
		list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
		spin_unlock(&inode->i_lock);
		put_nfs_open_context(ctx);
		put_nfs_open_context_sync(ctx);
	}
}

@@ -1169,6 +1183,9 @@ static void init_once(struct kmem_cache * cachep, void *foo)
	INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
	nfsi->ncommit = 0;
	nfsi->npages = 0;
	atomic_set(&nfsi->silly_count, 1);
	INIT_HLIST_HEAD(&nfsi->silly_list);
	init_waitqueue_head(&nfsi->waitqueue);
	nfs4_init_once(nfsi);
}

+2 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
@@ -209,6 +209,7 @@ extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
extern void nfs4_put_open_state(struct nfs4_state *);
extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t);
extern void nfs4_close_sync(struct path *, struct nfs4_state *, mode_t);
extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
extern void nfs4_schedule_state_recovery(struct nfs_client *);
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
Loading