diff options
Diffstat (limited to 'fs/9p/vfs_inode.c')
| -rw-r--r-- | fs/9p/vfs_inode.c | 141 |
1 files changed, 97 insertions, 44 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index bdc64d1c22fb..68f02973c338 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -662,19 +662,21 @@ error: | |||
| 662 | */ | 662 | */ |
| 663 | 663 | ||
| 664 | static int | 664 | static int |
| 665 | v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode, | 665 | v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, |
| 666 | struct nameidata *nd) | 666 | struct nameidata *nd) |
| 667 | { | 667 | { |
| 668 | int err = 0; | 668 | int err = 0; |
| 669 | char *name = NULL; | 669 | char *name = NULL; |
| 670 | gid_t gid; | 670 | gid_t gid; |
| 671 | int flags; | 671 | int flags; |
| 672 | mode_t mode; | ||
| 672 | struct v9fs_session_info *v9ses; | 673 | struct v9fs_session_info *v9ses; |
| 673 | struct p9_fid *fid = NULL; | 674 | struct p9_fid *fid = NULL; |
| 674 | struct p9_fid *dfid, *ofid; | 675 | struct p9_fid *dfid, *ofid; |
| 675 | struct file *filp; | 676 | struct file *filp; |
| 676 | struct p9_qid qid; | 677 | struct p9_qid qid; |
| 677 | struct inode *inode; | 678 | struct inode *inode; |
| 679 | struct posix_acl *pacl = NULL, *dacl = NULL; | ||
| 678 | 680 | ||
| 679 | v9ses = v9fs_inode2v9ses(dir); | 681 | v9ses = v9fs_inode2v9ses(dir); |
| 680 | if (nd && nd->flags & LOOKUP_OPEN) | 682 | if (nd && nd->flags & LOOKUP_OPEN) |
| @@ -684,7 +686,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode, | |||
| 684 | 686 | ||
| 685 | name = (char *) dentry->d_name.name; | 687 | name = (char *) dentry->d_name.name; |
| 686 | P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x " | 688 | P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x " |
| 687 | "mode:0x%x\n", name, flags, mode); | 689 | "mode:0x%x\n", name, flags, omode); |
| 688 | 690 | ||
| 689 | dfid = v9fs_fid_lookup(dentry->d_parent); | 691 | dfid = v9fs_fid_lookup(dentry->d_parent); |
| 690 | if (IS_ERR(dfid)) { | 692 | if (IS_ERR(dfid)) { |
| @@ -702,6 +704,15 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode, | |||
| 702 | } | 704 | } |
| 703 | 705 | ||
| 704 | gid = v9fs_get_fsgid_for_create(dir); | 706 | gid = v9fs_get_fsgid_for_create(dir); |
| 707 | |||
| 708 | mode = omode; | ||
| 709 | /* Update mode based on ACL value */ | ||
| 710 | err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); | ||
| 711 | if (err) { | ||
| 712 | P9_DPRINTK(P9_DEBUG_VFS, | ||
| 713 | "Failed to get acl values in creat %d\n", err); | ||
| 714 | goto error; | ||
| 715 | } | ||
| 705 | err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid); | 716 | err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid); |
| 706 | if (err < 0) { | 717 | if (err < 0) { |
| 707 | P9_DPRINTK(P9_DEBUG_VFS, | 718 | P9_DPRINTK(P9_DEBUG_VFS, |
| @@ -709,42 +720,48 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode, | |||
| 709 | err); | 720 | err); |
| 710 | goto error; | 721 | goto error; |
| 711 | } | 722 | } |
| 723 | /* instantiate inode and assign the unopened fid to the dentry */ | ||
| 724 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE || | ||
| 725 | (nd && nd->flags & LOOKUP_OPEN)) { | ||
| 726 | fid = p9_client_walk(dfid, 1, &name, 1); | ||
| 727 | if (IS_ERR(fid)) { | ||
| 728 | err = PTR_ERR(fid); | ||
| 729 | P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", | ||
| 730 | err); | ||
| 731 | fid = NULL; | ||
| 732 | goto error; | ||
| 733 | } | ||
| 712 | 734 | ||
| 713 | /* No need to populate the inode if we are not opening the file AND | 735 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); |
| 714 | * not in cached mode. | 736 | if (IS_ERR(inode)) { |
| 715 | */ | 737 | err = PTR_ERR(inode); |
| 716 | if (!v9ses->cache && !(nd && nd->flags & LOOKUP_OPEN)) { | 738 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", |
| 717 | /* Not in cached mode. No need to populate inode with stat */ | 739 | err); |
| 718 | dentry->d_op = &v9fs_dentry_operations; | 740 | goto error; |
| 719 | p9_client_clunk(ofid); | 741 | } |
| 720 | d_instantiate(dentry, NULL); | ||
| 721 | return 0; | ||
| 722 | } | ||
| 723 | |||
| 724 | /* Now walk from the parent so we can get an unopened fid. */ | ||
| 725 | fid = p9_client_walk(dfid, 1, &name, 1); | ||
| 726 | if (IS_ERR(fid)) { | ||
| 727 | err = PTR_ERR(fid); | ||
| 728 | P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); | ||
| 729 | fid = NULL; | ||
| 730 | goto error; | ||
| 731 | } | ||
| 732 | |||
| 733 | /* instantiate inode and assign the unopened fid to dentry */ | ||
| 734 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); | ||
| 735 | if (IS_ERR(inode)) { | ||
| 736 | err = PTR_ERR(inode); | ||
| 737 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); | ||
| 738 | goto error; | ||
| 739 | } | ||
| 740 | if (v9ses->cache) | ||
| 741 | dentry->d_op = &v9fs_cached_dentry_operations; | 742 | dentry->d_op = &v9fs_cached_dentry_operations; |
| 742 | else | 743 | d_instantiate(dentry, inode); |
| 744 | err = v9fs_fid_add(dentry, fid); | ||
| 745 | if (err < 0) | ||
| 746 | goto error; | ||
| 747 | /* The fid would get clunked via a dput */ | ||
| 748 | fid = NULL; | ||
| 749 | } else { | ||
| 750 | /* | ||
| 751 | * Not in cached mode. No need to populate | ||
| 752 | * inode with stat. We need to get an inode | ||
| 753 | * so that we can set the acl with dentry | ||
| 754 | */ | ||
| 755 | inode = v9fs_get_inode(dir->i_sb, mode); | ||
| 756 | if (IS_ERR(inode)) { | ||
| 757 | err = PTR_ERR(inode); | ||
| 758 | goto error; | ||
| 759 | } | ||
| 743 | dentry->d_op = &v9fs_dentry_operations; | 760 | dentry->d_op = &v9fs_dentry_operations; |
| 744 | d_instantiate(dentry, inode); | 761 | d_instantiate(dentry, inode); |
| 745 | err = v9fs_fid_add(dentry, fid); | 762 | } |
| 746 | if (err < 0) | 763 | /* Now set the ACL based on the default value */ |
| 747 | goto error; | 764 | v9fs_set_create_acl(dentry, dacl, pacl); |
| 748 | 765 | ||
| 749 | /* if we are opening a file, assign the open fid to the file */ | 766 | /* if we are opening a file, assign the open fid to the file */ |
| 750 | if (nd && nd->flags & LOOKUP_OPEN) { | 767 | if (nd && nd->flags & LOOKUP_OPEN) { |
| @@ -866,25 +883,28 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 866 | * | 883 | * |
| 867 | */ | 884 | */ |
| 868 | 885 | ||
| 869 | static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry, | 886 | static int v9fs_vfs_mkdir_dotl(struct inode *dir, |
| 870 | int mode) | 887 | struct dentry *dentry, int omode) |
| 871 | { | 888 | { |
| 872 | int err; | 889 | int err; |
| 873 | struct v9fs_session_info *v9ses; | 890 | struct v9fs_session_info *v9ses; |
| 874 | struct p9_fid *fid = NULL, *dfid = NULL; | 891 | struct p9_fid *fid = NULL, *dfid = NULL; |
| 875 | gid_t gid; | 892 | gid_t gid; |
| 876 | char *name; | 893 | char *name; |
| 894 | mode_t mode; | ||
| 877 | struct inode *inode; | 895 | struct inode *inode; |
| 878 | struct p9_qid qid; | 896 | struct p9_qid qid; |
| 879 | struct dentry *dir_dentry; | 897 | struct dentry *dir_dentry; |
| 898 | struct posix_acl *dacl = NULL, *pacl = NULL; | ||
| 880 | 899 | ||
| 881 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | 900 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); |
| 882 | err = 0; | 901 | err = 0; |
| 883 | v9ses = v9fs_inode2v9ses(dir); | 902 | v9ses = v9fs_inode2v9ses(dir); |
| 884 | 903 | ||
| 885 | mode |= S_IFDIR; | 904 | omode |= S_IFDIR; |
| 886 | if (dir->i_mode & S_ISGID) | 905 | if (dir->i_mode & S_ISGID) |
| 887 | mode |= S_ISGID; | 906 | omode |= S_ISGID; |
| 907 | |||
| 888 | dir_dentry = v9fs_dentry_from_dir_inode(dir); | 908 | dir_dentry = v9fs_dentry_from_dir_inode(dir); |
| 889 | dfid = v9fs_fid_lookup(dir_dentry); | 909 | dfid = v9fs_fid_lookup(dir_dentry); |
| 890 | if (IS_ERR(dfid)) { | 910 | if (IS_ERR(dfid)) { |
| @@ -895,7 +915,14 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry, | |||
| 895 | } | 915 | } |
| 896 | 916 | ||
| 897 | gid = v9fs_get_fsgid_for_create(dir); | 917 | gid = v9fs_get_fsgid_for_create(dir); |
| 898 | 918 | mode = omode; | |
| 919 | /* Update mode based on ACL value */ | ||
| 920 | err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); | ||
| 921 | if (err) { | ||
| 922 | P9_DPRINTK(P9_DEBUG_VFS, | ||
| 923 | "Failed to get acl values in mkdir %d\n", err); | ||
| 924 | goto error; | ||
| 925 | } | ||
| 899 | name = (char *) dentry->d_name.name; | 926 | name = (char *) dentry->d_name.name; |
| 900 | err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid); | 927 | err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid); |
| 901 | if (err < 0) | 928 | if (err < 0) |
| @@ -925,7 +952,23 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry, | |||
| 925 | if (err < 0) | 952 | if (err < 0) |
| 926 | goto error; | 953 | goto error; |
| 927 | fid = NULL; | 954 | fid = NULL; |
| 955 | } else { | ||
| 956 | /* | ||
| 957 | * Not in cached mode. No need to populate | ||
| 958 | * inode with stat. We need to get an inode | ||
| 959 | * so that we can set the acl with dentry | ||
| 960 | */ | ||
| 961 | inode = v9fs_get_inode(dir->i_sb, mode); | ||
| 962 | if (IS_ERR(inode)) { | ||
| 963 | err = PTR_ERR(inode); | ||
| 964 | goto error; | ||
| 965 | } | ||
| 966 | dentry->d_op = &v9fs_dentry_operations; | ||
| 967 | d_instantiate(dentry, inode); | ||
| 928 | } | 968 | } |
| 969 | /* Now set the ACL based on the default value */ | ||
| 970 | v9fs_set_create_acl(dentry, dacl, pacl); | ||
| 971 | |||
| 929 | error: | 972 | error: |
| 930 | if (fid) | 973 | if (fid) |
| 931 | p9_client_clunk(fid); | 974 | p9_client_clunk(fid); |
| @@ -1861,21 +1904,23 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
| 1861 | * | 1904 | * |
| 1862 | */ | 1905 | */ |
| 1863 | static int | 1906 | static int |
| 1864 | v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode, | 1907 | v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode, |
| 1865 | dev_t rdev) | 1908 | dev_t rdev) |
| 1866 | { | 1909 | { |
| 1867 | int err; | 1910 | int err; |
| 1868 | char *name; | 1911 | char *name; |
| 1912 | mode_t mode; | ||
| 1869 | struct v9fs_session_info *v9ses; | 1913 | struct v9fs_session_info *v9ses; |
| 1870 | struct p9_fid *fid = NULL, *dfid = NULL; | 1914 | struct p9_fid *fid = NULL, *dfid = NULL; |
| 1871 | struct inode *inode; | 1915 | struct inode *inode; |
| 1872 | gid_t gid; | 1916 | gid_t gid; |
| 1873 | struct p9_qid qid; | 1917 | struct p9_qid qid; |
| 1874 | struct dentry *dir_dentry; | 1918 | struct dentry *dir_dentry; |
| 1919 | struct posix_acl *dacl = NULL, *pacl = NULL; | ||
| 1875 | 1920 | ||
| 1876 | P9_DPRINTK(P9_DEBUG_VFS, | 1921 | P9_DPRINTK(P9_DEBUG_VFS, |
| 1877 | " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, | 1922 | " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, |
| 1878 | dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); | 1923 | dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev)); |
| 1879 | 1924 | ||
| 1880 | if (!new_valid_dev(rdev)) | 1925 | if (!new_valid_dev(rdev)) |
| 1881 | return -EINVAL; | 1926 | return -EINVAL; |
| @@ -1891,7 +1936,14 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode, | |||
| 1891 | } | 1936 | } |
| 1892 | 1937 | ||
| 1893 | gid = v9fs_get_fsgid_for_create(dir); | 1938 | gid = v9fs_get_fsgid_for_create(dir); |
| 1894 | 1939 | mode = omode; | |
| 1940 | /* Update mode based on ACL value */ | ||
| 1941 | err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); | ||
| 1942 | if (err) { | ||
| 1943 | P9_DPRINTK(P9_DEBUG_VFS, | ||
| 1944 | "Failed to get acl values in mknod %d\n", err); | ||
| 1945 | goto error; | ||
| 1946 | } | ||
| 1895 | name = (char *) dentry->d_name.name; | 1947 | name = (char *) dentry->d_name.name; |
| 1896 | 1948 | ||
| 1897 | err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid); | 1949 | err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid); |
| @@ -1935,7 +1987,8 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode, | |||
| 1935 | dentry->d_op = &v9fs_dentry_operations; | 1987 | dentry->d_op = &v9fs_dentry_operations; |
| 1936 | d_instantiate(dentry, inode); | 1988 | d_instantiate(dentry, inode); |
| 1937 | } | 1989 | } |
| 1938 | 1990 | /* Now set the ACL based on the default value */ | |
| 1991 | v9fs_set_create_acl(dentry, dacl, pacl); | ||
| 1939 | error: | 1992 | error: |
| 1940 | if (fid) | 1993 | if (fid) |
| 1941 | p9_client_clunk(fid); | 1994 | p9_client_clunk(fid); |
