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. Ffree: resp.Ffree,
  1126. Bsize: resp.Bsize,
  1127. Namelen: resp.Namelen,
  1128. Frsize: resp.Frsize,
  1129. }
  1130. r.respond(buf)
  1131. }
  1132. // A StatfsResponse is the response to a StatfsRequest.
  1133. type StatfsResponse struct {
  1134. Blocks uint64 // Total data blocks in file system.
  1135. Bfree uint64 // Free blocks in file system.
  1136. Bavail uint64 // Free blocks in file system if you're not root.
  1137. Files uint64 // Total files in file system.
  1138. Ffree uint64 // Free files in file system.
  1139. Bsize uint32 // Block size
  1140. Namelen uint32 // Maximum file name length?
  1141. Frsize uint32 // Fragment size, smallest addressable data size in the file system.
  1142. }
  1143. func (r *StatfsResponse) String() string {
  1144. return fmt.Sprintf("Statfs blocks=%d/%d/%d files=%d/%d bsize=%d frsize=%d namelen=%d",
  1145. r.Bavail, r.Bfree, r.Blocks,
  1146. r.Ffree, r.Files,
  1147. r.Bsize,
  1148. r.Frsize,
  1149. r.Namelen,
  1150. )
  1151. }
  1152. // An AccessRequest asks whether the file can be accessed
  1153. // for the purpose specified by the mask.
  1154. type AccessRequest struct {
  1155. Header `json:"-"`
  1156. Mask uint32
  1157. }
  1158. var _ = Request(&AccessRequest{})
  1159. func (r *AccessRequest) String() string {
  1160. return fmt.Sprintf("Access [%s] mask=%#x", &r.Header, r.Mask)
  1161. }
  1162. // Respond replies to the request indicating that access is allowed.
  1163. // To deny access, use RespondError.
  1164. func (r *AccessRequest) Respond() {
  1165. buf := newBuffer(0)
  1166. r.respond(buf)
  1167. }
  1168. // An Attr is the metadata for a single file or directory.
  1169. type Attr struct {
  1170. Valid time.Duration // how long Attr can be cached
  1171. Inode uint64 // inode number
  1172. Size uint64 // size in bytes
  1173. Blocks uint64 // size in 512-byte units
  1174. Atime time.Time // time of last access
  1175. Mtime time.Time // time of last modification
  1176. Ctime time.Time // time of last inode change
  1177. Crtime time.Time // time of creation (OS X only)
  1178. Mode os.FileMode // file mode
  1179. Nlink uint32 // number of links (usually 1)
  1180. Uid uint32 // owner uid
  1181. Gid uint32 // group gid
  1182. Rdev uint32 // device numbers
  1183. Flags uint32 // chflags(2) flags (OS X only)
  1184. BlockSize uint32 // preferred blocksize for filesystem I/O
  1185. }
  1186. func (a Attr) String() string {
  1187. return fmt.Sprintf("valid=%v ino=%v size=%d mode=%v", a.Valid, a.Inode, a.Size, a.Mode)
  1188. }
  1189. func unix(t time.Time) (sec uint64, nsec uint32) {
  1190. nano := t.UnixNano()
  1191. sec = uint64(nano / 1e9)
  1192. nsec = uint32(nano % 1e9)
  1193. return
  1194. }
  1195. func (a *Attr) attr(out *attr, proto Protocol) {
  1196. out.Ino = a.Inode
  1197. out.Size = a.Size
  1198. out.Blocks = a.Blocks
  1199. out.Atime, out.AtimeNsec = unix(a.Atime)
  1200. out.Mtime, out.MtimeNsec = unix(a.Mtime)
  1201. out.Ctime, out.CtimeNsec = unix(a.Ctime)
  1202. out.SetCrtime(unix(a.Crtime))
  1203. out.Mode = uint32(a.Mode) & 0777
  1204. switch {
  1205. default:
  1206. out.Mode |= syscall.S_IFREG
  1207. case a.Mode&os.ModeDir != 0:
  1208. out.Mode |= syscall.S_IFDIR
  1209. case a.Mode&os.ModeDevice != 0:
  1210. if a.Mode&os.ModeCharDevice != 0 {
  1211. out.Mode |= syscall.S_IFCHR
  1212. } else {
  1213. out.Mode |= syscall.S_IFBLK
  1214. }
  1215. case a.Mode&os.ModeNamedPipe != 0:
  1216. out.Mode |= syscall.S_IFIFO
  1217. case a.Mode&os.ModeSymlink != 0:
  1218. out.Mode |= syscall.S_IFLNK
  1219. case a.Mode&os.ModeSocket != 0:
  1220. out.Mode |= syscall.S_IFSOCK
  1221. }
  1222. if a.Mode&os.ModeSetuid != 0 {
  1223. out.Mode |= syscall.S_ISUID
  1224. }
  1225. if a.Mode&os.ModeSetgid != 0 {
  1226. out.Mode |= syscall.S_ISGID
  1227. }
  1228. out.Nlink = a.Nlink
  1229. out.Uid = a.Uid
  1230. out.Gid = a.Gid
  1231. out.Rdev = a.Rdev
  1232. out.SetFlags(a.Flags)
  1233. if proto.GE(Protocol{7, 9}) {
  1234. out.Blksize = a.BlockSize
  1235. }
  1236. return
  1237. }
  1238. // A GetattrRequest asks for the metadata for the file denoted by r.Node.
  1239. type GetattrRequest struct {
  1240. Header `json:"-"`
  1241. Flags GetattrFlags
  1242. Handle HandleID
  1243. }
  1244. var _ = Request(&GetattrRequest{})
  1245. func (r *GetattrRequest) String() string {
  1246. return fmt.Sprintf("Getattr [%s] %v fl=%v", &r.Header, r.Handle, r.Flags)
  1247. }
  1248. // Respond replies to the request with the given response.
  1249. func (r *GetattrRequest) Respond(resp *GetattrResponse) {
  1250. size := attrOutSize(r.Header.Conn.proto)
  1251. buf := newBuffer(size)
  1252. out := (*attrOut)(buf.alloc(size))
  1253. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1254. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1255. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1256. r.respond(buf)
  1257. }
  1258. // A GetattrResponse is the response to a GetattrRequest.
  1259. type GetattrResponse struct {
  1260. Attr Attr // file attributes
  1261. }
  1262. func (r *GetattrResponse) String() string {
  1263. return fmt.Sprintf("Getattr %v", r.Attr)
  1264. }
  1265. // A GetxattrRequest asks for the extended attributes associated with r.Node.
  1266. type GetxattrRequest struct {
  1267. Header `json:"-"`
  1268. // Maximum size to return.
  1269. Size uint32
  1270. // Name of the attribute requested.
  1271. Name string
  1272. // Offset within extended attributes.
  1273. //
  1274. // Only valid for OS X, and then only with the resource fork
  1275. // attribute.
  1276. Position uint32
  1277. }
  1278. var _ = Request(&GetxattrRequest{})
  1279. func (r *GetxattrRequest) String() string {
  1280. return fmt.Sprintf("Getxattr [%s] %q %d @%d", &r.Header, r.Name, r.Size, r.Position)
  1281. }
  1282. // Respond replies to the request with the given response.
  1283. func (r *GetxattrRequest) Respond(resp *GetxattrResponse) {
  1284. if r.Size == 0 {
  1285. buf := newBuffer(unsafe.Sizeof(getxattrOut{}))
  1286. out := (*getxattrOut)(buf.alloc(unsafe.Sizeof(getxattrOut{})))
  1287. out.Size = uint32(len(resp.Xattr))
  1288. r.respond(buf)
  1289. } else {
  1290. buf := newBuffer(uintptr(len(resp.Xattr)))
  1291. buf = append(buf, resp.Xattr...)
  1292. r.respond(buf)
  1293. }
  1294. }
  1295. // A GetxattrResponse is the response to a GetxattrRequest.
  1296. type GetxattrResponse struct {
  1297. Xattr []byte
  1298. }
  1299. func (r *GetxattrResponse) String() string {
  1300. return fmt.Sprintf("Getxattr %x", r.Xattr)
  1301. }
  1302. // A ListxattrRequest asks to list the extended attributes associated with r.Node.
  1303. type ListxattrRequest struct {
  1304. Header `json:"-"`
  1305. Size uint32 // maximum size to return
  1306. Position uint32 // offset within attribute list
  1307. }
  1308. var _ = Request(&ListxattrRequest{})
  1309. func (r *ListxattrRequest) String() string {
  1310. return fmt.Sprintf("Listxattr [%s] %d @%d", &r.Header, r.Size, r.Position)
  1311. }
  1312. // Respond replies to the request with the given response.
  1313. func (r *ListxattrRequest) Respond(resp *ListxattrResponse) {
  1314. if r.Size == 0 {
  1315. buf := newBuffer(unsafe.Sizeof(getxattrOut{}))
  1316. out := (*getxattrOut)(buf.alloc(unsafe.Sizeof(getxattrOut{})))
  1317. out.Size = uint32(len(resp.Xattr))
  1318. r.respond(buf)
  1319. } else {
  1320. buf := newBuffer(uintptr(len(resp.Xattr)))
  1321. buf = append(buf, resp.Xattr...)
  1322. r.respond(buf)
  1323. }
  1324. }
  1325. // A ListxattrResponse is the response to a ListxattrRequest.
  1326. type ListxattrResponse struct {
  1327. Xattr []byte
  1328. }
  1329. func (r *ListxattrResponse) String() string {
  1330. return fmt.Sprintf("Listxattr %x", r.Xattr)
  1331. }
  1332. // Append adds an extended attribute name to the response.
  1333. func (r *ListxattrResponse) Append(names ...string) {
  1334. for _, name := range names {
  1335. r.Xattr = append(r.Xattr, name...)
  1336. r.Xattr = append(r.Xattr, '\x00')
  1337. }
  1338. }
  1339. // A RemovexattrRequest asks to remove an extended attribute associated with r.Node.
  1340. type RemovexattrRequest struct {
  1341. Header `json:"-"`
  1342. Name string // name of extended attribute
  1343. }
  1344. var _ = Request(&RemovexattrRequest{})
  1345. func (r *RemovexattrRequest) String() string {
  1346. return fmt.Sprintf("Removexattr [%s] %q", &r.Header, r.Name)
  1347. }
  1348. // Respond replies to the request, indicating that the attribute was removed.
  1349. func (r *RemovexattrRequest) Respond() {
  1350. buf := newBuffer(0)
  1351. r.respond(buf)
  1352. }
  1353. // A SetxattrRequest asks to set an extended attribute associated with a file.
  1354. type SetxattrRequest struct {
  1355. Header `json:"-"`
  1356. // Flags can make the request fail if attribute does/not already
  1357. // exist. Unfortunately, the constants are platform-specific and
  1358. // not exposed by Go1.2. Look for XATTR_CREATE, XATTR_REPLACE.
  1359. //
  1360. // TODO improve this later
  1361. //
  1362. // TODO XATTR_CREATE and exist -> EEXIST
  1363. //
  1364. // TODO XATTR_REPLACE and not exist -> ENODATA
  1365. Flags uint32
  1366. // Offset within extended attributes.
  1367. //
  1368. // Only valid for OS X, and then only with the resource fork
  1369. // attribute.
  1370. Position uint32
  1371. Name string
  1372. Xattr []byte
  1373. }
  1374. var _ = Request(&SetxattrRequest{})
  1375. func trunc(b []byte, max int) ([]byte, string) {
  1376. if len(b) > max {
  1377. return b[:max], "..."
  1378. }
  1379. return b, ""
  1380. }
  1381. func (r *SetxattrRequest) String() string {
  1382. xattr, tail := trunc(r.Xattr, 16)
  1383. return fmt.Sprintf("Setxattr [%s] %q %x%s fl=%v @%#x", &r.Header, r.Name, xattr, tail, r.Flags, r.Position)
  1384. }
  1385. // Respond replies to the request, indicating that the extended attribute was set.
  1386. func (r *SetxattrRequest) Respond() {
  1387. buf := newBuffer(0)
  1388. r.respond(buf)
  1389. }
  1390. // A LookupRequest asks to look up the given name in the directory named by r.Node.
  1391. type LookupRequest struct {
  1392. Header `json:"-"`
  1393. Name string
  1394. }
  1395. var _ = Request(&LookupRequest{})
  1396. func (r *LookupRequest) String() string {
  1397. return fmt.Sprintf("Lookup [%s] %q", &r.Header, r.Name)
  1398. }
  1399. // Respond replies to the request with the given response.
  1400. func (r *LookupRequest) Respond(resp *LookupResponse) {
  1401. size := entryOutSize(r.Header.Conn.proto)
  1402. buf := newBuffer(size)
  1403. out := (*entryOut)(buf.alloc(size))
  1404. out.Nodeid = uint64(resp.Node)
  1405. out.Generation = resp.Generation
  1406. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1407. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1408. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1409. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1410. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1411. r.respond(buf)
  1412. }
  1413. // A LookupResponse is the response to a LookupRequest.
  1414. type LookupResponse struct {
  1415. Node NodeID
  1416. Generation uint64
  1417. EntryValid time.Duration
  1418. Attr Attr
  1419. }
  1420. func (r *LookupResponse) string() string {
  1421. return fmt.Sprintf("%v gen=%d valid=%v attr={%v}", r.Node, r.Generation, r.EntryValid, r.Attr)
  1422. }
  1423. func (r *LookupResponse) String() string {
  1424. return fmt.Sprintf("Lookup %s", r.string())
  1425. }
  1426. // An OpenRequest asks to open a file or directory
  1427. type OpenRequest struct {
  1428. Header `json:"-"`
  1429. Dir bool // is this Opendir?
  1430. Flags OpenFlags
  1431. }
  1432. var _ = Request(&OpenRequest{})
  1433. func (r *OpenRequest) String() string {
  1434. return fmt.Sprintf("Open [%s] dir=%v fl=%v", &r.Header, r.Dir, r.Flags)
  1435. }
  1436. // Respond replies to the request with the given response.
  1437. func (r *OpenRequest) Respond(resp *OpenResponse) {
  1438. buf := newBuffer(unsafe.Sizeof(openOut{}))
  1439. out := (*openOut)(buf.alloc(unsafe.Sizeof(openOut{})))
  1440. out.Fh = uint64(resp.Handle)
  1441. out.OpenFlags = uint32(resp.Flags)
  1442. r.respond(buf)
  1443. }
  1444. // A OpenResponse is the response to a OpenRequest.
  1445. type OpenResponse struct {
  1446. Handle HandleID
  1447. Flags OpenResponseFlags
  1448. }
  1449. func (r *OpenResponse) string() string {
  1450. return fmt.Sprintf("%v fl=%v", r.Handle, r.Flags)
  1451. }
  1452. func (r *OpenResponse) String() string {
  1453. return fmt.Sprintf("Open %s", r.string())
  1454. }
  1455. // A CreateRequest asks to create and open a file (not a directory).
  1456. type CreateRequest struct {
  1457. Header `json:"-"`
  1458. Name string
  1459. Flags OpenFlags
  1460. Mode os.FileMode
  1461. // Umask of the request. Not supported on OS X.
  1462. Umask os.FileMode
  1463. }
  1464. var _ = Request(&CreateRequest{})
  1465. func (r *CreateRequest) String() string {
  1466. return fmt.Sprintf("Create [%s] %q fl=%v mode=%v umask=%v", &r.Header, r.Name, r.Flags, r.Mode, r.Umask)
  1467. }
  1468. // Respond replies to the request with the given response.
  1469. func (r *CreateRequest) Respond(resp *CreateResponse) {
  1470. eSize := entryOutSize(r.Header.Conn.proto)
  1471. buf := newBuffer(eSize + unsafe.Sizeof(openOut{}))
  1472. e := (*entryOut)(buf.alloc(eSize))
  1473. e.Nodeid = uint64(resp.Node)
  1474. e.Generation = resp.Generation
  1475. e.EntryValid = uint64(resp.EntryValid / time.Second)
  1476. e.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1477. e.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1478. e.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1479. resp.Attr.attr(&e.Attr, r.Header.Conn.proto)
  1480. o := (*openOut)(buf.alloc(unsafe.Sizeof(openOut{})))
  1481. o.Fh = uint64(resp.Handle)
  1482. o.OpenFlags = uint32(resp.Flags)
  1483. r.respond(buf)
  1484. }
  1485. // A CreateResponse is the response to a CreateRequest.
  1486. // It describes the created node and opened handle.
  1487. type CreateResponse struct {
  1488. LookupResponse
  1489. OpenResponse
  1490. }
  1491. func (r *CreateResponse) String() string {
  1492. return fmt.Sprintf("Create {%s} {%s}", r.LookupResponse.string(), r.OpenResponse.string())
  1493. }
  1494. // A MkdirRequest asks to create (but not open) a directory.
  1495. type MkdirRequest struct {
  1496. Header `json:"-"`
  1497. Name string
  1498. Mode os.FileMode
  1499. // Umask of the request. Not supported on OS X.
  1500. Umask os.FileMode
  1501. }
  1502. var _ = Request(&MkdirRequest{})
  1503. func (r *MkdirRequest) String() string {
  1504. return fmt.Sprintf("Mkdir [%s] %q mode=%v umask=%v", &r.Header, r.Name, r.Mode, r.Umask)
  1505. }
  1506. // Respond replies to the request with the given response.
  1507. func (r *MkdirRequest) Respond(resp *MkdirResponse) {
  1508. size := entryOutSize(r.Header.Conn.proto)
  1509. buf := newBuffer(size)
  1510. out := (*entryOut)(buf.alloc(size))
  1511. out.Nodeid = uint64(resp.Node)
  1512. out.Generation = resp.Generation
  1513. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1514. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1515. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1516. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1517. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1518. r.respond(buf)
  1519. }
  1520. // A MkdirResponse is the response to a MkdirRequest.
  1521. type MkdirResponse struct {
  1522. LookupResponse
  1523. }
  1524. func (r *MkdirResponse) String() string {
  1525. return fmt.Sprintf("Mkdir %v", r.LookupResponse.string())
  1526. }
  1527. // A ReadRequest asks to read from an open file.
  1528. type ReadRequest struct {
  1529. Header `json:"-"`
  1530. Dir bool // is this Readdir?
  1531. Handle HandleID
  1532. Offset int64
  1533. Size int
  1534. Flags ReadFlags
  1535. LockOwner uint64
  1536. FileFlags OpenFlags
  1537. }
  1538. var _ = Request(&ReadRequest{})
  1539. func (r *ReadRequest) String() string {
  1540. 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)
  1541. }
  1542. // Respond replies to the request with the given response.
  1543. func (r *ReadRequest) Respond(resp *ReadResponse) {
  1544. buf := newBuffer(uintptr(len(resp.Data)))
  1545. buf = append(buf, resp.Data...)
  1546. r.respond(buf)
  1547. }
  1548. // A ReadResponse is the response to a ReadRequest.
  1549. type ReadResponse struct {
  1550. Data []byte
  1551. }
  1552. func (r *ReadResponse) String() string {
  1553. return fmt.Sprintf("Read %d", len(r.Data))
  1554. }
  1555. type jsonReadResponse struct {
  1556. Len uint64
  1557. }
  1558. func (r *ReadResponse) MarshalJSON() ([]byte, error) {
  1559. j := jsonReadResponse{
  1560. Len: uint64(len(r.Data)),
  1561. }
  1562. return json.Marshal(j)
  1563. }
  1564. // A ReleaseRequest asks to release (close) an open file handle.
  1565. type ReleaseRequest struct {
  1566. Header `json:"-"`
  1567. Dir bool // is this Releasedir?
  1568. Handle HandleID
  1569. Flags OpenFlags // flags from OpenRequest
  1570. ReleaseFlags ReleaseFlags
  1571. LockOwner uint32
  1572. }
  1573. var _ = Request(&ReleaseRequest{})
  1574. func (r *ReleaseRequest) String() string {
  1575. return fmt.Sprintf("Release [%s] %v fl=%v rfl=%v owner=%#x", &r.Header, r.Handle, r.Flags, r.ReleaseFlags, r.LockOwner)
  1576. }
  1577. // Respond replies to the request, indicating that the handle has been released.
  1578. func (r *ReleaseRequest) Respond() {
  1579. buf := newBuffer(0)
  1580. r.respond(buf)
  1581. }
  1582. // A DestroyRequest is sent by the kernel when unmounting the file system.
  1583. // No more requests will be received after this one, but it should still be
  1584. // responded to.
  1585. type DestroyRequest struct {
  1586. Header `json:"-"`
  1587. }
  1588. var _ = Request(&DestroyRequest{})
  1589. func (r *DestroyRequest) String() string {
  1590. return fmt.Sprintf("Destroy [%s]", &r.Header)
  1591. }
  1592. // Respond replies to the request.
  1593. func (r *DestroyRequest) Respond() {
  1594. buf := newBuffer(0)
  1595. r.respond(buf)
  1596. }
  1597. // A ForgetRequest is sent by the kernel when forgetting about r.Node
  1598. // as returned by r.N lookup requests.
  1599. type ForgetRequest struct {
  1600. Header `json:"-"`
  1601. N uint64
  1602. }
  1603. var _ = Request(&ForgetRequest{})
  1604. func (r *ForgetRequest) String() string {
  1605. return fmt.Sprintf("Forget [%s] %d", &r.Header, r.N)
  1606. }
  1607. // Respond replies to the request, indicating that the forgetfulness has been recorded.
  1608. func (r *ForgetRequest) Respond() {
  1609. // Don't reply to forget messages.
  1610. r.noResponse()
  1611. }
  1612. // A Dirent represents a single directory entry.
  1613. type Dirent struct {
  1614. // Inode this entry names.
  1615. Inode uint64
  1616. // Type of the entry, for example DT_File.
  1617. //
  1618. // Setting this is optional. The zero value (DT_Unknown) means
  1619. // callers will just need to do a Getattr when the type is
  1620. // needed. Providing a type can speed up operations
  1621. // significantly.
  1622. Type DirentType
  1623. // Name of the entry
  1624. Name string
  1625. }
  1626. // Type of an entry in a directory listing.
  1627. type DirentType uint32
  1628. const (
  1629. // These don't quite match os.FileMode; especially there's an
  1630. // explicit unknown, instead of zero value meaning file. They
  1631. // are also not quite syscall.DT_*; nothing says the FUSE
  1632. // protocol follows those, and even if they were, we don't
  1633. // want each fs to fiddle with syscall.
  1634. // The shift by 12 is hardcoded in the FUSE userspace
  1635. // low-level C library, so it's safe here.
  1636. DT_Unknown DirentType = 0
  1637. DT_Socket DirentType = syscall.S_IFSOCK >> 12
  1638. DT_Link DirentType = syscall.S_IFLNK >> 12
  1639. DT_File DirentType = syscall.S_IFREG >> 12
  1640. DT_Block DirentType = syscall.S_IFBLK >> 12
  1641. DT_Dir DirentType = syscall.S_IFDIR >> 12
  1642. DT_Char DirentType = syscall.S_IFCHR >> 12
  1643. DT_FIFO DirentType = syscall.S_IFIFO >> 12
  1644. )
  1645. func (t DirentType) String() string {
  1646. switch t {
  1647. case DT_Unknown:
  1648. return "unknown"
  1649. case DT_Socket:
  1650. return "socket"
  1651. case DT_Link:
  1652. return "link"
  1653. case DT_File:
  1654. return "file"
  1655. case DT_Block:
  1656. return "block"
  1657. case DT_Dir:
  1658. return "dir"
  1659. case DT_Char:
  1660. return "char"
  1661. case DT_FIFO:
  1662. return "fifo"
  1663. }
  1664. return "invalid"
  1665. }
  1666. // AppendDirent appends the encoded form of a directory entry to data
  1667. // and returns the resulting slice.
  1668. func AppendDirent(data []byte, dir Dirent) []byte {
  1669. de := dirent{
  1670. Ino: dir.Inode,
  1671. Namelen: uint32(len(dir.Name)),
  1672. Type: uint32(dir.Type),
  1673. }
  1674. de.Off = uint64(len(data) + direntSize + (len(dir.Name)+7)&^7)
  1675. data = append(data, (*[direntSize]byte)(unsafe.Pointer(&de))[:]...)
  1676. data = append(data, dir.Name...)
  1677. n := direntSize + uintptr(len(dir.Name))
  1678. if n%8 != 0 {
  1679. var pad [8]byte
  1680. data = append(data, pad[:8-n%8]...)
  1681. }
  1682. return data
  1683. }
  1684. // A WriteRequest asks to write to an open file.
  1685. type WriteRequest struct {
  1686. Header
  1687. Handle HandleID
  1688. Offset int64
  1689. Data []byte
  1690. Flags WriteFlags
  1691. LockOwner uint64
  1692. FileFlags OpenFlags
  1693. }
  1694. var _ = Request(&WriteRequest{})
  1695. func (r *WriteRequest) String() string {
  1696. 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)
  1697. }
  1698. type jsonWriteRequest struct {
  1699. Handle HandleID
  1700. Offset int64
  1701. Len uint64
  1702. Flags WriteFlags
  1703. }
  1704. func (r *WriteRequest) MarshalJSON() ([]byte, error) {
  1705. j := jsonWriteRequest{
  1706. Handle: r.Handle,
  1707. Offset: r.Offset,
  1708. Len: uint64(len(r.Data)),
  1709. Flags: r.Flags,
  1710. }
  1711. return json.Marshal(j)
  1712. }
  1713. // Respond replies to the request with the given response.
  1714. func (r *WriteRequest) Respond(resp *WriteResponse) {
  1715. buf := newBuffer(unsafe.Sizeof(writeOut{}))
  1716. out := (*writeOut)(buf.alloc(unsafe.Sizeof(writeOut{})))
  1717. out.Size = uint32(resp.Size)
  1718. r.respond(buf)
  1719. }
  1720. // A WriteResponse replies to a write indicating how many bytes were written.
  1721. type WriteResponse struct {
  1722. Size int
  1723. }
  1724. func (r *WriteResponse) String() string {
  1725. return fmt.Sprintf("Write %d", r.Size)
  1726. }
  1727. // A SetattrRequest asks to change one or more attributes associated with a file,
  1728. // as indicated by Valid.
  1729. type SetattrRequest struct {
  1730. Header `json:"-"`
  1731. Valid SetattrValid
  1732. Handle HandleID
  1733. Size uint64
  1734. Atime time.Time
  1735. Mtime time.Time
  1736. Mode os.FileMode
  1737. Uid uint32
  1738. Gid uint32
  1739. // OS X only
  1740. Bkuptime time.Time
  1741. Chgtime time.Time
  1742. Crtime time.Time
  1743. Flags uint32 // see chflags(2)
  1744. }
  1745. var _ = Request(&SetattrRequest{})
  1746. func (r *SetattrRequest) String() string {
  1747. var buf bytes.Buffer
  1748. fmt.Fprintf(&buf, "Setattr [%s]", &r.Header)
  1749. if r.Valid.Mode() {
  1750. fmt.Fprintf(&buf, " mode=%v", r.Mode)
  1751. }
  1752. if r.Valid.Uid() {
  1753. fmt.Fprintf(&buf, " uid=%d", r.Uid)
  1754. }
  1755. if r.Valid.Gid() {
  1756. fmt.Fprintf(&buf, " gid=%d", r.Gid)
  1757. }
  1758. if r.Valid.Size() {
  1759. fmt.Fprintf(&buf, " size=%d", r.Size)
  1760. }
  1761. if r.Valid.Atime() {
  1762. fmt.Fprintf(&buf, " atime=%v", r.Atime)
  1763. }
  1764. if r.Valid.AtimeNow() {
  1765. fmt.Fprintf(&buf, " atime=now")
  1766. }
  1767. if r.Valid.Mtime() {
  1768. fmt.Fprintf(&buf, " mtime=%v", r.Mtime)
  1769. }
  1770. if r.Valid.MtimeNow() {
  1771. fmt.Fprintf(&buf, " mtime=now")
  1772. }
  1773. if r.Valid.Handle() {
  1774. fmt.Fprintf(&buf, " handle=%v", r.Handle)
  1775. } else {
  1776. fmt.Fprintf(&buf, " handle=INVALID-%v", r.Handle)
  1777. }
  1778. if r.Valid.LockOwner() {
  1779. fmt.Fprintf(&buf, " lockowner")
  1780. }
  1781. if r.Valid.Crtime() {
  1782. fmt.Fprintf(&buf, " crtime=%v", r.Crtime)
  1783. }
  1784. if r.Valid.Chgtime() {
  1785. fmt.Fprintf(&buf, " chgtime=%v", r.Chgtime)
  1786. }
  1787. if r.Valid.Bkuptime() {
  1788. fmt.Fprintf(&buf, " bkuptime=%v", r.Bkuptime)
  1789. }
  1790. if r.Valid.Flags() {
  1791. fmt.Fprintf(&buf, " flags=%v", r.Flags)
  1792. }
  1793. return buf.String()
  1794. }
  1795. // Respond replies to the request with the given response,
  1796. // giving the updated attributes.
  1797. func (r *SetattrRequest) Respond(resp *SetattrResponse) {
  1798. size := attrOutSize(r.Header.Conn.proto)
  1799. buf := newBuffer(size)
  1800. out := (*attrOut)(buf.alloc(size))
  1801. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1802. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1803. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1804. r.respond(buf)
  1805. }
  1806. // A SetattrResponse is the response to a SetattrRequest.
  1807. type SetattrResponse struct {
  1808. Attr Attr // file attributes
  1809. }
  1810. func (r *SetattrResponse) String() string {
  1811. return fmt.Sprintf("Setattr %v", r.Attr)
  1812. }
  1813. // A FlushRequest asks for the current state of an open file to be flushed
  1814. // to storage, as when a file descriptor is being closed. A single opened Handle
  1815. // may receive multiple FlushRequests over its lifetime.
  1816. type FlushRequest struct {
  1817. Header `json:"-"`
  1818. Handle HandleID
  1819. Flags uint32
  1820. LockOwner uint64
  1821. }
  1822. var _ = Request(&FlushRequest{})
  1823. func (r *FlushRequest) String() string {
  1824. return fmt.Sprintf("Flush [%s] %v fl=%#x lk=%#x", &r.Header, r.Handle, r.Flags, r.LockOwner)
  1825. }
  1826. // Respond replies to the request, indicating that the flush succeeded.
  1827. func (r *FlushRequest) Respond() {
  1828. buf := newBuffer(0)
  1829. r.respond(buf)
  1830. }
  1831. // A RemoveRequest asks to remove a file or directory from the
  1832. // directory r.Node.
  1833. type RemoveRequest struct {
  1834. Header `json:"-"`
  1835. Name string // name of the entry to remove
  1836. Dir bool // is this rmdir?
  1837. }
  1838. var _ = Request(&RemoveRequest{})
  1839. func (r *RemoveRequest) String() string {
  1840. return fmt.Sprintf("Remove [%s] %q dir=%v", &r.Header, r.Name, r.Dir)
  1841. }
  1842. // Respond replies to the request, indicating that the file was removed.
  1843. func (r *RemoveRequest) Respond() {
  1844. buf := newBuffer(0)
  1845. r.respond(buf)
  1846. }
  1847. // A SymlinkRequest is a request to create a symlink making NewName point to Target.
  1848. type SymlinkRequest struct {
  1849. Header `json:"-"`
  1850. NewName, Target string
  1851. }
  1852. var _ = Request(&SymlinkRequest{})
  1853. func (r *SymlinkRequest) String() string {
  1854. return fmt.Sprintf("Symlink [%s] from %q to target %q", &r.Header, r.NewName, r.Target)
  1855. }
  1856. // Respond replies to the request, indicating that the symlink was created.
  1857. func (r *SymlinkRequest) Respond(resp *SymlinkResponse) {
  1858. size := entryOutSize(r.Header.Conn.proto)
  1859. buf := newBuffer(size)
  1860. out := (*entryOut)(buf.alloc(size))
  1861. out.Nodeid = uint64(resp.Node)
  1862. out.Generation = resp.Generation
  1863. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1864. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1865. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1866. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1867. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1868. r.respond(buf)
  1869. }
  1870. // A SymlinkResponse is the response to a SymlinkRequest.
  1871. type SymlinkResponse struct {
  1872. LookupResponse
  1873. }
  1874. func (r *SymlinkResponse) String() string {
  1875. return fmt.Sprintf("Symlink %v", r.LookupResponse.string())
  1876. }
  1877. // A ReadlinkRequest is a request to read a symlink's target.
  1878. type ReadlinkRequest struct {
  1879. Header `json:"-"`
  1880. }
  1881. var _ = Request(&ReadlinkRequest{})
  1882. func (r *ReadlinkRequest) String() string {
  1883. return fmt.Sprintf("Readlink [%s]", &r.Header)
  1884. }
  1885. func (r *ReadlinkRequest) Respond(target string) {
  1886. buf := newBuffer(uintptr(len(target)))
  1887. buf = append(buf, target...)
  1888. r.respond(buf)
  1889. }
  1890. // A LinkRequest is a request to create a hard link.
  1891. type LinkRequest struct {
  1892. Header `json:"-"`
  1893. OldNode NodeID
  1894. NewName string
  1895. }
  1896. var _ = Request(&LinkRequest{})
  1897. func (r *LinkRequest) String() string {
  1898. return fmt.Sprintf("Link [%s] node %d to %q", &r.Header, r.OldNode, r.NewName)
  1899. }
  1900. func (r *LinkRequest) Respond(resp *LookupResponse) {
  1901. size := entryOutSize(r.Header.Conn.proto)
  1902. buf := newBuffer(size)
  1903. out := (*entryOut)(buf.alloc(size))
  1904. out.Nodeid = uint64(resp.Node)
  1905. out.Generation = resp.Generation
  1906. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1907. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1908. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1909. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1910. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1911. r.respond(buf)
  1912. }
  1913. // A RenameRequest is a request to rename a file.
  1914. type RenameRequest struct {
  1915. Header `json:"-"`
  1916. NewDir NodeID
  1917. OldName, NewName string
  1918. }
  1919. var _ = Request(&RenameRequest{})
  1920. func (r *RenameRequest) String() string {
  1921. return fmt.Sprintf("Rename [%s] from %q to dirnode %v %q", &r.Header, r.OldName, r.NewDir, r.NewName)
  1922. }
  1923. func (r *RenameRequest) Respond() {
  1924. buf := newBuffer(0)
  1925. r.respond(buf)
  1926. }
  1927. type MknodRequest struct {
  1928. Header `json:"-"`
  1929. Name string
  1930. Mode os.FileMode
  1931. Rdev uint32
  1932. // Umask of the request. Not supported on OS X.
  1933. Umask os.FileMode
  1934. }
  1935. var _ = Request(&MknodRequest{})
  1936. func (r *MknodRequest) String() string {
  1937. return fmt.Sprintf("Mknod [%s] Name %q mode=%v umask=%v rdev=%d", &r.Header, r.Name, r.Mode, r.Umask, r.Rdev)
  1938. }
  1939. func (r *MknodRequest) Respond(resp *LookupResponse) {
  1940. size := entryOutSize(r.Header.Conn.proto)
  1941. buf := newBuffer(size)
  1942. out := (*entryOut)(buf.alloc(size))
  1943. out.Nodeid = uint64(resp.Node)
  1944. out.Generation = resp.Generation
  1945. out.EntryValid = uint64(resp.EntryValid / time.Second)
  1946. out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond)
  1947. out.AttrValid = uint64(resp.Attr.Valid / time.Second)
  1948. out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond)
  1949. resp.Attr.attr(&out.Attr, r.Header.Conn.proto)
  1950. r.respond(buf)
  1951. }
  1952. type FsyncRequest struct {
  1953. Header `json:"-"`
  1954. Handle HandleID
  1955. // TODO bit 1 is datasync, not well documented upstream
  1956. Flags uint32
  1957. Dir bool
  1958. }
  1959. var _ = Request(&FsyncRequest{})
  1960. func (r *FsyncRequest) String() string {
  1961. return fmt.Sprintf("Fsync [%s] Handle %v Flags %v", &r.Header, r.Handle, r.Flags)
  1962. }
  1963. func (r *FsyncRequest) Respond() {
  1964. buf := newBuffer(0)
  1965. r.respond(buf)
  1966. }
  1967. // An InterruptRequest is a request to interrupt another pending request. The
  1968. // response to that request should return an error status of EINTR.
  1969. type InterruptRequest struct {
  1970. Header `json:"-"`
  1971. IntrID RequestID // ID of the request to be interrupt.
  1972. }
  1973. var _ = Request(&InterruptRequest{})
  1974. func (r *InterruptRequest) Respond() {
  1975. // nothing to do here
  1976. r.noResponse()
  1977. }
  1978. func (r *InterruptRequest) String() string {
  1979. return fmt.Sprintf("Interrupt [%s] ID %v", &r.Header, r.IntrID)
  1980. }
  1981. // An ExchangeDataRequest is a request to exchange the contents of two
  1982. // files, while leaving most metadata untouched.
  1983. //
  1984. // This request comes from OS X exchangedata(2) and represents its
  1985. // specific semantics. Crucially, it is very different from Linux
  1986. // renameat(2) RENAME_EXCHANGE.
  1987. //
  1988. // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/exchangedata.2.html
  1989. type ExchangeDataRequest struct {
  1990. Header `json:"-"`
  1991. OldDir, NewDir NodeID
  1992. OldName, NewName string
  1993. // TODO options
  1994. }
  1995. var _ = Request(&ExchangeDataRequest{})
  1996. func (r *ExchangeDataRequest) String() string {
  1997. // TODO options
  1998. return fmt.Sprintf("ExchangeData [%s] %v %q and %v %q", &r.Header, r.OldDir, r.OldName, r.NewDir, r.NewName)
  1999. }
  2000. func (r *ExchangeDataRequest) Respond() {
  2001. buf := newBuffer(0)
  2002. r.respond(buf)
  2003. }