diff options
-rw-r--r-- | fs/namei.c | 154 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.c | 49 | ||||
-rw-r--r-- | include/linux/namei.h | 2 | ||||
-rw-r--r-- | net/unix/af_unix.c | 38 |
4 files changed, 106 insertions, 137 deletions
diff --git a/fs/namei.c b/fs/namei.c index f49d6abfa799..b292eb03d9d2 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2311,6 +2311,35 @@ fail: | |||
2311 | } | 2311 | } |
2312 | EXPORT_SYMBOL_GPL(lookup_create); | 2312 | EXPORT_SYMBOL_GPL(lookup_create); |
2313 | 2313 | ||
2314 | struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, int is_dir) | ||
2315 | { | ||
2316 | struct nameidata nd; | ||
2317 | struct dentry *res; | ||
2318 | int error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd); | ||
2319 | if (error) | ||
2320 | return ERR_PTR(error); | ||
2321 | res = lookup_create(&nd, is_dir); | ||
2322 | if (IS_ERR(res)) { | ||
2323 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
2324 | path_put(&nd.path); | ||
2325 | } | ||
2326 | *path = nd.path; | ||
2327 | return res; | ||
2328 | } | ||
2329 | EXPORT_SYMBOL(kern_path_create); | ||
2330 | |||
2331 | struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir) | ||
2332 | { | ||
2333 | char *tmp = getname(pathname); | ||
2334 | struct dentry *res; | ||
2335 | if (IS_ERR(tmp)) | ||
2336 | return ERR_CAST(tmp); | ||
2337 | res = kern_path_create(dfd, tmp, path, is_dir); | ||
2338 | putname(tmp); | ||
2339 | return res; | ||
2340 | } | ||
2341 | EXPORT_SYMBOL(user_path_create); | ||
2342 | |||
2314 | int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | 2343 | int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) |
2315 | { | 2344 | { |
2316 | int error = may_create(dir, dentry); | 2345 | int error = may_create(dir, dentry); |
@@ -2359,54 +2388,46 @@ static int may_mknod(mode_t mode) | |||
2359 | SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, | 2388 | SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, |
2360 | unsigned, dev) | 2389 | unsigned, dev) |
2361 | { | 2390 | { |
2362 | int error; | ||
2363 | char *tmp; | ||
2364 | struct dentry *dentry; | 2391 | struct dentry *dentry; |
2365 | struct nameidata nd; | 2392 | struct path path; |
2393 | int error; | ||
2366 | 2394 | ||
2367 | if (S_ISDIR(mode)) | 2395 | if (S_ISDIR(mode)) |
2368 | return -EPERM; | 2396 | return -EPERM; |
2369 | 2397 | ||
2370 | error = user_path_parent(dfd, filename, &nd, &tmp); | 2398 | dentry = user_path_create(dfd, filename, &path, 0); |
2371 | if (error) | 2399 | if (IS_ERR(dentry)) |
2372 | return error; | 2400 | return PTR_ERR(dentry); |
2373 | 2401 | ||
2374 | dentry = lookup_create(&nd, 0); | 2402 | if (!IS_POSIXACL(path.dentry->d_inode)) |
2375 | if (IS_ERR(dentry)) { | ||
2376 | error = PTR_ERR(dentry); | ||
2377 | goto out_unlock; | ||
2378 | } | ||
2379 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | ||
2380 | mode &= ~current_umask(); | 2403 | mode &= ~current_umask(); |
2381 | error = may_mknod(mode); | 2404 | error = may_mknod(mode); |
2382 | if (error) | 2405 | if (error) |
2383 | goto out_dput; | 2406 | goto out_dput; |
2384 | error = mnt_want_write(nd.path.mnt); | 2407 | error = mnt_want_write(path.mnt); |
2385 | if (error) | 2408 | if (error) |
2386 | goto out_dput; | 2409 | goto out_dput; |
2387 | error = security_path_mknod(&nd.path, dentry, mode, dev); | 2410 | error = security_path_mknod(&path, dentry, mode, dev); |
2388 | if (error) | 2411 | if (error) |
2389 | goto out_drop_write; | 2412 | goto out_drop_write; |
2390 | switch (mode & S_IFMT) { | 2413 | switch (mode & S_IFMT) { |
2391 | case 0: case S_IFREG: | 2414 | case 0: case S_IFREG: |
2392 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,NULL); | 2415 | error = vfs_create(path.dentry->d_inode,dentry,mode,NULL); |
2393 | break; | 2416 | break; |
2394 | case S_IFCHR: case S_IFBLK: | 2417 | case S_IFCHR: case S_IFBLK: |
2395 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode, | 2418 | error = vfs_mknod(path.dentry->d_inode,dentry,mode, |
2396 | new_decode_dev(dev)); | 2419 | new_decode_dev(dev)); |
2397 | break; | 2420 | break; |
2398 | case S_IFIFO: case S_IFSOCK: | 2421 | case S_IFIFO: case S_IFSOCK: |
2399 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); | 2422 | error = vfs_mknod(path.dentry->d_inode,dentry,mode,0); |
2400 | break; | 2423 | break; |
2401 | } | 2424 | } |
2402 | out_drop_write: | 2425 | out_drop_write: |
2403 | mnt_drop_write(nd.path.mnt); | 2426 | mnt_drop_write(path.mnt); |
2404 | out_dput: | 2427 | out_dput: |
2405 | dput(dentry); | 2428 | dput(dentry); |
2406 | out_unlock: | 2429 | mutex_unlock(&path.dentry->d_inode->i_mutex); |
2407 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2430 | path_put(&path); |
2408 | path_put(&nd.path); | ||
2409 | putname(tmp); | ||
2410 | 2431 | ||
2411 | return error; | 2432 | return error; |
2412 | } | 2433 | } |
@@ -2439,38 +2460,29 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
2439 | 2460 | ||
2440 | SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) | 2461 | SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) |
2441 | { | 2462 | { |
2442 | int error = 0; | ||
2443 | char * tmp; | ||
2444 | struct dentry *dentry; | 2463 | struct dentry *dentry; |
2445 | struct nameidata nd; | 2464 | struct path path; |
2446 | 2465 | int error; | |
2447 | error = user_path_parent(dfd, pathname, &nd, &tmp); | ||
2448 | if (error) | ||
2449 | goto out_err; | ||
2450 | 2466 | ||
2451 | dentry = lookup_create(&nd, 1); | 2467 | dentry = user_path_create(dfd, pathname, &path, 1); |
2452 | error = PTR_ERR(dentry); | ||
2453 | if (IS_ERR(dentry)) | 2468 | if (IS_ERR(dentry)) |
2454 | goto out_unlock; | 2469 | return PTR_ERR(dentry); |
2455 | 2470 | ||
2456 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 2471 | if (!IS_POSIXACL(path.dentry->d_inode)) |
2457 | mode &= ~current_umask(); | 2472 | mode &= ~current_umask(); |
2458 | error = mnt_want_write(nd.path.mnt); | 2473 | error = mnt_want_write(path.mnt); |
2459 | if (error) | 2474 | if (error) |
2460 | goto out_dput; | 2475 | goto out_dput; |
2461 | error = security_path_mkdir(&nd.path, dentry, mode); | 2476 | error = security_path_mkdir(&path, dentry, mode); |
2462 | if (error) | 2477 | if (error) |
2463 | goto out_drop_write; | 2478 | goto out_drop_write; |
2464 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); | 2479 | error = vfs_mkdir(path.dentry->d_inode, dentry, mode); |
2465 | out_drop_write: | 2480 | out_drop_write: |
2466 | mnt_drop_write(nd.path.mnt); | 2481 | mnt_drop_write(path.mnt); |
2467 | out_dput: | 2482 | out_dput: |
2468 | dput(dentry); | 2483 | dput(dentry); |
2469 | out_unlock: | 2484 | mutex_unlock(&path.dentry->d_inode->i_mutex); |
2470 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2485 | path_put(&path); |
2471 | path_put(&nd.path); | ||
2472 | putname(tmp); | ||
2473 | out_err: | ||
2474 | return error; | 2486 | return error; |
2475 | } | 2487 | } |
2476 | 2488 | ||
@@ -2730,38 +2742,31 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, | |||
2730 | { | 2742 | { |
2731 | int error; | 2743 | int error; |
2732 | char *from; | 2744 | char *from; |
2733 | char *to; | ||
2734 | struct dentry *dentry; | 2745 | struct dentry *dentry; |
2735 | struct nameidata nd; | 2746 | struct path path; |
2736 | 2747 | ||
2737 | from = getname(oldname); | 2748 | from = getname(oldname); |
2738 | if (IS_ERR(from)) | 2749 | if (IS_ERR(from)) |
2739 | return PTR_ERR(from); | 2750 | return PTR_ERR(from); |
2740 | 2751 | ||
2741 | error = user_path_parent(newdfd, newname, &nd, &to); | 2752 | dentry = user_path_create(newdfd, newname, &path, 0); |
2742 | if (error) | ||
2743 | goto out_putname; | ||
2744 | |||
2745 | dentry = lookup_create(&nd, 0); | ||
2746 | error = PTR_ERR(dentry); | 2753 | error = PTR_ERR(dentry); |
2747 | if (IS_ERR(dentry)) | 2754 | if (IS_ERR(dentry)) |
2748 | goto out_unlock; | 2755 | goto out_putname; |
2749 | 2756 | ||
2750 | error = mnt_want_write(nd.path.mnt); | 2757 | error = mnt_want_write(path.mnt); |
2751 | if (error) | 2758 | if (error) |
2752 | goto out_dput; | 2759 | goto out_dput; |
2753 | error = security_path_symlink(&nd.path, dentry, from); | 2760 | error = security_path_symlink(&path, dentry, from); |
2754 | if (error) | 2761 | if (error) |
2755 | goto out_drop_write; | 2762 | goto out_drop_write; |
2756 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); | 2763 | error = vfs_symlink(path.dentry->d_inode, dentry, from); |
2757 | out_drop_write: | 2764 | out_drop_write: |
2758 | mnt_drop_write(nd.path.mnt); | 2765 | mnt_drop_write(path.mnt); |
2759 | out_dput: | 2766 | out_dput: |
2760 | dput(dentry); | 2767 | dput(dentry); |
2761 | out_unlock: | 2768 | mutex_unlock(&path.dentry->d_inode->i_mutex); |
2762 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2769 | path_put(&path); |
2763 | path_put(&nd.path); | ||
2764 | putname(to); | ||
2765 | out_putname: | 2770 | out_putname: |
2766 | putname(from); | 2771 | putname(from); |
2767 | return error; | 2772 | return error; |
@@ -2826,11 +2831,9 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, | |||
2826 | int, newdfd, const char __user *, newname, int, flags) | 2831 | int, newdfd, const char __user *, newname, int, flags) |
2827 | { | 2832 | { |
2828 | struct dentry *new_dentry; | 2833 | struct dentry *new_dentry; |
2829 | struct nameidata nd; | 2834 | struct path old_path, new_path; |
2830 | struct path old_path; | ||
2831 | int how = 0; | 2835 | int how = 0; |
2832 | int error; | 2836 | int error; |
2833 | char *to; | ||
2834 | 2837 | ||
2835 | if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) | 2838 | if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) |
2836 | return -EINVAL; | 2839 | return -EINVAL; |
@@ -2852,32 +2855,27 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, | |||
2852 | if (error) | 2855 | if (error) |
2853 | return error; | 2856 | return error; |
2854 | 2857 | ||
2855 | error = user_path_parent(newdfd, newname, &nd, &to); | 2858 | new_dentry = user_path_create(newdfd, newname, &new_path, 0); |
2856 | if (error) | ||
2857 | goto out; | ||
2858 | error = -EXDEV; | ||
2859 | if (old_path.mnt != nd.path.mnt) | ||
2860 | goto out_release; | ||
2861 | new_dentry = lookup_create(&nd, 0); | ||
2862 | error = PTR_ERR(new_dentry); | 2859 | error = PTR_ERR(new_dentry); |
2863 | if (IS_ERR(new_dentry)) | 2860 | if (IS_ERR(new_dentry)) |
2864 | goto out_unlock; | 2861 | goto out; |
2865 | error = mnt_want_write(nd.path.mnt); | 2862 | |
2863 | error = -EXDEV; | ||
2864 | if (old_path.mnt != new_path.mnt) | ||
2865 | goto out_dput; | ||
2866 | error = mnt_want_write(new_path.mnt); | ||
2866 | if (error) | 2867 | if (error) |
2867 | goto out_dput; | 2868 | goto out_dput; |
2868 | error = security_path_link(old_path.dentry, &nd.path, new_dentry); | 2869 | error = security_path_link(old_path.dentry, &new_path, new_dentry); |
2869 | if (error) | 2870 | if (error) |
2870 | goto out_drop_write; | 2871 | goto out_drop_write; |
2871 | error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); | 2872 | error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry); |
2872 | out_drop_write: | 2873 | out_drop_write: |
2873 | mnt_drop_write(nd.path.mnt); | 2874 | mnt_drop_write(new_path.mnt); |
2874 | out_dput: | 2875 | out_dput: |
2875 | dput(new_dentry); | 2876 | dput(new_dentry); |
2876 | out_unlock: | 2877 | mutex_unlock(&new_path.dentry->d_inode->i_mutex); |
2877 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2878 | path_put(&new_path); |
2878 | out_release: | ||
2879 | path_put(&nd.path); | ||
2880 | putname(to); | ||
2881 | out: | 2879 | out: |
2882 | path_put(&old_path); | 2880 | path_put(&old_path); |
2883 | 2881 | ||
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index ebfd3825f12a..cf7823382664 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -4368,25 +4368,6 @@ static inline int ocfs2_may_create(struct inode *dir, struct dentry *child) | |||
4368 | return inode_permission(dir, MAY_WRITE | MAY_EXEC); | 4368 | return inode_permission(dir, MAY_WRITE | MAY_EXEC); |
4369 | } | 4369 | } |
4370 | 4370 | ||
4371 | /* copied from user_path_parent. */ | ||
4372 | static int ocfs2_user_path_parent(const char __user *path, | ||
4373 | struct nameidata *nd, char **name) | ||
4374 | { | ||
4375 | char *s = getname(path); | ||
4376 | int error; | ||
4377 | |||
4378 | if (IS_ERR(s)) | ||
4379 | return PTR_ERR(s); | ||
4380 | |||
4381 | error = kern_path_parent(s, nd); | ||
4382 | if (error) | ||
4383 | putname(s); | ||
4384 | else | ||
4385 | *name = s; | ||
4386 | |||
4387 | return error; | ||
4388 | } | ||
4389 | |||
4390 | /** | 4371 | /** |
4391 | * ocfs2_vfs_reflink - Create a reference-counted link | 4372 | * ocfs2_vfs_reflink - Create a reference-counted link |
4392 | * | 4373 | * |
@@ -4460,10 +4441,8 @@ int ocfs2_reflink_ioctl(struct inode *inode, | |||
4460 | bool preserve) | 4441 | bool preserve) |
4461 | { | 4442 | { |
4462 | struct dentry *new_dentry; | 4443 | struct dentry *new_dentry; |
4463 | struct nameidata nd; | 4444 | struct path old_path, new_path; |
4464 | struct path old_path; | ||
4465 | int error; | 4445 | int error; |
4466 | char *to = NULL; | ||
4467 | 4446 | ||
4468 | if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) | 4447 | if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) |
4469 | return -EOPNOTSUPP; | 4448 | return -EOPNOTSUPP; |
@@ -4474,39 +4453,33 @@ int ocfs2_reflink_ioctl(struct inode *inode, | |||
4474 | return error; | 4453 | return error; |
4475 | } | 4454 | } |
4476 | 4455 | ||
4477 | error = ocfs2_user_path_parent(newname, &nd, &to); | 4456 | new_dentry = user_path_create(AT_FDCWD, newname, &new_path, 0); |
4478 | if (error) { | 4457 | error = PTR_ERR(new_dentry); |
4458 | if (IS_ERR(new_dentry)) { | ||
4479 | mlog_errno(error); | 4459 | mlog_errno(error); |
4480 | goto out; | 4460 | goto out; |
4481 | } | 4461 | } |
4482 | 4462 | ||
4483 | error = -EXDEV; | 4463 | error = -EXDEV; |
4484 | if (old_path.mnt != nd.path.mnt) | 4464 | if (old_path.mnt != new_path.mnt) { |
4485 | goto out_release; | ||
4486 | new_dentry = lookup_create(&nd, 0); | ||
4487 | error = PTR_ERR(new_dentry); | ||
4488 | if (IS_ERR(new_dentry)) { | ||
4489 | mlog_errno(error); | 4465 | mlog_errno(error); |
4490 | goto out_unlock; | 4466 | goto out_dput; |
4491 | } | 4467 | } |
4492 | 4468 | ||
4493 | error = mnt_want_write(nd.path.mnt); | 4469 | error = mnt_want_write(new_path.mnt); |
4494 | if (error) { | 4470 | if (error) { |
4495 | mlog_errno(error); | 4471 | mlog_errno(error); |
4496 | goto out_dput; | 4472 | goto out_dput; |
4497 | } | 4473 | } |
4498 | 4474 | ||
4499 | error = ocfs2_vfs_reflink(old_path.dentry, | 4475 | error = ocfs2_vfs_reflink(old_path.dentry, |
4500 | nd.path.dentry->d_inode, | 4476 | new_path.dentry->d_inode, |
4501 | new_dentry, preserve); | 4477 | new_dentry, preserve); |
4502 | mnt_drop_write(nd.path.mnt); | 4478 | mnt_drop_write(new_path.mnt); |
4503 | out_dput: | 4479 | out_dput: |
4504 | dput(new_dentry); | 4480 | dput(new_dentry); |
4505 | out_unlock: | 4481 | mutex_unlock(&new_path.dentry->d_inode->i_mutex); |
4506 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 4482 | path_put(&new_path); |
4507 | out_release: | ||
4508 | path_put(&nd.path); | ||
4509 | putname(to); | ||
4510 | out: | 4483 | out: |
4511 | path_put(&old_path); | 4484 | path_put(&old_path); |
4512 | 4485 | ||
diff --git a/include/linux/namei.h b/include/linux/namei.h index 3439ab862e1d..b8cea804d31a 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h | |||
@@ -74,6 +74,8 @@ extern int user_path_at(int, const char __user *, unsigned, struct path *); | |||
74 | 74 | ||
75 | extern int kern_path(const char *, unsigned, struct path *); | 75 | extern int kern_path(const char *, unsigned, struct path *); |
76 | 76 | ||
77 | extern struct dentry *kern_path_create(int, const char *, struct path *, int); | ||
78 | extern struct dentry *user_path_create(int, const char __user *, struct path *, int); | ||
77 | extern int kern_path_parent(const char *, struct nameidata *); | 79 | extern int kern_path_parent(const char *, struct nameidata *); |
78 | extern int vfs_path_lookup(struct dentry *, struct vfsmount *, | 80 | extern int vfs_path_lookup(struct dentry *, struct vfsmount *, |
79 | const char *, unsigned int, struct nameidata *); | 81 | const char *, unsigned int, struct nameidata *); |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 0722a25a3a33..ec68e1c05b85 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -808,8 +808,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
808 | struct net *net = sock_net(sk); | 808 | struct net *net = sock_net(sk); |
809 | struct unix_sock *u = unix_sk(sk); | 809 | struct unix_sock *u = unix_sk(sk); |
810 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; | 810 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; |
811 | char *sun_path = sunaddr->sun_path; | ||
811 | struct dentry *dentry = NULL; | 812 | struct dentry *dentry = NULL; |
812 | struct nameidata nd; | 813 | struct path path; |
813 | int err; | 814 | int err; |
814 | unsigned hash; | 815 | unsigned hash; |
815 | struct unix_address *addr; | 816 | struct unix_address *addr; |
@@ -845,48 +846,44 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
845 | addr->hash = hash ^ sk->sk_type; | 846 | addr->hash = hash ^ sk->sk_type; |
846 | atomic_set(&addr->refcnt, 1); | 847 | atomic_set(&addr->refcnt, 1); |
847 | 848 | ||
848 | if (sunaddr->sun_path[0]) { | 849 | if (sun_path[0]) { |
849 | unsigned int mode; | 850 | unsigned int mode; |
850 | err = 0; | 851 | err = 0; |
851 | /* | 852 | /* |
852 | * Get the parent directory, calculate the hash for last | 853 | * Get the parent directory, calculate the hash for last |
853 | * component. | 854 | * component. |
854 | */ | 855 | */ |
855 | err = kern_path_parent(sunaddr->sun_path, &nd); | 856 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); |
856 | if (err) | ||
857 | goto out_mknod_parent; | ||
858 | |||
859 | dentry = lookup_create(&nd, 0); | ||
860 | err = PTR_ERR(dentry); | 857 | err = PTR_ERR(dentry); |
861 | if (IS_ERR(dentry)) | 858 | if (IS_ERR(dentry)) |
862 | goto out_mknod_unlock; | 859 | goto out_mknod_parent; |
863 | 860 | ||
864 | /* | 861 | /* |
865 | * All right, let's create it. | 862 | * All right, let's create it. |
866 | */ | 863 | */ |
867 | mode = S_IFSOCK | | 864 | mode = S_IFSOCK | |
868 | (SOCK_INODE(sock)->i_mode & ~current_umask()); | 865 | (SOCK_INODE(sock)->i_mode & ~current_umask()); |
869 | err = mnt_want_write(nd.path.mnt); | 866 | err = mnt_want_write(path.mnt); |
870 | if (err) | 867 | if (err) |
871 | goto out_mknod_dput; | 868 | goto out_mknod_dput; |
872 | err = security_path_mknod(&nd.path, dentry, mode, 0); | 869 | err = security_path_mknod(&path, dentry, mode, 0); |
873 | if (err) | 870 | if (err) |
874 | goto out_mknod_drop_write; | 871 | goto out_mknod_drop_write; |
875 | err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); | 872 | err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0); |
876 | out_mknod_drop_write: | 873 | out_mknod_drop_write: |
877 | mnt_drop_write(nd.path.mnt); | 874 | mnt_drop_write(path.mnt); |
878 | if (err) | 875 | if (err) |
879 | goto out_mknod_dput; | 876 | goto out_mknod_dput; |
880 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 877 | mutex_unlock(&path.dentry->d_inode->i_mutex); |
881 | dput(nd.path.dentry); | 878 | dput(path.dentry); |
882 | nd.path.dentry = dentry; | 879 | path.dentry = dentry; |
883 | 880 | ||
884 | addr->hash = UNIX_HASH_SIZE; | 881 | addr->hash = UNIX_HASH_SIZE; |
885 | } | 882 | } |
886 | 883 | ||
887 | spin_lock(&unix_table_lock); | 884 | spin_lock(&unix_table_lock); |
888 | 885 | ||
889 | if (!sunaddr->sun_path[0]) { | 886 | if (!sun_path[0]) { |
890 | err = -EADDRINUSE; | 887 | err = -EADDRINUSE; |
891 | if (__unix_find_socket_byname(net, sunaddr, addr_len, | 888 | if (__unix_find_socket_byname(net, sunaddr, addr_len, |
892 | sk->sk_type, hash)) { | 889 | sk->sk_type, hash)) { |
@@ -897,8 +894,8 @@ out_mknod_drop_write: | |||
897 | list = &unix_socket_table[addr->hash]; | 894 | list = &unix_socket_table[addr->hash]; |
898 | } else { | 895 | } else { |
899 | list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; | 896 | list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; |
900 | u->dentry = nd.path.dentry; | 897 | u->dentry = path.dentry; |
901 | u->mnt = nd.path.mnt; | 898 | u->mnt = path.mnt; |
902 | } | 899 | } |
903 | 900 | ||
904 | err = 0; | 901 | err = 0; |
@@ -915,9 +912,8 @@ out: | |||
915 | 912 | ||
916 | out_mknod_dput: | 913 | out_mknod_dput: |
917 | dput(dentry); | 914 | dput(dentry); |
918 | out_mknod_unlock: | 915 | mutex_unlock(&path.dentry->d_inode->i_mutex); |
919 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 916 | path_put(&path); |
920 | path_put(&nd.path); | ||
921 | out_mknod_parent: | 917 | out_mknod_parent: |
922 | if (err == -EEXIST) | 918 | if (err == -EEXIST) |
923 | err = -EADDRINUSE; | 919 | err = -EADDRINUSE; |