Skip to content

Commit a03ce27

Browse files
author
dzsekijo
committed
make keep_cache and direct_io settable filewise
1 parent 2aeccd0 commit a03ce27

4 files changed

Lines changed: 108 additions & 3 deletions

File tree

ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2007-05-01 Csaba Henk <csaba.henk@creo.hu>
2+
* Make keep_cache and direct_io settable filewise.
3+
14
2007-03-13 Csaba Henk <csaba.henk@creo.hu>
25
* Check for float stat fields everywhere, not only on OS X.
36

README.new_fusepy_api

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,20 @@ and there are not that many of them (there is no `writedir`). You can
267267
register a directory class by setting the ``dir_class`` ``Fuse``
268268
attribute. I bet you don't wanna use this feature, though.
269269

270+
Another use of filehandles is that they can be used for adjusting some FUSE
271+
tunables *filewise*. That is, if you return a py-filehandle object so that it
272+
has a ``keep_cache`` or ``direct_io`` attribute of value ``True``, then the
273+
respective option will be enabled for the given file by FUSE [#]_. As a special
274+
case, if the returned py-filehandle is an instance of ``fuse.FuseFileInfo``, it
275+
will be used for nothing else apart from testing the ``keep_cache`` /
276+
``direct_io`` attributes (after which it will be disposed).
277+
270278
.. [#] although it should not be an integer, as integers are treated as
271279
error values
272280

281+
.. [#] See the meaning of these options eg. in standard FUSE help message,
282+
which you can read by, eg., running ``example/xmp.py -h`` from the root of
283+
the FUSE Python bindings source tree.
273284

274285
Complete support for hi-lib
275286
---------------------------

fuse.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,16 @@ def __init__(self, name):
429429
self.ino = 0
430430

431431

432+
433+
class FuseFileInfo:
434+
435+
def __init__(self, keep = False, direct_io = False):
436+
self.keep = keep
437+
self.direct_io = direct_io
438+
439+
440+
441+
432442
########## Interface for requiring certain features from your underlying FUSE library.
433443

434444
def feature_needs(*feas):
@@ -468,6 +478,10 @@ def feature_needs(*feas):
468478
fmap = {'stateful_files': 22,
469479
'stateful_dirs': 23,
470480
'stateful_io': ('stateful_files', 'stateful_dirs'),
481+
'stateful_files_keep_cache': 23,
482+
'stateful_files_direct_io': 23,
483+
'keep_cache': ('stateful_files_keep_cache',),
484+
'direct_io': ('stateful_files_direct_io',),
471485
'has_opendir': ('stateful_dirs',),
472486
'has_releasedir': ('stateful_dirs',),
473487
'has_fsyncdir': ('stateful_dirs',),
@@ -640,14 +654,40 @@ def main(self, args=None):
640654
c = ''
641655
if get_compat_0_1() and hasattr(self, a + '_compat_0_1'):
642656
c = '_compat_0_1'
643-
d[a] = ErrnoWrapper(getattr(self, a + c))
657+
d[a] = ErrnoWrapper(self.lowwrap(a + c))
644658

645659
try:
646660
main(**d)
647661
except FuseError:
648662
if args or self.fuse_args.mount_expected():
649663
raise
650664

665+
def lowwrap(self, fname):
666+
"""
667+
Wraps the fname method when the C code expects a different kind of
668+
callback than we have in the fusepy API. (The wrapper is usually for
669+
performing some checks or transfromations which could be done in C but
670+
is simpler if done in Python.)
671+
672+
Currently `open` and `create` are wrapped: a boolean flag is added
673+
which indicates if the result is to be kept during the opened file's
674+
lifetime or can be thrown away. Namely, it's considered disposable
675+
if it's an instance of FuseFileInfo.
676+
"""
677+
fun = getattr(self, fname)
678+
679+
if not fname in ('open', 'create'):
680+
return fun
681+
682+
def wrap(*a, **kw):
683+
res = fun(*a, **kw)
684+
if not res or type(res) == type(0):
685+
return res
686+
else:
687+
return (res, type(res) != FuseFileInfo)
688+
689+
return wrap
690+
651691
def GetContext(self):
652692
return FuseGetContext(self)
653693

fuseparts/_fusemodule.c

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,31 @@ write_func(const char *path, const char *buf, size_t t, off_t off)
506506
static int
507507
open_func(const char *path, struct fuse_file_info *fi)
508508
{
509+
PyObject *pytmp, *pytmp1;
510+
509511
PROLOGUE( PyObject_CallFunction(open_cb, "si", path, fi->flags) )
510512

511-
fi->fh = (uintptr_t) v;
513+
pytmp = PyTuple_GetItem(v, 0);
514+
515+
#if FUSE_VERSION >= 23
516+
pytmp1 = PyObject_GetAttrString(pytmp, "keep_cache");
517+
if (pytmp1) {
518+
fi->keep_cache = PyObject_IsTrue(pytmp1);
519+
Py_DECREF(pytmp1);
520+
}
521+
pytmp1 = PyObject_GetAttrString(pytmp, "direct_io");
522+
if (pytmp1) {
523+
fi->direct_io = PyObject_IsTrue(pytmp1);
524+
Py_DECREF(pytmp1);
525+
}
526+
527+
if (PyObject_IsTrue(PyTuple_GetItem(v, 1)))
528+
#endif
529+
{
530+
Py_INCREF(pytmp);
531+
fi->fh = (uintptr_t) pytmp;
532+
}
533+
512534
ret = 0;
513535
goto OUT;
514536

@@ -527,11 +549,30 @@ open_func(const char *path, int mode)
527549
static int
528550
create_func(const char *path, mode_t mode, struct fuse_file_info *fi)
529551
{
552+
PyObject *pytmp, *pytmp1;
553+
530554
PROLOGUE(
531555
PyObject_CallFunction(create_cb, "sii", path, fi->flags, mode)
532556
)
533557

534-
fi->fh = (uintptr_t) v;
558+
pytmp = PyTuple_GetItem(v, 0);
559+
560+
pytmp1 = PyObject_GetAttrString(pytmp, "keep_cache");
561+
if (pytmp1) {
562+
fi->keep_cache = PyObject_IsTrue(pytmp1);
563+
Py_DECREF(pytmp1);
564+
}
565+
pytmp1 = PyObject_GetAttrString(pytmp, "direct_io");
566+
if (pytmp1) {
567+
fi->direct_io = PyObject_IsTrue(pytmp1);
568+
Py_DECREF(pytmp1);
569+
}
570+
571+
if (PyObject_IsTrue(PyTuple_GetItem(v, 1))) {
572+
Py_INCREF(pytmp);
573+
fi->fh = (uintptr_t) pytmp;
574+
}
575+
535576
ret = 0;
536577
goto OUT;
537578

@@ -735,6 +776,16 @@ fsdestroy_func(void *param)
735776
}
736777
#endif
737778

779+
static int
780+
lock_func(const char *path, struct fuse_file_info *fi, int cmd,
781+
struct flock *lock)
782+
{
783+
(void) path;
784+
785+
return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
786+
sizeof(fi->lock_owner));
787+
}
788+
738789
static int
739790
pyfuse_loop_mt(struct fuse *f)
740791
{

0 commit comments

Comments
 (0)