Skip to content

Commit

Permalink
Merge branch 'nfs-for-2.6.36' of git://git.linux-nfs.org/projects/tro…
Browse files Browse the repository at this point in the history
…ndmy/nfs-2.6

* 'nfs-for-2.6.36' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (42 commits)
  NFS: NFSv4.1 is no longer a "developer only" feature
  NFS: NFS_V4 is no longer an EXPERIMENTAL feature
  NFS: Fix /proc/mount for legacy binary interface
  NFS: Fix the locking in nfs4_callback_getattr
  SUNRPC: Defer deleting the security context until gss_do_free_ctx()
  SUNRPC: prevent task_cleanup running on freed xprt
  SUNRPC: Reduce asynchronous RPC task stack usage
  SUNRPC: Move the bound cred to struct rpc_rqst
  SUNRPC: Clean up of rpc_bindcred()
  SUNRPC: Move remaining RPC client related task initialisation into clnt.c
  SUNRPC: Ensure that rpc_exit() always wakes up a sleeping task
  SUNRPC: Make the credential cache hashtable size configurable
  SUNRPC: Store the hashtable size in struct rpc_cred_cache
  NFS: Ensure the AUTH_UNIX credcache is allocated dynamically
  NFS: Fix the NFS users of rpc_restart_call()
  SUNRPC: The function rpc_restart_call() should return success/failure
  NFSv4: Get rid of the bogus RPC_ASSASSINATED(task) checks
  NFSv4: Clean up the process of renewing the NFSv4 lease
  NFSv4.1: Handle NFS4ERR_DELAY on SEQUENCE correctly
  NFS: nfs_rename() should not have to flush out writebacks
  ...
  • Loading branch information
Linus Torvalds committed Aug 7, 2010
2 parents fe21ea1 + 3dce9a5 commit 5df6b8e
Show file tree
Hide file tree
Showing 41 changed files with 963 additions and 647 deletions.
10 changes: 5 additions & 5 deletions fs/nfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ config NFS_V3_ACL
If unsure, say N.

config NFS_V4
bool "NFS client support for NFS version 4 (EXPERIMENTAL)"
depends on NFS_FS && EXPERIMENTAL
bool "NFS client support for NFS version 4"
depends on NFS_FS
select RPCSEC_GSS_KRB5
help
This option enables support for version 4 of the NFS protocol
Expand All @@ -72,16 +72,16 @@ config NFS_V4
space programs which can be found in the Linux nfs-utils package,
available from http://linux-nfs.org/.

If unsure, say N.
If unsure, say Y.

config NFS_V4_1
bool "NFS client support for NFSv4.1 (DEVELOPER ONLY)"
bool "NFS client support for NFSv4.1 (EXPERIMENTAL)"
depends on NFS_V4 && EXPERIMENTAL
help
This option enables support for minor version 1 of the NFSv4 protocol
(draft-ietf-nfsv4-minorversion1) in the kernel's NFS client.

Unless you're an NFS developer, say N.
If unsure, say N.

config ROOT_NFS
bool "Root file system on NFS"
Expand Down
19 changes: 4 additions & 15 deletions fs/nfs/callback_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *
if (inode == NULL)
goto out_putclient;
nfsi = NFS_I(inode);
down_read(&nfsi->rwsem);
delegation = nfsi->delegation;
rcu_read_lock();
delegation = rcu_dereference(nfsi->delegation);
if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
goto out_iput;
res->size = i_size_read(inode);
Expand All @@ -53,7 +53,7 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *
args->bitmap[1];
res->status = 0;
out_iput:
up_read(&nfsi->rwsem);
rcu_read_unlock();
iput(inode);
out_putclient:
nfs_put_client(clp);
Expand All @@ -62,16 +62,6 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *
return res->status;
}

static int (*nfs_validate_delegation_stateid(struct nfs_client *clp))(struct nfs_delegation *, const nfs4_stateid *)
{
#if defined(CONFIG_NFS_V4_1)
if (clp->cl_minorversion > 0)
return nfs41_validate_delegation_stateid;
#endif
return nfs4_validate_delegation_stateid;
}


__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
{
struct nfs_client *clp;
Expand All @@ -92,8 +82,7 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
inode = nfs_delegation_find_inode(clp, &args->fh);
if (inode != NULL) {
/* Set up a helper thread to actually return the delegation */
switch (nfs_async_inode_return_delegation(inode, &args->stateid,
nfs_validate_delegation_stateid(clp))) {
switch (nfs_async_inode_return_delegation(inode, &args->stateid)) {
case 0:
res = 0;
break;
Expand Down
21 changes: 13 additions & 8 deletions fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
clp->cl_boot_time = CURRENT_TIME;
clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
clp->cl_minorversion = cl_init->minorversion;
clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
#endif
cred = rpc_lookup_machine_cred();
if (!IS_ERR(cred))
Expand Down Expand Up @@ -178,7 +179,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
clp->cl_session = NULL;
}

clp->cl_call_sync = _nfs4_call_sync;
clp->cl_mvops = nfs_v4_minor_ops[0];
#endif /* CONFIG_NFS_V4_1 */
}

Expand All @@ -188,7 +189,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
static void nfs4_destroy_callback(struct nfs_client *clp)
{
if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
nfs_callback_down(clp->cl_minorversion);
nfs_callback_down(clp->cl_mvops->minor_version);
}

static void nfs4_shutdown_client(struct nfs_client *clp)
Expand Down Expand Up @@ -1126,7 +1127,7 @@ static int nfs4_init_callback(struct nfs_client *clp)
return error;
}

error = nfs_callback_up(clp->cl_minorversion,
error = nfs_callback_up(clp->cl_mvops->minor_version,
clp->cl_rpcclient->cl_xprt);
if (error < 0) {
dprintk("%s: failed to start callback. Error = %d\n",
Expand All @@ -1143,10 +1144,8 @@ static int nfs4_init_callback(struct nfs_client *clp)
*/
static int nfs4_init_client_minor_version(struct nfs_client *clp)
{
clp->cl_call_sync = _nfs4_call_sync;

#if defined(CONFIG_NFS_V4_1)
if (clp->cl_minorversion) {
if (clp->cl_mvops->minor_version) {
struct nfs4_session *session = NULL;
/*
* Create the session and mark it expired.
Expand All @@ -1158,7 +1157,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
return -ENOMEM;

clp->cl_session = session;
clp->cl_call_sync = _nfs4_call_sync_session;
/*
* The create session reply races with the server back
* channel probe. Mark the client NFS_CS_SESSION_INITING
* so that the client back channel can find the
* nfs_client struct
*/
clp->cl_cons_state = NFS_CS_SESSION_INITING;
}
#endif /* CONFIG_NFS_V4_1 */

Expand Down Expand Up @@ -1454,7 +1459,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
data->authflavor,
parent_server->client->cl_xprt->prot,
parent_server->client->cl_timeout,
parent_client->cl_minorversion);
parent_client->cl_mvops->minor_version);
if (error < 0)
goto error;

Expand Down
16 changes: 3 additions & 13 deletions fs/nfs/delegation.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,6 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
return status;
}

/* Sync all data to disk upon delegation return */
static void nfs_msync_inode(struct inode *inode)
{
filemap_fdatawrite(inode->i_mapping);
nfs_wb_all(inode);
filemap_fdatawait(inode->i_mapping);
}

/*
* Basic procedure for returning a delegation to the server
*/
Expand Down Expand Up @@ -367,7 +359,7 @@ int nfs_inode_return_delegation(struct inode *inode)
delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
spin_unlock(&clp->cl_lock);
if (delegation != NULL) {
nfs_msync_inode(inode);
nfs_wb_all(inode);
err = __nfs_inode_return_delegation(inode, delegation, 1);
}
}
Expand Down Expand Up @@ -471,17 +463,15 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
/*
* Asynchronous delegation recall!
*/
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
int (*validate_stateid)(struct nfs_delegation *delegation,
const nfs4_stateid *stateid))
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid)
{
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
struct nfs_delegation *delegation;

rcu_read_lock();
delegation = rcu_dereference(NFS_I(inode)->delegation);

if (!validate_stateid(delegation, stateid)) {
if (!clp->cl_mvops->validate_stateid(delegation, stateid)) {
rcu_read_unlock();
return -ENOENT;
}
Expand Down
4 changes: 1 addition & 3 deletions fs/nfs/delegation.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ enum {
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
int nfs_inode_return_delegation(struct inode *inode);
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
int (*validate_stateid)(struct nfs_delegation *delegation,
const nfs4_stateid *stateid));
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
void nfs_inode_return_delegation_noreclaim(struct inode *inode);

struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
Expand Down
9 changes: 0 additions & 9 deletions fs/nfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1652,16 +1652,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
}
}

/*
* ... prune child dentries and writebacks if needed.
*/
if (atomic_read(&old_dentry->d_count) > 1) {
if (S_ISREG(old_inode->i_mode))
nfs_wb_all(old_inode);
shrink_dcache_parent(old_dentry);
}
nfs_inode_return_delegation(old_inode);

if (new_inode != NULL)
nfs_inode_return_delegation(new_inode);

Expand Down
29 changes: 22 additions & 7 deletions fs/nfs/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct nfs_direct_req {

/* I/O parameters */
struct nfs_open_context *ctx; /* file open context info */
struct nfs_lock_context *l_ctx; /* Lock context info */
struct kiocb * iocb; /* controlling i/o request */
struct inode * inode; /* target file of i/o */

Expand Down Expand Up @@ -160,6 +161,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
INIT_LIST_HEAD(&dreq->rewrite_list);
dreq->iocb = NULL;
dreq->ctx = NULL;
dreq->l_ctx = NULL;
spin_lock_init(&dreq->lock);
atomic_set(&dreq->io_count, 0);
dreq->count = 0;
Expand All @@ -173,6 +175,8 @@ static void nfs_direct_req_free(struct kref *kref)
{
struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);

if (dreq->l_ctx != NULL)
nfs_put_lock_context(dreq->l_ctx);
if (dreq->ctx != NULL)
put_nfs_open_context(dreq->ctx);
kmem_cache_free(nfs_direct_cachep, dreq);
Expand Down Expand Up @@ -336,6 +340,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
data->cred = msg.rpc_cred;
data->args.fh = NFS_FH(inode);
data->args.context = ctx;
data->args.lock_context = dreq->l_ctx;
data->args.offset = pos;
data->args.pgbase = pgbase;
data->args.pages = data->pagevec;
Expand Down Expand Up @@ -416,24 +421,28 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
ssize_t result = 0;
ssize_t result = -ENOMEM;
struct inode *inode = iocb->ki_filp->f_mapping->host;
struct nfs_direct_req *dreq;

dreq = nfs_direct_req_alloc();
if (!dreq)
return -ENOMEM;
if (dreq == NULL)
goto out;

dreq->inode = inode;
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
if (dreq->l_ctx == NULL)
goto out_release;
if (!is_sync_kiocb(iocb))
dreq->iocb = iocb;

result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos);
if (!result)
result = nfs_direct_wait(dreq);
out_release:
nfs_direct_req_release(dreq);

out:
return result;
}

Expand Down Expand Up @@ -574,6 +583,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
data->args.offset = 0;
data->args.count = 0;
data->args.context = dreq->ctx;
data->args.lock_context = dreq->l_ctx;
data->res.count = 0;
data->res.fattr = &data->fattr;
data->res.verf = &data->verf;
Expand Down Expand Up @@ -761,6 +771,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
data->cred = msg.rpc_cred;
data->args.fh = NFS_FH(inode);
data->args.context = ctx;
data->args.lock_context = dreq->l_ctx;
data->args.offset = pos;
data->args.pgbase = pgbase;
data->args.pages = data->pagevec;
Expand Down Expand Up @@ -845,30 +856,34 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos,
size_t count)
{
ssize_t result = 0;
ssize_t result = -ENOMEM;
struct inode *inode = iocb->ki_filp->f_mapping->host;
struct nfs_direct_req *dreq;
size_t wsize = NFS_SERVER(inode)->wsize;
int sync = NFS_UNSTABLE;

dreq = nfs_direct_req_alloc();
if (!dreq)
return -ENOMEM;
goto out;
nfs_alloc_commit_data(dreq);

if (dreq->commit_data == NULL || count < wsize)
sync = NFS_FILE_SYNC;

dreq->inode = inode;
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
if (dreq->l_ctx != NULL)
goto out_release;
if (!is_sync_kiocb(iocb))
dreq->iocb = iocb;

result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, sync);
if (!result)
result = nfs_direct_wait(dreq);
out_release:
nfs_direct_req_release(dreq);

out:
return result;
}

Expand Down
Loading

0 comments on commit 5df6b8e

Please sign in to comment.