diff options
Diffstat (limited to 'fs/nfsd/nfs3xdr.c')
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 72 |
1 files changed, 34 insertions, 38 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 01d4ec1c88e0..f16184a39941 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -814,17 +814,6 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, | |||
814 | return p; | 814 | return p; |
815 | } | 815 | } |
816 | 816 | ||
817 | static __be32 * | ||
818 | encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, | ||
819 | struct svc_fh *fhp) | ||
820 | { | ||
821 | p = encode_post_op_attr(cd->rqstp, p, fhp); | ||
822 | *p++ = xdr_one; /* yes, a file handle follows */ | ||
823 | p = encode_fh(p, fhp); | ||
824 | fh_put(fhp); | ||
825 | return p; | ||
826 | } | ||
827 | |||
828 | static int | 817 | static int |
829 | compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, | 818 | compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, |
830 | const char *name, int namlen) | 819 | const char *name, int namlen) |
@@ -843,22 +832,46 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, | |||
843 | if (dchild == dparent) { | 832 | if (dchild == dparent) { |
844 | /* filesystem root - cannot return filehandle for ".." */ | 833 | /* filesystem root - cannot return filehandle for ".." */ |
845 | dput(dchild); | 834 | dput(dchild); |
846 | return 1; | 835 | return -ENOENT; |
847 | } | 836 | } |
848 | } else | 837 | } else |
849 | dchild = dget(dparent); | 838 | dchild = dget(dparent); |
850 | } else | 839 | } else |
851 | dchild = lookup_one_len(name, dparent, namlen); | 840 | dchild = lookup_one_len(name, dparent, namlen); |
852 | if (IS_ERR(dchild)) | 841 | if (IS_ERR(dchild)) |
853 | return 1; | 842 | return -ENOENT; |
854 | if (d_mountpoint(dchild) || | 843 | rv = -ENOENT; |
855 | fh_compose(fhp, exp, dchild, &cd->fh) != 0 || | 844 | if (d_mountpoint(dchild)) |
856 | !dchild->d_inode) | 845 | goto out; |
857 | rv = 1; | 846 | rv = fh_compose(fhp, exp, dchild, &cd->fh); |
847 | if (rv) | ||
848 | goto out; | ||
849 | if (!dchild->d_inode) | ||
850 | goto out; | ||
851 | rv = 0; | ||
852 | out: | ||
858 | dput(dchild); | 853 | dput(dchild); |
859 | return rv; | 854 | return rv; |
860 | } | 855 | } |
861 | 856 | ||
857 | __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) | ||
858 | { | ||
859 | struct svc_fh fh; | ||
860 | int err; | ||
861 | |||
862 | err = compose_entry_fh(cd, &fh, name, namlen); | ||
863 | if (err) { | ||
864 | *p++ = 0; | ||
865 | *p++ = 0; | ||
866 | return p; | ||
867 | } | ||
868 | p = encode_post_op_attr(cd->rqstp, p, &fh); | ||
869 | *p++ = xdr_one; /* yes, a file handle follows */ | ||
870 | p = encode_fh(p, &fh); | ||
871 | fh_put(&fh); | ||
872 | return p; | ||
873 | } | ||
874 | |||
862 | /* | 875 | /* |
863 | * Encode a directory entry. This one works for both normal readdir | 876 | * Encode a directory entry. This one works for both normal readdir |
864 | * and readdirplus. | 877 | * and readdirplus. |
@@ -929,16 +942,8 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen, | |||
929 | 942 | ||
930 | p = encode_entry_baggage(cd, p, name, namlen, ino); | 943 | p = encode_entry_baggage(cd, p, name, namlen, ino); |
931 | 944 | ||
932 | /* throw in readdirplus baggage */ | 945 | if (plus) |
933 | if (plus) { | 946 | p = encode_entryplus_baggage(cd, p, name, namlen); |
934 | struct svc_fh fh; | ||
935 | |||
936 | if (compose_entry_fh(cd, &fh, name, namlen) > 0) { | ||
937 | *p++ = 0; | ||
938 | *p++ = 0; | ||
939 | } else | ||
940 | p = encode_entryplus_baggage(cd, p, &fh); | ||
941 | } | ||
942 | num_entry_words = p - cd->buffer; | 947 | num_entry_words = p - cd->buffer; |
943 | } else if (cd->rqstp->rq_respages[pn+1] != NULL) { | 948 | } else if (cd->rqstp->rq_respages[pn+1] != NULL) { |
944 | /* temporarily encode entry into next page, then move back to | 949 | /* temporarily encode entry into next page, then move back to |
@@ -951,17 +956,8 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen, | |||
951 | 956 | ||
952 | p1 = encode_entry_baggage(cd, p1, name, namlen, ino); | 957 | p1 = encode_entry_baggage(cd, p1, name, namlen, ino); |
953 | 958 | ||
954 | /* throw in readdirplus baggage */ | 959 | if (plus) |
955 | if (plus) { | 960 | p = encode_entryplus_baggage(cd, p1, name, namlen); |
956 | struct svc_fh fh; | ||
957 | |||
958 | if (compose_entry_fh(cd, &fh, name, namlen) > 0) { | ||
959 | /* zero out the filehandle */ | ||
960 | *p1++ = 0; | ||
961 | *p1++ = 0; | ||
962 | } else | ||
963 | p1 = encode_entryplus_baggage(cd, p1, &fh); | ||
964 | } | ||
965 | 961 | ||
966 | /* determine entry word length and lengths to go in pages */ | 962 | /* determine entry word length and lengths to go in pages */ |
967 | num_entry_words = p1 - tmp; | 963 | num_entry_words = p1 - tmp; |