aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-07 13:20:54 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-19 16:53:15 -0400
commitc1d519312dcdf11532fed9f99a8ecc3547ffd9d6 (patch)
treef91e0d8df3fc424aaa6eddbc54aaf55bdbfb245b /fs
parent35d05778e25ee16dbddb60331be0bc1309efba19 (diff)
NFSv4: Only increment the sequence id if the server saw it
It is quite possible that the OPEN, CLOSE, LOCK, LOCKU,... compounds fail before the actual stateful operation has been executed (for instance in the PUTFH call). There is no way to tell from the overall status result which operations were executed from the COMPOUND. The fix is to move incrementing of the sequence id into the XDR layer, so that we do it as we process the results from the stateful operation. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4proc.c12
-rw-r--r--fs/nfs/nfs4xdr.c18
2 files changed, 23 insertions, 7 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 424aa206470f..9f2759da74eb 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -240,6 +240,8 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
240{ 240{
241 p->o_res.f_attr = &p->f_attr; 241 p->o_res.f_attr = &p->f_attr;
242 p->o_res.dir_attr = &p->dir_attr; 242 p->o_res.dir_attr = &p->dir_attr;
243 p->o_res.seqid = p->o_arg.seqid;
244 p->c_res.seqid = p->c_arg.seqid;
243 p->o_res.server = p->o_arg.server; 245 p->o_res.server = p->o_arg.server;
244 nfs_fattr_init(&p->f_attr); 246 nfs_fattr_init(&p->f_attr);
245 nfs_fattr_init(&p->dir_attr); 247 nfs_fattr_init(&p->dir_attr);
@@ -730,7 +732,6 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
730 renew_lease(data->o_res.server, data->timestamp); 732 renew_lease(data->o_res.server, data->timestamp);
731 data->rpc_done = 1; 733 data->rpc_done = 1;
732 } 734 }
733 nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
734} 735}
735 736
736static void nfs4_open_confirm_release(void *calldata) 737static void nfs4_open_confirm_release(void *calldata)
@@ -860,7 +861,6 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
860 if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)) 861 if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))
861 nfs_confirm_seqid(&data->owner->so_seqid, 0); 862 nfs_confirm_seqid(&data->owner->so_seqid, 0);
862 } 863 }
863 nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid);
864 data->rpc_done = 1; 864 data->rpc_done = 1;
865} 865}
866 866
@@ -1226,7 +1226,6 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1226 /* hmm. we are done with the inode, and in the process of freeing 1226 /* hmm. we are done with the inode, and in the process of freeing
1227 * the state_owner. we keep this around to process errors 1227 * the state_owner. we keep this around to process errors
1228 */ 1228 */
1229 nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
1230 switch (task->tk_status) { 1229 switch (task->tk_status) {
1231 case 0: 1230 case 0:
1232 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1231 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
@@ -1333,6 +1332,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1333 goto out_free_calldata; 1332 goto out_free_calldata;
1334 calldata->arg.bitmask = server->attr_bitmask; 1333 calldata->arg.bitmask = server->attr_bitmask;
1335 calldata->res.fattr = &calldata->fattr; 1334 calldata->res.fattr = &calldata->fattr;
1335 calldata->res.seqid = calldata->arg.seqid;
1336 calldata->res.server = server; 1336 calldata->res.server = server;
1337 calldata->path.mnt = mntget(path->mnt); 1337 calldata->path.mnt = mntget(path->mnt);
1338 calldata->path.dentry = dget(path->dentry); 1338 calldata->path.dentry = dget(path->dentry);
@@ -3159,6 +3159,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
3159 p->arg.fh = NFS_FH(inode); 3159 p->arg.fh = NFS_FH(inode);
3160 p->arg.fl = &p->fl; 3160 p->arg.fl = &p->fl;
3161 p->arg.seqid = seqid; 3161 p->arg.seqid = seqid;
3162 p->res.seqid = seqid;
3162 p->arg.stateid = &lsp->ls_stateid; 3163 p->arg.stateid = &lsp->ls_stateid;
3163 p->lsp = lsp; 3164 p->lsp = lsp;
3164 atomic_inc(&lsp->ls_count); 3165 atomic_inc(&lsp->ls_count);
@@ -3184,7 +3185,6 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3184 3185
3185 if (RPC_ASSASSINATED(task)) 3186 if (RPC_ASSASSINATED(task))
3186 return; 3187 return;
3187 nfs_increment_lock_seqid(task->tk_status, calldata->arg.seqid);
3188 switch (task->tk_status) { 3188 switch (task->tk_status) {
3189 case 0: 3189 case 0:
3190 memcpy(calldata->lsp->ls_stateid.data, 3190 memcpy(calldata->lsp->ls_stateid.data,
@@ -3322,6 +3322,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
3322 p->arg.lock_stateid = &lsp->ls_stateid; 3322 p->arg.lock_stateid = &lsp->ls_stateid;
3323 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; 3323 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
3324 p->arg.lock_owner.id = lsp->ls_id.id; 3324 p->arg.lock_owner.id = lsp->ls_id.id;
3325 p->res.lock_seqid = p->arg.lock_seqid;
3325 p->lsp = lsp; 3326 p->lsp = lsp;
3326 atomic_inc(&lsp->ls_count); 3327 atomic_inc(&lsp->ls_count);
3327 p->ctx = get_nfs_open_context(ctx); 3328 p->ctx = get_nfs_open_context(ctx);
@@ -3348,6 +3349,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3348 return; 3349 return;
3349 data->arg.open_stateid = &state->stateid; 3350 data->arg.open_stateid = &state->stateid;
3350 data->arg.new_lock_owner = 1; 3351 data->arg.new_lock_owner = 1;
3352 data->res.open_seqid = data->arg.open_seqid;
3351 } else 3353 } else
3352 data->arg.new_lock_owner = 0; 3354 data->arg.new_lock_owner = 0;
3353 data->timestamp = jiffies; 3355 data->timestamp = jiffies;
@@ -3365,7 +3367,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3365 if (RPC_ASSASSINATED(task)) 3367 if (RPC_ASSASSINATED(task))
3366 goto out; 3368 goto out;
3367 if (data->arg.new_lock_owner != 0) { 3369 if (data->arg.new_lock_owner != 0) {
3368 nfs_increment_open_seqid(data->rpc_status, data->arg.open_seqid);
3369 if (data->rpc_status == 0) 3370 if (data->rpc_status == 0)
3370 nfs_confirm_seqid(&data->lsp->ls_seqid, 0); 3371 nfs_confirm_seqid(&data->lsp->ls_seqid, 0);
3371 else 3372 else
@@ -3377,7 +3378,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3377 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; 3378 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
3378 renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp); 3379 renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp);
3379 } 3380 }
3380 nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid);
3381out: 3381out:
3382 dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status); 3382 dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status);
3383} 3383}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 2b519f6325f9..b8b2e391d183 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -3005,6 +3005,8 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
3005 int status; 3005 int status;
3006 3006
3007 status = decode_op_hdr(xdr, OP_CLOSE); 3007 status = decode_op_hdr(xdr, OP_CLOSE);
3008 if (status != -EIO)
3009 nfs_increment_open_seqid(status, res->seqid);
3008 if (status) 3010 if (status)
3009 return status; 3011 return status;
3010 READ_BUF(NFS4_STATEID_SIZE); 3012 READ_BUF(NFS4_STATEID_SIZE);
@@ -3296,11 +3298,17 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
3296 int status; 3298 int status;
3297 3299
3298 status = decode_op_hdr(xdr, OP_LOCK); 3300 status = decode_op_hdr(xdr, OP_LOCK);
3301 if (status == -EIO)
3302 goto out;
3299 if (status == 0) { 3303 if (status == 0) {
3300 READ_BUF(NFS4_STATEID_SIZE); 3304 READ_BUF(NFS4_STATEID_SIZE);
3301 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); 3305 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3302 } else if (status == -NFS4ERR_DENIED) 3306 } else if (status == -NFS4ERR_DENIED)
3303 return decode_lock_denied(xdr, NULL); 3307 status = decode_lock_denied(xdr, NULL);
3308 if (res->open_seqid != NULL)
3309 nfs_increment_open_seqid(status, res->open_seqid);
3310 nfs_increment_lock_seqid(status, res->lock_seqid);
3311out:
3304 return status; 3312 return status;
3305} 3313}
3306 3314
@@ -3319,6 +3327,8 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
3319 int status; 3327 int status;
3320 3328
3321 status = decode_op_hdr(xdr, OP_LOCKU); 3329 status = decode_op_hdr(xdr, OP_LOCKU);
3330 if (status != -EIO)
3331 nfs_increment_lock_seqid(status, res->seqid);
3322 if (status == 0) { 3332 if (status == 0) {
3323 READ_BUF(NFS4_STATEID_SIZE); 3333 READ_BUF(NFS4_STATEID_SIZE);
3324 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); 3334 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
@@ -3384,6 +3394,8 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
3384 int status; 3394 int status;
3385 3395
3386 status = decode_op_hdr(xdr, OP_OPEN); 3396 status = decode_op_hdr(xdr, OP_OPEN);
3397 if (status != -EIO)
3398 nfs_increment_open_seqid(status, res->seqid);
3387 if (status) 3399 if (status)
3388 return status; 3400 return status;
3389 READ_BUF(NFS4_STATEID_SIZE); 3401 READ_BUF(NFS4_STATEID_SIZE);
@@ -3416,6 +3428,8 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre
3416 int status; 3428 int status;
3417 3429
3418 status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); 3430 status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
3431 if (status != -EIO)
3432 nfs_increment_open_seqid(status, res->seqid);
3419 if (status) 3433 if (status)
3420 return status; 3434 return status;
3421 READ_BUF(NFS4_STATEID_SIZE); 3435 READ_BUF(NFS4_STATEID_SIZE);
@@ -3429,6 +3443,8 @@ static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *re
3429 int status; 3443 int status;
3430 3444
3431 status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE); 3445 status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE);
3446 if (status != -EIO)
3447 nfs_increment_open_seqid(status, res->seqid);
3432 if (status) 3448 if (status)
3433 return status; 3449 return status;
3434 READ_BUF(NFS4_STATEID_SIZE); 3450 READ_BUF(NFS4_STATEID_SIZE);