2 * This is sample code generated by rpcgen.
3 * These are only templates and you can use them
4 * as a guideline for developing your own functions.
13 static void *null_result = (void *)&null_int;
15 /* Check that a string is a valid file name. We require that it be valid
16 * UTF-8, that it not be empty, and that it not contain embedded forward
17 * slashes. Also checks that the length of the string is not more than the
18 * maximum allowed length. This function does allow the names "." and "..".
19 * Returns TRUE if the string is allowed as a filename. */
20 gboolean validate_filename(const char *filename)
22 if (filename == NULL || filename[0] == '\0')
24 if (strlen(filename) > 255)
26 if (!g_utf8_validate(filename, -1, NULL))
28 if (strchr(filename, '/') != NULL)
33 /* Look up a BlueSkyInode given an NFS filehandle. Returns NULL if the
34 * filehandle is invalid. */
35 BlueSkyInode *lookup_fh(nfs_fh3 *fh)
37 BlueSkyInode *inode = NULL;
38 if (fh->data.data_len == 8) {
39 uint64_t inum = GUINT64_FROM_BE(*(uint64_t *)(fh->data.data_val));
40 inode = bluesky_get_inode(fs, inum);
45 int64_t decode_nfstime3(nfstime3 *time)
47 int64_t result = (int64_t)time->seconds * 1000000;
48 result += time->nseconds / 1000;
52 void set_attributes(BlueSkyInode *inode, sattr3 *attributes)
54 int64_t now = bluesky_get_current_time();
56 if (attributes->mode.set) {
57 inode->mode = attributes->mode.set_uint32_u.val;
60 if (attributes->uid.set) {
61 inode->uid = attributes->uid.set_uint32_u.val;
64 if (attributes->gid.set) {
65 inode->gid = attributes->gid.set_uint32_u.val;
68 if (attributes->size.set) {
69 if (inode->type == BLUESKY_REGULAR) {
70 bluesky_file_truncate(inode, attributes->size.set_uint64_u.val);
75 switch (attributes->atime.set) {
78 case SET_TO_SERVER_TIME:
81 case SET_TO_CLIENT_TIME:
82 inode->atime = decode_nfstime3(&attributes->atime.set_time_u.time);
86 switch (attributes->mtime.set) {
89 case SET_TO_SERVER_TIME:
92 case SET_TO_CLIENT_TIME:
93 inode->mtime = decode_nfstime3(&attributes->mtime.set_time_u.time);
98 inode->change_count++;
101 /* Copy inode attributes into NFS response. The BlueSkyInode should be locked
103 void encode_fattr3(struct fattr3 *result, BlueSkyInode *inode)
105 result->type = inode->type;
106 result->mode = inode->mode;
107 result->nlink = inode->nlink;
108 result->uid = inode->uid;
109 result->gid = inode->gid;
110 result->size = inode->size;
112 result->rdev.major = 0;
113 result->rdev.minor = 0;
115 result->fileid = inode->inum;
116 result->atime.seconds = inode->atime / 1000000;
117 result->atime.nseconds = (inode->atime % 1000000) * 1000;
118 result->mtime.seconds = inode->mtime / 1000000;
119 result->mtime.nseconds = (inode->mtime % 1000000) * 1000;
120 result->ctime.seconds = inode->ctime / 1000000;
121 result->ctime.nseconds = (inode->ctime % 1000000) * 1000;
123 switch (inode->type) {
124 case BLUESKY_SYMLINK:
125 result->size = strlen(inode->symlink_contents);
132 void encode_pre_wcc(struct wcc_data *wcc, BlueSkyInode *inode)
134 wcc->before.present = TRUE;
135 wcc->before.pre_op_attr_u.attributes.size = inode->size;
136 wcc->before.pre_op_attr_u.attributes.mtime.seconds = inode->mtime / 1000000;
137 wcc->before.pre_op_attr_u.attributes.mtime.nseconds = (inode->mtime % 1000000) * 1000;
138 wcc->before.pre_op_attr_u.attributes.ctime.seconds = inode->ctime / 1000000;
139 wcc->before.pre_op_attr_u.attributes.ctime.nseconds = (inode->ctime % 1000000) * 1000;
143 nfsproc3_null_3_svc(void *argp, struct svc_req *rqstp)
149 nfsproc3_getattr_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
151 static getattr3res result;
153 BlueSkyInode *inode = lookup_fh(argp);
155 result.status = NFS3_OK;
156 encode_fattr3(&result.getattr3res_u.attributes, inode);
158 result.status = NFS3ERR_STALE;
165 nfsproc3_setattr_3_svc(setattr3args *argp, struct svc_req *rqstp)
167 static wccstat3 result;
169 result.wccstat3_u.wcc.before.present = FALSE;
170 result.wccstat3_u.wcc.after.present = FALSE;
171 BlueSkyInode *inode = lookup_fh(&argp->object);
173 result.status = NFS3ERR_STALE;
177 encode_pre_wcc(&result.wccstat3_u.wcc, inode);
178 if (argp->guard.check) {
179 if (inode->ctime != decode_nfstime3(&argp->guard.sattrguard3_u.ctime)) {
180 result.status = NFS3ERR_NOT_SYNC;
181 result.wccstat3_u.wcc.after.present = TRUE;
182 encode_fattr3(&result.wccstat3_u.wcc.after.post_op_attr_u.attributes, inode);
187 set_attributes(inode, &argp->new_attributes);
189 result.wccstat3_u.wcc.after.present = TRUE;
190 encode_fattr3(&result.wccstat3_u.wcc.after.post_op_attr_u.attributes,
192 result.status = NFS3_OK;
198 nfsproc3_lookup_3_svc(diropargs3 *argp, struct svc_req *rqstp)
200 static lookup3res result;
202 BlueSkyInode *dir = lookup_fh(&argp->dir);
204 result.status = NFS3ERR_STALE;
205 result.lookup3res_u.resfail.present = FALSE;
209 result.lookup3res_u.resfail.present = TRUE;
210 encode_fattr3(&result.lookup3res_u.resfail.post_op_attr_u.attributes, dir);
211 if (!validate_filename(argp->name)) {
212 if (strlen(argp->name) > 255)
213 result.status = NFS3ERR_NAMETOOLONG;
215 result.status = NFS3ERR_NOENT;
219 /* TODO: Special-case "." and "..". */
220 uint64_t inum = bluesky_directory_lookup(dir, argp->name);
222 result.status = NFS3ERR_NOENT;
225 BlueSkyInode *inode = bluesky_get_inode(fs, inum);
227 result.status = NFS3ERR_NOENT;
231 result.status = NFS3_OK;
232 result.lookup3res_u.resok.dir_attributes.present = TRUE;
233 encode_fattr3(&result.lookup3res_u.resok.dir_attributes.post_op_attr_u.attributes, dir);
234 result.lookup3res_u.resok.obj_attributes.present = TRUE;
235 encode_fattr3(&result.lookup3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
237 static uint64_t fh_bytes;
238 fh_bytes = GUINT64_TO_BE(inum);
239 result.lookup3res_u.resok.object.data.data_len = 8;
240 result.lookup3res_u.resok.object.data.data_val = (char *)&fh_bytes;
246 nfsproc3_access_3_svc(access3args *argp, struct svc_req *rqstp)
248 static access3res result;
250 BlueSkyInode *inode = lookup_fh(&argp->object);
252 result.status = NFS3ERR_STALE;
253 result.access3res_u.resfail.present = FALSE;
257 result.status = NFS3_OK;
258 result.access3res_u.resok.obj_attributes.present = TRUE;
259 encode_fattr3(&result.access3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
260 result.access3res_u.resok.access = argp->access;
266 nfsproc3_readlink_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
268 static readlink3res result;
269 memset(&result, 0, sizeof(result));
271 BlueSkyInode *inode = lookup_fh(argp);
273 if (inode->type == BLUESKY_SYMLINK) {
274 result.status = NFS3_OK;
275 result.readlink3res_u.resok.symlink_attributes.present = TRUE;
276 encode_fattr3(&result.readlink3res_u.resok.symlink_attributes.post_op_attr_u.attributes, inode);
277 result.readlink3res_u.resok.data = inode->symlink_contents;
279 result.status = NFS3ERR_INVAL;
280 result.readlink3res_u.resfail.present = TRUE;
281 encode_fattr3(&result.readlink3res_u.resfail.post_op_attr_u.attributes, inode);
284 result.status = NFS3ERR_STALE;
291 nfsproc3_read_3_svc(read3args *argp, struct svc_req *rqstp)
293 static read3res result;
294 static char buf[32768];
296 BlueSkyInode *inode = lookup_fh(&argp->file);
298 result.status = NFS3ERR_STALE;
299 result.read3res_u.resfail.present = FALSE;
303 int count = argp->count;
304 if (argp->offset >= inode->size) {
306 result.read3res_u.resok.eof = TRUE;
308 count = MIN(count, inode->size - argp->offset);
309 if (argp->offset + count == inode->size)
310 result.read3res_u.resok.eof = TRUE;
312 result.read3res_u.resok.eof = FALSE;
314 bluesky_file_read(inode, argp->offset, buf, count);
317 result.status = NFS3_OK;
318 result.read3res_u.resok.file_attributes.present = TRUE;
319 encode_fattr3(&result.read3res_u.resok.file_attributes.post_op_attr_u.attributes, inode);
320 result.read3res_u.resok.count = count;
321 result.read3res_u.resok.data.data_val = buf;
322 result.read3res_u.resok.data.data_len = count;
328 nfsproc3_write_3_svc(write3args *argp, struct svc_req *rqstp)
330 static write3res result;
332 memset(&wcc, 0, sizeof(wcc));
334 BlueSkyInode *inode = lookup_fh(&argp->file);
336 result.status = NFS3ERR_STALE;
337 result.write3res_u.resfail = wcc;
341 encode_pre_wcc(&wcc, inode);
342 if (inode->type != BLUESKY_REGULAR) {
343 result.status = NFS3ERR_INVAL;
344 result.write3res_u.resfail = wcc;
348 uint64_t lastbyte = argp->offset + argp->count;
349 if (lastbyte > inode->size) {
350 bluesky_file_truncate(inode, lastbyte);
353 if (argp->data.data_len < argp->count) {
356 bluesky_file_write(inode, argp->offset,
357 argp->data.data_val, argp->count);
360 wcc.after.present = TRUE;
361 encode_fattr3(&wcc.after.post_op_attr_u.attributes, inode);
362 result.write3res_u.resok.file_wcc = wcc;
363 result.write3res_u.resok.count = argp->count;
364 result.write3res_u.resok.committed = FILE_SYNC;
370 nfsproc3_create_3_svc(create3args *argp, struct svc_req *rqstp)
372 static diropres3 result;
374 memset(&wcc, 0, sizeof(wcc));
376 BlueSkyInode *dir = lookup_fh(&argp->where.dir);
378 result.status = NFS3ERR_STALE;
379 result.diropres3_u.resfail = wcc;
383 encode_pre_wcc(&wcc, dir);
384 if (dir->type != BLUESKY_DIRECTORY) {
385 result.status = NFS3ERR_NOTDIR;
386 result.diropres3_u.resfail = wcc;
390 if (!validate_filename(argp->where.name)
391 || strcmp(argp->where.name, ".") == 0
392 || strcmp(argp->where.name, "..") == 0)
394 result.status = NFS3ERR_EXIST;
395 result.diropres3_u.resfail = wcc;
400 file = bluesky_new_inode(bluesky_fs_alloc_inode(fs), fs, BLUESKY_REGULAR);
403 int64_t time = bluesky_get_current_time();
404 printf("time: %"PRIi64"\n", time);
409 bluesky_insert_inode(fs, file);
410 bluesky_directory_insert(dir, argp->where.name, file->inum);
412 dir->mtime = dir->ctime = bluesky_get_current_time();
415 wcc.after.present = TRUE;
416 encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir);
417 result.diropres3_u.resok.obj_attributes.present = TRUE;
418 encode_fattr3(&result.diropres3_u.resok.obj_attributes.post_op_attr_u.attributes, file);
419 result.diropres3_u.resok.dir_wcc = wcc;
421 static uint64_t fh_bytes;
422 fh_bytes = GUINT64_TO_BE(file->inum);
423 result.diropres3_u.resok.obj.present = TRUE;
424 result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_len = 8;
425 result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_val = (char *)&fh_bytes;
431 nfsproc3_mkdir_3_svc(mkdir3args *argp, struct svc_req *rqstp)
433 static diropres3 result;
435 memset(&wcc, 0, sizeof(wcc));
437 BlueSkyInode *dir = lookup_fh(&argp->where.dir);
439 result.status = NFS3ERR_STALE;
440 result.diropres3_u.resfail = wcc;
444 encode_pre_wcc(&wcc, dir);
445 if (dir->type != BLUESKY_DIRECTORY) {
446 result.status = NFS3ERR_NOTDIR;
447 result.diropres3_u.resfail = wcc;
451 if (!validate_filename(argp->where.name)
452 || strcmp(argp->where.name, ".") == 0
453 || strcmp(argp->where.name, "..") == 0)
455 result.status = NFS3ERR_EXIST;
456 result.diropres3_u.resfail = wcc;
461 file = bluesky_new_inode(bluesky_fs_alloc_inode(fs), fs, BLUESKY_DIRECTORY);
464 int64_t time = bluesky_get_current_time();
469 bluesky_insert_inode(fs, file);
470 bluesky_directory_insert(dir, argp->where.name, file->inum);
471 set_attributes(file, &argp->attributes);
473 dir->mtime = dir->ctime = bluesky_get_current_time();
476 wcc.after.present = TRUE;
477 encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir);
478 result.diropres3_u.resok.obj_attributes.present = TRUE;
479 encode_fattr3(&result.diropres3_u.resok.obj_attributes.post_op_attr_u.attributes, file);
480 result.diropres3_u.resok.dir_wcc = wcc;
482 static uint64_t fh_bytes;
483 fh_bytes = GUINT64_TO_BE(file->inum);
484 result.diropres3_u.resok.obj.present = TRUE;
485 result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_len = 8;
486 result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_val = (char *)&fh_bytes;
492 nfsproc3_symlink_3_svc(symlink3args *argp, struct svc_req *rqstp)
494 static diropres3 result;
496 memset(&wcc, 0, sizeof(wcc));
498 BlueSkyInode *dir = lookup_fh(&argp->where.dir);
500 result.status = NFS3ERR_STALE;
501 result.diropres3_u.resfail = wcc;
505 encode_pre_wcc(&wcc, dir);
506 if (dir->type != BLUESKY_DIRECTORY) {
507 result.status = NFS3ERR_NOTDIR;
508 result.diropres3_u.resfail = wcc;
512 if (!validate_filename(argp->where.name)
513 || strcmp(argp->where.name, ".") == 0
514 || strcmp(argp->where.name, "..") == 0)
516 result.status = NFS3ERR_EXIST;
517 result.diropres3_u.resfail = wcc;
522 file = bluesky_new_inode(bluesky_fs_alloc_inode(fs), fs, BLUESKY_SYMLINK);
525 int64_t time = bluesky_get_current_time();
530 file->symlink_contents = g_strdup(argp->symlink.symlink_data);
531 bluesky_insert_inode(fs, file);
532 bluesky_directory_insert(dir, argp->where.name, file->inum);
534 dir->mtime = dir->ctime = bluesky_get_current_time();
537 wcc.after.present = TRUE;
538 encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir);
539 result.diropres3_u.resok.obj_attributes.present = TRUE;
540 encode_fattr3(&result.diropres3_u.resok.obj_attributes.post_op_attr_u.attributes, file);
541 result.diropres3_u.resok.dir_wcc = wcc;
543 static uint64_t fh_bytes;
544 fh_bytes = GUINT64_TO_BE(file->inum);
545 result.diropres3_u.resok.obj.present = TRUE;
546 result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_len = 8;
547 result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_val = (char *)&fh_bytes;
553 nfsproc3_mknod_3_svc(mknod3args *argp, struct svc_req *rqstp)
555 static diropres3 result;
557 result.status = NFS3ERR_NOTSUPP;
563 nfsproc3_remove_3_svc(diropargs3 *argp, struct svc_req *rqstp)
565 static wccstat3 result;
567 result.wccstat3_u.wcc.before.present = FALSE;
568 result.wccstat3_u.wcc.after.present = FALSE;
570 BlueSkyInode *dir = lookup_fh(&argp->dir);
572 result.status = NFS3ERR_STALE;
576 encode_pre_wcc(&result.wccstat3_u.wcc, dir);
578 if (!validate_filename(argp->name)
579 || strcmp(argp->name, ".") == 0
580 || strcmp(argp->name, "..") == 0)
582 result.status = NFS3ERR_NOENT;
586 /* TODO: Decrement link count, deallocate inode if needed. */
588 bluesky_directory_remove(dir, argp->name);
590 result.status = NFS3_OK;
591 result.wccstat3_u.wcc.after.present = TRUE;
592 encode_fattr3(&result.wccstat3_u.wcc.after.post_op_attr_u.attributes,
599 nfsproc3_rmdir_3_svc(diropargs3 *argp, struct svc_req *rqstp)
601 static wccstat3 result;
603 result.wccstat3_u.wcc.before.present = FALSE;
604 result.wccstat3_u.wcc.after.present = FALSE;
606 BlueSkyInode *dir = lookup_fh(&argp->dir);
608 result.status = NFS3ERR_STALE;
612 encode_pre_wcc(&result.wccstat3_u.wcc, dir);
614 if (!validate_filename(argp->name)
615 || strcmp(argp->name, ".") == 0
616 || strcmp(argp->name, "..") == 0)
618 result.status = NFS3ERR_NOENT;
622 uint64_t inum = bluesky_directory_lookup(dir, argp->name);
623 BlueSkyInode *inode = bluesky_get_inode(fs, inum);
625 result.status = NFS3ERR_NOENT;
629 if (inode->type != BLUESKY_DIRECTORY) {
630 result.status = NFS3ERR_NOTDIR;
633 if (g_sequence_get_length(inode->dirents) > 0) {
634 printf("Directory not empty: %d entries\n",
635 g_sequence_get_length(inode->dirents));
636 result.status = NFS3ERR_NOTEMPTY;
640 /* TODO: Decrement link count, deallocate inode if needed. */
642 bluesky_directory_remove(dir, argp->name);
644 result.status = NFS3_OK;
645 result.wccstat3_u.wcc.after.present = TRUE;
646 encode_fattr3(&result.wccstat3_u.wcc.after.post_op_attr_u.attributes,
653 nfsproc3_rename_3_svc(rename3args *argp, struct svc_req *rqstp)
655 static rename3res result;
656 wcc_data *wcc1 = &result.rename3res_u.res.fromdir_wcc;
657 wcc_data *wcc2 = &result.rename3res_u.res.todir_wcc;
658 memset(wcc1, 0, sizeof(*wcc1));
659 memset(wcc2, 0, sizeof(*wcc2));
661 BlueSkyInode *dir1 = lookup_fh(&argp->from.dir);
663 result.status = NFS3ERR_STALE;
666 encode_pre_wcc(wcc1, dir1);
668 BlueSkyInode *dir2 = lookup_fh(&argp->to.dir);
670 result.status = NFS3ERR_STALE;
673 encode_pre_wcc(wcc2, dir1);
675 gboolean status = bluesky_rename(dir1, argp->from.name,
679 wcc1->after.present = TRUE;
680 encode_fattr3(&wcc1->after.post_op_attr_u.attributes, dir1);
681 wcc2->after.present = TRUE;
682 encode_fattr3(&wcc2->after.post_op_attr_u.attributes, dir2);
684 result.status = NFS3_OK;
686 result.status = NFS3ERR_PERM;
692 nfsproc3_link_3_svc(link3args *argp, struct svc_req *rqstp)
694 static link3res result;
696 memset(&wcc, 0, sizeof(wcc));
698 BlueSkyInode *inode = lookup_fh(&argp->file);
700 result.status = NFS3ERR_STALE;
701 result.link3res_u.res.linkdir_wcc = wcc;
705 BlueSkyInode *dir = lookup_fh(&argp->link.dir);
707 result.status = NFS3ERR_STALE;
708 result.link3res_u.res.linkdir_wcc = wcc;
712 encode_pre_wcc(&wcc, dir);
713 if (dir->type != BLUESKY_DIRECTORY) {
714 result.status = NFS3ERR_NOTDIR;
715 result.link3res_u.res.linkdir_wcc = wcc;
719 if (!validate_filename(argp->link.name)
720 || strcmp(argp->link.name, ".") == 0
721 || strcmp(argp->link.name, "..") == 0
722 || bluesky_directory_lookup(dir, argp->link.name) != 0)
724 result.status = NFS3ERR_EXIST;
725 result.link3res_u.res.linkdir_wcc = wcc;
729 if (!bluesky_directory_insert(dir, argp->link.name, inode->inum)) {
730 result.status = NFS3ERR_EXIST;
731 result.link3res_u.res.linkdir_wcc = wcc;
735 bluesky_inode_update_ctime(inode, 0);
737 result.status = NFS3_OK;
738 wcc.after.present = TRUE;
739 encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir);
740 result.link3res_u.res.file_attributes.present = TRUE;
741 encode_fattr3(&result.link3res_u.res.file_attributes.post_op_attr_u.attributes, inode);
742 result.link3res_u.res.linkdir_wcc = wcc;
747 gint bluesky_dirent_compare(gconstpointer a, gconstpointer b,
750 #define MAX_READDIR_DIRENTS 64
752 nfsproc3_readdir_3_svc(readdir3args *argp, struct svc_req *rqstp)
754 static readdir3res result;
756 BlueSkyInode *dir = lookup_fh(&argp->dir);
758 result.status = NFS3ERR_STALE;
759 result.readdir3res_u.resfail.present = FALSE;
763 result.status = NFS3_OK;
764 result.readdir3res_u.resok.dir_attributes.present = TRUE;
765 encode_fattr3(&result.readdir3res_u.resok.dir_attributes.post_op_attr_u.attributes, dir);
766 memset(result.readdir3res_u.resok.cookieverf, 0,
767 sizeof(result.readdir3res_u.resok.cookieverf));
769 static entry3 dirents[MAX_READDIR_DIRENTS];
772 BlueSkyDirent start = {NULL, NULL, argp->cookie, 0};
773 GSequenceIter *i = g_sequence_search(dir->dirents, &start,
774 bluesky_dirent_compare, NULL);
776 while (count < MAX_READDIR_DIRENTS && !g_sequence_iter_is_end(i)) {
777 BlueSkyDirent *d = g_sequence_get(i);
778 dirents[count].fileid = d->inum;
779 dirents[count].name = d->name;
780 dirents[count].cookie = d->cookie;
781 dirents[count].nextentry = NULL;
783 dirents[count - 1].nextentry = &dirents[count];
784 i = g_sequence_iter_next(i);
789 result.readdir3res_u.resok.reply.entries = &dirents[0];
791 result.readdir3res_u.resok.reply.entries = NULL;
792 result.readdir3res_u.resok.reply.eof = g_sequence_iter_is_end(i);
798 nfsproc3_readdirplus_3_svc(readdirplus3args *argp, struct svc_req *rqstp)
800 /* XDR-encoded sizes:
801 * post_op_attr: 88 bytes
802 * base readdirplus3resok: 88 + 16 bytes
803 * base directory entry: 24 bytes + filename
804 * attributes/fh3: 88 + 8 + filehandle size
806 size_t dircount = 88 + 16, attrcount = 0;
807 static readdirplus3res result;
809 BlueSkyInode *dir = lookup_fh(&argp->dir);
811 result.status = NFS3ERR_STALE;
812 result.readdirplus3res_u.resfail.present = FALSE;
816 result.status = NFS3_OK;
817 result.readdirplus3res_u.resok.dir_attributes.present = TRUE;
818 encode_fattr3(&result.readdirplus3res_u.resok.dir_attributes.post_op_attr_u.attributes, dir);
819 memset(result.readdirplus3res_u.resok.cookieverf, 0,
820 sizeof(result.readdirplus3res_u.resok.cookieverf));
822 static entryplus3 dirents[MAX_READDIR_DIRENTS];
823 static uint64_t fh_bytes[MAX_READDIR_DIRENTS];
826 /* TODO: Handle dircount, maxcount arguments from client. */
828 BlueSkyDirent start = {NULL, NULL, argp->cookie, 0};
829 GSequenceIter *i = g_sequence_search(dir->dirents, &start,
830 bluesky_dirent_compare, NULL);
832 while (count < MAX_READDIR_DIRENTS && !g_sequence_iter_is_end(i)) {
833 BlueSkyDirent *d = g_sequence_get(i);
834 BlueSkyInode *inode = bluesky_get_inode(fs, d->inum);
836 dircount += 24 + ((strlen(d->name) + 3) & ~3);
837 attrcount += 88 + 8 + 8;
838 if (dircount > argp->dircount
839 || dircount + attrcount > argp->maxcount)
841 dirents[count].fileid = d->inum;
842 dirents[count].name = d->name;
843 dirents[count].cookie = d->cookie;
844 dirents[count].nextentry = NULL;
845 dirents[count].name_attributes.present = TRUE;
846 encode_fattr3(&dirents[count].name_attributes.post_op_attr_u.attributes, inode);
847 fh_bytes[count] = GUINT64_TO_BE(d->inum);
848 dirents[count].name_handle.present = TRUE;
849 dirents[count].name_handle.post_op_fh3_u.handle.data.data_len = 8;
850 dirents[count].name_handle.post_op_fh3_u.handle.data.data_val
851 = (char *)&fh_bytes[count];
853 dirents[count - 1].nextentry = &dirents[count];
856 i = g_sequence_iter_next(i);
860 result.readdirplus3res_u.resok.reply.entries = &dirents[0];
862 result.readdirplus3res_u.resok.reply.entries = NULL;
863 result.readdirplus3res_u.resok.reply.eof = g_sequence_iter_is_end(i);
869 nfsproc3_fsstat_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
871 static fsstat3res result;
873 BlueSkyInode *inode = lookup_fh(argp);
875 result.status = NFS3ERR_STALE;
876 result.fsstat3res_u.resfail.present = FALSE;
880 result.status = NFS3_OK;
881 result.fsstat3res_u.resok.obj_attributes.present = TRUE;
882 encode_fattr3(&result.fsstat3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
884 result.fsstat3res_u.resok.tbytes = (1 << 30);
885 result.fsstat3res_u.resok.fbytes = (1 << 30);
886 result.fsstat3res_u.resok.abytes = (1 << 30);
887 result.fsstat3res_u.resok.tfiles = 0;
888 result.fsstat3res_u.resok.ffiles = 0;
889 result.fsstat3res_u.resok.afiles = 0;
890 result.fsstat3res_u.resok.invarsec = 0;
896 nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
898 static fsinfo3res result;
900 BlueSkyInode *inode = bluesky_get_inode(fs, 1);
901 result.status = NFS3_OK;
902 result.fsinfo3res_u.resok.obj_attributes.present = TRUE;
903 encode_fattr3(&result.fsinfo3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
904 result.fsinfo3res_u.resok.rtmax = 32768;
905 result.fsinfo3res_u.resok.rtpref = 32768;
906 result.fsinfo3res_u.resok.rtmult = 4096;
907 result.fsinfo3res_u.resok.wtmax = 32768;
908 result.fsinfo3res_u.resok.wtpref = 32768;
909 result.fsinfo3res_u.resok.wtmult = 4096;
910 result.fsinfo3res_u.resok.dtpref = 4096;
911 result.fsinfo3res_u.resok.maxfilesize = 0x7fffffffffffffffULL;
912 result.fsinfo3res_u.resok.time_delta.seconds = 0;
913 result.fsinfo3res_u.resok.time_delta.nseconds = 1000;
914 result.fsinfo3res_u.resok.properties
915 = FSF3_LINK | FSF3_SYMLINK | FSF3_HOMOGENEOUS | FSF3_CANSETTIME;
921 nfsproc3_pathconf_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
923 static pathconf3res result;
925 BlueSkyInode *inode = bluesky_get_inode(fs, 1);
926 result.status = NFS3_OK;
927 result.pathconf3res_u.resok.obj_attributes.present = TRUE;
928 encode_fattr3(&result.pathconf3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
929 result.pathconf3res_u.resok.linkmax = 0xffffffff;
930 result.pathconf3res_u.resok.name_max = 255;
931 result.pathconf3res_u.resok.no_trunc = TRUE;
932 result.pathconf3res_u.resok.chown_restricted = TRUE;
933 result.pathconf3res_u.resok.case_insensitive = FALSE;
934 result.pathconf3res_u.resok.case_preserving = TRUE;
940 nfsproc3_commit_3_svc(commit3args *argp, struct svc_req *rqstp)
942 static commit3res result;
944 result.status = NFS3ERR_NOTSUPP;