diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-07 08:04:47 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:42 -0400 |
commit | 1b370bc28f90955bccda8be5e7d7047ad1381da7 (patch) | |
tree | a63507ba14abd869a6645fc604e62f854a39af54 | |
parent | 6f43ddccb31b5bd2297878f6f3735d45fd4dfce3 (diff) |
NFSv4: Allow nfs4_opendata_to_nfs4_state to return errors.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3b59c5ded3fb..52ba7630794c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -385,15 +385,19 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data | |||
385 | struct nfs4_state *state = NULL; | 385 | struct nfs4_state *state = NULL; |
386 | struct nfs_delegation *delegation; | 386 | struct nfs_delegation *delegation; |
387 | nfs4_stateid *deleg_stateid = NULL; | 387 | nfs4_stateid *deleg_stateid = NULL; |
388 | int ret; | ||
388 | 389 | ||
390 | ret = -EAGAIN; | ||
389 | if (!(data->f_attr.valid & NFS_ATTR_FATTR)) | 391 | if (!(data->f_attr.valid & NFS_ATTR_FATTR)) |
390 | goto out; | 392 | goto err; |
391 | inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr); | 393 | inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr); |
394 | ret = PTR_ERR(inode); | ||
392 | if (IS_ERR(inode)) | 395 | if (IS_ERR(inode)) |
393 | goto out; | 396 | goto err; |
397 | ret = -ENOMEM; | ||
394 | state = nfs4_get_open_state(inode, data->owner); | 398 | state = nfs4_get_open_state(inode, data->owner); |
395 | if (state == NULL) | 399 | if (state == NULL) |
396 | goto put_inode; | 400 | goto err_put_inode; |
397 | if (data->o_res.delegation_type != 0) { | 401 | if (data->o_res.delegation_type != 0) { |
398 | int delegation_flags = 0; | 402 | int delegation_flags = 0; |
399 | 403 | ||
@@ -417,10 +421,12 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data | |||
417 | deleg_stateid = &delegation->stateid; | 421 | deleg_stateid = &delegation->stateid; |
418 | update_open_stateid(state, &data->o_res.stateid, deleg_stateid, data->o_arg.open_flags); | 422 | update_open_stateid(state, &data->o_res.stateid, deleg_stateid, data->o_arg.open_flags); |
419 | rcu_read_unlock(); | 423 | rcu_read_unlock(); |
420 | put_inode: | ||
421 | iput(inode); | 424 | iput(inode); |
422 | out: | ||
423 | return state; | 425 | return state; |
426 | err_put_inode: | ||
427 | iput(inode); | ||
428 | err: | ||
429 | return ERR_PTR(ret); | ||
424 | } | 430 | } |
425 | 431 | ||
426 | static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state) | 432 | static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state) |
@@ -453,8 +459,9 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openf | |||
453 | if (ret != 0) | 459 | if (ret != 0) |
454 | return ret; | 460 | return ret; |
455 | newstate = nfs4_opendata_to_nfs4_state(opendata); | 461 | newstate = nfs4_opendata_to_nfs4_state(opendata); |
456 | if (newstate != NULL) | 462 | if (IS_ERR(newstate)) |
457 | nfs4_close_state(&opendata->path, newstate, openflags); | 463 | return PTR_ERR(newstate); |
464 | nfs4_close_state(&opendata->path, newstate, openflags); | ||
458 | *res = newstate; | 465 | *res = newstate; |
459 | return 0; | 466 | return 0; |
460 | } | 467 | } |
@@ -631,7 +638,7 @@ static void nfs4_open_confirm_release(void *calldata) | |||
631 | goto out_free; | 638 | goto out_free; |
632 | nfs_confirm_seqid(&data->owner->so_seqid, 0); | 639 | nfs_confirm_seqid(&data->owner->so_seqid, 0); |
633 | state = nfs4_opendata_to_nfs4_state(data); | 640 | state = nfs4_opendata_to_nfs4_state(data); |
634 | if (state != NULL) | 641 | if (!IS_ERR(state)) |
635 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); | 642 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); |
636 | out_free: | 643 | out_free: |
637 | nfs4_opendata_put(data); | 644 | nfs4_opendata_put(data); |
@@ -736,7 +743,7 @@ static void nfs4_open_release(void *calldata) | |||
736 | goto out_free; | 743 | goto out_free; |
737 | nfs_confirm_seqid(&data->owner->so_seqid, 0); | 744 | nfs_confirm_seqid(&data->owner->so_seqid, 0); |
738 | state = nfs4_opendata_to_nfs4_state(data); | 745 | state = nfs4_opendata_to_nfs4_state(data); |
739 | if (state != NULL) | 746 | if (!IS_ERR(state)) |
740 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); | 747 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); |
741 | out_free: | 748 | out_free: |
742 | nfs4_opendata_put(data); | 749 | nfs4_opendata_put(data); |
@@ -1036,9 +1043,9 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct | |||
1036 | if (opendata->o_arg.open_flags & O_EXCL) | 1043 | if (opendata->o_arg.open_flags & O_EXCL) |
1037 | nfs4_exclusive_attrset(opendata, sattr); | 1044 | nfs4_exclusive_attrset(opendata, sattr); |
1038 | 1045 | ||
1039 | status = -ENOMEM; | ||
1040 | state = nfs4_opendata_to_nfs4_state(opendata); | 1046 | state = nfs4_opendata_to_nfs4_state(opendata); |
1041 | if (state == NULL) | 1047 | status = PTR_ERR(state); |
1048 | if (IS_ERR(state)) | ||
1042 | goto err_opendata_put; | 1049 | goto err_opendata_put; |
1043 | nfs4_opendata_put(opendata); | 1050 | nfs4_opendata_put(opendata); |
1044 | nfs4_put_state_owner(sp); | 1051 | nfs4_put_state_owner(sp); |