add os.statvfs() compatible statvfs method

[mark statfs deprecated but keep working via a compat shim]
This commit is contained in:
dzsekijo 2006-05-27 18:58:51 +00:00
parent b69e8d0b8e
commit 4158d7b0f7
5 changed files with 81 additions and 38 deletions

View file

@ -15,6 +15,8 @@
- Add compat hooks (python variable, environment variable).
- Document these changes in README.new_fusepy_api.
- bump __version__ to 0.2pre1.
- add os.statvfs() compatible statvfs method, mark statfs
deprecated, keep statfs useable via statfs -> statvfs conversion
2006-05-24 Csaba Henk <csaba.henk@creo.hu>
* Revamp fs initialization code.

View file

@ -104,3 +104,11 @@ This is what's addressed by the new API.
partially parsed pieces of the FUSE command line to the C code, which
used these directly in low level functions of the library, getting behind
the main commandline parsing routine of the FUSE lib with no real reason.
Anything else?
--------------
We deprecated the ``statfs()`` method (which was to return a tuple containing
some fs characteristics, in a somewhat ad hoc order). Instead of that, you are
suggested to implement ``statvfs()`` which is to return a tuple of the same
layout as of ``os.statvfs()`` return values.

View file

@ -374,42 +374,45 @@ static int
statfs_func(const char *dummy, struct statfs *fst)
#endif
{
int i, seqs;
long retvalues[8];
int i;
long retvalues[10];
PyObject *v = PyObject_CallFunction(statfs_cb, "");
PROLOGUE
if (!PySequence_Check(v))
goto OUT_DECREF;
#if FUSE_VERSION >= 25
seqs = MIN(PySequence_Size(v), 8);
#else
seqs = MIN(PySequence_Size(v), 7);
#endif
if (seqs < 7)
if (PySequence_Size(v) < 10)
goto OUT_DECREF;
for(i=0; i<seqs; i++) {
for(i = 0; i < 10; i++) {
PyObject *tmp = PySequence_GetItem(v, i);
retvalues[i] = PyInt_Check(tmp) ? PyInt_AsLong(tmp) :
(PyLong_Check(tmp) ? PyLong_AsLong(tmp) : 0);
}
/*
* To be completely theoretically correct, we should identify
* the indices via Python's statvfs module, but these indices
* are unlikely to change, so we just use direct idexing.
*/
fst->f_bsize = retvalues[0];
fst->f_blocks = retvalues[1];
fst->f_bfree = retvalues[2];
fst->f_bavail = retvalues[3];
fst->f_files = retvalues[4];
fst->f_ffree = retvalues[5];
#if FUSE_VERSION >= 25
fst->f_namemax = retvalues[6];
fst->f_frsize = retvalues[seqs >= 8 ? 7 : 0];
#else
fst->f_namelen = retvalues[6];
#endif
#if FUSE_VERSION >= 25
fst->f_frsize = retvalues[1];
#endif
fst->f_blocks = retvalues[2];
fst->f_bfree = retvalues[3];
fst->f_bavail = retvalues[4];
fst->f_files = retvalues[5];
fst->f_ffree = retvalues[6];
#if FUSE_VERSION >= 25
fst->f_favail = retvalues[7];
fst->f_flag = retvalues[8];
fst->f_namemax = retvalues[9];
#else
fst->f_namelen = retvalues[9];
#endif
ret = 0;
@ -493,7 +496,7 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
"getattr", "readlink", "getdir", "mknod",
"mkdir", "unlink", "rmdir", "symlink", "rename",
"link", "chmod", "chown", "truncate", "utime",
"open", "read", "write", "release", "statfs", "fsync",
"open", "read", "write", "release", "statvfs", "fsync",
"fuse_args", "multithreaded", NULL};
memset(&op, 0, sizeof(op));

31
fuse.py
View file

@ -427,7 +427,7 @@ class Fuse(object):
_attrs = ['getattr', 'readlink', 'getdir', 'mknod', 'mkdir',
'unlink', 'rmdir', 'symlink', 'rename', 'link', 'chmod',
'chown', 'truncate', 'utime', 'open', 'read', 'write', 'release',
'statfs', 'fsync']
'statvfs', 'fsync']
fusage = "%prog [mountpoint] [options]"
@ -436,6 +436,35 @@ class Fuse(object):
self.fuse_args = \
kw.has_key('fuse_args') and kw.pop('fuse_args') or FuseArgs()
# Convert statfs to the new, Python statvfs compatible statvfs method
if not hasattr(self, 'statvfs') and hasattr(self, 'statfs'):
def statvfs(self):
import statvfs
if not compat_0_1:
from warnings import warn
warn("`statfs' fs method is deprecated, use `statvfs' instead",
DeprecationWarning, stacklevel=1)
oout = self.statfs()
lo = len(oout)
nout = [0] * 10
nout[statvfs.F_BSIZE] = oout[0] # 0
nout[statvfs.F_FRSIZE] = oout[lo >= 8 and 7 or 0] # 1
nout[statvfs.F_BLOCKS] = oout[1] # 2
nout[statvfs.F_BFREE] = oout[2] # 3
nout[statvfs.F_BAVAIL] = oout[3] # 4
nout[statvfs.F_FILES] = oout[4] # 5
nout[statvfs.F_FFREE] = oout[5] # 6
nout[statvfs.F_FAVAIL] = lo >= 9 and oout[8] or 0 # 7
nout[statvfs.F_FLAG] = lo >= 10 and oout[9] or 0 # 8
nout[statvfs.F_NAMEMAX] = oout[6] # 9
return nout
self.__class__.statvfs = statvfs
if compat_0_1:
return self.__init_0_1__(*args, **kw)

29
xmp.py
View file

@ -123,26 +123,27 @@ class Xmp(Fuse):
print "xmp.py:Xmp:release: %s %s" % (path, flags)
return 0
def statfs(self):
def statvfs(self):
"""
Should return a tuple with the following 6 elements:
- blocksize - size of file blocks, in bytes
Should return a tuple like those returned by os.statvfs().
Feel free to set any of the above values to 0, which tells
the kernel that the info is not available.
However, to provide usable information (ie., you want sensible df(1)
output, you are suggested to specify at least the following 7 values
(in that order):
- blocksize - preferred size of file blocks, in bytes
- frsize - fundamental size of file blcoks, in bytes
[if you have no idea, use the same as blocksize]
- totalblocks - total number of blocks in the filesystem
- freeblocks - number of free blocks
- totalfiles - total number of file inodes
- freefiles - nunber of free file inodes
Feel free to set any of the above values to 0, which tells
the kernel that the info is not available.
"""
print "xmp.py:Xmp:statfs: returning fictitious values"
blocks_size = 1024
blocks = 100000
blocks_free = 25000
files = 100000
files_free = 60000
namelen = 80
return (blocks_size, blocks, blocks - blocks_free, blocks_free, files, files_free, namelen)
return os.statvfs(self.root)
def fsync(self, path, isfsyncfile):
print "xmp.py:Xmp:fsync: path=%s, isfsyncfile=%s" % (self.root + path, isfsyncfile)