Reimplement fuse backend

The magic inode numbers we used before are problematic.

The inode nrs are tied to the file names, so inode changes on rename, which breaks posix expectations.

Also, it relied on 64bit inode space which is not true on i386.

So, this is a new implementation that uses a more traditional approach
of dynamically allocating inodes as needed.
This commit is contained in:
Alexander Larsson
2016-03-08 16:02:17 +01:00
parent 3e5d4a02d8
commit 7a61eaa91d
5 changed files with 1814 additions and 1889 deletions

View File

File diff suppressed because it is too large Load Diff

View File

@@ -7,18 +7,16 @@
G_BEGIN_DECLS
char ** xdp_list_apps (void);
guint32 * xdp_list_docs (void);
XdgAppDbEntry *xdp_lookup_doc (guint32 id);
char ** xdp_list_docs (void);
XdgAppDbEntry *xdp_lookup_doc (const char *doc_id);
gboolean xdp_fuse_init (GError **error);
void xdp_fuse_exit (void);
const char *xdp_fuse_get_mountpoint (void);
void xdp_fuse_invalidate_doc_app (const char *doc_id,
const char *app_id,
const char *opt_app_id,
XdgAppDbEntry *entry);
void xdp_fuse_invalidate_doc (const char *doc_id,
XdgAppDbEntry *entry);
guint32 xdp_fuse_lookup_id_for_inode (ino_t inode);
char *xdp_fuse_lookup_id_for_inode (ino_t inode);
G_END_DECLS

View File

@@ -51,37 +51,16 @@ xdp_list_apps (void)
return xdg_app_db_list_apps (db);
}
guint32 *
char **
xdp_list_docs (void)
{
GArray *res;
g_auto(GStrv) ids = NULL;
guint32 id;
int i;
AUTOLOCK(db);
res = g_array_new (TRUE, FALSE, sizeof (guint32));
ids = xdg_app_db_list_ids (db);
for (i = 0; ids[i] != NULL; i++)
{
guint32 id = xdp_id_from_name (ids[i]);
g_array_append_val (res, id);
}
id = 0;
g_array_append_val (res, id);
return (guint32 *)g_array_free (res, FALSE);
return xdg_app_db_list_ids (db);
}
XdgAppDbEntry *
xdp_lookup_doc (guint32 id)
xdp_lookup_doc (const char *doc_id)
{
g_autofree char *doc_id = xdp_name_from_id (id);
AUTOLOCK(db);
return xdg_app_db_lookup (db, doc_id);
}
@@ -252,7 +231,7 @@ portal_delete (GDBusMethodInvocation *invocation,
old_apps = xdg_app_db_entry_list_apps (entry);
for (i = 0; old_apps[i] != NULL; i++)
xdp_fuse_invalidate_doc_app (id, old_apps[i], entry);
xdp_fuse_invalidate_doc (id, entry);
xdp_fuse_invalidate_doc_app (id, NULL, entry);
if (persist_entry (entry))
xdg_app_permission_store_call_delete (permission_store, TABLE_NAME,
@@ -305,7 +284,7 @@ do_create_doc (struct stat *parent_st_buf, const char *path, gboolean reuse_exis
entry = xdg_app_db_entry_new (data);
xdg_app_db_set_entry (db, id, entry);
xdp_fuse_invalidate_doc (id, entry);
xdp_fuse_invalidate_doc_app (id, NULL, entry);
if (persistent)
xdg_app_permission_store_call_set (permission_store,
@@ -402,12 +381,11 @@ portal_add (GDBusMethodInvocation *invocation,
if (st_buf.st_dev == fuse_dev)
{
/* The passed in fd is on the fuse filesystem itself */
guint32 old_id;
g_autoptr(XdgAppDbEntry) old_entry = NULL;
old_id = xdp_fuse_lookup_id_for_inode (st_buf.st_ino);
g_debug ("path on fuse, id %x\n", old_id);
if (old_id == 0)
id = xdp_fuse_lookup_id_for_inode (st_buf.st_ino);
g_debug ("path on fuse, id %s\n", id);
if (id == NULL)
{
g_dbus_method_invocation_return_error (invocation,
XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
@@ -415,8 +393,6 @@ portal_add (GDBusMethodInvocation *invocation,
return;
}
id = xdp_name_from_id (old_id);
/* If the entry doesn't exist anymore, fail. Also fail if not
resuse_existing, because otherwise the user could use this to
get a copy with permissions and thus escape later permission

View File

@@ -74,12 +74,6 @@ xdp_entry_has_permissions (XdgAppDbEntry *entry,
return (current_perms & perms) == perms;
}
guint32
xdp_id_from_name (const char *name)
{
return g_ascii_strtoull (name, NULL, 16);
}
char *
xdp_name_from_id (guint32 doc_id)
{
@@ -133,50 +127,3 @@ xdp_entry_get_flags (XdgAppDbEntry *entry)
g_autoptr(GVariant) c = g_variant_get_child_value (v, 3);
return g_variant_get_uint32 (c);
}
int
xdp_entry_open_dir (XdgAppDbEntry *entry)
{
g_autofree char *dirname = xdp_entry_dup_dirname (entry);
struct stat st_buf;
int fd;
fd = open (dirname, O_CLOEXEC | O_PATH | O_DIRECTORY);
if (fd == -1)
return -1;
if (fstat (fd, &st_buf) < 0)
{
close (fd);
errno = ENOENT;
return -1;
}
if (st_buf.st_ino != xdp_entry_get_inode (entry) ||
st_buf.st_dev != xdp_entry_get_device (entry))
{
close (fd);
errno = ENOENT;
return -1;
}
return fd;
}
int
xdp_entry_stat (XdgAppDbEntry *entry,
struct stat *buf,
int flags)
{
glnx_fd_close int fd = -1;
g_autofree char *basename = xdp_entry_dup_basename (entry);
fd = xdp_entry_open_dir (entry);
if (fd < 0)
return -1;
if (fstatat (fd, basename, buf, flags) != 0)
return -1;
return 0;
}

View File

@@ -24,12 +24,7 @@ char * xdp_entry_dup_dirname (XdgAppDbEntry *entry);
guint64 xdp_entry_get_device (XdgAppDbEntry *entry);
guint64 xdp_entry_get_inode (XdgAppDbEntry *entry);
guint32 xdp_entry_get_flags (XdgAppDbEntry *entry);
int xdp_entry_open_dir (XdgAppDbEntry *entry);
int xdp_entry_stat (XdgAppDbEntry *entry,
struct stat *buf,
int flags);
guint32 xdp_id_from_name (const char *name);
char * xdp_name_from_id (guint32 doc_id);