diff options
author | Sascha Silbe <sascha-pgp@silbe.org> | 2010-06-03 15:24:01 (GMT) |
---|---|---|
committer | Sascha Silbe <sascha-pgp@silbe.org> | 2010-06-03 15:24:01 (GMT) |
commit | b23d2cddda0e1a80d94983ee36dbcba4034d8cf3 (patch) | |
tree | 27ef157e008b471ce70defcad865effc9a91746a | |
parent | 0f7ed2303db25860e206902d1b59e94d42ed84c1 (diff) |
add support for modifying metadata/extended attributes
-rwxr-xr-x | datastore-fuse.py | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/datastore-fuse.py b/datastore-fuse.py index ee32aad..de0f215 100755 --- a/datastore-fuse.py +++ b/datastore-fuse.py @@ -43,6 +43,9 @@ DS_DBUS_SERVICE = "org.laptop.sugar.DataStore" DS_DBUS_INTERFACE = "org.laptop.sugar.DataStore" DS_DBUS_PATH = "/org/laptop/sugar/DataStore" +XATTR_CREATE = 1 +XATTR_REPLACE = 2 + class DataStoreObjectStat(fuse.Stat): @@ -120,6 +123,9 @@ class Directory(fuse.Stat): def remove(self, name_): raise IOError(errno.EACCES, os.strerror(errno.EACCES)) + def setxattr(self, name_, attribute_, value_, flags_): + raise IOError(errno.ENOTSUP, os.strerror(errno.ENOTSUP)) + class ByTitleDirectory(Directory): def __init__(self, filesystem, root): @@ -164,6 +170,19 @@ class ByTitleDirectory(Directory): object_id = self._filesystem.resolve_title_name(name) self._filesystem.remove_entry(object_id) + def setxattr(self, name, attribute, value, flags): + object_id = self._filesystem.resolve_title_name(name) + metadata = self._filesystem.get_metadata(object_id) + if flags & XATTR_CREATE and attribute in metadata: + raise IOError(errno.EEXIST, os.strerror(errno.EEXIST)) + + if flags & XATTR_REPLACE and attribute not in metadata: + # on Linux ENOATTR=ENODATA (Python errno doesn't contain ENOATTR) + raise IOError(errno.ENODATA, os.strerror(errno.ENODATA)) + + metadata[attribute] = value + self._filesystem.write_metadata(object_id, metadata) + class ByIdDirectory(Directory): def __init__(self, filesystem): @@ -460,6 +479,13 @@ class DataStoreFS(fuse.Fuse): return attribute_names + def setxattr(self, path, name, value, flags): + if not name.startswith('user.'): + raise IOError(errno.EACCES, os.strerror(errno.EACCES)) + + name = name[5:] + return self._delegate(path, 'setxattr', name, value, flags) + def should_truncate(self, object_id): return object_id in self._truncate_object_ids @@ -527,6 +553,12 @@ class DataStoreFS(fuse.Fuse): return self._data_store.update(object_id, metadata, file_name, False, timeout=-1, byte_arrays=True) + def write_metadata(self, object_id, metadata): + # Current data store doesn't support metadata-only updates + file_name = self.get_data(object_id) + return self._data_store.update(object_id, metadata, file_name, + True, timeout=-1, byte_arrays=True) + def resolve_title_name(self, name): if name not in self._title_name_to_object_id: # FIXME: Hack to fill self._title_name_to_object_id. To be |