aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs3xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs3xdr.c')
-rw-r--r--fs/nfsd/nfs3xdr.c72
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
817static __be32 *
818encode_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
828static int 817static int
829compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, 818compose_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;
852out:
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;