fuse.go 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304
  1. // See the file LICENSE for copyright and licensing information.
  2. // Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
  3. // which carries this notice:
  4. //
  5. // The files in this directory are subject to the following license.
  6. //
  7. // The author of this software is Russ Cox.
  8. //
  9. // Copyright (c) 2006 Russ Cox
  10. //
  11. // Permission to use, copy, modify, and distribute this software for any
  12. // purpose without fee is hereby granted, provided that this entire notice
  13. // is included in all copies of any software which is or includes a copy
  14. // or modification of this software and in all copies of the supporting
  15. // documentation for such software.
  16. //
  17. // THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
  18. // WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY
  19. // OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
  20. // FITNESS FOR ANY PARTICULAR PURPOSE.
  21. // Package fuse enables writing FUSE file systems on Linux, OS X, and FreeBSD.
  22. //
  23. // On OS X, it requires OSXFUSE (http://osxfuse.github.com/).
  24. //
  25. // There are two approaches to writing a FUSE file system. The first is to speak
  26. // the low-level message protocol, reading from a Conn using ReadRequest and
  27. // writing using the various Respond methods. This approach is closest to
  28. // the actual interaction with the kernel and can be the simplest one in contexts
  29. // such as protocol translators.
  30. //
  31. // Servers of synthesized file systems tend to share common
  32. // bookkeeping abstracted away by the second approach, which is to
  33. // call fs.Serve to serve the FUSE protocol using an implementation of
  34. // the service methods in the interfaces FS* (file system), Node* (file
  35. // or directory), and Handle* (opened file or directory).
  36. // There are a daunting number of such methods that can be written,
  37. // but few are required.
  38. // The specific methods are described in the documentation for those interfaces.
  39. //
  40. // The hellofs subdirectory contains a simple illustration of the fs.Serve approach.
  41. //
  42. // Service Methods
  43. //
  44. // The required and optional methods for the FS, Node, and Handle interfaces
  45. // have the general form
  46. //
  47. // Op(ctx context.Context, req *OpRequest, resp *OpResponse) error
  48. //
  49. // where Op is the name of a FUSE operation. Op reads request
  50. // parameters from req and writes results to resp. An operation whose
  51. // only result is the error result omits the resp parameter.
  52. //
  53. // Multiple goroutines may call service methods simultaneously; the
  54. // methods being called are responsible for appropriate
  55. // synchronization.
  56. //
  57. // The operation must not hold on to the request or response,
  58. // including any []byte fields such as WriteRequest.Data or
  59. // SetxattrRequest.Xattr.
  60. //
  61. // Errors
  62. //
  63. // Operations can return errors. The FUSE interface can only
  64. // communicate POSIX errno error numbers to file system clients, the
  65. // message is not visible to file system clients. The returned error
  66. // can implement ErrorNumber to control the errno returned. Without
  67. // ErrorNumber, a generic errno (EIO) is returned.
  68. //
  69. // Error messages will be visible in the debug log as part of the
  70. // response.
  71. //
  72. // Interrupted Operations
  73. //
  74. // In some file systems, some operations
  75. // may take an undetermined amount of time. For example, a Read waiting for
  76. // a network message or a matching Write might wait indefinitely. If the request
  77. // is cancelled and no longer needed, the context will be cancelled.
  78. // Blocking operations should select on a receive from ctx.Done() and attempt to
  79. // abort the operation early if the receive succeeds (meaning the channel is closed).
  80. // To indicate that the operation failed because it was aborted, return fuse.EINTR.
  81. //
  82. // If an operation does not block for an indefinite amount of time, supporting
  83. // cancellation is not necessary.
  84. //
  85. // Authentication
  86. //
  87. // All requests types embed a Header, meaning that the method can
  88. // inspect req.Pid, req.Uid, and req.Gid as necessary to implement
  89. // permission checking. The kernel FUSE layer normally prevents other
  90. // users from accessing the FUSE file system (to change this, see
  91. // AllowOther, AllowRoot), but does not enforce access modes (to
  92. // change this, see DefaultPermissions).
  93. //
  94. // Mount Options
  95. //
  96. // Behavior and metadata of the mounted file system can be changed by
  97. // passing MountOption values to Mount.
  98. //
  99. package fuse // import "bazil.org/fuse"
  100. import (
  101. "bytes"
  102. "encoding/json"
  103. "errors"
  104. "fmt"
  105. "io"
  106. "os"
  107. "sync"
  108. "syscall"
  109. "time"
  110. "unsafe"
  111. )
  112. // A Conn represents a connection to a mounted FUSE file system.
  113. type Conn struct {
  114. // Ready is closed when the mount is complete or has failed.
  115. Ready <-chan struct{}
  116. // MountError stores any error from the mount process. Only valid
  117. // after Ready is closed.
  118. MountError error
  119. // File handle for kernel communication. Only safe to access if
  120. // rio or wio is held.
  121. dev *os.File
  122. wio sync.RWMutex
  123. rio sync.RWMutex
  124. // Protocol version negotiated with InitRequest/InitResponse.
  125. proto Protocol
  126. }
  127. // MountpointDoesNotExistError is an error returned when the
  128. // mountpoint does not exist.
  129. type MountpointDoesNotExistError struct {
  130. Path string
  131. }
  132. var _ error = (*MountpointDoesNotExistError)(nil)
  133. func (e *MountpointDoesNotExistError) Error() string {
  134. return fmt.Sprintf("mountpoint does not exist: %v", e.Path)
  135. }
  136. // Mount mounts a new FUSE connection on the named directory
  137. // and returns a connection for reading and writing FUSE messages.
  138. //
  139. // After a successful return, caller must call Close to free
  140. // resources.
  141. //
  142. // Even on successful return, the new mount is not guaranteed to be
  143. // visible until after Conn.Ready is closed. See Conn.MountError for
  144. // possible errors. Incoming requests on Conn must be served to make
  145. // progress.
  146. func Mount(dir string, options ...MountOption) (*Conn, error) {
  147. conf := mountConfig{
  148. options: make(map[string]string),
  149. }
  150. for _, option := range options {
  151. if err := option(&conf); err != nil {
  152. return nil, err
  153. }
  154. }
  155. ready := make(chan struct{}, 1)
  156. c := &Conn{
  157. Ready: ready,
  158. }
  159. f, err := mount(dir, &conf, ready, &c.MountError)
  160. if err != nil {
  161. return nil, err
  162. }
  163. c.dev = f
  164. if err := initMount(c, &conf); err != nil {
  165. c.Close()
  166. if err == ErrClosedWithoutInit {
  167. // see if we can provide a better error
  168. <-c.Ready
  169. if err := c.MountError; err != nil {
  170. return nil, err
  171. }
  172. }
  173. return nil, err
  174. }
  175. return c, nil
  176. }
  177. type OldVersionError struct {
  178. Kernel Protocol
  179. LibraryMin Protocol
  180. }
  181. func (e *OldVersionError) Error() string {
  182. return fmt.Sprintf("kernel FUSE version is too old: %v < %v", e.Kernel, e.LibraryMin)
  183. }
  184. var (
  185. ErrClosedWithoutInit = errors.New("fuse connection closed without init")
  186. )
  187. func initMount(c *Conn, conf *mountConfig) error {
  188. req, err := c.ReadRequest()
  189. if err != nil {
  190. if err == io.EOF {
  191. return ErrClosedWithoutInit
  192. }
  193. return err
  194. }
  195. r, ok := req.(*InitRequest)
  196. if !ok {
  197. return fmt.Errorf("missing init, got: %T", req)
  198. }
  199. min := Protocol{protoVersionMinMajor, protoVersionMinMinor}
  200. if r.Kernel.LT(min) {
  201. req.RespondError(Errno(syscall.EPROTO))
  202. c.Close()
  203. return &OldVersionError{
  204. Kernel: r.Kernel,
  205. LibraryMin: min,
  206. }
  207. }
  208. proto := Protocol{protoVersionMaxMajor, protoVersionMaxMinor}
  209. if r.Kernel.LT(proto) {
  210. // Kernel doesn't support the latest version we have.
  211. proto = r.Kernel
  212. }
  213. c.proto = proto
  214. s := &InitResponse{
  215. Library: proto,
  216. MaxReadahead: conf.maxReadahead,
  217. MaxWrite: maxWrite,
  218. Flags: InitBigWrites | conf.initFlags,
  219. }
  220. r.Respond(s)
  221. return nil
  222. }
  223. // A Request represents a single FUSE request received from the kernel.
  224. // Use a type switch to determine the specific kind.
  225. // A request of unrecognized type will have concrete type *Header.
  226. type Request interface {
  227. // Hdr returns the Header associated with this request.
  228. Hdr() *Header
  229. // RespondError responds to the request with the given error.
  230. RespondError(error)
  231. String() string
  232. }
  233. // A RequestID identifies an active FUSE request.
  234. type RequestID uint64
  235. func (r RequestID) String() string {
  236. return fmt.Sprintf("%#x", uint64(r))
  237. }
  238. // A NodeID is a number identifying a directory or file.
  239. // It must be unique among IDs returned in LookupResponses
  240. // that have not yet been forgotten by ForgetRequests.
  241. type NodeID uint64
  242. func (n NodeID) String() string {
  243. return fmt.Sprintf("%#x", uint64(n))
  244. }
  245. // A HandleID is a number identifying an open directory or file.
  246. // It only needs to be unique while the directory or file is open.
  247. type HandleID uint64
  248. func (h HandleID) String() string {
  249. return fmt.Sprintf("%#x", uint64(h))
  250. }
  251. // The RootID identifies the root directory of a FUSE file system.
  252. const RootID NodeID = rootID
  253. // A Header describes the basic information sent in every request.
  254. type Header struct {
  255. Conn *Conn `json:"-"` // connection this request was received on
  256. ID RequestID // unique ID for request
  257. Node NodeID // file or directory the request is about
  258. Uid uint32 // user ID of process making request
  259. Gid uint32 // group ID of process making request
  260. Pid uint32 // process ID of process making request
  261. // for returning to reqPool
  262. msg *message
  263. }
  264. func (h *Header) String() string {
  265. return fmt.Sprintf("ID=%v Node=%v Uid=%d Gid=%d Pid=%d", h.ID, h.Node, h.Uid, h.Gid, h.Pid)
  266. }
  267. func (h *Header) Hdr() *Header {
  268. return h
  269. }
  270. func (h *Header) noResponse() {
  271. putMessage(h.msg)
  272. }
  273. func (h *Header) respond(msg []byte) {
  274. out := (*outHeader)(unsafe.Pointer(&msg[0]))
  275. out.Unique = uint64(h.ID)
  276. h.Conn.respond(msg)
  277. putMessage(h.msg)
  278. }
  279. // An ErrorNumber is an error with a specific error number.
  280. //
  281. // Operations may return an error value that implements ErrorNumber to
  282. // control what specific error number (errno) to return.
  283. type ErrorNumber interface {
  284. // Errno returns the the error number (errno) for this error.
  285. Errno() Errno
  286. }
  287. const (
  288. // ENOSYS indicates that the call is not supported.
  289. ENOSYS = Errno(syscall.ENOSYS)
  290. // ESTALE is used by Serve to respond to violations of the FUSE protocol.
  291. ESTALE = Errno(syscall.ESTALE)
  292. ENOENT = Errno(syscall.ENOENT)
  293. EIO = Errno(syscall.EIO)
  294. EPERM = Errno(syscall.EPERM)
  295. // EINTR indicates request was interrupted by an InterruptRequest.
  296. // See also fs.Intr.
  297. EINTR = Errno(syscall.EINTR)
  298. ERANGE = Errno(syscall.ERANGE)
  299. ENOTSUP = Errno(syscall.ENOTSUP)
  300. EEXIST = Errno(syscall.EEXIST)
  301. )
  302. // DefaultErrno is the errno used when error returned does not
  303. // implement ErrorNumber.
  304. const DefaultErrno = EIO
  305. var errnoNames = map[Errno]string{
  306. ENOSYS: "ENOSYS",
  307. ESTALE: "ESTALE",
  308. ENOENT: "ENOENT",
  309. EIO: "EIO",
  310. EPERM: "EPERM",
  311. EINTR: "EINTR",
  312. EEXIST: "EEXIST",
  313. }
  314. // Errno implements Error and ErrorNumber using a syscall.Errno.
  315. type Errno syscall.Errno
  316. var _ = ErrorNumber(Errno(0))
  317. var _ = error(Errno(0))
  318. func (e Errno) Errno() Errno {
  319. return e
  320. }
  321. func (e Errno) String() string {
  322. return syscall.Errno(e).Error()
  323. }
  324. func (e Errno) Error() string {
  325. return syscall.Errno(e).Error()
  326. }
  327. // ErrnoName returns the short non-numeric identifier for this errno.
  328. // For example, "EIO".
  329. func (e Errno) ErrnoName() string {
  330. s := errnoNames[e]
  331. if s == "" {
  332. s = fmt.Sprint(e.Errno())
  333. }
  334. return s
  335. }
  336. func (e Errno) MarshalText() ([]byte, error) {
  337. s := e.ErrnoName()
  338. return []byte(s), nil
  339. }
  340. func (h *Header) RespondError(err error) {
  341. errno := DefaultErrno
  342. if ferr, ok := err.(ErrorNumber); ok {
  343. errno = ferr.Errno()
  344. }
  345. // FUSE uses negative errors!
  346. // TODO: File bug report against OSXFUSE: positive error causes kernel panic.
  347. buf := newBuffer(0)
  348. hOut := (*outHeader)(unsafe.Pointer(&buf[0]))
  349. hOut.Error = -int32(errno)
  350. h.respond(buf)
  351. }
  352. // All requests read from the kernel, without data, are shorter than
  353. // this.
  354. var maxRequestSize = syscall.Getpagesize()
  355. var bufSize = maxRequestSize + maxWrite
  356. // reqPool is a pool of messages.
  357. //
  358. // Lifetime of a logical message is from getMessage to putMessage.
  359. // getMessage is called by ReadRequest. putMessage is called by
  360. // Conn.ReadRequest, Request.Respond, or Request.RespondError.
  361. //
  362. // Messages in the pool are guaranteed to have conn and off zeroed,
  363. // buf allocated and len==bufSize, and hdr set.
  364. var reqPool = sync.Pool{
  365. New: allocMessage,
  366. }
  367. func allocMessage() interface{} {
  368. m := &message{buf: make([]byte, bufSize)}
  369. m.hdr = (*inHeader)(unsafe.Pointer(&m.buf[0]))
  370. return m
  371. }
  372. func getMessage(c *Conn) *message {
  373. m := reqPool.Get().(*message)
  374. m.conn = c
  375. return m
  376. }
  377. func putMessage(m *message) {
  378. m.buf = m.buf[:bufSize]
  379. m.conn = nil
  380. m.off = 0
  381. reqPool.Put(m)
  382. }
  383. // a message represents the bytes of a single FUSE message
  384. type message struct {
  385. conn *Conn
  386. buf []byte // all bytes
  387. hdr *inHeader // header
  388. off int // offset for reading additional fields
  389. }
  390. func (m *message) len() uintptr {
  391. return uintptr(len(m.buf) - m.off)
  392. }
  393. func (m *message) data() unsafe.Pointer {
  394. var p unsafe.Pointer
  395. if m.off < len(m.buf) {
  396. p = unsafe.Pointer(&m.buf[m.off])
  397. }
  398. return p
  399. }
  400. func (m *message) bytes() []byte {
  401. return m.buf[m.off:]
  402. }
  403. func (m *message) Header() Header {
  404. h := m.hdr
  405. return Header{
  406. Conn: m.conn,
  407. ID: RequestID(h.Unique),
  408. Node: NodeID(h.Nodeid),
  409. Uid: h.Uid,
  410. Gid: h.Gid,
  411. Pid: h.Pid,
  412. msg: m,
  413. }
  414. }
  415. // fileMode returns a Go os.FileMode from a Unix mode.
  416. func fileMode(unixMode uint32) os.FileMode {
  417. mode := os.FileMode(unixMode & 0777)
  418. switch unixMode & syscall.S_IFMT {
  419. case syscall.S_IFREG:
  420. // nothing
  421. case syscall.S_IFDIR:
  422. mode |= os.ModeDir
  423. case syscall.S_IFCHR:
  424. mode |= os.ModeCharDevice | os.ModeDevice
  425. case syscall.S_IFBLK:
  426. mode |= os.ModeDevice
  427. case syscall.S_IFIFO:
  428. mode |= os.ModeNamedPipe
  429. case syscall.S_IFLNK:
  430. mode |= os.ModeSymlink
  431. case syscall.S_IFSOCK:
  432. mode |= os.ModeSocket
  433. default:
  434. // no idea
  435. mode |= os.ModeDevice
  436. }
  437. if unixMode&syscall.S_ISUID != 0 {
  438. mode |= os.ModeSetuid
  439. }
  440. if unixMode&syscall.S_ISGID != 0 {
  441. mode |= os.ModeSetgid
  442. }
  443. return mode
  444. }
  445. type noOpcode struct {
  446. Opcode uint32
  447. }
  448. func (m noOpcode) String() string {
  449. return fmt.Sprintf("No opcode %v", m.Opcode)
  450. }
  451. type malformedMessage struct {
  452. }
  453. func (malformedMessage) String() string {
  454. return "malformed message"
  455. }
  456. // Close closes the FUSE connection.
  457. func (c *Conn) Close() error {
  458. c.wio.Lock()
  459. defer c.wio.Unlock()
  460. c.rio.Lock()
  461. defer c.rio.Unlock()
  462. return c.dev.Close()
  463. }
  464. // caller must hold wio or rio
  465. func (c *Conn) fd() int {
  466. return int(c.dev.Fd())
  467. }
  468. func (c *Conn) Protocol() Protocol {
  469. return c.proto
  470. }
  471. // ReadRequest returns the next FUSE request from the kernel.
  472. //
  473. // Caller must call either Request.Respond or Request.RespondError in
  474. // a reasonable time. Caller must not retain Request after that call.
  475. func (c *Conn) ReadRequest() (Request, error) {
  476. m := getMessage(c)
  477. loop:
  478. c.rio.RLock()
  479. n, err := syscall.Read(c.fd(), m.buf)
  480. c.rio.RUnlock()
  481. if err == syscall.EINTR {
  482. // OSXFUSE sends EINTR to userspace when a request interrupt
  483. // completed before it got sent to userspace?
  484. goto loop
  485. }
  486. if err != nil && err != syscall.ENODEV {
  487. putMessage(m)
  488. return nil, err
  489. }
  490. if n <= 0 {
  491. putMessage(m)
  492. return nil, io.EOF
  493. }
  494. m.buf = m.buf[:n]
  495. if n < inHeaderSize {
  496. putMessage(m)
  497. return nil, errors.New("fuse: message too short")
  498. }
  499. // FreeBSD FUSE sends a short length in the header
  500. // for FUSE_INIT even though the actual read length is correct.
  501. if n == inHeaderSize+initInSize && m.hdr.Opcode == opInit && m.hdr.Len < uint32(n) {
  502. m.hdr.Len = uint32(n)
  503. }
  504. // OSXFUSE sometimes sends the wrong m.hdr.Len in a FUSE_WRITE message.
  505. if m.hdr.Len < uint32(n) && m.hdr.Len >= uint32(unsafe.Sizeof(writeIn{})) && m.hdr.Opcode == opWrite {
  506. m.hdr.Len = uint32(n)
  507. }
  508. if m.hdr.Len != uint32(n) {
  509. // prepare error message before returning m to pool
  510. err := fmt.Errorf("fuse: read %d opcode %d but expected %d", n, m.hdr.Opcode, m.hdr.Len)
  511. putMessage(m)
  512. return nil, err
  513. }
  514. m.off = inHeaderSize
  515. // Convert to data structures.
  516. // Do not trust kernel to hand us well-formed data.
  517. var req Request
  518. switch m.hdr.Opcode {
  519. default:
  520. Debug(noOpcode{Opcode: m.hdr.Opcode})
  521. goto unrecognized
  522. case opLookup:
  523. buf := m.bytes()
  524. n := len(buf)
  525. if n == 0 || buf[n-1] != '\x00' {
  526. goto corrupt
  527. }
  528. req = &LookupRequest{
  529. Header: m.Header(),
  530. Name: string(buf[:n-1]),
  531. }
  532. case opForget:
  533. in := (*forgetIn)(m.data())
  534. if m.len() < unsafe.Sizeof(*in) {
  535. goto corrupt
  536. }
  537. req = &ForgetRequest{
  538. Header: m.Header(),
  539. N: in.Nlookup,
  540. }
  541. case opGetattr:
  542. switch {
  543. case c.proto.LT(Protocol{7, 9}):
  544. req = &GetattrRequest{
  545. Header: m.Header(),
  546. }
  547. default:
  548. in := (*getattrIn)(m.data())
  549. if m.len() < unsafe.Sizeof(*in) {
  550. goto corrupt
  551. }
  552. req = &GetattrRequest{
  553. Header: m.Header(),
  554. Flags: GetattrFlags(in.GetattrFlags),
  555. Handle: HandleID(in.Fh),
  556. }
  557. }
  558. case opSetattr:
  559. in := (*setattrIn)(m.data())
  560. if m.len() < unsafe.Sizeof(*in) {
  561. goto corrupt
  562. }
  563. req = &SetattrRequest{
  564. Header: m.Header(),
  565. Valid: SetattrValid(in.Valid),
  566. Handle: HandleID(in.Fh),
  567. Size: in.Size,
  568. Atime: time.Unix(int64(in.Atime), int64(in.AtimeNsec)),
  569. Mtime: time.Unix(int64(in.Mtime), int64(in.MtimeNsec)),
  570. Mode: fileMode(in.Mode),
  571. Uid: in.Uid,
  572. Gid: in.Gid,
  573. Bkuptime: in.BkupTime(),
  574. Chgtime: in.Chgtime(),
  575. Flags: in.Flags(),
  576. }
  577. case opReadlink:
  578. if len(m.bytes()) > 0 {
  579. goto corrupt
  580. }
  581. req = &ReadlinkRequest{
  582. Header: m.Header(),
  583. }
  584. case opSymlink:
  585. // m.bytes() is "newName\0target\0"
  586. names := m.bytes()
  587. if len(names) == 0 || names[len(names)-1] != 0 {
  588. goto corrupt
  589. }
  590. i := bytes.IndexByte(names, '\x00')
  591. if i < 0 {
  592. goto corrupt
  593. }
  594. newName, target := names[0:i], names[i+1:len(names)-1]
  595. req = &SymlinkRequest{
  596. Header: m.Header(),
  597. NewName: string(newName),
  598. Target: string(target),
  599. }
  600. case opLink:
  601. in := (*linkIn)(m.data())
  602. if m.len() < unsafe.Sizeof(*in) {
  603. goto corrupt
  604. }
  605. newName := m.bytes()[unsafe.Sizeof(*in):]
  606. if len(newName) < 2 || newName[len(newName)-1] != 0 {
  607. goto corrupt
  608. }
  609. newName = newName[:len(newName)-1]
  610. req = &LinkRequest{
  611. Header: m.Header(),
  612. OldNode: NodeID(in.Oldnodeid),
  613. NewName: string(newName),
  614. }
  615. case opMknod:
  616. size := mknodInSize(c.proto)
  617. if m.len() < size {
  618. goto corrupt
  619. }
  620. in := (*mknodIn)(m.data())
  621. name := m.bytes()[size:]
  622. if len(name) < 2 || name[len(name)-1] != '\x00' {
  623. goto corrupt
  624. }
  625. name = name[:len(name)-1]
  626. r := &MknodRequest{
  627. Header: m.Header(),
  628. Mode: fileMode(in.Mode),
  629. Rdev: in.Rdev,
  630. Name: string(name),
  631. }
  632. if c.proto.GE(Protocol{7, 12}) {
  633. r.Umask = fileMode(in.Umask) & os.ModePerm
  634. }
  635. req = r
  636. case opMkdir:
  637. size := mkdirInSize(c.proto)
  638. if m.len() < size {
  639. goto corrupt
  640. }
  641. in := (*mkdirIn)(m.data())
  642. name := m.bytes()[size:]
  643. i := bytes.IndexByte(name, '\x00')
  644. if i < 0 {
  645. goto corrupt
  646. }
  647. r := &MkdirRequest{
  648. Header: m.Header(),
  649. Name: string(name[:i]),
  650. // observed on Linux: mkdirIn.Mode & syscall.S_IFMT == 0,
  651. // and this causes fileMode to go into it's "no idea"
  652. // code branch; enforce type to directory
  653. Mode: fileMode((in.Mode &^ syscall.S_IFMT) | syscall.S_IFDIR),
  654. }
  655. if c.proto.GE(Protocol{7, 12}) {
  656. r.Umask = fileMode(in.Umask) & os.ModePerm
  657. }
  658. req = r
  659. case opUnlink, opRmdir:
  660. buf := m.bytes()
  661. n := len(buf)
  662. if n == 0 || buf[n-1] != '\x00' {
  663. goto corrupt
  664. }
  665. req = &RemoveRequest{
  666. Header: m.Header(),
  667. Name: string(buf[:n-1]),
  668. Dir: m.hdr.Opcode == opRmdir,
  669. }
  670. case opRename:
  671. in := (*renameIn)(m.data())
  672. if m.len() < unsafe.Sizeof(*in) {
  673. goto corrupt
  674. }
  675. newDirNodeID := NodeID(in.Newdir)
  676. oldNew := m.bytes()[unsafe.Sizeof(*in):]
  677. // oldNew should be "old\x00new\x00"
  678. if len(oldNew) < 4 {
  679. goto corrupt
  680. }
  681. if oldNew[len(oldNew)-1] != '\x00' {
  682. goto corrupt
  683. }
  684. i := bytes.IndexByte(oldNew, '\x00')
  685. if i < 0 {
  686. goto corrupt
  687. }
  688. oldName, newName := string(oldNew[:i]), string(oldNew[i+1:len(oldNew)-1])
  689. req = &RenameRequest{
  690. Header: m.Header(),
  691. NewDir: newDirNodeID,
  692. OldName: oldName,
  693. NewName: newName,
  694. }
  695. case opOpendir, opOpen:
  696. in := (*openIn)(m.data())
  697. if m.len() < unsafe.Sizeof(*in) {
  698. goto corrupt
  699. }
  700. req = &OpenRequest{
  701. Header: m.Header(),
  702. Dir: m.hdr.Opcode == opOpendir,
  703. Flags: openFlags(in.Flags),
  704. }
  705. case opRead, opReaddir:
  706. in := (*readIn)(m.data())
  707. if m.len() < readInSize(c.proto) {
  708. goto corrupt
  709. }
  710. r := &ReadRequest{
  711. Header: m.Header(),
  712. Dir: m.hdr.Opcode == opReaddir,
  713. Handle: HandleID(in.Fh),
  714. Offset: int64(in.Offset),
  715. Size: int(in.Size),
  716. }
  717. if c.proto.GE(Protocol{7, 9}) {
  718. r.Flags = ReadFlags(in.ReadFlags)
  719. r.LockOwner = in.LockOwner
  720. r.FileFlags = openFlags(in.Flags)
  721. }
  722. req = r
  723. case opWrite:
  724. in := (*writeIn)(m.data())
  725. if m.len() < writeInSize(c.proto) {
  726. goto corrupt
  727. }
  728. r := &WriteRequest{
  729. Header: m.Header(),
  730. Handle: HandleID(in.Fh),
  731. Offset: int64(in.Offset),
  732. Flags: WriteFlags(in.WriteFlags),
  733. }
  734. if c.proto.GE(Protocol{7, 9}) {
  735. r.LockOwner = in.LockOwner
  736. r.FileFlags = openFlags(in.Flags)
  737. }
  738. buf := m.bytes()[writeInSize(c.proto):]
  739. if uint32(len(buf)) < in.Size {
  740. goto corrupt
  741. }
  742. r.Data = buf
  743. req = r
  744. case opStatfs:
  745. req = &StatfsRequest{
  746. Header: m.Header(),
  747. }
  748. case opRelease, opReleasedir:
  749. in := (*releaseIn)(m.data())
  750. if m.len() < unsafe.Sizeof(*in) {
  751. goto corrupt
  752. }
  753. req = &ReleaseRequest{
  754. Header: m.Header(),
  755. Dir: m.hdr.Opcode == opReleasedir,
  756. Handle: HandleID(in.Fh),
  757. Flags: openFlags(in.Flags),
  758. ReleaseFlags: ReleaseFlags(in.ReleaseFlags),
  759. LockOwner: in.LockOwner,
  760. }
  761. case opFsync, opFsyncdir:
  762. in := (*fsyncIn)(m.data())
  763. if m.len() < unsafe.Sizeof(*in) {
  764. goto corrupt
  765. }
  766. req = &FsyncRequest{
  767. Dir: m.hdr.Opcode == opFsyncdir,
  768. Header: m.Header(),
  769. Handle: HandleID(in.Fh),
  770. Flags: in.FsyncFlags,
  771. }
  772. case opSetxattr:
  773. in := (*setxattrIn)(m.data())
  774. if m.len() < unsafe.Sizeof(*in) {
  775. goto corrupt
  776. }
  777. m.off += int(unsafe.Sizeof(*in))
  778. name := m.bytes()
  779. i := bytes.IndexByte(name, '\x00')
  780. if i < 0 {
  781. goto corrupt
  782. }
  783. xattr := name[i+1:]
  784. if uint32(len(xattr)) < in.Size {
  785. goto corrupt
  786. }
  787. xattr = xattr[:in.Size]
  788. req = &SetxattrRequest{
  789. Header: m.Header(),
  790. Flags: in.Flags,
  791. Position: in.position(),
  792. Name: string(name[:i]),
  793. Xattr: xattr,
  794. }
  795. case opGetxattr:
  796. in := (*getxattrIn)(m.data())
  797. if m.len() < unsafe.Sizeof(*in) {
  798. goto corrupt
  799. }
  800. name := m.bytes()[unsafe.Sizeof(*in):]
  801. i := bytes.IndexByte(name, '\x00')
  802. if i < 0 {
  803. goto corrupt
  804. }
  805. req = &GetxattrRequest{
  806. Header: m.Header(),
  807. Name: string(name[:i]),
  808. Size: in.Size,
  809. Position: in.position(),
  810. }
  811. case opListxattr:
  812. in := (*getxattrIn)(m.data())
  813. if m.len() < unsafe.Sizeof(*in) {
  814. goto corrupt
  815. }
  816. req = &ListxattrRequest{
  817. Header: m.Header(),
  818. Size: in.Size,
  819. Position: in.position(),
  820. }
  821. case opRemovexattr:
  822. buf := m.bytes()
  823. n := len(buf)
  824. if n == 0 || buf[n-1] != '\x00' {
  825. goto corrupt
  826. }
  827. req = &RemovexattrRequest{
  828. Header: m.Header(),
  829. Name: string(buf[:n-1]),
  830. }
  831. case opFlush:
  832. in := (*flushIn)(m.data())
  833. if m.len() < unsafe.Sizeof(*in) {
  834. goto corrupt
  835. }
  836. req = &FlushRequest{
  837. Header: m.Header(),
  838. Handle: HandleID(in.Fh),
  839. Flags: in.FlushFlags,
  840. LockOwner: in.LockOwner,
  841. }
  842. case opInit:
  843. in := (*initIn)(m.data())
  844. if m.len() < unsafe.Sizeof(*in) {
  845. goto corrupt
  846. }
  847. req = &InitRequest{
  848. Header: m.Header(),
  849. Kernel: Protocol{in.Major, in.Minor},
  850. MaxReadahead: in.MaxReadahead,
  851. Flags: InitFlags(in.Flags),
  852. }
  853. case opGetlk:
  854. panic("opGetlk")
  855. case opSetlk:
  856. panic("opSetlk")
  857. case opSetlkw:
  858. panic("opSetlkw")
  859. case opAccess:
  860. in := (*accessIn)(m.data())
  861. if m.len() < unsafe.Sizeof(*in) {
  862. goto corrupt
  863. }
  864. req = &AccessRequest{
  865. Header: m.Header(),
  866. Mask: in.Mask,
  867. }
  868. case opCreate:
  869. size := createInSize(c.proto)
  870. if m.len() < size {
  871. goto corrupt
  872. }
  873. in := (*createIn)(m.data())
  874. name := m.bytes()[size:]
  875. i := bytes.IndexByte(name, '\x00')
  876. if i < 0 {
  877. goto corrupt
  878. }
  879. r := &CreateRequest{
  880. Header: m.Header(),
  881. Flags: openFlags(in.Flags),
  882. Mode: fileMode(in.Mode),
  883. Name: string(name[:i]),
  884. }
  885. if c.proto.GE(Protocol{7, 12}) {
  886. r.Umask = fileMode(in.Umask) & os.ModePerm
  887. }
  888. req = r
  889. case opInterrupt:
  890. in := (*interruptIn)(m.data())
  891. if m.len() < unsafe.Sizeof(*in) {
  892. goto corrupt
  893. }
  894. req = &InterruptRequest{
  895. Header: m.Header(),
  896. IntrID: RequestID(in.Unique),
  897. }
  898. case opBmap:
  899. panic("opBmap")
  900. case opDestroy:
  901. req = &DestroyRequest{
  902. Header: m.Header(),
  903. }
  904. // OS X
  905. case opSetvolname:
  906. panic("opSetvolname")
  907. case opGetxtimes:
  908. panic("opGetxtimes")
  909. case opExchange:
  910. in := (*exchangeIn)(m.data())
  911. if m.len() < unsafe.Sizeof(*in) {
  912. goto corrupt
  913. }
  914. oldDirNodeID := NodeID(in.Olddir)
  915. newDirNodeID := NodeID(in.Newdir)
  916. oldNew := m.bytes()[unsafe.Sizeof(*in):]
  917. // oldNew should be "oldname\x00newname\x00"
  918. if len(oldNew) < 4 {
  919. goto corrupt
  920. }
  921. if oldNew[len(oldNew)-1] != '\x00' {
  922. goto corrupt
  923. }
  924. i := bytes.IndexByte(oldNew, '\x00')
  925. if i < 0 {
  926. goto corrupt
  927. }
  928. oldName, newName := string(oldNew[:i]), string(oldNew[i+1:len(oldNew)-1])
  929. req = &ExchangeDataRequest{
  930. Header: m.Header(),
  931. OldDir: oldDirNodeID,
  932. NewDir: newDirNodeID,
  933. OldName: oldName,
  934. NewName: newName,
  935. // TODO options
  936. }
  937. }
  938. return req, nil
  939. corrupt:
  940. Debug(malformedMessage{})
  941. putMessage(m)
  942. return nil, fmt.Errorf("fuse: malformed message")
  943. unrecognized:
  944. // Unrecognized message.
  945. // Assume higher-level code will send a "no idea what you mean" error.
  946. h := m.Header()
  947. return &h, nil
  948. }
  949. type bugShortKernelWrite struct {
  950. Written int64
  951. Length int64
  952. Error string
  953. Stack string
  954. }
  955. func (b bugShortKernelWrite) String() string {
  956. return fmt.Sprintf("short kernel write: written=%d/%d error=%q stack=\n%s", b.Written, b.Length, b.Error, b.Stack)
  957. }
  958. type bugKernelWriteError struct {
  959. Error string
  960. Stack string
  961. }
  962. func (b bugKernelWriteError) String() string {
  963. return fmt.Sprintf("kernel write error: error=%q stack=\n%s", b.Error, b.Stack)
  964. }
  965. // safe to call even with nil error
  966. func errorString(err error) string {
  967. if err == nil {
  968. return ""
  969. }
  970. return err.Error()
  971. }
  972. func (c *Conn) writeToKernel(msg []byte) error {
  973. out := (*outHeader)(unsafe.Pointer(&msg[0]))
  974. out.Len = uint32(len(msg))
  975. c.wio.RLock()
  976. defer c.wio.RUnlock()
  977. nn, err := syscall.Write(c.fd(), msg)
  978. if err == nil && nn != len(msg) {
  979. Debug(bugShortKernelWrite{
  980. Written: int64(nn),
  981. Length: int64(len(msg)),
  982. Error: errorString(err),
  983. Stack: stack(),
  984. })
  985. }
  986. return err
  987. }
  988. func (c *Conn) respond(msg []byte) {
  989. if err := c.writeToKernel(msg); err != nil {
  990. Debug(bugKernelWriteError{
  991. Error: errorString(err),
  992. Stack: stack(),
  993. })
  994. }
  995. }
  996. type notCachedError struct{}
  997. func (notCachedError) Error() string {
  998. return "node not cached"
  999. }
  1000. var _ ErrorNumber = notCachedError{}
  1001. func (notCachedError) Errno() Errno {
  1002. // Behave just like if the original syscall.ENOENT had been passed
  1003. // straight through.
  1004. return ENOENT
  1005. }
  1006. var (
  1007. ErrNotCached = notCachedError{}
  1008. )
  1009. // sendInvalidate sends an invalidate notification to kernel.
  1010. //
  1011. // A returned ENOENT is translated to a friendlier error.
  1012. func (c *Conn) sendInvalidate(msg []byte) error {
  1013. switch err := c.writeToKernel(msg); err {
  1014. case syscall.ENOENT:
  1015. return ErrNotCached
  1016. default:
  1017. return err
  1018. }
  1019. }
  1020. // InvalidateNode invalidates the kernel cache of the attributes and a
  1021. // range of the data of a node.
  1022. //
  1023. // Giving offset 0 and size -1 means all data. To invalidate just the
  1024. // attributes, give offset 0 and size 0.
  1025. //
  1026. // Returns ErrNotCached if the kernel is not currently caching the
  1027. // node.
  1028. func (c *Conn) InvalidateNode(nodeID NodeID, off int64, size int64) error {
  1029. buf := newBuffer(unsafe.Sizeof(notifyInvalInodeOut{}))
  1030. h := (*outHeader)(unsafe.Pointer(&buf[0]))
  1031. // h.Unique is 0
  1032. h.Error = notifyCodeInvalInode
  1033. out := (*notifyInvalInodeOut)(buf.alloc(unsafe.Sizeof(notifyInvalInodeOut{})))
  1034. out.Ino = uint64(nodeID)
  1035. out.Off = off
  1036. out.Len = size
  1037. return c.sendInvalidate(buf)
  1038. }
  1039. // InvalidateEntry invalidates the kernel cache of the directory entry
  1040. // identified by parent directory node ID and entry basename.
  1041. //
  1042. // Kernel may or may not cache directory listings. To invalidate
  1043. // those, use InvalidateNode to invalidate all of the data for a
  1044. // directory. (As of 2015-06, Linux FUSE does not cache directory
  1045. // listings.)
  1046. //
  1047. // Returns ErrNotCached if the kernel is not currently caching the
  1048. // node.
  1049. func (c *Conn) InvalidateEntry(parent NodeID, name string) error {
  1050. const maxUint32 = ^uint32(0)
  1051. if uint64(len(name)) > uint64(maxUint32) {
  1052. // very unlikely, but we don't want to silently truncate
  1053. return syscall.ENAMETOOLONG
  1054. }
  1055. buf := newBuffer(unsafe.Sizeof(notifyInvalEntryOut{}) + uintptr(len(name)) + 1)
  1056. h := (*outHeader)(unsafe.Pointer(&buf[0]))
  1057. // h.Unique is 0
  1058. h.Error = notifyCodeInvalEntry
  1059. out := (*notifyInvalEntryOut)(buf.alloc(unsafe.Sizeof(notifyInvalEntryOut{})))
  1060. out.Parent = uint64(parent)
  1061. out.Namelen = uint32(len(name))
  1062. buf = append(buf, name...)
  1063. buf = append(buf, '\x00')
  1064. return c.sendInvalidate(buf)
  1065. }
  1066. // An InitRequest is the first request sent on a FUSE file system.
  1067. type InitRequest struct {
  1068. Header `json:"-"`
  1069. Kernel Protocol
  1070. // Maximum readahead in bytes that the kernel plans to use.
  1071. MaxReadahead uint32
  1072. Flags InitFlags
  1073. }
  1074. var _ = Request(&InitRequest{})
  1075. func (r *InitRequest) String() string {
  1076. return fmt.Sprintf("Init [%v] %v ra=%d fl=%v", &r.Header, r.Kernel, r.MaxReadahead, r.Flags)
  1077. }
  1078. // An InitResponse is the response to an InitRequest.
  1079. type InitResponse struct {
  1080. Library Protocol
  1081. // Maximum readahead in bytes that the kernel can use. Ignored if
  1082. // greater than InitRequest.MaxReadahead.
  1083. MaxReadahead uint32
  1084. Flags InitFlags
  1085. // Maximum size of a single write operation.
  1086. // Linux enforces a minimum of 4 KiB.
  1087. MaxWrite uint32
  1088. }
  1089. func (r *InitResponse) String() string {
  1090. return fmt.Sprintf("Init %v ra=%d fl=%v w=%d", r.Library, r.MaxReadahead, r.Flags, r.MaxWrite)
  1091. }
  1092. // Respond replies to the request with the given response.
  1093. func (r *InitRequest) Respond(resp *InitResponse) {
  1094. buf := newBuffer(unsafe.Sizeof(initOut{}))
  1095. out := (*initOut)(buf.alloc(unsafe.Sizeof(initOut{})))
  1096. out.Major = resp.Library.Major
  1097. out.Minor = resp.Library.Minor
  1098. out.MaxReadahead = resp.MaxReadahead
  1099. out.Flags = uint32(resp.Flags)
  1100. out.MaxWrite = resp.MaxWrite
  1101. // MaxWrite larger than our receive buffer would just lead to
  1102. // errors on large writes.
  1103. if out.MaxWrite > maxWrite {
  1104. out.MaxWrite = maxWrite
  1105. }
  1106. r.respond(buf)
  1107. }
  1108. // A StatfsRequest requests information about the mounted file system.
  1109. type StatfsRequest struct {
  1110. Header `json:"-"`
  1111. }
  1112. var _ = Request(&StatfsRequest{})
  1113. func (r *StatfsRequest) String() string {
  1114. return fmt.Sprintf("Statfs [%s]", &r.Header)
  1115. }
  1116. // Respond replies to the request with the given response.
  1117. func (r *StatfsRequest) Respond(resp *StatfsResponse) {
  1118. buf := newBuffer(unsafe.Sizeof(statfsOut{}))
  1119. out := (*statfsOut)(buf.alloc(unsafe.Sizeof(statfsOut{})))
  1120. out.St = kstatfs{
  1121. Blocks: resp.Blocks,
  1122. Bfree: resp.Bfree,
  1123. Bavail: resp.Bavail,
  1124. Files: resp.Files,
  1125. Bsize: resp.Bsize,
  1126. Namelen: resp.Namelen,
  1127. Frsize: resp.Frsize,
  1128. }
  1129. r.respond(buf)
  1130. }
  1131. // A StatfsResponse is the response to a StatfsRequest.
  1132. type StatfsResponse struct {
  1133. Blocks uint64 // Total data blocks in file system.
  1134. Bfree uint64 // Free blocks in file system.
  1135. Bavail uint64 // Free blocks in file system if you're not root.
  1136. Files uint64 // Total files in file system.
  1137. Ffree uint64 // Free files in file system.
  1138. Bsize uint32 // Block size
  1139. Namelen uint32 // Maximum file name length?
  1140. Frsize uint32 // Fragment size, smallest addressable data size in the file system.
  1141. }
  1142. func (r *StatfsResponse) String() string {
  1143. return fmt.Sprintf("Statfs blocks=%d/%d/%d files=%d/%d bsize=%d frsize=%d namelen=%d",
  1144. r.Bavail, r.Bfree, r.Blocks,
  1145. r.Ffree, r.Files,
  1146. r.Bsize,
  1147. r.Frsize,
  1148. r.Namelen,
  1149. )
  1150. }
  1151. // An AccessRequest asks whether the file can be accessed
  1152. // for the purpose specified by the mask.
  1153. type AccessRequest struct {
  1154. Header `json:"-"`
  1155. Mask uint32
  1156. }
  1157. var _ = Request(&AccessRequest{})
  1158. func (r *AccessRequest) String() string {
  1159. return fmt.Sprintf("Access [%s] mask=%#x", &r.Header, r.Mask)
  1160. }
  1161. // Respond replies to the request indicating that access is allowed.
  1162. // To deny access, use RespondError.
  1163. func (r *AccessRequest) Respond() {
  1164. buf := newBuffer(0)
  1165. r.respond(buf)
  1166. }
  1167. // An Attr is the metadata for a single file or directory.
  1168. type Attr struct {
  1169. Valid time.Duration // how long Attr can be cached
  1170. Inode uint64 // inode number
  1171. Size uint64 // size in bytes
  1172. Blocks uint64 // size in 512-byte units
  1173. Atime time.Time // time of last access
  1174. Mtime time.Time // time of last modification
  1175. Ctime time.Time // time of last inode change
  1176. Crtime time.Time // time of creation (OS X only)
  1177. Mode os.FileMode // file mode
  1178. Nlink uint32 // number of links (usually 1)
  1179. Uid uint32 // owner uid
  1180. Gid uint32 // group gid
  1181. Rdev uint32 // device numbers
  1182. Flags uint32 // chflags(2) flags (OS X only)
  1183. BlockSize uint32 // preferred blocksize for filesystem I/O
  1184. }
  1185. func (a Attr) String() string {
  1186. return fmt.Sprintf("valid=%v ino=%v size=%d mode=%v", a.Valid, a.Inode, a.Size, a.Mode)
  1187. }
  1188. func unix(t time.Time) (sec uint64, nsec uint32) {
  1189. nano := t.UnixNano()
  1190. sec = uint64(nano / 1e9)
  1191. nsec = uint32(nano % 1e9)
  1192. return
  1193. }
  1194. func (a *Attr) attr(out *attr, proto Protocol) {
  1195. out.Ino = a.Inode
  1196. out.Size = a.Size
  1197. out.Blocks = a.Blocks
  1198. out.Atime, out.AtimeNsec = unix(a.Atime)
  1199. out.Mtime, out.MtimeNsec = unix(a.Mtime)
  1200. out.Ctime, out.CtimeNsec = unix(a.Ctime)
  1201. out.SetCrtime(unix(a.Crtime))
  1202. out.Mode = uint32(a.Mode) & 0777
  1203. switch {
  1204. default:
  1205. out.Mode |= syscall.S_IFREG
  1206. case a.Mode&os.ModeDir != 0:
  1207. out.Mode |= syscall.S_IFDIR
  1208. case a.Mode&os.ModeDevice != 0:
  1209. if a.Mode&os.ModeCharDevice != 0 {
  1210. out.Mode |= syscall.S_IFCHR
  1211. } else {
  1212. out.Mode |= syscall.S_IFBLK
  1213. }
  1214. case a.Mode&os.ModeNamedPipe != 0:
  1215. out.Mode |= syscall.S_IFIFO
  1216. case a.Mode&os.ModeSymlink != 0:
  1217. out.Mode |= syscall.S_IFLNK
  1218. case a.Mode&os.ModeSocket != 0:
  1219. out.Mode |= syscall.S_IFSOCK
  1220. }
  1221. if a.Mode&os.ModeSetuid != 0 {
  1222. out.Mode |= syscall.S_ISUID
  1223. }
  1224. if a.Mode&os.ModeSetgid != 0 {
  1225. out.Mode |= syscall.S_ISGID
  1226. }
  1227. out.Nlink = a.Nlink
  1228. out.Uid = a.Uid
  1229. out.Gid = a.Gid
  1230. out.Rdev = a.Rdev
  1231. out.SetFlags(a.Flags)
  1232. if proto.GE(Protocol{7, 9}) {
  1233. out.Blksize = a.BlockSize
  1234. }
  1235. return
  1236. }
  1237. // A GetattrRequest asks for the metadata for the file denoted by r.Node.
  1238. type GetattrRequest struct {
  1239. Header `json:"-"`
  1240. Flags GetattrFlags
  1241. Handle HandleID
  1242. }
  1243. var _ = Request(&GetattrRequest{})
  1244. func (r *GetattrRequest) String() string {
  1245. return fmt.Sprintf("Getattr [%s] %v fl=%v", &r.Header, r.Handle, r.Flags)
  1246. }
  1247. // Respond replies to the request with the given response.
  1248. func (r *GetattrRequest) Respond(resp *GetattrResponse) {
  1249. size := attrOutSize(r.Header.Conn.proto)
  1250. buf := newBuffer(size)
  1251. out := (*attrOut)(buf.alloc(size))
  1252. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1253. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1254. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1255. r.respond(buf)
  1256. }
  1257. // A GetattrResponse is the response to a GetattrRequest.
  1258. type GetattrResponse struct {
  1259. Attr Attr // file attributes
  1260. }
  1261. func (r *GetattrResponse) String() string {
  1262. return fmt.Sprintf("Getattr %v", r.Attr)
  1263. }
  1264. // A GetxattrRequest asks for the extended attributes associated with r.Node.
  1265. type GetxattrRequest struct {
  1266. Header `json:"-"`
  1267. // Maximum size to return.
  1268. Size uint32
  1269. // Name of the attribute requested.
  1270. Name string
  1271. // Offset within extended attributes.
  1272. //
  1273. // Only valid for OS X, and then only with the resource fork
  1274. // attribute.
  1275. Position uint32
  1276. }
  1277. var _ = Request(&GetxattrRequest{})
  1278. func (r *GetxattrRequest) String() string {
  1279. return fmt.Sprintf("Getxattr [%s] %q %d @%d", &r.Header, r.Name, r.Size, r.Position)
  1280. }
  1281. // Respond replies to the request with the given response.
  1282. func (r *GetxattrRequest) Respond(resp *GetxattrResponse) {
  1283. if r.Size == 0 {
  1284. buf := newBuffer(unsafe.Sizeof(getxattrOut{}))
  1285. out := (*getxattrOut)(buf.alloc(unsafe.Sizeof(getxattrOut{})))
  1286. out.Size = uint32(len(resp.Xattr))
  1287. r.respond(buf)
  1288. } else {
  1289. buf := newBuffer(uintptr(len(resp.Xattr)))
  1290. buf = append(buf, resp.Xattr...)
  1291. r.respond(buf)
  1292. }
  1293. }
  1294. // A GetxattrResponse is the response to a GetxattrRequest.
  1295. type GetxattrResponse struct {
  1296. Xattr []byte
  1297. }
  1298. func (r *GetxattrResponse) String() string {
  1299. return fmt.Sprintf("Getxattr %x", r.Xattr)
  1300. }
  1301. // A ListxattrRequest asks to list the extended attributes associated with r.Node.
  1302. type ListxattrRequest struct {
  1303. Header `json:"-"`
  1304. Size uint32 // maximum size to return
  1305. Position uint32 // offset within attribute list
  1306. }
  1307. var _ = Request(&ListxattrRequest{})
  1308. func (r *ListxattrRequest) String() string {
  1309. return fmt.Sprintf("Listxattr [%s] %d @%d", &r.Header, r.Size, r.Position)
  1310. }
  1311. // Respond replies to the request with the given response.
  1312. func (r *ListxattrRequest) Respond(resp *ListxattrResponse) {
  1313. if r.Size == 0 {
  1314. buf := newBuffer(unsafe.Sizeof(getxattrOut{}))
  1315. out := (*getxattrOut)(buf.alloc(unsafe.Sizeof(getxattrOut{})))
  1316. out.Size = uint32(len(resp.Xattr))
  1317. r.respond(buf)
  1318. } else {
  1319. buf := newBuffer(uintptr(len(resp.Xattr)))
  1320. buf = append(buf, resp.Xattr...)
  1321. r.respond(buf)
  1322. }
  1323. }
  1324. // A ListxattrResponse is the response to a ListxattrRequest.
  1325. type ListxattrResponse struct {
  1326. Xattr []byte
  1327. }
  1328. func (r *ListxattrResponse) String() string {
  1329. return fmt.Sprintf("Listxattr %x", r.Xattr)
  1330. }
  1331. // Append adds an extended attribute name to the response.
  1332. func (r *ListxattrResponse) Append(names ...string) {
  1333. for _, name := range names {
  1334. r.Xattr = append(r.Xattr, name...)
  1335. r.Xattr = append(r.Xattr, '\x00')
  1336. }
  1337. }
  1338. // A RemovexattrRequest asks to remove an extended attribute associated with r.Node.
  1339. type RemovexattrRequest struct {
  1340. Header `json:"-"`
  1341. Name string // name of extended attribute
  1342. }
  1343. var _ = Request(&RemovexattrRequest{})
  1344. func (r *RemovexattrRequest) String() string {
  1345. return fmt.Sprintf("Removexattr [%s] %q", &r.Header, r.Name)
  1346. }
  1347. // Respond replies to the request, indicating that the attribute was removed.
  1348. func (r *RemovexattrRequest) Respond() {
  1349. buf := newBuffer(0)
  1350. r.respond(buf)
  1351. }
  1352. // A SetxattrRequest asks to set an extended attribute associated with a file.
  1353. type SetxattrRequest struct {
  1354. Header `json:"-"`
  1355. // Flags can make the request fail if attribute does/not already
  1356. // exist. Unfortunately, the constants are platform-specific and
  1357. // not exposed by Go1.2. Look for XATTR_CREATE, XATTR_REPLACE.
  1358. //
  1359. // TODO improve this later
  1360. //
  1361. // TODO XATTR_CREATE and exist -> EEXIST
  1362. //
  1363. // TODO XATTR_REPLACE and not exist -> ENODATA
  1364. Flags uint32
  1365. // Offset within extended attributes.
  1366. //
  1367. // Only valid for OS X, and then only with the resource fork
  1368. // attribute.
  1369. Position uint32
  1370. Name string
  1371. Xattr []byte
  1372. }
  1373. var _ = Request(&SetxattrRequest{})
  1374. func trunc(b []byte, max int) ([]byte, string) {
  1375. if len(b) > max {
  1376. return b[:max], "..."
  1377. }
  1378. return b, ""
  1379. }
  1380. func (r *SetxattrRequest) String() string {
  1381. xattr, tail := trunc(r.Xattr, 16)
  1382. return fmt.Sprintf("Setxattr [%s] %q %x%s fl=%v @%#x", &r.Header, r.Name, xattr, tail, r.Flags, r.Position)
  1383. }
  1384. // Respond replies to the request, indicating that the extended attribute was set.
  1385. func (r *SetxattrRequest) Respond() {
  1386. buf := newBuffer(0)
  1387. r.respond(buf)
  1388. }
  1389. // A LookupRequest asks to look up the given name in the directory named by r.Node.
  1390. type LookupRequest struct {
  1391. Header `json:"-"`
  1392. Name string
  1393. }
  1394. var _ = Request(&LookupRequest{})
  1395. func (r *LookupRequest) String() string {
  1396. return fmt.Sprintf("Lookup [%s] %q", &r.Header, r.Name)
  1397. }
  1398. // Respond replies to the request with the given response.
  1399. func (r *LookupRequest) Respond(resp *LookupResponse) {
  1400. size := entryOutSize(r.Header.Conn.proto)
  1401. buf := newBuffer(size)
  1402. out := (*entryOut)(buf.alloc(size))
  1403. out.Nodeid = uint64(resp.Node)
  1404. out.Generation = resp.Generation
  1405. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1406. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1407. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1408. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1409. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1410. r.respond(buf)
  1411. }
  1412. // A LookupResponse is the response to a LookupRequest.
  1413. type LookupResponse struct {
  1414. Node NodeID
  1415. Generation uint64
  1416. EntryValid time.Duration
  1417. Attr Attr
  1418. }
  1419. func (r *LookupResponse) string() string {
  1420. return fmt.Sprintf("%v gen=%d valid=%v attr={%v}", r.Node, r.Generation, r.EntryValid, r.Attr)
  1421. }
  1422. func (r *LookupResponse) String() string {
  1423. return fmt.Sprintf("Lookup %s", r.string())
  1424. }
  1425. // An OpenRequest asks to open a file or directory
  1426. type OpenRequest struct {
  1427. Header `json:"-"`
  1428. Dir bool // is this Opendir?
  1429. Flags OpenFlags
  1430. }
  1431. var _ = Request(&OpenRequest{})
  1432. func (r *OpenRequest) String() string {
  1433. return fmt.Sprintf("Open [%s] dir=%v fl=%v", &r.Header, r.Dir, r.Flags)
  1434. }
  1435. // Respond replies to the request with the given response.
  1436. func (r *OpenRequest) Respond(resp *OpenResponse) {
  1437. buf := newBuffer(unsafe.Sizeof(openOut{}))
  1438. out := (*openOut)(buf.alloc(unsafe.Sizeof(openOut{})))
  1439. out.Fh = uint64(resp.Handle)
  1440. out.OpenFlags = uint32(resp.Flags)
  1441. r.respond(buf)
  1442. }
  1443. // A OpenResponse is the response to a OpenRequest.
  1444. type OpenResponse struct {
  1445. Handle HandleID
  1446. Flags OpenResponseFlags
  1447. }
  1448. func (r *OpenResponse) string() string {
  1449. return fmt.Sprintf("%v fl=%v", r.Handle, r.Flags)
  1450. }
  1451. func (r *OpenResponse) String() string {
  1452. return fmt.Sprintf("Open %s", r.string())
  1453. }
  1454. // A CreateRequest asks to create and open a file (not a directory).
  1455. type CreateRequest struct {
  1456. Header `json:"-"`
  1457. Name string
  1458. Flags OpenFlags
  1459. Mode os.FileMode
  1460. // Umask of the request. Not supported on OS X.
  1461. Umask os.FileMode
  1462. }
  1463. var _ = Request(&CreateRequest{})
  1464. func (r *CreateRequest) String() string {
  1465. return fmt.Sprintf("Create [%s] %q fl=%v mode=%v umask=%v", &r.Header, r.Name, r.Flags, r.Mode, r.Umask)
  1466. }
  1467. // Respond replies to the request with the given response.
  1468. func (r *CreateRequest) Respond(resp *CreateResponse) {
  1469. eSize := entryOutSize(r.Header.Conn.proto)
  1470. buf := newBuffer(eSize + unsafe.Sizeof(openOut{}))
  1471. e := (*entryOut)(buf.alloc(eSize))
  1472. e.Nodeid = uint64(resp.Node)
  1473. e.Generation = resp.Generation
  1474. e.EntryValid = uint64(resp.EntryValid / time.Second)
  1475. e.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1476. e.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1477. e.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1478. resp.Attr.attr(&e.Attr, r.Header.Conn.proto)
  1479. o := (*openOut)(buf.alloc(unsafe.Sizeof(openOut{})))
  1480. o.Fh = uint64(resp.Handle)
  1481. o.OpenFlags = uint32(resp.Flags)
  1482. r.respond(buf)
  1483. }
  1484. // A CreateResponse is the response to a CreateRequest.
  1485. // It describes the created node and opened handle.
  1486. type CreateResponse struct {
  1487. LookupResponse
  1488. OpenResponse
  1489. }
  1490. func (r *CreateResponse) String() string {
  1491. return fmt.Sprintf("Create {%s} {%s}", r.LookupResponse.string(), r.OpenResponse.string())
  1492. }
  1493. // A MkdirRequest asks to create (but not open) a directory.
  1494. type MkdirRequest struct {
  1495. Header `json:"-"`
  1496. Name string
  1497. Mode os.FileMode
  1498. // Umask of the request. Not supported on OS X.
  1499. Umask os.FileMode
  1500. }
  1501. var _ = Request(&MkdirRequest{})
  1502. func (r *MkdirRequest) String() string {
  1503. return fmt.Sprintf("Mkdir [%s] %q mode=%v umask=%v", &r.Header, r.Name, r.Mode, r.Umask)
  1504. }
  1505. // Respond replies to the request with the given response.
  1506. func (r *MkdirRequest) Respond(resp *MkdirResponse) {
  1507. size := entryOutSize(r.Header.Conn.proto)
  1508. buf := newBuffer(size)
  1509. out := (*entryOut)(buf.alloc(size))
  1510. out.Nodeid = uint64(resp.Node)
  1511. out.Generation = resp.Generation
  1512. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1513. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1514. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1515. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1516. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1517. r.respond(buf)
  1518. }
  1519. // A MkdirResponse is the response to a MkdirRequest.
  1520. type MkdirResponse struct {
  1521. LookupResponse
  1522. }
  1523. func (r *MkdirResponse) String() string {
  1524. return fmt.Sprintf("Mkdir %v", r.LookupResponse.string())
  1525. }
  1526. // A ReadRequest asks to read from an open file.
  1527. type ReadRequest struct {
  1528. Header `json:"-"`
  1529. Dir bool // is this Readdir?
  1530. Handle HandleID
  1531. Offset int64
  1532. Size int
  1533. Flags ReadFlags
  1534. LockOwner uint64
  1535. FileFlags OpenFlags
  1536. }
  1537. var _ = Request(&ReadRequest{})
  1538. func (r *ReadRequest) String() string {
  1539. return fmt.Sprintf("Read [%s] %v %d @%#x dir=%v fl=%v lock=%d ffl=%v", &r.Header, r.Handle, r.Size, r.Offset, r.Dir, r.Flags, r.LockOwner, r.FileFlags)
  1540. }
  1541. // Respond replies to the request with the given response.
  1542. func (r *ReadRequest) Respond(resp *ReadResponse) {
  1543. buf := newBuffer(uintptr(len(resp.Data)))
  1544. buf = append(buf, resp.Data...)
  1545. r.respond(buf)
  1546. }
  1547. // A ReadResponse is the response to a ReadRequest.
  1548. type ReadResponse struct {
  1549. Data []byte
  1550. }
  1551. func (r *ReadResponse) String() string {
  1552. return fmt.Sprintf("Read %d", len(r.Data))
  1553. }
  1554. type jsonReadResponse struct {
  1555. Len uint64
  1556. }
  1557. func (r *ReadResponse) MarshalJSON() ([]byte, error) {
  1558. j := jsonReadResponse{
  1559. Len: uint64(len(r.Data)),
  1560. }
  1561. return json.Marshal(j)
  1562. }
  1563. // A ReleaseRequest asks to release (close) an open file handle.
  1564. type ReleaseRequest struct {
  1565. Header `json:"-"`
  1566. Dir bool // is this Releasedir?
  1567. Handle HandleID
  1568. Flags OpenFlags // flags from OpenRequest
  1569. ReleaseFlags ReleaseFlags
  1570. LockOwner uint32
  1571. }
  1572. var _ = Request(&ReleaseRequest{})
  1573. func (r *ReleaseRequest) String() string {
  1574. return fmt.Sprintf("Release [%s] %v fl=%v rfl=%v owner=%#x", &r.Header, r.Handle, r.Flags, r.ReleaseFlags, r.LockOwner)
  1575. }
  1576. // Respond replies to the request, indicating that the handle has been released.
  1577. func (r *ReleaseRequest) Respond() {
  1578. buf := newBuffer(0)
  1579. r.respond(buf)
  1580. }
  1581. // A DestroyRequest is sent by the kernel when unmounting the file system.
  1582. // No more requests will be received after this one, but it should still be
  1583. // responded to.
  1584. type DestroyRequest struct {
  1585. Header `json:"-"`
  1586. }
  1587. var _ = Request(&DestroyRequest{})
  1588. func (r *DestroyRequest) String() string {
  1589. return fmt.Sprintf("Destroy [%s]", &r.Header)
  1590. }
  1591. // Respond replies to the request.
  1592. func (r *DestroyRequest) Respond() {
  1593. buf := newBuffer(0)
  1594. r.respond(buf)
  1595. }
  1596. // A ForgetRequest is sent by the kernel when forgetting about r.Node
  1597. // as returned by r.N lookup requests.
  1598. type ForgetRequest struct {
  1599. Header `json:"-"`
  1600. N uint64
  1601. }
  1602. var _ = Request(&ForgetRequest{})
  1603. func (r *ForgetRequest) String() string {
  1604. return fmt.Sprintf("Forget [%s] %d", &r.Header, r.N)
  1605. }
  1606. // Respond replies to the request, indicating that the forgetfulness has been recorded.
  1607. func (r *ForgetRequest) Respond() {
  1608. // Don't reply to forget messages.
  1609. r.noResponse()
  1610. }
  1611. // A Dirent represents a single directory entry.
  1612. type Dirent struct {
  1613. // Inode this entry names.
  1614. Inode uint64
  1615. // Type of the entry, for example DT_File.
  1616. //
  1617. // Setting this is optional. The zero value (DT_Unknown) means
  1618. // callers will just need to do a Getattr when the type is
  1619. // needed. Providing a type can speed up operations
  1620. // significantly.
  1621. Type DirentType
  1622. // Name of the entry
  1623. Name string
  1624. }
  1625. // Type of an entry in a directory listing.
  1626. type DirentType uint32
  1627. const (
  1628. // These don't quite match os.FileMode; especially there's an
  1629. // explicit unknown, instead of zero value meaning file. They
  1630. // are also not quite syscall.DT_*; nothing says the FUSE
  1631. // protocol follows those, and even if they were, we don't
  1632. // want each fs to fiddle with syscall.
  1633. // The shift by 12 is hardcoded in the FUSE userspace
  1634. // low-level C library, so it's safe here.
  1635. DT_Unknown DirentType = 0
  1636. DT_Socket DirentType = syscall.S_IFSOCK >> 12
  1637. DT_Link DirentType = syscall.S_IFLNK >> 12
  1638. DT_File DirentType = syscall.S_IFREG >> 12
  1639. DT_Block DirentType = syscall.S_IFBLK >> 12
  1640. DT_Dir DirentType = syscall.S_IFDIR >> 12
  1641. DT_Char DirentType = syscall.S_IFCHR >> 12
  1642. DT_FIFO DirentType = syscall.S_IFIFO >> 12
  1643. )
  1644. func (t DirentType) String() string {
  1645. switch t {
  1646. case DT_Unknown:
  1647. return "unknown"
  1648. case DT_Socket:
  1649. return "socket"
  1650. case DT_Link:
  1651. return "link"
  1652. case DT_File:
  1653. return "file"
  1654. case DT_Block:
  1655. return "block"
  1656. case DT_Dir:
  1657. return "dir"
  1658. case DT_Char:
  1659. return "char"
  1660. case DT_FIFO:
  1661. return "fifo"
  1662. }
  1663. return "invalid"
  1664. }
  1665. // AppendDirent appends the encoded form of a directory entry to data
  1666. // and returns the resulting slice.
  1667. func AppendDirent(data []byte, dir Dirent) []byte {
  1668. de := dirent{
  1669. Ino: dir.Inode,
  1670. Namelen: uint32(len(dir.Name)),
  1671. Type: uint32(dir.Type),
  1672. }
  1673. de.Off = uint64(len(data) + direntSize + (len(dir.Name)+7)&^7)
  1674. data = append(data, (*[direntSize]byte)(unsafe.Pointer(&de))[:]...)
  1675. data = append(data, dir.Name...)
  1676. n := direntSize + uintptr(len(dir.Name))
  1677. if n%8 != 0 {
  1678. var pad [8]byte
  1679. data = append(data, pad[:8-n%8]...)
  1680. }
  1681. return data
  1682. }
  1683. // A WriteRequest asks to write to an open file.
  1684. type WriteRequest struct {
  1685. Header
  1686. Handle HandleID
  1687. Offset int64
  1688. Data []byte
  1689. Flags WriteFlags
  1690. LockOwner uint64
  1691. FileFlags OpenFlags
  1692. }
  1693. var _ = Request(&WriteRequest{})
  1694. func (r *WriteRequest) String() string {
  1695. return fmt.Sprintf("Write [%s] %v %d @%d fl=%v lock=%d ffl=%v", &r.Header, r.Handle, len(r.Data), r.Offset, r.Flags, r.LockOwner, r.FileFlags)
  1696. }
  1697. type jsonWriteRequest struct {
  1698. Handle HandleID
  1699. Offset int64
  1700. Len uint64
  1701. Flags WriteFlags
  1702. }
  1703. func (r *WriteRequest) MarshalJSON() ([]byte, error) {
  1704. j := jsonWriteRequest{
  1705. Handle: r.Handle,
  1706. Offset: r.Offset,
  1707. Len: uint64(len(r.Data)),
  1708. Flags: r.Flags,
  1709. }
  1710. return json.Marshal(j)
  1711. }
  1712. // Respond replies to the request with the given response.
  1713. func (r *WriteRequest) Respond(resp *WriteResponse) {
  1714. buf := newBuffer(unsafe.Sizeof(writeOut{}))
  1715. out := (*writeOut)(buf.alloc(unsafe.Sizeof(writeOut{})))
  1716. out.Size = uint32(resp.Size)
  1717. r.respond(buf)
  1718. }
  1719. // A WriteResponse replies to a write indicating how many bytes were written.
  1720. type WriteResponse struct {
  1721. Size int
  1722. }
  1723. func (r *WriteResponse) String() string {
  1724. return fmt.Sprintf("Write %d", r.Size)
  1725. }
  1726. // A SetattrRequest asks to change one or more attributes associated with a file,
  1727. // as indicated by Valid.
  1728. type SetattrRequest struct {
  1729. Header `json:"-"`
  1730. Valid SetattrValid
  1731. Handle HandleID
  1732. Size uint64
  1733. Atime time.Time
  1734. Mtime time.Time
  1735. Mode os.FileMode
  1736. Uid uint32
  1737. Gid uint32
  1738. // OS X only
  1739. Bkuptime time.Time
  1740. Chgtime time.Time
  1741. Crtime time.Time
  1742. Flags uint32 // see chflags(2)
  1743. }
  1744. var _ = Request(&SetattrRequest{})
  1745. func (r *SetattrRequest) String() string {
  1746. var buf bytes.Buffer
  1747. fmt.Fprintf(&buf, "Setattr [%s]", &r.Header)
  1748. if r.Valid.Mode() {
  1749. fmt.Fprintf(&buf, " mode=%v", r.Mode)
  1750. }
  1751. if r.Valid.Uid() {
  1752. fmt.Fprintf(&buf, " uid=%d", r.Uid)
  1753. }
  1754. if r.Valid.Gid() {
  1755. fmt.Fprintf(&buf, " gid=%d", r.Gid)
  1756. }
  1757. if r.Valid.Size() {
  1758. fmt.Fprintf(&buf, " size=%d", r.Size)
  1759. }
  1760. if r.Valid.Atime() {
  1761. fmt.Fprintf(&buf, " atime=%v", r.Atime)
  1762. }
  1763. if r.Valid.AtimeNow() {
  1764. fmt.Fprintf(&buf, " atime=now")
  1765. }
  1766. if r.Valid.Mtime() {
  1767. fmt.Fprintf(&buf, " mtime=%v", r.Mtime)
  1768. }
  1769. if r.Valid.MtimeNow() {
  1770. fmt.Fprintf(&buf, " mtime=now")
  1771. }
  1772. if r.Valid.Handle() {
  1773. fmt.Fprintf(&buf, " handle=%v", r.Handle)
  1774. } else {
  1775. fmt.Fprintf(&buf, " handle=INVALID-%v", r.Handle)
  1776. }
  1777. if r.Valid.LockOwner() {
  1778. fmt.Fprintf(&buf, " lockowner")
  1779. }
  1780. if r.Valid.Crtime() {
  1781. fmt.Fprintf(&buf, " crtime=%v", r.Crtime)
  1782. }
  1783. if r.Valid.Chgtime() {
  1784. fmt.Fprintf(&buf, " chgtime=%v", r.Chgtime)
  1785. }
  1786. if r.Valid.Bkuptime() {
  1787. fmt.Fprintf(&buf, " bkuptime=%v", r.Bkuptime)
  1788. }
  1789. if r.Valid.Flags() {
  1790. fmt.Fprintf(&buf, " flags=%v", r.Flags)
  1791. }
  1792. return buf.String()
  1793. }
  1794. // Respond replies to the request with the given response,
  1795. // giving the updated attributes.
  1796. func (r *SetattrRequest) Respond(resp *SetattrResponse) {
  1797. size := attrOutSize(r.Header.Conn.proto)
  1798. buf := newBuffer(size)
  1799. out := (*attrOut)(buf.alloc(size))
  1800. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1801. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1802. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1803. r.respond(buf)
  1804. }
  1805. // A SetattrResponse is the response to a SetattrRequest.
  1806. type SetattrResponse struct {
  1807. Attr Attr // file attributes
  1808. }
  1809. func (r *SetattrResponse) String() string {
  1810. return fmt.Sprintf("Setattr %v", r.Attr)
  1811. }
  1812. // A FlushRequest asks for the current state of an open file to be flushed
  1813. // to storage, as when a file descriptor is being closed. A single opened Handle
  1814. // may receive multiple FlushRequests over its lifetime.
  1815. type FlushRequest struct {
  1816. Header `json:"-"`
  1817. Handle HandleID
  1818. Flags uint32
  1819. LockOwner uint64
  1820. }
  1821. var _ = Request(&FlushRequest{})
  1822. func (r *FlushRequest) String() string {
  1823. return fmt.Sprintf("Flush [%s] %v fl=%#x lk=%#x", &r.Header, r.Handle, r.Flags, r.LockOwner)
  1824. }
  1825. // Respond replies to the request, indicating that the flush succeeded.
  1826. func (r *FlushRequest) Respond() {
  1827. buf := newBuffer(0)
  1828. r.respond(buf)
  1829. }
  1830. // A RemoveRequest asks to remove a file or directory from the
  1831. // directory r.Node.
  1832. type RemoveRequest struct {
  1833. Header `json:"-"`
  1834. Name string // name of the entry to remove
  1835. Dir bool // is this rmdir?
  1836. }
  1837. var _ = Request(&RemoveRequest{})
  1838. func (r *RemoveRequest) String() string {
  1839. return fmt.Sprintf("Remove [%s] %q dir=%v", &r.Header, r.Name, r.Dir)
  1840. }
  1841. // Respond replies to the request, indicating that the file was removed.
  1842. func (r *RemoveRequest) Respond() {
  1843. buf := newBuffer(0)
  1844. r.respond(buf)
  1845. }
  1846. // A SymlinkRequest is a request to create a symlink making NewName point to Target.
  1847. type SymlinkRequest struct {
  1848. Header `json:"-"`
  1849. NewName, Target string
  1850. }
  1851. var _ = Request(&SymlinkRequest{})
  1852. func (r *SymlinkRequest) String() string {
  1853. return fmt.Sprintf("Symlink [%s] from %q to target %q", &r.Header, r.NewName, r.Target)
  1854. }
  1855. // Respond replies to the request, indicating that the symlink was created.
  1856. func (r *SymlinkRequest) Respond(resp *SymlinkResponse) {
  1857. size := entryOutSize(r.Header.Conn.proto)
  1858. buf := newBuffer(size)
  1859. out := (*entryOut)(buf.alloc(size))
  1860. out.Nodeid = uint64(resp.Node)
  1861. out.Generation = resp.Generation
  1862. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1863. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1864. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1865. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1866. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1867. r.respond(buf)
  1868. }
  1869. // A SymlinkResponse is the response to a SymlinkRequest.
  1870. type SymlinkResponse struct {
  1871. LookupResponse
  1872. }
  1873. func (r *SymlinkResponse) String() string {
  1874. return fmt.Sprintf("Symlink %v", r.LookupResponse.string())
  1875. }
  1876. // A ReadlinkRequest is a request to read a symlink's target.
  1877. type ReadlinkRequest struct {
  1878. Header `json:"-"`
  1879. }
  1880. var _ = Request(&ReadlinkRequest{})
  1881. func (r *ReadlinkRequest) String() string {
  1882. return fmt.Sprintf("Readlink [%s]", &r.Header)
  1883. }
  1884. func (r *ReadlinkRequest) Respond(target string) {
  1885. buf := newBuffer(uintptr(len(target)))
  1886. buf = append(buf, target...)
  1887. r.respond(buf)
  1888. }
  1889. // A LinkRequest is a request to create a hard link.
  1890. type LinkRequest struct {
  1891. Header `json:"-"`
  1892. OldNode NodeID
  1893. NewName string
  1894. }
  1895. var _ = Request(&LinkRequest{})
  1896. func (r *LinkRequest) String() string {
  1897. return fmt.Sprintf("Link [%s] node %d to %q", &r.Header, r.OldNode, r.NewName)
  1898. }
  1899. func (r *LinkRequest) Respond(resp *LookupResponse) {
  1900. size := entryOutSize(r.Header.Conn.proto)
  1901. buf := newBuffer(size)
  1902. out := (*entryOut)(buf.alloc(size))
  1903. out.Nodeid = uint64(resp.Node)
  1904. out.Generation = resp.Generation
  1905. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1906. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1907. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1908. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1909. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1910. r.respond(buf)
  1911. }
  1912. // A RenameRequest is a request to rename a file.
  1913. type RenameRequest struct {
  1914. Header `json:"-"`
  1915. NewDir NodeID
  1916. OldName, NewName string
  1917. }
  1918. var _ = Request(&RenameRequest{})
  1919. func (r *RenameRequest) String() string {
  1920. return fmt.Sprintf("Rename [%s] from %q to dirnode %v %q", &r.Header, r.OldName, r.NewDir, r.NewName)
  1921. }
  1922. func (r *RenameRequest) Respond() {
  1923. buf := newBuffer(0)
  1924. r.respond(buf)
  1925. }
  1926. type MknodRequest struct {
  1927. Header `json:"-"`
  1928. Name string
  1929. Mode os.FileMode
  1930. Rdev uint32
  1931. // Umask of the request. Not supported on OS X.
  1932. Umask os.FileMode
  1933. }
  1934. var _ = Request(&MknodRequest{})
  1935. func (r *MknodRequest) String() string {
  1936. return fmt.Sprintf("Mknod [%s] Name %q mode=%v umask=%v rdev=%d", &r.Header, r.Name, r.Mode, r.Umask, r.Rdev)
  1937. }
  1938. func (r *MknodRequest) Respond(resp *LookupResponse) {
  1939. size := entryOutSize(r.Header.Conn.proto)
  1940. buf := newBuffer(size)
  1941. out := (*entryOut)(buf.alloc(size))
  1942. out.Nodeid = uint64(resp.Node)
  1943. out.Generation = resp.Generation
  1944. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1945. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1946. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1947. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1948. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1949. r.respond(buf)
  1950. }
  1951. type FsyncRequest struct {
  1952. Header `json:"-"`
  1953. Handle HandleID
  1954. // TODO bit 1 is datasync, not well documented upstream
  1955. Flags uint32
  1956. Dir bool
  1957. }
  1958. var _ = Request(&FsyncRequest{})
  1959. func (r *FsyncRequest) String() string {
  1960. return fmt.Sprintf("Fsync [%s] Handle %v Flags %v", &r.Header, r.Handle, r.Flags)
  1961. }
  1962. func (r *FsyncRequest) Respond() {
  1963. buf := newBuffer(0)
  1964. r.respond(buf)
  1965. }
  1966. // An InterruptRequest is a request to interrupt another pending request. The
  1967. // response to that request should return an error status of EINTR.
  1968. type InterruptRequest struct {
  1969. Header `json:"-"`
  1970. IntrID RequestID // ID of the request to be interrupt.
  1971. }
  1972. var _ = Request(&InterruptRequest{})
  1973. func (r *InterruptRequest) Respond() {
  1974. // nothing to do here
  1975. r.noResponse()
  1976. }
  1977. func (r *InterruptRequest) String() string {
  1978. return fmt.Sprintf("Interrupt [%s] ID %v", &r.Header, r.IntrID)
  1979. }
  1980. // An ExchangeDataRequest is a request to exchange the contents of two
  1981. // files, while leaving most metadata untouched.
  1982. //
  1983. // This request comes from OS X exchangedata(2) and represents its
  1984. // specific semantics. Crucially, it is very different from Linux
  1985. // renameat(2) RENAME_EXCHANGE.
  1986. //
  1987. // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/exchangedata.2.html
  1988. type ExchangeDataRequest struct {
  1989. Header `json:"-"`
  1990. OldDir, NewDir NodeID
  1991. OldName, NewName string
  1992. // TODO options
  1993. }
  1994. var _ = Request(&ExchangeDataRequest{})
  1995. func (r *ExchangeDataRequest) String() string {
  1996. // TODO options
  1997. return fmt.Sprintf("ExchangeData [%s] %v %q and %v %q", &r.Header, r.OldDir, r.OldName, r.NewDir, r.NewName)
  1998. }
  1999. func (r *ExchangeDataRequest) Respond() {
  2000. buf := newBuffer(0)
  2001. r.respond(buf)
  2002. }