return p;
}
-char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
+static int
+defer_free(struct nfsd4_compoundargs *argp,
+ void (*release)(const void *), void *p)
{
struct tmpbuf *tb;
+
+ tb = kmalloc(sizeof(*tb), GFP_KERNEL);
+ if (!tb)
+ return -ENOMEM;
+ tb->buf = p;
+ tb->release = release;
+ tb->next = argp->to_free;
+ argp->to_free = tb;
+ return 0;
+}
+
+char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
+{
+ void *new = NULL;
if (p == argp->tmp) {
- p = kmalloc(nbytes, GFP_KERNEL);
- if (!p) return NULL;
+ new = kmalloc(nbytes, GFP_KERNEL);
+ if (!new) return NULL;
+ p = new;
memcpy(p, argp->tmp, nbytes);
} else {
if (p != argp->tmpp)
BUG();
argp->tmpp = NULL;
}
- tb = kmalloc(sizeof(*tb), GFP_KERNEL);
- if (!tb) {
- kfree(p);
+ if (defer_free(argp, kfree, p)) {
+ kfree(new);
return NULL;
- }
- tb->buf = p;
- tb->next = argp->to_free;
- argp->to_free = tb;
- return (char*)p;
+ } else
+ return (char *)p;
}
NF4SOCK, NF4BAD, NF4LNK, NF4BAD,
};
-static inline int
-xdr_padding(int l)
-{
- return 3 - ((l - 1) & 3); /* smallest i>=0 such that (l+i)%4 = 0 */
-}
-
static int
nfsd4_encode_name(struct svc_rqst *rqstp, int group, uid_t id,
u32 **p, int *buflen)
{
int status;
- u32 len;
if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
return nfserr_resource;
status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
if (status < 0)
return nfserrno(status);
- len = (unsigned)status;
- *(*p)++ = htonl(len);
- memset((u8 *)*p + len, 0, xdr_padding(len));
- *p += XDR_QUADLEN(len);
- *buflen -= (XDR_QUADLEN(len) << 2) + 4;
+ *p = xdr_encode_opaque(*p, NULL, status);
+ *buflen -= (XDR_QUADLEN(status) << 2) + 4;
BUG_ON(*buflen < 0);
return 0;
}
}
if (bmval1 & FATTR4_WORD1_OWNER) {
status = nfsd4_encode_user(rqstp,
- XIDINO_UID(stat.uid, stat.xid), &p, &buflen);
+ XIDINO_UID(XID_TAG(dentry->d_inode),
+ stat.uid, stat.xid), &p, &buflen);
if (status == nfserr_resource)
goto out_resource;
if (status)
}
if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
status = nfsd4_encode_group(rqstp,
- XIDINO_GID(stat.gid, stat.xid), &p, &buflen);
+ XIDINO_GID(XID_TAG(dentry->d_inode),
+ stat.gid, stat.xid), &p, &buflen);
if (status == nfserr_resource)
goto out_resource;
if (status)
return xdr_ressize_check(rqstp, p);
}
+void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
+{
+ if (args->ops != args->iops) {
+ kfree(args->ops);
+ args->ops = args->iops;
+ }
+ if (args->tmpp) {
+ kfree(args->tmpp);
+ args->tmpp = NULL;
+ }
+ while (args->to_free) {
+ struct tmpbuf *tb = args->to_free;
+ args->to_free = tb->next;
+ tb->release(tb->buf);
+ kfree(tb);
+ }
+}
+
int
nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundargs *args)
{
status = nfsd4_decode_compound(args);
if (status) {
- if (args->ops != args->iops) {
- kfree(args->ops);
- args->ops = args->iops;
- }
- if (args->tmpp) {
- kfree(args->tmpp);
- args->tmpp = NULL;
- }
- while (args->to_free) {
- struct tmpbuf *tb = args->to_free;
- args->to_free = tb->next;
- kfree(tb->buf);
- kfree(tb);
- }
+ nfsd4_release_compoundargs(args);
}
return !status;
}
/*
* All that remains is to write the tag and operation count...
*/
- struct iovec *iov;
+ struct kvec *iov;
p = resp->tagp;
*p++ = htonl(resp->taglen);
memcpy(p, resp->tag, resp->taglen);