@@ -43,8 +43,8 @@ static PyObject *getattr_cb=NULL, *readlink_cb=NULL, *readdir_cb=NULL,
4343 * statfs_cb = NULL , * fsync_cb = NULL , * create_cb = NULL , * opendir_cb = NULL ,
4444 * releasedir_cb = NULL , * fsyncdir_cb = NULL , * flush_cb = NULL , * ftruncate_cb = NULL ,
4545 * fgetattr_cb = NULL , * getxattr_cb = NULL , * listxattr_cb = NULL , * setxattr_cb = NULL ,
46- * removexattr_cb = NULL , * access_cb = NULL , * lock_cb = NULL , * fsinit_cb = NULL ,
47- * fsdestroy_cb = NULL ;
46+ * removexattr_cb = NULL , * access_cb = NULL , * lock_cb = NULL , * utimens_cb = NULL ,
47+ * bmap_cb = NULL , * fsinit_cb = NULL , * fsdestroy_cb = NULL ;
4848
4949static PyObject * Py_FuseError ;
5050static PyInterpreterState * interp ;
@@ -792,6 +792,7 @@ fsdestroy_func(void *param)
792792}
793793#endif
794794
795+ #if FUSE_VERSION >= 26
795796static inline PyObject *
796797lock_func_i (const char * path , struct fuse_file_info * fi , int cmd ,
797798 struct flock * lock )
@@ -841,6 +842,48 @@ lock_func(const char *path, struct fuse_file_info *fi, int cmd,
841842 EPILOGUE
842843}
843844
845+ static int
846+ utimens_func (const char * path , const struct timespec ts [2 ])
847+ {
848+ PROLOGUE (
849+ PyObject_CallFunction (utimens_cb , "siiii" , path ,
850+ ts [0 ].tv_sec , ts [0 ].tv_nsec ,
851+ ts [1 ].tv_sec , ts [1 ].tv_nsec )
852+ )
853+
854+ EPILOGUE
855+ }
856+
857+ static int
858+ bmap_func (const char * path , size_t blocksize , uint64_t * idx )
859+ {
860+ PyObject * pytmp ;
861+ unsigned long long ctmp ;
862+ struct { uint64_t idx ; } idxwrapper ;
863+
864+ PROLOGUE (
865+ #if PY_VERSION_HEX < 0x02050000
866+ PyObject_CallFunction (bmap_cb , "siK" , path , blocksize , * idx )
867+ #else
868+ PyObject_CallFunction (bmap_cb , "snK" , path , blocksize , * idx )
869+ #endif
870+ )
871+
872+ /*
873+ * We can make use of our py -> C numeric conversion macro with some
874+ * customization of the parameters...
875+ */
876+ pytmp = v ;
877+ Py_INCREF (pytmp );
878+ py2attr (& idxwrapper , idx );
879+
880+ * idx = idxwrapper .idx ;
881+ ret = 0 ;
882+
883+ EPILOGUE
884+ }
885+ #endif
886+
844887static int
845888pyfuse_loop_mt (struct fuse * f )
846889{
@@ -882,14 +925,14 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
882925 "open" , "read" , "write" , "release" , "statfs" , "fsync" ,
883926 "create" , "opendir" , "releasedir" , "fsyncdir" , "flush" ,
884927 "ftruncate" , "fgetattr" , "getxattr" , "listxattr" , "setxattr" ,
885- "removexattr" , "access" , "lock" , "fsinit " , "fsdestroy " ,
886- "fuse_args" , "multithreaded" , NULL
928+ "removexattr" , "access" , "lock" , "utimens " , "bmap " ,
929+ "fsinit" , "fsdestroy" , " fuse_args" , "multithreaded" , NULL
887930 };
888931
889932 memset (& op , 0 , sizeof (op ));
890933
891934 if (!PyArg_ParseTupleAndKeywords (args , kw ,
892- "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOi " ,
935+ "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOi " ,
893936 kwlist , & getattr_cb , & readlink_cb ,
894937 & readdir_cb , & mknod_cb , & mkdir_cb ,
895938 & unlink_cb , & rmdir_cb , & symlink_cb ,
@@ -902,7 +945,8 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
902945 & flush_cb , & ftruncate_cb ,
903946 & fgetattr_cb , & getxattr_cb ,
904947 & listxattr_cb , & setxattr_cb ,
905- & removexattr_cb , & access_cb , & lock_cb ,
948+ & removexattr_cb , & access_cb ,
949+ & lock_cb , & utimens_cb , & bmap_cb ,
906950 & fsinit_cb , & fsdestroy_cb ,
907951 & fargseq , & multithreaded ))
908952 return NULL ;
@@ -957,6 +1001,8 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
9571001#endif
9581002#if FUSE_VERSION >= 26
9591003 DO_ONE_ATTR (lock );
1004+ DO_ONE_ATTR (utimens );
1005+ DO_ONE_ATTR (bmap );
9601006#endif
9611007#if FUSE_VERSION >= 23
9621008 DO_ONE_ATTR_AS (init , fsinit );
0 commit comments