aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-10-05 08:36:26 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-05 08:36:26 -0400
commitbd0d10498826ed150da5e4c45baf8b9c7088fb71 (patch)
treecdee4371121a355d627a655c4eef5c0047b0462a /net/unix/af_unix.c
parent89de0f2cda8b784e51ebd6655fff7339e4ac552b (diff)
parent2425bb3d4016ed95ce83a90b53bd92c7f31091e4 (diff)
Merge branch 'staging/for_v3.7' into v4l_for_linus
* staging/for_v3.7: (2891 commits) em28xx: regression fix: use DRX-K sync firmware requests on em28xx drxk: allow loading firmware synchrousnously em28xx: Make all em28xx extensions to be initialized asynchronously [media] tda18271: properly report read errors in tda18271_get_id [media] tda18271: delay IR & RF calibration until init() if delay_cal is set [media] MAINTAINERS: add Michael Krufky as tda827x maintainer [media] MAINTAINERS: add Michael Krufky as tda8290 maintainer [media] MAINTAINERS: add Michael Krufky as cxusb maintainer [media] MAINTAINERS: add Michael Krufky as lg2160 maintainer [media] MAINTAINERS: add Michael Krufky as lgdt3305 maintainer [media] MAINTAINERS: add Michael Krufky as mxl111sf maintainer [media] MAINTAINERS: add Michael Krufky as mxl5007t maintainer [media] MAINTAINERS: add Michael Krufky as tda18271 maintainer [media] s5p-tv: Report only multi-plane capabilities in vidioc_querycap [media] s5p-mfc: Fix misplaced return statement in s5p_mfc_suspend() [media] exynos-gsc: Add missing static storage class specifiers [media] exynos-gsc: Remove <linux/version.h> header file inclusion [media] s5p-fimc: Fix incorrect condition in fimc_lite_reqbufs() [media] s5p-tv: Fix potential NULL pointer dereference error [media] s5k6aa: Fix possible NULL pointer dereference ... Conflicts: drivers/media/platform/s5p-fimc/fimc-capture.c drivers/media/platform/s5p-fimc/fimc-lite.c
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c97
1 files changed, 45 insertions, 52 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 79981d97bc9c..c5ee4ff61364 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -823,6 +823,34 @@ fail:
823 return NULL; 823 return NULL;
824} 824}
825 825
826static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
827{
828 struct dentry *dentry;
829 struct path path;
830 int err = 0;
831 /*
832 * Get the parent directory, calculate the hash for last
833 * component.
834 */
835 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
836 err = PTR_ERR(dentry);
837 if (IS_ERR(dentry))
838 return err;
839
840 /*
841 * All right, let's create it.
842 */
843 err = security_path_mknod(&path, dentry, mode, 0);
844 if (!err) {
845 err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
846 if (!err) {
847 res->mnt = mntget(path.mnt);
848 res->dentry = dget(dentry);
849 }
850 }
851 done_path_create(&path, dentry);
852 return err;
853}
826 854
827static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 855static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
828{ 856{
@@ -831,8 +859,6 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
831 struct unix_sock *u = unix_sk(sk); 859 struct unix_sock *u = unix_sk(sk);
832 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; 860 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
833 char *sun_path = sunaddr->sun_path; 861 char *sun_path = sunaddr->sun_path;
834 struct dentry *dentry = NULL;
835 struct path path;
836 int err; 862 int err;
837 unsigned int hash; 863 unsigned int hash;
838 struct unix_address *addr; 864 struct unix_address *addr;
@@ -869,43 +895,23 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
869 atomic_set(&addr->refcnt, 1); 895 atomic_set(&addr->refcnt, 1);
870 896
871 if (sun_path[0]) { 897 if (sun_path[0]) {
872 umode_t mode; 898 struct path path;
873 err = 0; 899 umode_t mode = S_IFSOCK |
874 /*
875 * Get the parent directory, calculate the hash for last
876 * component.
877 */
878 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
879 err = PTR_ERR(dentry);
880 if (IS_ERR(dentry))
881 goto out_mknod_parent;
882
883 /*
884 * All right, let's create it.
885 */
886 mode = S_IFSOCK |
887 (SOCK_INODE(sock)->i_mode & ~current_umask()); 900 (SOCK_INODE(sock)->i_mode & ~current_umask());
888 err = mnt_want_write(path.mnt); 901 err = unix_mknod(sun_path, mode, &path);
889 if (err) 902 if (err) {
890 goto out_mknod_dput; 903 if (err == -EEXIST)
891 err = security_path_mknod(&path, dentry, mode, 0); 904 err = -EADDRINUSE;
892 if (err) 905 unix_release_addr(addr);
893 goto out_mknod_drop_write; 906 goto out_up;
894 err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0); 907 }
895out_mknod_drop_write:
896 mnt_drop_write(path.mnt);
897 if (err)
898 goto out_mknod_dput;
899 mutex_unlock(&path.dentry->d_inode->i_mutex);
900 dput(path.dentry);
901 path.dentry = dentry;
902
903 addr->hash = UNIX_HASH_SIZE; 908 addr->hash = UNIX_HASH_SIZE;
904 } 909 hash = path.dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1);
905 910 spin_lock(&unix_table_lock);
906 spin_lock(&unix_table_lock); 911 u->path = path;
907 912 list = &unix_socket_table[hash];
908 if (!sun_path[0]) { 913 } else {
914 spin_lock(&unix_table_lock);
909 err = -EADDRINUSE; 915 err = -EADDRINUSE;
910 if (__unix_find_socket_byname(net, sunaddr, addr_len, 916 if (__unix_find_socket_byname(net, sunaddr, addr_len,
911 sk->sk_type, hash)) { 917 sk->sk_type, hash)) {
@@ -914,9 +920,6 @@ out_mknod_drop_write:
914 } 920 }
915 921
916 list = &unix_socket_table[addr->hash]; 922 list = &unix_socket_table[addr->hash];
917 } else {
918 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
919 u->path = path;
920 } 923 }
921 924
922 err = 0; 925 err = 0;
@@ -930,16 +933,6 @@ out_up:
930 mutex_unlock(&u->readlock); 933 mutex_unlock(&u->readlock);
931out: 934out:
932 return err; 935 return err;
933
934out_mknod_dput:
935 dput(dentry);
936 mutex_unlock(&path.dentry->d_inode->i_mutex);
937 path_put(&path);
938out_mknod_parent:
939 if (err == -EEXIST)
940 err = -EADDRINUSE;
941 unix_release_addr(addr);
942 goto out_up;
943} 936}
944 937
945static void unix_state_double_lock(struct sock *sk1, struct sock *sk2) 938static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
@@ -1457,7 +1450,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1457 if (NULL == siocb->scm) 1450 if (NULL == siocb->scm)
1458 siocb->scm = &tmp_scm; 1451 siocb->scm = &tmp_scm;
1459 wait_for_unix_gc(); 1452 wait_for_unix_gc();
1460 err = scm_send(sock, msg, siocb->scm); 1453 err = scm_send(sock, msg, siocb->scm, false);
1461 if (err < 0) 1454 if (err < 0)
1462 return err; 1455 return err;
1463 1456
@@ -1626,7 +1619,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1626 if (NULL == siocb->scm) 1619 if (NULL == siocb->scm)
1627 siocb->scm = &tmp_scm; 1620 siocb->scm = &tmp_scm;
1628 wait_for_unix_gc(); 1621 wait_for_unix_gc();
1629 err = scm_send(sock, msg, siocb->scm); 1622 err = scm_send(sock, msg, siocb->scm, false);
1630 if (err < 0) 1623 if (err < 0)
1631 return err; 1624 return err;
1632 1625