|
@@ -88,46 +88,6 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
|
|
|
}
|
|
|
|
|
|
|
|
|
-/*
|
|
|
- * Common NFS XDR functions as inlines
|
|
|
- */
|
|
|
-static inline __be32*
|
|
|
-xdr_decode_time(__be32 *p, struct timespec *timep)
|
|
|
-{
|
|
|
- timep->tv_sec = ntohl(*p++);
|
|
|
- /* Convert microseconds into nanoseconds */
|
|
|
- timep->tv_nsec = ntohl(*p++) * 1000;
|
|
|
- return p;
|
|
|
-}
|
|
|
-
|
|
|
-static __be32 *
|
|
|
-xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
|
|
|
-{
|
|
|
- u32 rdev, type;
|
|
|
- type = ntohl(*p++);
|
|
|
- fattr->mode = ntohl(*p++);
|
|
|
- fattr->nlink = ntohl(*p++);
|
|
|
- fattr->uid = ntohl(*p++);
|
|
|
- fattr->gid = ntohl(*p++);
|
|
|
- fattr->size = ntohl(*p++);
|
|
|
- fattr->du.nfs2.blocksize = ntohl(*p++);
|
|
|
- rdev = ntohl(*p++);
|
|
|
- fattr->du.nfs2.blocks = ntohl(*p++);
|
|
|
- fattr->fsid.major = ntohl(*p++);
|
|
|
- fattr->fsid.minor = 0;
|
|
|
- fattr->fileid = ntohl(*p++);
|
|
|
- p = xdr_decode_time(p, &fattr->atime);
|
|
|
- p = xdr_decode_time(p, &fattr->mtime);
|
|
|
- p = xdr_decode_time(p, &fattr->ctime);
|
|
|
- fattr->valid |= NFS_ATTR_FATTR_V2;
|
|
|
- fattr->rdev = new_decode_dev(rdev);
|
|
|
- if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
|
|
|
- fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
|
|
|
- fattr->rdev = 0;
|
|
|
- }
|
|
|
- return p;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Encode/decode NFSv2 basic data types
|
|
|
*
|
|
@@ -207,6 +167,27 @@ out_overflow:
|
|
|
return -EIO;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * 2.3.2. ftype
|
|
|
+ *
|
|
|
+ * enum ftype {
|
|
|
+ * NFNON = 0,
|
|
|
+ * NFREG = 1,
|
|
|
+ * NFDIR = 2,
|
|
|
+ * NFBLK = 3,
|
|
|
+ * NFCHR = 4,
|
|
|
+ * NFLNK = 5
|
|
|
+ * };
|
|
|
+ *
|
|
|
+ */
|
|
|
+static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
|
|
|
+{
|
|
|
+ *type = be32_to_cpup(p++);
|
|
|
+ if (unlikely(*type > NF2FIFO))
|
|
|
+ *type = NFBAD;
|
|
|
+ return p;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* 2.3.3. fhandle
|
|
|
*
|
|
@@ -269,6 +250,13 @@ static __be32 *xdr_encode_current_server_time(__be32 *p,
|
|
|
return p;
|
|
|
}
|
|
|
|
|
|
+static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
|
|
|
+{
|
|
|
+ timep->tv_sec = be32_to_cpup(p++);
|
|
|
+ timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
|
|
|
+ return p;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* 2.3.5. fattr
|
|
|
*
|
|
@@ -292,12 +280,39 @@ static __be32 *xdr_encode_current_server_time(__be32 *p,
|
|
|
*/
|
|
|
static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
|
|
|
{
|
|
|
+ u32 rdev, type;
|
|
|
__be32 *p;
|
|
|
|
|
|
p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
|
|
|
if (unlikely(p == NULL))
|
|
|
goto out_overflow;
|
|
|
- xdr_decode_fattr(p, fattr);
|
|
|
+
|
|
|
+ fattr->valid |= NFS_ATTR_FATTR_V2;
|
|
|
+
|
|
|
+ p = xdr_decode_ftype(p, &type);
|
|
|
+
|
|
|
+ fattr->mode = be32_to_cpup(p++);
|
|
|
+ fattr->nlink = be32_to_cpup(p++);
|
|
|
+ fattr->uid = be32_to_cpup(p++);
|
|
|
+ fattr->gid = be32_to_cpup(p++);
|
|
|
+ fattr->size = be32_to_cpup(p++);
|
|
|
+ fattr->du.nfs2.blocksize = be32_to_cpup(p++);
|
|
|
+
|
|
|
+ rdev = be32_to_cpup(p++);
|
|
|
+ fattr->rdev = new_decode_dev(rdev);
|
|
|
+ if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
|
|
|
+ fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
|
|
|
+ fattr->rdev = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ fattr->du.nfs2.blocks = be32_to_cpup(p++);
|
|
|
+ fattr->fsid.major = be32_to_cpup(p++);
|
|
|
+ fattr->fsid.minor = 0;
|
|
|
+ fattr->fileid = be32_to_cpup(p++);
|
|
|
+
|
|
|
+ p = xdr_decode_time(p, &fattr->atime);
|
|
|
+ p = xdr_decode_time(p, &fattr->mtime);
|
|
|
+ xdr_decode_time(p, &fattr->ctime);
|
|
|
return 0;
|
|
|
out_overflow:
|
|
|
print_overflow_msg(__func__, xdr);
|