diff options
author | Alexander Larsson <alexl@redhat.com> | 2015-09-08 11:09:40 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2015-09-08 11:09:40 +0200 |
commit | 8fe6a115f6c577a0cfc432239eda9d54bdcf72d4 (patch) | |
tree | 87f77b3c581e36da3a2f213ce424fde09700f945 /document-portal | |
parent | 18cc81d8a7893c7348b7d6bd728852749423f720 (diff) | |
download | xdg-app-8fe6a115f6c577a0cfc432239eda9d54bdcf72d4.tar.gz |
fuse: Properly invalidate inodes and entries
Diffstat (limited to 'document-portal')
-rw-r--r-- | document-portal/xdp-fuse.c | 60 | ||||
-rw-r--r-- | document-portal/xdp-fuse.h | 12 | ||||
-rw-r--r-- | document-portal/xdp-main.c | 11 |
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, |