*/
#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 *
{
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;
}
{
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;
{
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;