aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c61
1 files changed, 1 insertions, 60 deletions
diff --git a/ipc/util.c b/ipc/util.c
index 3339177b336c..49b3ea615dc5 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -688,10 +688,6 @@ void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out)
688 * Look for an id in the ipc ids idr and lock the associated ipc object. 688 * Look for an id in the ipc ids idr and lock the associated ipc object.
689 * 689 *
690 * The ipc object is locked on exit. 690 * The ipc object is locked on exit.
691 *
692 * This is the routine that should be called when the rw_mutex is not already
693 * held, i.e. idr tree not protected: it protects the idr tree in read mode
694 * during the idr_find().
695 */ 691 */
696 692
697struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id) 693struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
@@ -699,18 +695,13 @@ struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
699 struct kern_ipc_perm *out; 695 struct kern_ipc_perm *out;
700 int lid = ipcid_to_idx(id); 696 int lid = ipcid_to_idx(id);
701 697
702 down_read(&ids->rw_mutex);
703
704 rcu_read_lock(); 698 rcu_read_lock();
705 out = idr_find(&ids->ipcs_idr, lid); 699 out = idr_find(&ids->ipcs_idr, lid);
706 if (out == NULL) { 700 if (out == NULL) {
707 rcu_read_unlock(); 701 rcu_read_unlock();
708 up_read(&ids->rw_mutex);
709 return ERR_PTR(-EINVAL); 702 return ERR_PTR(-EINVAL);
710 } 703 }
711 704
712 up_read(&ids->rw_mutex);
713
714 spin_lock(&out->lock); 705 spin_lock(&out->lock);
715 706
716 /* ipc_rmid() may have already freed the ID while ipc_lock 707 /* ipc_rmid() may have already freed the ID while ipc_lock
@@ -725,56 +716,6 @@ struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
725 return out; 716 return out;
726} 717}
727 718
728/**
729 * ipc_lock_down - Lock an ipc structure with rw_sem held
730 * @ids: IPC identifier set
731 * @id: ipc id to look for
732 *
733 * Look for an id in the ipc ids idr and lock the associated ipc object.
734 *
735 * The ipc object is locked on exit.
736 *
737 * This is the routine that should be called when the rw_mutex is already
738 * held, i.e. idr tree protected.
739 */
740
741struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *ids, int id)
742{
743 struct kern_ipc_perm *out;
744 int lid = ipcid_to_idx(id);
745
746 rcu_read_lock();
747 out = idr_find(&ids->ipcs_idr, lid);
748 if (out == NULL) {
749 rcu_read_unlock();
750 return ERR_PTR(-EINVAL);
751 }
752
753 spin_lock(&out->lock);
754
755 /*
756 * No need to verify that the structure is still valid since the
757 * rw_mutex is held.
758 */
759 return out;
760}
761
762struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids, int id)
763{
764 struct kern_ipc_perm *out;
765
766 out = ipc_lock_down(ids, id);
767 if (IS_ERR(out))
768 return out;
769
770 if (ipc_checkid(out, id)) {
771 ipc_unlock(out);
772 return ERR_PTR(-EIDRM);
773 }
774
775 return out;
776}
777
778struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id) 719struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id)
779{ 720{
780 struct kern_ipc_perm *out; 721 struct kern_ipc_perm *out;
@@ -846,7 +787,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
846 int err; 787 int err;
847 788
848 down_write(&ids->rw_mutex); 789 down_write(&ids->rw_mutex);
849 ipcp = ipc_lock_check_down(ids, id); 790 ipcp = ipc_lock_check(ids, id);
850 if (IS_ERR(ipcp)) { 791 if (IS_ERR(ipcp)) {
851 err = PTR_ERR(ipcp); 792 err = PTR_ERR(ipcp);
852 goto out_up; 793 goto out_up;