summaryrefslogtreecommitdiff
path: root/document-portal
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2015-09-08 11:09:40 +0200
committerAlexander Larsson <alexl@redhat.com>2015-09-08 11:09:40 +0200
commit8fe6a115f6c577a0cfc432239eda9d54bdcf72d4 (patch)
tree87f77b3c581e36da3a2f213ce424fde09700f945 /document-portal
parent18cc81d8a7893c7348b7d6bd728852749423f720 (diff)
downloadxdg-app-8fe6a115f6c577a0cfc432239eda9d54bdcf72d4.tar.gz
fuse: Properly invalidate inodes and entries
Diffstat (limited to 'document-portal')
-rw-r--r--document-portal/xdp-fuse.c60
-rw-r--r--document-portal/xdp-fuse.h12
-rw-r--r--document-portal/xdp-main.c11
3 files changed, 75 insertions, 8 deletions
diff --git a/document-portal/xdp-fuse.c b/document-portal/xdp-fuse.c
index f2527c8..65f1e65 100644
--- a/document-portal/xdp-fuse.c
+++ b/document-portal/xdp-fuse.c
@@ -63,6 +63,12 @@ static guint32 next_app_id = 1;
G_LOCK_DEFINE(app_id);
+static GThread *fuse_thread = NULL;
+static struct fuse_session *session = NULL;
+static struct fuse_chan *main_ch = NULL;
+static char *mount_path = NULL;
+static pthread_t fuse_pthread = 0;
+
static int
steal_fd (int *fdp)
{
@@ -1740,6 +1746,7 @@ xdp_fuse_rename (fuse_req_t req,
g_autoptr(XdpTmp) tmp = NULL;
g_autoptr(XdpTmp) other_tmp = NULL;
guint32 app_id = 0;
+ guint32 doc_id = 0;
gboolean can_write;
g_debug ("xdp_fuse_rename %lx/%s -> %lx/%s", parent, name, newparent, newname);
@@ -1754,9 +1761,11 @@ xdp_fuse_rename (fuse_req_t req,
if (parent_class == APP_DOC_DIR_INO_CLASS)
{
app_id = get_app_id_from_app_doc_ino (parent_class_ino);
+ doc_id = get_doc_id_from_app_doc_ino (parent_class_ino);
}
else if (parent_class == DOC_DIR_INO_CLASS)
{
+ doc_id = parent_class_ino;
}
else
{
@@ -1816,6 +1825,16 @@ xdp_fuse_rename (fuse_req_t req,
xdp_tmp_unlink_nolock (tmp);
fuse_reply_err (req, 0);
+
+ /* We actually turn the old inode to a different one after the rename, so
+ we need to invalidate the target entry */
+
+ if (app_id != 0)
+ fuse_lowlevel_notify_inval_entry (main_ch, make_app_doc_dir_inode (app_id, doc_id),
+ basename, strlen (basename));
+ else
+ fuse_lowlevel_notify_inval_entry (main_ch, make_inode (DOC_DIR_INO_CLASS, doc_id),
+ basename, strlen (basename));
}
else
{
@@ -2114,11 +2133,42 @@ static struct fuse_lowlevel_ops xdp_fuse_oper = {
.unlink = xdp_fuse_unlink,
};
-static GThread *fuse_thread = NULL;
-static struct fuse_session *session = NULL;
-static struct fuse_chan *main_ch = NULL;
-static char *mount_path = NULL;
-static pthread_t fuse_pthread = 0;
+/* Called when a apps permissions to see a document is changed */
+void
+xdp_fuse_invalidate_doc_app (const char *doc_id_s,
+ const char *app_id_s,
+ XdgAppDbEntry *entry)
+{
+ guint32 app_id = get_app_id_from_name (app_id_s);
+ guint32 doc_id = xdp_id_from_name (doc_id_s);
+ g_autofree char *basename = xdp_entry_dup_basename (entry);
+
+ g_debug ("invalidate %s/%s\n", doc_id_s, app_id_s);
+
+ fuse_lowlevel_notify_inval_inode (main_ch, make_app_doc_file_inode (app_id, doc_id), 0, 0);
+ fuse_lowlevel_notify_inval_entry (main_ch, make_app_doc_dir_inode (app_id, doc_id),
+ basename, strlen (basename));
+ fuse_lowlevel_notify_inval_inode (main_ch, make_app_doc_dir_inode (app_id, doc_id), 0, 0);
+ fuse_lowlevel_notify_inval_entry (main_ch, make_inode (APP_DIR_INO_CLASS, app_id),
+ doc_id_s, strlen (doc_id_s));
+}
+
+/* Called when a document id is created/removed */
+void
+xdp_fuse_invalidate_doc (const char *doc_id_s,
+ XdgAppDbEntry *entry)
+{
+ guint32 doc_id = xdp_id_from_name (doc_id_s);
+ g_autofree char *basename = xdp_entry_dup_basename (entry);
+
+ g_debug ("invalidate %s\n", doc_id_s);
+
+ fuse_lowlevel_notify_inval_inode (main_ch, make_app_doc_file_inode (0, doc_id), 0, 0);
+ fuse_lowlevel_notify_inval_entry (main_ch, make_inode (DOC_DIR_INO_CLASS, doc_id),
+ basename, strlen (basename));
+ fuse_lowlevel_notify_inval_inode (main_ch, make_inode (DOC_DIR_INO_CLASS, doc_id), 0, 0);
+ fuse_lowlevel_notify_inval_entry (main_ch, FUSE_ROOT_ID, doc_id_s, strlen (doc_id_s));
+}
const char *
xdp_fuse_get_mountpoint (void)
diff --git a/document-portal/xdp-fuse.h b/document-portal/xdp-fuse.h
index b593065..16e08a8 100644
--- a/document-portal/xdp-fuse.h
+++ b/document-portal/xdp-fuse.h
@@ -10,9 +10,15 @@ char ** xdp_list_apps (void);
guint32 * xdp_list_docs (void);
XdgAppDbEntry *xdp_lookup_doc (guint32 id);
-gboolean xdp_fuse_init (GError **error);
-void xdp_fuse_exit (void);
-const char * xdp_fuse_get_mountpoint (void);
+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,
+ XdgAppDbEntry *entry);
+void xdp_fuse_invalidate_doc (const char *doc_id,
+ XdgAppDbEntry *entry);
+
G_END_DECLS
diff --git a/document-portal/xdp-main.c b/document-portal/xdp-main.c
index e33e74d..18ed826 100644
--- a/document-portal/xdp-main.c
+++ b/document-portal/xdp-main.c
@@ -97,6 +97,8 @@ do_set_permissions (XdgAppDbEntry *entry,
new_entry = xdg_app_db_entry_set_app_permissions (entry, app_id, perms_s);
xdg_app_db_set_entry (db, doc_id, new_entry);
+ xdp_fuse_invalidate_doc_app (doc_id, app_id, entry);
+
xdg_app_permission_store_call_set_permission (permission_store,
TABLE_NAME,
FALSE,
@@ -205,6 +207,8 @@ portal_delete (GDBusMethodInvocation *invocation,
{
const char *id;
g_autoptr(XdgAppDbEntry) entry = NULL;
+ g_autofree const char **old_apps = NULL;
+ int i;
g_variant_get (parameters, "(s)", &id);
@@ -225,6 +229,11 @@ portal_delete (GDBusMethodInvocation *invocation,
xdg_app_db_set_entry (db, id, NULL);
+ 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);
+
xdg_app_permission_store_call_delete (permission_store, TABLE_NAME,
id, NULL, NULL, NULL);
@@ -271,6 +280,8 @@ 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);
+
xdg_app_permission_store_call_set (permission_store,
TABLE_NAME,
TRUE,