#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/xdr3.h>
+#include <linux/vserver/xid.h>
#define NFSDDBG_FACILITY NFSDDBG_XDR
*p++ = htonl(nfs3_ftypes[(stat.mode & S_IFMT) >> 12]);
*p++ = htonl((u32) stat.mode);
*p++ = htonl((u32) stat.nlink);
- *p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid));
- *p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid));
+ *p++ = htonl((u32) nfsd_ruid(rqstp,
+ XIDINO_UID(stat.uid, stat.xid)));
+ *p++ = htonl((u32) nfsd_rgid(rqstp,
+ XIDINO_GID(stat.gid, stat.xid)));
if (S_ISLNK(stat.mode) && stat.size > NFS3_MAXPATHLEN) {
p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
} else {
{
struct svc_export *exp;
struct dentry *dparent, *dchild;
+ int rv = 0;
dparent = cd->fh.fh_dentry;
exp = cd->fh.fh_export;
dchild = lookup_one_len(name, dparent, namlen);
if (IS_ERR(dchild))
return 1;
- if (d_mountpoint(dchild))
- return 1;
- if (fh_compose(fhp, exp, dchild, &cd->fh) != 0 || !dchild->d_inode)
- return 1;
- return 0;
+ if (d_mountpoint(dchild) ||
+ fh_compose(fhp, exp, dchild, &cd->fh) != 0 ||
+ !dchild->d_inode)
+ rv = 1;
+ dput(dchild);
+ return rv;
}
/*
int elen; /* estimated entry length in words */
int num_entry_words = 0; /* actual number of words */
- if (cd->offset)
- xdr_encode_hyper(cd->offset, (u64) offset);
+ if (cd->offset) {
+ u64 offset64 = offset;
+
+ if (unlikely(cd->offset1)) {
+ /* we ended up with offset on a page boundary */
+ *cd->offset = htonl(offset64 >> 32);
+ *cd->offset1 = htonl(offset64 & 0xffffffff);
+ cd->offset1 = NULL;
+ } else {
+ xdr_encode_hyper(cd->offset, (u64) offset);
+ }
+ }
/*
dprintk("encode_entry(%.*s @%ld%s)\n",
/* update offset */
cd->offset = cd->buffer + (cd->offset - tmp);
} else {
+ unsigned int offset_r = (cd->offset - tmp) << 2;
+
+ /* update pointer to offset location.
+ * This is a 64bit quantity, so we need to
+ * deal with 3 cases:
+ * - entirely in first page
+ * - entirely in second page
+ * - 4 bytes in each page
+ */
+ if (offset_r + 8 <= len1) {
+ cd->offset = p + (cd->offset - tmp);
+ } else if (offset_r >= len1) {
+ cd->offset -= len1 >> 2;
+ } else {
+ /* sitting on the fence */
+ BUG_ON(offset_r != len1 - 4);
+ cd->offset = p + (cd->offset - tmp);
+ cd->offset1 = tmp;
+ }
+
len2 = (num_entry_words << 2) - len1;
/* move from temp page to current and next pages */
memmove(p, tmp, len1);
memmove(tmp, (caddr_t)tmp+len1, len2);
- /* update offset */
- if (((cd->offset - tmp) << 2) <= len1)
- cd->offset = p + (cd->offset - tmp);
- else
- cd->offset -= len1 >> 2;
p = tmp + (len2 >> 2);
}
}