aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-01-24 16:17:06 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-24 16:17:06 -0500
commite92427b289d252cfbd4cb5282d92f4ce1a5bb1fb (patch)
tree6d30e5e7b7f8e9aaa51d43b7128ac56860fa03bb /fs/nfs/nfs4proc.c
parentc506653d35249bb4738bb139c24362e1ae724bc1 (diff)
parentec30f343d61391ab23705e50a525da1d55395780 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c188
1 files changed, 128 insertions, 60 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4435e5e1f904..9d992b0346e3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -49,6 +49,7 @@
49#include <linux/mount.h> 49#include <linux/mount.h>
50#include <linux/module.h> 50#include <linux/module.h>
51#include <linux/sunrpc/bc_xprt.h> 51#include <linux/sunrpc/bc_xprt.h>
52#include <linux/xattr.h>
52 53
53#include "nfs4_fs.h" 54#include "nfs4_fs.h"
54#include "delegation.h" 55#include "delegation.h"
@@ -355,9 +356,9 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *free_slot)
355} 356}
356 357
357/* 358/*
358 * Signal state manager thread if session is drained 359 * Signal state manager thread if session fore channel is drained
359 */ 360 */
360static void nfs41_check_drain_session_complete(struct nfs4_session *ses) 361static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
361{ 362{
362 struct rpc_task *task; 363 struct rpc_task *task;
363 364
@@ -371,8 +372,20 @@ static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
371 if (ses->fc_slot_table.highest_used_slotid != -1) 372 if (ses->fc_slot_table.highest_used_slotid != -1)
372 return; 373 return;
373 374
374 dprintk("%s COMPLETE: Session Drained\n", __func__); 375 dprintk("%s COMPLETE: Session Fore Channel Drained\n", __func__);
375 complete(&ses->complete); 376 complete(&ses->fc_slot_table.complete);
377}
378
379/*
380 * Signal state manager thread if session back channel is drained
381 */
382void nfs4_check_drain_bc_complete(struct nfs4_session *ses)
383{
384 if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state) ||
385 ses->bc_slot_table.highest_used_slotid != -1)
386 return;
387 dprintk("%s COMPLETE: Session Back Channel Drained\n", __func__);
388 complete(&ses->bc_slot_table.complete);
376} 389}
377 390
378static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) 391static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
@@ -389,7 +402,7 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
389 402
390 spin_lock(&tbl->slot_tbl_lock); 403 spin_lock(&tbl->slot_tbl_lock);
391 nfs4_free_slot(tbl, res->sr_slot); 404 nfs4_free_slot(tbl, res->sr_slot);
392 nfs41_check_drain_session_complete(res->sr_session); 405 nfs4_check_drain_fc_complete(res->sr_session);
393 spin_unlock(&tbl->slot_tbl_lock); 406 spin_unlock(&tbl->slot_tbl_lock);
394 res->sr_slot = NULL; 407 res->sr_slot = NULL;
395} 408}
@@ -1826,6 +1839,8 @@ struct nfs4_closedata {
1826 struct nfs_closeres res; 1839 struct nfs_closeres res;
1827 struct nfs_fattr fattr; 1840 struct nfs_fattr fattr;
1828 unsigned long timestamp; 1841 unsigned long timestamp;
1842 bool roc;
1843 u32 roc_barrier;
1829}; 1844};
1830 1845
1831static void nfs4_free_closedata(void *data) 1846static void nfs4_free_closedata(void *data)
@@ -1833,6 +1848,8 @@ static void nfs4_free_closedata(void *data)
1833 struct nfs4_closedata *calldata = data; 1848 struct nfs4_closedata *calldata = data;
1834 struct nfs4_state_owner *sp = calldata->state->owner; 1849 struct nfs4_state_owner *sp = calldata->state->owner;
1835 1850
1851 if (calldata->roc)
1852 pnfs_roc_release(calldata->state->inode);
1836 nfs4_put_open_state(calldata->state); 1853 nfs4_put_open_state(calldata->state);
1837 nfs_free_seqid(calldata->arg.seqid); 1854 nfs_free_seqid(calldata->arg.seqid);
1838 nfs4_put_state_owner(sp); 1855 nfs4_put_state_owner(sp);
@@ -1865,6 +1882,9 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1865 */ 1882 */
1866 switch (task->tk_status) { 1883 switch (task->tk_status) {
1867 case 0: 1884 case 0:
1885 if (calldata->roc)
1886 pnfs_roc_set_barrier(state->inode,
1887 calldata->roc_barrier);
1868 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1888 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
1869 renew_lease(server, calldata->timestamp); 1889 renew_lease(server, calldata->timestamp);
1870 nfs4_close_clear_stateid_flags(state, 1890 nfs4_close_clear_stateid_flags(state,
@@ -1917,8 +1937,15 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1917 return; 1937 return;
1918 } 1938 }
1919 1939
1920 if (calldata->arg.fmode == 0) 1940 if (calldata->arg.fmode == 0) {
1921 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE]; 1941 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
1942 if (calldata->roc &&
1943 pnfs_roc_drain(calldata->inode, &calldata->roc_barrier)) {
1944 rpc_sleep_on(&NFS_SERVER(calldata->inode)->roc_rpcwaitq,
1945 task, NULL);
1946 return;
1947 }
1948 }
1922 1949
1923 nfs_fattr_init(calldata->res.fattr); 1950 nfs_fattr_init(calldata->res.fattr);
1924 calldata->timestamp = jiffies; 1951 calldata->timestamp = jiffies;
@@ -1946,7 +1973,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
1946 * 1973 *
1947 * NOTE: Caller must be holding the sp->so_owner semaphore! 1974 * NOTE: Caller must be holding the sp->so_owner semaphore!
1948 */ 1975 */
1949int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait) 1976int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
1950{ 1977{
1951 struct nfs_server *server = NFS_SERVER(state->inode); 1978 struct nfs_server *server = NFS_SERVER(state->inode);
1952 struct nfs4_closedata *calldata; 1979 struct nfs4_closedata *calldata;
@@ -1981,11 +2008,12 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i
1981 calldata->res.fattr = &calldata->fattr; 2008 calldata->res.fattr = &calldata->fattr;
1982 calldata->res.seqid = calldata->arg.seqid; 2009 calldata->res.seqid = calldata->arg.seqid;
1983 calldata->res.server = server; 2010 calldata->res.server = server;
2011 calldata->roc = roc;
1984 path_get(path); 2012 path_get(path);
1985 calldata->path = *path; 2013 calldata->path = *path;
1986 2014
1987 msg.rpc_argp = &calldata->arg, 2015 msg.rpc_argp = &calldata->arg;
1988 msg.rpc_resp = &calldata->res, 2016 msg.rpc_resp = &calldata->res;
1989 task_setup_data.callback_data = calldata; 2017 task_setup_data.callback_data = calldata;
1990 task = rpc_run_task(&task_setup_data); 2018 task = rpc_run_task(&task_setup_data);
1991 if (IS_ERR(task)) 2019 if (IS_ERR(task))
@@ -1998,6 +2026,8 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i
1998out_free_calldata: 2026out_free_calldata:
1999 kfree(calldata); 2027 kfree(calldata);
2000out: 2028out:
2029 if (roc)
2030 pnfs_roc_release(state->inode);
2001 nfs4_put_open_state(state); 2031 nfs4_put_open_state(state);
2002 nfs4_put_state_owner(sp); 2032 nfs4_put_state_owner(sp);
2003 return status; 2033 return status;
@@ -2486,6 +2516,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2486 path = &ctx->path; 2516 path = &ctx->path;
2487 fmode = ctx->mode; 2517 fmode = ctx->mode;
2488 } 2518 }
2519 sattr->ia_mode &= ~current_umask();
2489 state = nfs4_do_open(dir, path, fmode, flags, sattr, cred); 2520 state = nfs4_do_open(dir, path, fmode, flags, sattr, cred);
2490 d_drop(dentry); 2521 d_drop(dentry);
2491 if (IS_ERR(state)) { 2522 if (IS_ERR(state)) {
@@ -2816,6 +2847,8 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
2816{ 2847{
2817 struct nfs4_exception exception = { }; 2848 struct nfs4_exception exception = { };
2818 int err; 2849 int err;
2850
2851 sattr->ia_mode &= ~current_umask();
2819 do { 2852 do {
2820 err = nfs4_handle_exception(NFS_SERVER(dir), 2853 err = nfs4_handle_exception(NFS_SERVER(dir),
2821 _nfs4_proc_mkdir(dir, dentry, sattr), 2854 _nfs4_proc_mkdir(dir, dentry, sattr),
@@ -2916,6 +2949,8 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
2916{ 2949{
2917 struct nfs4_exception exception = { }; 2950 struct nfs4_exception exception = { };
2918 int err; 2951 int err;
2952
2953 sattr->ia_mode &= ~current_umask();
2919 do { 2954 do {
2920 err = nfs4_handle_exception(NFS_SERVER(dir), 2955 err = nfs4_handle_exception(NFS_SERVER(dir),
2921 _nfs4_proc_mknod(dir, dentry, sattr, rdev), 2956 _nfs4_proc_mknod(dir, dentry, sattr, rdev),
@@ -3478,6 +3513,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3478 struct nfs4_setclientid setclientid = { 3513 struct nfs4_setclientid setclientid = {
3479 .sc_verifier = &sc_verifier, 3514 .sc_verifier = &sc_verifier,
3480 .sc_prog = program, 3515 .sc_prog = program,
3516 .sc_cb_ident = clp->cl_cb_ident,
3481 }; 3517 };
3482 struct rpc_message msg = { 3518 struct rpc_message msg = {
3483 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], 3519 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
@@ -3517,7 +3553,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3517 if (signalled()) 3553 if (signalled())
3518 break; 3554 break;
3519 if (loop++ & 1) 3555 if (loop++ & 1)
3520 ssleep(clp->cl_lease_time + 1); 3556 ssleep(clp->cl_lease_time / HZ + 1);
3521 else 3557 else
3522 if (++clp->cl_id_uniquifier == 0) 3558 if (++clp->cl_id_uniquifier == 0)
3523 break; 3559 break;
@@ -3663,8 +3699,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
3663 data->rpc_status = 0; 3699 data->rpc_status = 0;
3664 3700
3665 task_setup_data.callback_data = data; 3701 task_setup_data.callback_data = data;
3666 msg.rpc_argp = &data->args, 3702 msg.rpc_argp = &data->args;
3667 msg.rpc_resp = &data->res, 3703 msg.rpc_resp = &data->res;
3668 task = rpc_run_task(&task_setup_data); 3704 task = rpc_run_task(&task_setup_data);
3669 if (IS_ERR(task)) 3705 if (IS_ERR(task))
3670 return PTR_ERR(task); 3706 return PTR_ERR(task);
@@ -3743,6 +3779,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3743 goto out; 3779 goto out;
3744 lsp = request->fl_u.nfs4_fl.owner; 3780 lsp = request->fl_u.nfs4_fl.owner;
3745 arg.lock_owner.id = lsp->ls_id.id; 3781 arg.lock_owner.id = lsp->ls_id.id;
3782 arg.lock_owner.s_dev = server->s_dev;
3746 status = nfs4_call_sync(server, &msg, &arg, &res, 1); 3783 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
3747 switch (status) { 3784 switch (status) {
3748 case 0: 3785 case 0:
@@ -3908,8 +3945,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
3908 return ERR_PTR(-ENOMEM); 3945 return ERR_PTR(-ENOMEM);
3909 } 3946 }
3910 3947
3911 msg.rpc_argp = &data->arg, 3948 msg.rpc_argp = &data->arg;
3912 msg.rpc_resp = &data->res, 3949 msg.rpc_resp = &data->res;
3913 task_setup_data.callback_data = data; 3950 task_setup_data.callback_data = data;
3914 return rpc_run_task(&task_setup_data); 3951 return rpc_run_task(&task_setup_data);
3915} 3952}
@@ -3988,6 +4025,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
3988 p->arg.lock_stateid = &lsp->ls_stateid; 4025 p->arg.lock_stateid = &lsp->ls_stateid;
3989 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; 4026 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
3990 p->arg.lock_owner.id = lsp->ls_id.id; 4027 p->arg.lock_owner.id = lsp->ls_id.id;
4028 p->arg.lock_owner.s_dev = server->s_dev;
3991 p->res.lock_seqid = p->arg.lock_seqid; 4029 p->res.lock_seqid = p->arg.lock_seqid;
3992 p->lsp = lsp; 4030 p->lsp = lsp;
3993 p->server = server; 4031 p->server = server;
@@ -4145,8 +4183,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
4145 data->arg.reclaim = NFS_LOCK_RECLAIM; 4183 data->arg.reclaim = NFS_LOCK_RECLAIM;
4146 task_setup_data.callback_ops = &nfs4_recover_lock_ops; 4184 task_setup_data.callback_ops = &nfs4_recover_lock_ops;
4147 } 4185 }
4148 msg.rpc_argp = &data->arg, 4186 msg.rpc_argp = &data->arg;
4149 msg.rpc_resp = &data->res, 4187 msg.rpc_resp = &data->res;
4150 task_setup_data.callback_data = data; 4188 task_setup_data.callback_data = data;
4151 task = rpc_run_task(&task_setup_data); 4189 task = rpc_run_task(&task_setup_data);
4152 if (IS_ERR(task)) 4190 if (IS_ERR(task))
@@ -4392,48 +4430,43 @@ void nfs4_release_lockowner(const struct nfs4_lock_state *lsp)
4392 return; 4430 return;
4393 args->lock_owner.clientid = server->nfs_client->cl_clientid; 4431 args->lock_owner.clientid = server->nfs_client->cl_clientid;
4394 args->lock_owner.id = lsp->ls_id.id; 4432 args->lock_owner.id = lsp->ls_id.id;
4433 args->lock_owner.s_dev = server->s_dev;
4395 msg.rpc_argp = args; 4434 msg.rpc_argp = args;
4396 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, args); 4435 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, args);
4397} 4436}
4398 4437
4399#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" 4438#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
4400 4439
4401int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf, 4440static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key,
4402 size_t buflen, int flags) 4441 const void *buf, size_t buflen,
4442 int flags, int type)
4403{ 4443{
4404 struct inode *inode = dentry->d_inode; 4444 if (strcmp(key, "") != 0)
4405 4445 return -EINVAL;
4406 if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
4407 return -EOPNOTSUPP;
4408 4446
4409 return nfs4_proc_set_acl(inode, buf, buflen); 4447 return nfs4_proc_set_acl(dentry->d_inode, buf, buflen);
4410} 4448}
4411 4449
4412/* The getxattr man page suggests returning -ENODATA for unknown attributes, 4450static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key,
4413 * and that's what we'll do for e.g. user attributes that haven't been set. 4451 void *buf, size_t buflen, int type)
4414 * But we'll follow ext2/ext3's lead by returning -EOPNOTSUPP for unsupported
4415 * attributes in kernel-managed attribute namespaces. */
4416ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf,
4417 size_t buflen)
4418{ 4452{
4419 struct inode *inode = dentry->d_inode; 4453 if (strcmp(key, "") != 0)
4420 4454 return -EINVAL;
4421 if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
4422 return -EOPNOTSUPP;
4423 4455
4424 return nfs4_proc_get_acl(inode, buf, buflen); 4456 return nfs4_proc_get_acl(dentry->d_inode, buf, buflen);
4425} 4457}
4426 4458
4427ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen) 4459static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
4460 size_t list_len, const char *name,
4461 size_t name_len, int type)
4428{ 4462{
4429 size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1; 4463 size_t len = sizeof(XATTR_NAME_NFSV4_ACL);
4430 4464
4431 if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode))) 4465 if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode)))
4432 return 0; 4466 return 0;
4433 if (buf && buflen < len) 4467
4434 return -ERANGE; 4468 if (list && len <= list_len)
4435 if (buf) 4469 memcpy(list, XATTR_NAME_NFSV4_ACL, len);
4436 memcpy(buf, XATTR_NAME_NFSV4_ACL, len);
4437 return len; 4470 return len;
4438} 4471}
4439 4472
@@ -4486,6 +4519,25 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4486 4519
4487#ifdef CONFIG_NFS_V4_1 4520#ifdef CONFIG_NFS_V4_1
4488/* 4521/*
4522 * Check the exchange flags returned by the server for invalid flags, having
4523 * both PNFS and NON_PNFS flags set, and not having one of NON_PNFS, PNFS, or
4524 * DS flags set.
4525 */
4526static int nfs4_check_cl_exchange_flags(u32 flags)
4527{
4528 if (flags & ~EXCHGID4_FLAG_MASK_R)
4529 goto out_inval;
4530 if ((flags & EXCHGID4_FLAG_USE_PNFS_MDS) &&
4531 (flags & EXCHGID4_FLAG_USE_NON_PNFS))
4532 goto out_inval;
4533 if (!(flags & (EXCHGID4_FLAG_MASK_PNFS)))
4534 goto out_inval;
4535 return NFS_OK;
4536out_inval:
4537 return -NFS4ERR_INVAL;
4538}
4539
4540/*
4489 * nfs4_proc_exchange_id() 4541 * nfs4_proc_exchange_id()
4490 * 4542 *
4491 * Since the clientid has expired, all compounds using sessions 4543 * Since the clientid has expired, all compounds using sessions
@@ -4498,7 +4550,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4498 nfs4_verifier verifier; 4550 nfs4_verifier verifier;
4499 struct nfs41_exchange_id_args args = { 4551 struct nfs41_exchange_id_args args = {
4500 .client = clp, 4552 .client = clp,
4501 .flags = clp->cl_exchange_flags, 4553 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER,
4502 }; 4554 };
4503 struct nfs41_exchange_id_res res = { 4555 struct nfs41_exchange_id_res res = {
4504 .client = clp, 4556 .client = clp,
@@ -4515,9 +4567,6 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4515 dprintk("--> %s\n", __func__); 4567 dprintk("--> %s\n", __func__);
4516 BUG_ON(clp == NULL); 4568 BUG_ON(clp == NULL);
4517 4569
4518 /* Remove server-only flags */
4519 args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
4520
4521 p = (u32 *)verifier.data; 4570 p = (u32 *)verifier.data;
4522 *p++ = htonl((u32)clp->cl_boot_time.tv_sec); 4571 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4523 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4572 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
@@ -4543,6 +4592,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4543 break; 4592 break;
4544 } 4593 }
4545 4594
4595 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
4546 dprintk("<-- %s status= %d\n", __func__, status); 4596 dprintk("<-- %s status= %d\n", __func__, status);
4547 return status; 4597 return status;
4548} 4598}
@@ -4776,17 +4826,17 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4776 if (!session) 4826 if (!session)
4777 return NULL; 4827 return NULL;
4778 4828
4779 init_completion(&session->complete);
4780
4781 tbl = &session->fc_slot_table; 4829 tbl = &session->fc_slot_table;
4782 tbl->highest_used_slotid = -1; 4830 tbl->highest_used_slotid = -1;
4783 spin_lock_init(&tbl->slot_tbl_lock); 4831 spin_lock_init(&tbl->slot_tbl_lock);
4784 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); 4832 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4833 init_completion(&tbl->complete);
4785 4834
4786 tbl = &session->bc_slot_table; 4835 tbl = &session->bc_slot_table;
4787 tbl->highest_used_slotid = -1; 4836 tbl->highest_used_slotid = -1;
4788 spin_lock_init(&tbl->slot_tbl_lock); 4837 spin_lock_init(&tbl->slot_tbl_lock);
4789 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table"); 4838 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
4839 init_completion(&tbl->complete);
4790 4840
4791 session->session_state = 1<<NFS4_SESSION_INITING; 4841 session->session_state = 1<<NFS4_SESSION_INITING;
4792 4842
@@ -5280,13 +5330,23 @@ static void
5280nfs4_layoutget_prepare(struct rpc_task *task, void *calldata) 5330nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
5281{ 5331{
5282 struct nfs4_layoutget *lgp = calldata; 5332 struct nfs4_layoutget *lgp = calldata;
5283 struct inode *ino = lgp->args.inode; 5333 struct nfs_server *server = NFS_SERVER(lgp->args.inode);
5284 struct nfs_server *server = NFS_SERVER(ino);
5285 5334
5286 dprintk("--> %s\n", __func__); 5335 dprintk("--> %s\n", __func__);
5336 /* Note the is a race here, where a CB_LAYOUTRECALL can come in
5337 * right now covering the LAYOUTGET we are about to send.
5338 * However, that is not so catastrophic, and there seems
5339 * to be no way to prevent it completely.
5340 */
5287 if (nfs4_setup_sequence(server, &lgp->args.seq_args, 5341 if (nfs4_setup_sequence(server, &lgp->args.seq_args,
5288 &lgp->res.seq_res, 0, task)) 5342 &lgp->res.seq_res, 0, task))
5289 return; 5343 return;
5344 if (pnfs_choose_layoutget_stateid(&lgp->args.stateid,
5345 NFS_I(lgp->args.inode)->layout,
5346 lgp->args.ctx->state)) {
5347 rpc_exit(task, NFS4_OK);
5348 return;
5349 }
5290 rpc_call_start(task); 5350 rpc_call_start(task);
5291} 5351}
5292 5352
@@ -5313,7 +5373,6 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
5313 return; 5373 return;
5314 } 5374 }
5315 } 5375 }
5316 lgp->status = task->tk_status;
5317 dprintk("<-- %s\n", __func__); 5376 dprintk("<-- %s\n", __func__);
5318} 5377}
5319 5378
@@ -5322,7 +5381,6 @@ static void nfs4_layoutget_release(void *calldata)
5322 struct nfs4_layoutget *lgp = calldata; 5381 struct nfs4_layoutget *lgp = calldata;
5323 5382
5324 dprintk("--> %s\n", __func__); 5383 dprintk("--> %s\n", __func__);
5325 put_layout_hdr(lgp->args.inode);
5326 if (lgp->res.layout.buf != NULL) 5384 if (lgp->res.layout.buf != NULL)
5327 free_page((unsigned long) lgp->res.layout.buf); 5385 free_page((unsigned long) lgp->res.layout.buf);
5328 put_nfs_open_context(lgp->args.ctx); 5386 put_nfs_open_context(lgp->args.ctx);
@@ -5367,13 +5425,10 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
5367 if (IS_ERR(task)) 5425 if (IS_ERR(task))
5368 return PTR_ERR(task); 5426 return PTR_ERR(task);
5369 status = nfs4_wait_for_completion_rpc_task(task); 5427 status = nfs4_wait_for_completion_rpc_task(task);
5370 if (status != 0) 5428 if (status == 0)
5371 goto out; 5429 status = task->tk_status;
5372 status = lgp->status; 5430 if (status == 0)
5373 if (status != 0) 5431 status = pnfs_layout_process(lgp);
5374 goto out;
5375 status = pnfs_layout_process(lgp);
5376out:
5377 rpc_put_task(task); 5432 rpc_put_task(task);
5378 dprintk("<-- %s status=%d\n", __func__, status); 5433 dprintk("<-- %s status=%d\n", __func__, status);
5379 return status; 5434 return status;
@@ -5504,9 +5559,10 @@ static const struct inode_operations nfs4_file_inode_operations = {
5504 .permission = nfs_permission, 5559 .permission = nfs_permission,
5505 .getattr = nfs_getattr, 5560 .getattr = nfs_getattr,
5506 .setattr = nfs_setattr, 5561 .setattr = nfs_setattr,
5507 .getxattr = nfs4_getxattr, 5562 .getxattr = generic_getxattr,
5508 .setxattr = nfs4_setxattr, 5563 .setxattr = generic_setxattr,
5509 .listxattr = nfs4_listxattr, 5564 .listxattr = generic_listxattr,
5565 .removexattr = generic_removexattr,
5510}; 5566};
5511 5567
5512const struct nfs_rpc_ops nfs_v4_clientops = { 5568const struct nfs_rpc_ops nfs_v4_clientops = {
@@ -5551,6 +5607,18 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
5551 .open_context = nfs4_atomic_open, 5607 .open_context = nfs4_atomic_open,
5552}; 5608};
5553 5609
5610static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
5611 .prefix = XATTR_NAME_NFSV4_ACL,
5612 .list = nfs4_xattr_list_nfs4_acl,
5613 .get = nfs4_xattr_get_nfs4_acl,
5614 .set = nfs4_xattr_set_nfs4_acl,
5615};
5616
5617const struct xattr_handler *nfs4_xattr_handlers[] = {
5618 &nfs4_xattr_nfs4_acl_handler,
5619 NULL
5620};
5621
5554/* 5622/*
5555 * Local variables: 5623 * Local variables:
5556 * c-basic-offset: 8 5624 * c-basic-offset: 8