aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/idmap.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-09-27 15:44:19 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-09-28 13:42:41 -0400
commite9ab41b620e4b679ed069ab05cb85e67870b7c87 (patch)
tree4b61840469aadfc05296e8b6859b6640e9d43193 /fs/nfs/idmap.c
parent0e24d849c4ea777c59955b241fd3af14a1b84af5 (diff)
NFSv4: Clean up the legacy idmapper upcall
Replace the BUG_ON(idmap->idmap_key_cons != NULL) with a WARN_ON_ONCE(). Then get rid of the ACCESS_ONCE(idmap->idmap_key_cons). Then add helper functions for starting, finishing and aborting the legacy upcall. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Bryan Schumaker <bjschuma@netapp.com>
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r--fs/nfs/idmap.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 79f6424aa081..8222ad861456 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -330,7 +330,6 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
330 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, 330 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
331 name, namelen, type, data, 331 name, namelen, type, data,
332 data_size, idmap); 332 data_size, idmap);
333 idmap->idmap_key_cons = NULL;
334 mutex_unlock(&idmap->idmap_mutex); 333 mutex_unlock(&idmap->idmap_mutex);
335 } 334 }
336 return ret; 335 return ret;
@@ -662,6 +661,34 @@ out:
662 return ret; 661 return ret;
663} 662}
664 663
664static bool
665nfs_idmap_prepare_pipe_upcall(struct idmap *idmap,
666 struct key_construction *cons)
667{
668 if (idmap->idmap_key_cons != NULL) {
669 WARN_ON_ONCE(1);
670 return false;
671 }
672 idmap->idmap_key_cons = cons;
673 return true;
674}
675
676static void
677nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret)
678{
679 struct key_construction *cons = idmap->idmap_key_cons;
680
681 idmap->idmap_key_cons = NULL;
682 complete_request_key(cons, ret);
683}
684
685static void
686nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret)
687{
688 if (idmap->idmap_key_cons != NULL)
689 nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
690}
691
665static int nfs_idmap_legacy_upcall(struct key_construction *cons, 692static int nfs_idmap_legacy_upcall(struct key_construction *cons,
666 const char *op, 693 const char *op,
667 void *aux) 694 void *aux)
@@ -686,21 +713,17 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
686 if (ret < 0) 713 if (ret < 0)
687 goto out2; 714 goto out2;
688 715
689 if (idmap->idmap_key_cons != NULL) { 716 ret = -EAGAIN;
690 WARN_ON_ONCE(1); 717 if (!nfs_idmap_prepare_pipe_upcall(idmap, cons))
691 ret = -EAGAIN;
692 goto out2; 718 goto out2;
693 }
694 idmap->idmap_key_cons = cons;
695 719
696 ret = rpc_queue_upcall(idmap->idmap_pipe, msg); 720 ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
697 if (ret < 0) 721 if (ret < 0) {
698 goto out3; 722 nfs_idmap_abort_pipe_upcall(idmap, ret);
723 kfree(data);
724 }
699 725
700 return ret; 726 return ret;
701
702out3:
703 idmap->idmap_key_cons = NULL;
704out2: 727out2:
705 kfree(data); 728 kfree(data);
706out1: 729out1:
@@ -741,14 +764,15 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
741 struct key_construction *cons; 764 struct key_construction *cons;
742 struct idmap_msg im; 765 struct idmap_msg im;
743 size_t namelen_in; 766 size_t namelen_in;
744 int ret; 767 int ret = -ENOKEY;
745 768
746 /* If instantiation is successful, anyone waiting for key construction 769 /* If instantiation is successful, anyone waiting for key construction
747 * will have been woken up and someone else may now have used 770 * will have been woken up and someone else may now have used
748 * idmap_key_cons - so after this point we may no longer touch it. 771 * idmap_key_cons - so after this point we may no longer touch it.
749 */ 772 */
750 cons = idmap->idmap_key_cons; 773 cons = idmap->idmap_key_cons;
751 idmap->idmap_key_cons = NULL; 774 if (cons == NULL)
775 goto out_noupcall;
752 776
753 if (mlen != sizeof(im)) { 777 if (mlen != sizeof(im)) {
754 ret = -ENOSPC; 778 ret = -ENOSPC;
@@ -778,7 +802,8 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
778 } 802 }
779 803
780out: 804out:
781 complete_request_key(cons, ret); 805 nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
806out_noupcall:
782 return ret; 807 return ret;
783} 808}
784 809
@@ -789,12 +814,9 @@ idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
789 struct idmap_legacy_upcalldata, 814 struct idmap_legacy_upcalldata,
790 pipe_msg); 815 pipe_msg);
791 struct idmap *idmap = data->idmap; 816 struct idmap *idmap = data->idmap;
792 struct key_construction *cons; 817
793 if (msg->errno) { 818 if (msg->errno)
794 cons = idmap->idmap_key_cons; 819 nfs_idmap_abort_pipe_upcall(idmap, msg->errno);
795 idmap->idmap_key_cons = NULL;
796 complete_request_key(cons, msg->errno);
797 }
798 /* Free memory allocated in nfs_idmap_legacy_upcall() */ 820 /* Free memory allocated in nfs_idmap_legacy_upcall() */
799 kfree(data); 821 kfree(data);
800} 822}
@@ -804,7 +826,8 @@ idmap_release_pipe(struct inode *inode)
804{ 826{
805 struct rpc_inode *rpci = RPC_I(inode); 827 struct rpc_inode *rpci = RPC_I(inode);
806 struct idmap *idmap = (struct idmap *)rpci->private; 828 struct idmap *idmap = (struct idmap *)rpci->private;
807 idmap->idmap_key_cons = NULL; 829
830 nfs_idmap_abort_pipe_upcall(idmap, -EPIPE);
808} 831}
809 832
810int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) 833int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)