Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
.\"	$NetBSD: puffs_ops.3,v 1.46 2017/07/03 21:32:51 wiz Exp $
.\"
.\" Copyright (c) 2007 Antti Kantee.  All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd August 29, 2016
.Dt PUFFS_OPS 3
.Os
.Sh NAME
.Nm puffs_ops
.Nd puffs callback operations
.Sh LIBRARY
.Lb libpuffs
.Sh SYNOPSIS
.In puffs.h
.Ft int
.Fo puffs_fs_statvfs
.Fa "struct puffs_usermount *pu" "struct statvfs *sbp"
.Fc
.Ft int
.Fo puffs_fs_sync
.Fa "struct puffs_usermount *pu" "int waitfor" "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_fs_fhtonode
.Fa "struct puffs_usermount *pu" "void *fid" "size_t fidsize"
.Fa "struct puffs_newinfo *pni"
.Fc
.Ft int
.Fo puffs_fs_nodetofh
.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" "void *fid"
.Fa "size_t *fidsize"
.Fc
.Ft int
.Fo puffs_fs_extattrctl
.Fa "struct puffs_usermount *pu" "int cmd" "puffs_cookie_t cookie" "int flags"
.Fa "int attrnamespace" "const char *attrname"
.Fc
.Ft int
.Fo puffs_fs_unmount
.Fa "struct puffs_usermount *pu" "int flags"
.Fc
.Ft int
.Fo puffs_node_lookup
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
.Fc
.Ft int
.Fo puffs_node_create
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
.Fa "const struct vattr *vap"
.Fc
.Ft int
.Fo puffs_node_mknod
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
.Fa "const struct vattr *vap"
.Fc
.Ft int
.Fo puffs_node_open
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_open2
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int modep"
.Fa "const struct puffs_cred *pcr" "int *oflags"
.Fc
.Ft int
.Fo puffs_node_close
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_access
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_getattr
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_setattr
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "const struct vattr *vap"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_getattr_ttl
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap"
.Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl"
.Fc
.Ft int
.Fo puffs_node_setattr_ttl
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap"
.Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl" "int xflag"
.Fc
.Ft int
.Fo puffs_node_pathconf
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int name"
.Fa "register_t *retval"
.Fc
.Ft int
.Fo puffs_node_advlock
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "void *id" "int op"
.Fa "struct flock *fl" "int flags"
.Fc
.Ft int
.Fo puffs_node_poll
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int *events"
.Fc
.Ft int
.Fo puffs_node_mmap
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_fsync
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "const struct puffs_cred *pcr" "int flags" "off_t offlo" "off_t offhi"
.Fc
.Ft int
.Fo puffs_node_seek
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t oldoff"
.Fa "off_t newoff" "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_remove
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
.Fa "const struct puffs_cn *pcn"
.Fc
.Ft int
.Fo puffs_node_link
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
.Fa "const struct puffs_cn *pcn"
.Fc
.Ft int
.Fo puffs_node_rename
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t src"
.Fa "const struct puffs_cn *pcn_src" "puffs_cookie_t targ_dir"
.Fa "puffs_cookie_t targ" "const struct puffs_cn *pcn_targ"
.Fc
.Ft int
.Fo puffs_node_mkdir
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
.Fa "const struct vattr *vap"
.Fc
.Ft int
.Fo puffs_node_rmdir
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
.Fa "const struct puffs_cn *pcn"
.Fc
.Ft int
.Fo puffs_node_readdir
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct dirent *dent"
.Fa "off_t *readoff" "size_t *reslen" "const struct puffs_cred *pcr"
.Fa "int *eofflag" "off_t *cookies" "size_t *ncookies"
.Fc
.Ft int
.Fo puffs_node_symlink
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "struct puffs_newinfo *pni"
.Fa "const struct puffs_cn *pcn_src" "const struct vattr *vap"
.Fa "const char *link_target"
.Fc
.Ft int
.Fo puffs_node_readlink
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "const struct puffs_cred *pcr" "char *link" "size_t *linklen"
.Fc
.Ft int
.Fo puffs_node_read
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
.Fc
.Ft int
.Fo puffs_node_write
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
.Fc
.Ft int
.Fo puffs_node_write2
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
.Fa "int xflag"
.Fc
.Ft int
.Fo puffs_node_abortop
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fa "const struct puffs_cn *pcn"
.Fc
.Ft int
.Fo puffs_node_getextattr
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
.Fa "const char *attrname" "size_t *attrsize" "uint8_t *attr" "size_t *resid"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_setextattr
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
.Fa "const char *attrname" "uint8_t *attr" "size_t *resid"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_listextattr
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
.Fa "size_t *attrssize" "uint8_t *attrs" "size_t *resid" "int flag"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_deleteextattr
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
.Fa "const char *attrname"
.Fa "const struct puffs_cred *pcr"
.Fc
.Ft int
.Fo puffs_node_fallocate
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t pos" "off_t len"
.Fc
.Ft int
.Fo puffs_node_fdiscard
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t pos" "off_t len"
.Fc
.Ft int
.Fo puffs_node_print
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fc
.Ft int
.Fo puffs_node_reclaim
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fc
.Ft int
.Fo puffs_node_reclaim2
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int nlookup"
.Fc
.Ft int
.Fo puffs_node_inactive
.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
.Fc
.Ft void
.Fn puffs_setback "struct puffs_cc *pcc" "int op"
.Ft void
.Fn puffs_newinfo_setcookie "struct puffs_newinfo *pni" "puffs_cookie_t cookie"
.Ft void
.Fn puffs_newinfo_setvtype "struct puffs_newinfo *pni" "enum vtype vtype"
.Ft void
.Fn puffs_newinfo_setsize "struct puffs_newinfo *pni" "voff_t size"
.Ft void
.Fn puffs_newinfo_setrdev "struct puffs_newinfo *pni" "dev_t rdev"
.Ft void
.Fn puffs_newinfo_setva "struct puffs_newinfo *pni" "struct vattr *vap"
.Ft void
.Fn puffs_newinfo_setvattl "struct puffs_newinfo *pni" "struct timespec *va_ttl"
.Ft void
.Fn puffs_newinfo_setcnttl "struct puffs_newinfo *pni" "struct timespec *cn_ttl"
.Sh DESCRIPTION
The operations
.Nm puffs
requires to function can be divided into two categories: file system
callbacks and node callbacks.
The former affect the entire file system while the latter are targeted
at a file or a directory and a file.
They are roughly equivalent to the vfs and vnode operations in the
kernel.
.Pp
All callbacks can be prototyped with the file system name and operation
name using the macro
.Fn PUFFSOP_PROTOS fsname .
.Ss File system callbacks (puffs_fs)
.Bl -tag -width xxxx
.It Fn puffs_fs_statvfs "pu" "sbp"
The following fields of the argument
.Fa sbp
need to be filled:
.Bd -literal
 * unsigned long  f_bsize;     file system block size
 * unsigned long  f_frsize;    fundamental file system block size
 * fsblkcnt_t     f_blocks;    number of blocks in file system,
 *                                      (in units of f_frsize)
 *
 * fsblkcnt_t     f_bfree;     free blocks avail in file system
 * fsblkcnt_t     f_bavail;    free blocks avail to non-root
 * fsblkcnt_t     f_bresvd;    blocks reserved for root

 * fsfilcnt_t     f_files;     total file nodes in file system
 * fsfilcnt_t     f_ffree;     free file nodes in file system
 * fsfilcnt_t     f_favail;    free file nodes avail to non-root
 * fsfilcnt_t     f_fresvd;    file nodes reserved for root

.Ed
.It Fn puffs_fs_sync "pu" "waitfor" "pcr"
All the dirty buffers that have been cached at the file server
level including metadata should be committed to stable storage.
The
.Fa waitfor
parameter affects the operation.
Possible values are:
.Bl -tag -width XMNT_NOWAITX
.It Dv MNT_WAIT
Wait for all I/O for complete until returning.
.It Dv MNT_NOWAIT
Initiate I/O, but do not wait for completion.
.It Dv MNT_LAZY
Synchorize data not synchoronized by the file system syncer,
i.e., data not written when
.Fn node_fsync
is called with
.Dv FSYNC_LAZY .
.El
.Pp
The credentials for the initiator of the sync operation are present in
.Fa pcr
and will usually be either file system or kernel credentials, but might
also be user credentials.
However, most of the time it is advisable to sync regardless of the
credentials of the caller.
.It Fn puffs_fs_fhtonode "pu" "fid" "fidsize" "pni"
Translates a file handle
.Fa fid
to a node.
The parameter
.Fa fidsize
indicates how large the file handle is.
In case the file system's handles are static length, this parameter can
be ignored as the kernel guarantees all file handles passed to the file
server are of correct length.
For dynamic length handles the field should be examined and
.Er EINVAL
returned in case the file handle length is not correct.
.Pp
This function provides essentially the same information to the kernel as
.Fn puffs_node_lookup .
The information is necessary for creating a new vnode corresponding to
the file handle.
.It Fn puffs_fs_nodetofh "pu" "cookie" "fid" "fidsize"
Create a file handle from the node described by
.Fa cookie .
The file handle should contain enough information to reliably identify
the node even after reboots and the pathname/inode being replaced by
another file.
If this is not possible, it is up to the author of the file system to
act responsibly and decide if the file system can support file handles
at all.
.Pp
For file systems which want dynamic length file handles, this function
must check if the file handle space indicated by
.Fa fidsize
is large enough to accommodate the file handle for the node.
If not, it must fill in the correct size and return
.Er E2BIG .
In either case, the handle length should be supplied to the kernel in
.Fa fidsize .
File systems with static length handles can ignore the size parameter as
the kernel always supplies the correct size buffer.
.It Fn puffs_fs_unmount "pu" "flags"
Unmount the file system.
The kernel has assumedly flushed all cached data when this callback
is executed.
If the file system cannot currently be safely be unmounted, for whatever
reason, the kernel will honor an error value and not forcibly unmount.
However, if the flag
.Dv MNT_FORCE
is not honored by the file server, the kernel will forcibly unmount
the file system.
.El
.Ss Node callbacks
These operations operate in the level of individual files.
The file cookie is always provided as the second argument
.Fa opc .
If the operation is for a file, it will be the cookie of the file.
The case the operation involves a directory (such as
.Dq create file in directory ) ,
the cookie will be for the directory.
Some operations take additional cookies to describe the rest of
the operands.
The return value 0 signals success, else an appropriate errno value
should be returned.
Please note that neither this list nor the descriptions are complete.
.Bl -tag -width xxxx
.It Fn puffs_node_lookup "pu" "opc" "pni" "pcn"
This function is used to locate nodes, or in other words translate
pathname components to file system data structures.
The implementation should match the name in
.Fa pcn
against the existing entries in the directory provided by the cookie
.Fa opc .
If found, the cookie for the located node should be set in
.Fa pni
using
.Fn puffs_newinfo_setcookie .
Additionally, the vnode type and size (latter applicable to regular files only)
should be set using
.Fn puffs_newinfo_setvtype
and
.Fn puffs_newinfo_setsize ,
respectively.
If the located entry is a block device or character device file,
the dev_t for the entry should be set using
.Fn puffs_newinfo_setrdev .
.Pp
If
.Fn puffs_init
was called with
.Dv PUFFS_KFLAG_CACHE_FS_TTL
then
.Fn puffs_newinfo_setva ,
.Fn puffs_newinfo_setvattl ,
and
.Fn puffs_newinfo_setcnttl
can be called to specify the new node attributes, cached attributes
time to live, and cached name time to live.
.Pp
The type of operation is found from
.Va pcn->pcn_nameiop :
.Bl -tag -width XNAMEI_LOOKUPX
.It Dv NAMEI_LOOKUP
Normal lookup operation.
.It Dv NAMEI_CREATE
Lookup to create a node.
.It Dv NAMEI_DELETE
Lookup for node deletion.
.It Dv NAMEI_RENAME
Lookup for the target of a rename operation (source will be looked
up using
.Dv NAMEI_DELETE ) .
.El
.Pp
The final component from a pathname lookup usually requires special
treatment.
It can be identified by looking at the
.Va pcn->pcn_flags
fields for the flag
.Dv PUFFSLOOKUP_ISLASTCN .
For example, in most cases the lookup operation will want to check if
a delete, rename or create operation has enough credentials to perform
the operation.
.Pp
The return value 0 signals a found node and a nonzero value signals
an errno.
As a special case,
.Er ENOENT
signals "success" for cases where the lookup operation is
.Dv NAMEI_CREATE
or
.Dv NAMEI_RENAME .
Failure in these cases can be signalled by returning another appropriate
error code, for example
.Er EACCESS .
.Pp
Usually a null-terminated string for the next pathname component is
provided in
.Ar pcn->pcn_name .
In case the file system is using the option
.Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF ,
the remainder of the complete pathname under lookup is found in
the same location.
.Ar pcn->pcn_namelen
always specifies the length of the next component.
If operating with a full path, the file system is allowed to consume
more than the next component's length in node lookup.
This is done by setting
.Ar pcn->pcn_consume
to indicate the amount of
.Em extra
characters in addition to
.Ar pcn->pcn_namelen
processed.
.It Fn puffs_node_create "pu" "opc" "pni" "pcn" "va"
.It Fn puffs_node_mkdir "pu" "opc" "pni" "pcn" "va"
.It Fn puffs_node_mknod "pu" "opc" "pni" "pcn" "va"
A file node is created in the directory denoted by the cookie
.Fa opc
by any of the above callbacks.
The name of the new file can be found from
.Fa pcn
and the attributes are specified by
.Fa va
and the cookie for the newly created node should be set in
.Fa pni .
The only difference between these three is that they create a regular
file, directory and device special file, respectively.
.Pp
In case of mknod, the device identifier can be found in
.Fa va->va_rdev .
.It Fn puffs_node_open "pu" "opc" "mode" "pcr"
.It Fn puffs_node_open2 "pu" "opc" "mode" "pcr" "oflags"
Open the node denoted by the cookie
.Fa opc .
The parameter
.Fa mode
specifies the flags that
.Xr open 2
was called with, e.g.
.Dv O_APPEND
and
.Dv O_NONBLOCK .
.Fn puffs_node_open2
allows the file system to pass back information for the file in
.Fa oflags .
The only implemented flag for now is
.Dv PUFFS_OPEN_IO_DIRECT
that cause file read/write to bypass the page cache.
.It Fn puffs_node_close "pu" "opc" "flags" "pcr"
Close a node.
The parameter
.Fa flags
parameter describes the flags that the file was opened with.
.It Fn puffs_node_access "pu" "opc" "mode" "pcr"
Check if the credentials of
.Fa pcr
have the right to perform the operation specified by
.Fa mode
onto the node
.Fa opc .
The argument
.Fa mode
can specify read, write or execute by
.Dv PUFFS_VREAD ,
.Dv PUFFS_VWRITE ,
and
.Dv PUFFS_VEXEC ,
respectively.
.It Fn puffs_node_getattr "pu" "opc" "va" "pcr"
The attributes of the node specified by
.Fa opc
must be copied to the space pointed by
.Fa va .
.It Fn puffs_node_getattr_ttl "pu" "opc" "va" "pcr" "va_ttl"
Same as
.Fn puffs_node_getattr
with cached attribute time to live specified in
.Fa va_ttl
.It Fn puffs_node_setattr "pu" "opc" "va" "pcr"
The attributes for the node specified by
.Fa opc
must be set to those contained in
.Fa va .
Only fields of
.Fa va
which contain a value different from
.Dv PUFFS_VNOVAL
(typecast to the field's type!) contain a valid value.
.It Fn puffs_node_setattr_ttl "pu" "opc" "va" "pcr" "va_ttl" "xflag"
Same as
.Fn puffs_node_setattr
with cached attribute time to live specified in
.Fa va_ttl .
.Dv PUFFS_SETATTR_FAF
will be set in
.Fa xflag
for Fire-And-Forget operations.
.It Fn puffs_node_pathconf "pu" "opc" "name" "retval"
The value of the
.Xr pathconf 2
filesystem limit specified in
.Ar name
for the node
.Ar opc
should be copied to the space pointed to by
.Ar retval .
.It Fn puffs_node_advlock "po" "opc" "id" "op" "fl" "flags"
Manipulate advisory record locks on the node
.Ar opc .
The argument
.Ar id
is the id token which is changing the lock,
.Ar op
is the
.Xr fcntl 2
operation to perform,
.Ar fl
is the lock descriptor structure and
.Ar flags
are the flags as defined in
.Xr VOP_ADVLOCK 9 .
.It Fn puffs_node_poll "pu" "opc" "events"
Poll for events on node
.Ar opc .
If
.Xr poll 2
events specified in
.Ar events
are available, the function should set the bitmask to match available
events and return immediately.
Otherwise, the function should block (yield) until some events in
.Ar events
become available and only then set the
.Ar events
bitmask and return.
.Pp
In case this function returns an error,
.Dv POLLERR
(or its
.Xr select 2
equivalent) will be delivered to the calling process.
.Pp
.Em NOTE!
The system call interface for
.Fn poll
contains a timeout parameter.
At this level, however, the timeout is not supplied.
In case input does not arrive, the file system should periodically
unblock and return 0 new events to avoid hanging forever.
This will hopefully be better supported by libpuffs in the future.
.It Fn puffs_node_mmap "pu" "opc" "flags" "pcr"
Called when a regular file is being memory mapped by
.Xr mmap 2 .
.Fa flags
is currently always 0.
.It Fn puffs_node_fsync "pu" "opc" "pcr" "flags" "offlo" "offhi"
Sychronize a node's contents onto stable storage.
This is necessary only if the file server caches some information
before committing it.
The parameter
.Fa flags
specifies the minimum level of sychronization required (XXX: they are
not yet available).
The parameters
.Fa offlo
and
.Fa offhi
specify the data offsets requiring to be synced.
A high offset of 0 means sync from
.Fa offlo
to the end of the file.
.It Fn puffs_node_seek "pu" "opc" "oldoff" "newoff" "pcr"
Test if the node
.Ar opc
is seekable to the location
.Ar newoff .
The argument
.Ar oldoff
specifies the offset we are starting the seek from.
Most file systems dealing only with regular will choose to not
implement this.
However, it is useful for example in cases where files are
unseekable streams.
.It Fn puffs_node_remove "pu" "opc" "targ" "pcn"
.It Fn puffs_node_rmdir "pu" "opc" "targ" "pcn"
Remove the node
.Fa targ
from the directory indicated by
.Fa opc .
The directory entry name to be removed is provided by
.Fa pcn .
The rmdir operation removes only directories, while the remove
operation removes all other types except directories.
.Pp
It is paramount to note that the file system may not remove the
node data structures at this point, only the directory entry and prevent
lookups from finding the node again.
This is to retain the
.Ux
open file semantics.
The data may be removed only when
.Fn puffs_node_reclaim
or
.Fn puffs_node_reclaim2
is called for the node, as this assures there are no further users.
.It Fn puffs_node_link "pu" "opc" "targ" "pcn"
Create a hard link for the node
.Fa targ
into the directory
.Fa opc .
The argument
.Fa pcn
provides the directory entry name for the new link.
.It Fn puffs_node_rename "pu" "src_dir" "src" "pcn_src" "targ_dir" "targ" "pcn_targ"
Rename the node
.Fa src
with the name specified by
.Fa pcn_src
from the directory
.Fa src_dir .
The target directory and target name are given by
.Fa targ_dir
and
.Fa pcn_targ ,
respectively.
.Em If
the target node already exists, it is specified by
.Fa targ
and must be replaced atomically.
Otherwise
.Fa targ
is gives as
.Dv NULL .
.Pp
It is legal to replace a directory node by another directory node with
the means of rename if the target directory is empty, otherwise
.Er ENOTEMPTY
should be returned.
All other types can replace all other types.
In case a rename between incompatible types is attempted, the errors
.Er ENOTDIR
or
.Er EISDIR
should be returned, depending on the target type.
.It Fn puffs_node_readdir "pu" "opc" "dent" "readoff" "reslen" "pcr" "eofflag" "cookies" "ncookies"
To read directory entries,
.Fn puffs_node_readdir
is called.
It should store directories as
.Va struct dirent
in the space pointed to by
.Fa dent .
The amount of space available is given by
.Fa reslen
and before returning it should be set to the amount of space
.Em remaining
in the buffer.
The argument
.Fa offset
is used to specify the offset to the directory.
Its intepretation is up to the file system and it should be set to
signal the continuation point when there is no more room for the next
entry in
.Fa dent .
It is most performant to return the maximal amount of directory
entries each call.
It is easiest to generate directory entries by using
.Fn puffs_nextdent ,
which also automatically advances the necessary pointers.
.Pp
In case end-of-directory is reached,
.Fa eofflag
should be set to one.
Note that even a new call to readdir may start where
.Fa readoff
points to end-of-directory.
.Pp
If the file system supports file handles, the arguments
.Fa cookies
and
.Fa ncookies
must be filled out.
.Fa cookies
is a vector for offsets corresponding to read offsets.
One cookie should be filled out for each directory entry.
The value of the cookie should equal the offset of the
.Em next
directory entry, i.e., which offset should be passed to readdir for
the first entry read to be the entry following the current one.
.Fa ncookies
is the number of slots for cookies in the cookie vector upon entry to
the function and must be set to the amount of cookies stored in the
vector (i.e., amount of directory entries read) upon exit.
There is always enough space in the cookie vector for the maximal number
of entries that will fit into the directory entry buffer.
For filling out the vector, the helper function
.Fn PUFFS_STORE_DCOOKIE cookies ncookies offset
can be used.
This properly checks against
.Fa cookies
being
.Dv NULL .
Note that
.Fa ncookies
must be initialized to zero before the first call to
.Fn PUFFS_STORE_DCOOKIE .
.It Fn puffs_node_symlink "pu" "opc" "pni" "pcn_src" "va" "link_target"
Create a symbolic link into the directory
.Fa opc
with the name in
.Fa pcn_src
and the initial attributes in
.Fa va .
The argument
.Ar link_target
contains a null-terminated string for the link target.
The created node cookie should be set in
.Fa pni .
.It Fn puffs_node_readlink "pu" "opc" "pcr" "link" "linklen"
Read the target of a symbolic link
.Fa opc .
The result is placed in the buffer pointed to by
.Fa link .
This buffer's length is given in
.Fa linklen
and it must be updated to reflect the real link length.
A terminating nul character should not be put into the buffer and
.Em "must not"
be included in the link length.
.It Fn puffs_node_read "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
Read the contents of a file
.Fa opc .
It will gather the data from
.Fa offset
in the file and read the number
.Fa resid
octets.
The buffer is guaranteed to have this much space.
The amount of data requested by
.Fa resid
should be read, except in the case of eof-of-file or an error.
The parameter
.Fa resid
should be set to indicate the amount of request NOT completed.
In the normal case this should be 0.
.It Fn puffs_node_write "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
.It Fn puffs_node_write2 "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag" \
"xflag"
.Fn puffs_node_write
writes data to a file
.Fa opc
at
.Fa offset
and extend the file if necessary.
The number of octets written is indicated by
.Fa resid ;
everything must be written or an error will be generated.
The parameter must be set to indicate the amount of data NOT written.
In case the ioflag
.Dv PUFFS_IO_APPEND
is specified, the data should be appended to the end of the file.
.Fn puffs_node_write2
serves the same purpose as
.Fn puffs_node_write
with an additional
.Fa xflag
in which
.Dv PUFFS_WRITE_FAF
is set for Fire-And-Forget operations.
.It Fn puffs_node_fallocate "pu" "opc" "pos" "len"
Allocate
.Fa len
bytes of backing store at offset
.Fa pos
for the node referenced by the cookie
.Fa opc .
.It Fn puffs_node_fdiscard "pu" "opc" "pos" "len"
Free
.Fa len
bytes of backing store (creating a hole) at offset
.Fa pos
for the node referenced by the cookie
.Fa opc .
.It Fn puffs_node_print "pu" "opc"
Print information about node.
This is used only for kernel-initiated diagnostic purposes.
.It Fn puffs_node_reclaim "pu" "opc"
The kernel will no longer reference the cookie and resources associated
with it may be freed.
In case the file
.Fa opc
has a link count of zero, it may be safely removed now.
.It Fn puffs_node_reclaim2 "pu" "opc" "nlookup"
Same as
.Fn puffs_node_reclaim
with an addditional argument for the number of lookups that have been done
on the node (Node creation is counted as a lookup). This can be used by the
file system to avoid a race condition, where the kernel sends a reclaim
while it does not have received the reply for a lookup.
If the file system tracks lookup count, and compares to
.Fa nlookup
it can detect this situation and ignore the reclaim.
.Pp
If the file system maps cookies to
.Vt struct puffs_node
then the framework will do that work, and
.Fn puffs_node_reclaim
can be reliabily used without the race condition.
.It Fn puffs_node_abortop "pu" "opc" "pcn"
In case the operation following lookup (e.g., mkdir or remove) is not
executed for some reason, abortop will be issued.
This is useful only for servers which cache state between lookup
and a directory operation and is generally left unimplemented.
.It Fn puffs_node_inactive "pu" "opc"
The node
.Fa opc
has lost its last reference in the kernel.
However, the cookie must still remain valid until
.Fn puffs_node_reclaim
or
.Fn puffs_node_reclaim2
is called.
.It Fn puffs_setback "pcc" "op"
Issue a "setback" operation which will be handled when the request response
is returned to the kernel.
Currently this can be only called from mmap, open, remove and rmdir.
The valid parameters for
.Ar op
are
.Dv PUFFS_SETBACK_INACT_N1
and
.Dv PUFFS_SETBACK_INACT_N2 .
These signal that a file system mounted with
.Dv PUFFS_KFLAG_IAONDEMAND
should call the file system inactive method for the specified node.
The node number 1 always means the operation cookie
.Ar opc ,
while the node number 2 can be used to specify the second node argument
present in some methods, e.g., remove.
.It Fn puffs_newinfo_setcookie pni cookie
Set cookie for node provided by this method to
.Ar cookie .
.It Fn puffs_newinfo_setvtype pni vtype
Set the type of the newly located node to
.Ar vtype .
This call is valid only for
.Fn lookup
and
.Fn fhtonode .
.It Fn puffs_newinfo_setsize pni size
Set the size of the newly located node to
.Ar size .
If left unset, the value defaults to 0.
This call is valid only for
.Fn lookup
and
.Fn fhtovp .
.It Fn puffs_newinfo_setrdev pni rdev
Set the type of the newly located node to
.Ar vtype .
This call is valid only for
.Fn lookup
and
.Fn fhtovp
producing device type nodes.
.It Fn puffs_newinfo_setva pni vap
Set the attributes for newly created vnode.
This call is valid for
.Fn lookup ,
.Fn create ,
.Fn mkdir ,
.Fn mknod ,
and
.Fn symlink ,
if
.Fn puffs_init
was called with
.Dv PUFFS_KFLAG_CACHE_FS_TTL
flag set.
.It Fn puffs_newinfo_setvattl pni va_ttl
Set cached attribute time to live for newly created vnode.
This call is valid for
.Fn lookup ,
.Fn create ,
.Fn mkdir ,
.Fn mknod ,
and
.Fn symlink ,
if
.Fn puffs_init
was called with
.Dv PUFFS_KFLAG_CACHE_FS_TTL
flag set.
.It Fn puffs_newinfo_setcnttl pni cn_ttl
Set cached name time to live for newly created vnode.
This call is valid for
.Fn lookup ,
.Fn create ,
.Fn mkdir ,
.Fn mknod ,
and
.Fn symlink ,
if
.Fn puffs_init
was called with
.Dv PUFFS_KFLAG_CACHE_FS_TTL
flag set.
.El
.Sh SEE ALSO
.Xr puffs 3 ,
.Xr vfsops 9 ,
.Xr vnodeops 9