Hook NFS proxy together with BlueSky core.
[bluesky.git] / nfs3 / nfs3.c
index cbf5650..25552a7 100644 (file)
@@ -5,29 +5,46 @@
  */
 
 #include "nfs3_prot.h"
+#include "bluesky.h"
+
+extern BlueSkyFS *fs;
 
 static int null_int;
 static void *null_result = (void *)&null_int;
 
-void encode_fattr3(struct fattr3 *result, uint64_t inum)
+/* Look up a BlueSkyInode given an NFS filehandle.  Returns NULL if the
+ * filehandle is invalid. */
+BlueSkyInode *lookup_fh(nfs_fh3 *fh)
 {
-    result->type = NF3DIR;
-    result->mode = 0755;
-    result->nlink = 1;
-    result->uid = 0;
-    result->gid = 0;
-    result->size = 0;
+    BlueSkyInode *inode = NULL;
+    if (fh->data.data_len == 8) {
+        uint64_t inum = GUINT64_FROM_BE(*(uint64_t *)(fh->data.data_val));
+        inode = bluesky_get_inode(fs, inum);
+    }
+    return inode;
+}
+
+/* Copy inode attributes into NFS response.  The BlueSkyInode should be locked
+ * by the caller. */
+void encode_fattr3(struct fattr3 *result, BlueSkyInode *inode)
+{
+    result->type = inode->type;
+    result->mode = inode->mode;
+    result->nlink = inode->nlink;
+    result->uid = inode->uid;
+    result->gid = inode->gid;
+    result->size = inode->size;
     result->used = 0;
     result->rdev.major = 0;
     result->rdev.minor = 0;
     result->fsid = 0;
-    result->fileid = inum;
-    result->atime.seconds = 0;
-    result->atime.nseconds = 0;
-    result->mtime.seconds = 0;
-    result->mtime.nseconds = 0;
-    result->ctime.seconds = 0;
-    result->ctime.nseconds = 0;
+    result->fileid = inode->inum;
+    result->atime.seconds = inode->atime / 1000000;
+    result->atime.nseconds = (inode->atime % 1000000) * 1000;
+    result->mtime.seconds = inode->mtime / 1000000;
+    result->mtime.nseconds = (inode->mtime % 1000000) * 1000;
+    result->ctime.seconds = inode->ctime / 1000000;
+    result->ctime.nseconds = (inode->ctime % 1000000) * 1000;
 }
 
 void *
@@ -41,8 +58,13 @@ nfsproc3_getattr_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
 {
     static getattr3res result;
 
-    result.status = NFS3_OK;
-    encode_fattr3(&result.getattr3res_u.attributes, 1);
+    BlueSkyInode *inode = lookup_fh(argp);
+    if (inode != NULL) {
+        result.status = NFS3_OK;
+        encode_fattr3(&result.getattr3res_u.attributes, inode);
+    } else {
+        result.status = NFS3ERR_STALE;
+    }
 
     return &result;
 }
@@ -222,9 +244,10 @@ nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
 {
     static fsinfo3res result;
 
+    BlueSkyInode *inode = bluesky_get_inode(fs, 1);
     result.status = NFS3_OK;
     result.fsinfo3res_u.resok.obj_attributes.present = TRUE;
-    encode_fattr3(&result.fsinfo3res_u.resok.obj_attributes.post_op_attr_u.attributes, 1);
+    encode_fattr3(&result.fsinfo3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
     result.fsinfo3res_u.resok.rtmax = 32768;
     result.fsinfo3res_u.resok.rtpref = 32768;
     result.fsinfo3res_u.resok.rtmult = 4096;
@@ -246,9 +269,10 @@ nfsproc3_pathconf_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
 {
     static pathconf3res result;
 
+    BlueSkyInode *inode = bluesky_get_inode(fs, 1);
     result.status = NFS3_OK;
     result.pathconf3res_u.resok.obj_attributes.present = TRUE;
-    encode_fattr3(&result.pathconf3res_u.resok.obj_attributes.post_op_attr_u.attributes, 1);
+    encode_fattr3(&result.pathconf3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
     result.pathconf3res_u.resok.linkmax = 0xffffffff;
     result.pathconf3res_u.resok.name_max = 255;
     result.pathconf3res_u.resok.no_trunc = TRUE;