Skip to content

Commit 324b954

Browse files
lostjefflehsiangkao
authored andcommitted
cachefiles: notify the user daemon when withdrawing cookie
Notify the user daemon that cookie is going to be withdrawn, providing a hint that the associated anonymous fd can be closed. Be noted that this is only a hint. The user daemon may close the associated anonymous fd when receiving the CLOSE request, then it will receive another anonymous fd when the cookie gets looked up. Or it may ignore the CLOSE request, and keep writing data through the anonymous fd. However the next time the cookie gets looked up, the user daemon will still receive another new anonymous fd. Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com> Acked-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/20220425122143.56815-5-jefflexu@linux.alibaba.com Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
1 parent d11b0b0 commit 324b954

4 files changed

Lines changed: 46 additions & 0 deletions

File tree

fs/cachefiles/interface.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ static void cachefiles_withdraw_cookie(struct fscache_cookie *cookie)
362362
spin_unlock(&cache->object_list_lock);
363363
}
364364

365+
cachefiles_ondemand_clean_object(object);
366+
365367
if (object->file) {
366368
cachefiles_begin_secure(cache, &saved_cred);
367369
cachefiles_clean_up_object(object, cache);

fs/cachefiles/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ extern int cachefiles_ondemand_copen(struct cachefiles_cache *cache,
290290
char *args);
291291

292292
extern int cachefiles_ondemand_init_object(struct cachefiles_object *object);
293+
extern void cachefiles_ondemand_clean_object(struct cachefiles_object *object);
293294

294295
#else
295296
static inline ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
@@ -302,6 +303,10 @@ static inline int cachefiles_ondemand_init_object(struct cachefiles_object *obje
302303
{
303304
return 0;
304305
}
306+
307+
static inline void cachefiles_ondemand_clean_object(struct cachefiles_object *object)
308+
{
309+
}
305310
#endif
306311

307312
/*

fs/cachefiles/ondemand.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
229229
goto err_put_fd;
230230
}
231231

232+
/* CLOSE request has no reply */
233+
if (msg->opcode == CACHEFILES_OP_CLOSE) {
234+
xa_erase(&cache->reqs, id);
235+
complete(&req->done);
236+
}
237+
232238
return n;
233239

234240
err_put_fd:
@@ -300,6 +306,13 @@ static int cachefiles_ondemand_send_req(struct cachefiles_object *object,
300306
/* coupled with the barrier in cachefiles_flush_reqs() */
301307
smp_mb();
302308

309+
if (opcode != CACHEFILES_OP_OPEN && object->ondemand_id <= 0) {
310+
WARN_ON_ONCE(object->ondemand_id == 0);
311+
xas_unlock(&xas);
312+
ret = -EIO;
313+
goto out;
314+
}
315+
303316
xas.xa_index = 0;
304317
xas_find_marked(&xas, UINT_MAX, XA_FREE_MARK);
305318
if (xas.xa_node == XAS_RESTART)
@@ -356,6 +369,25 @@ static int cachefiles_ondemand_init_open_req(struct cachefiles_req *req,
356369
return 0;
357370
}
358371

372+
static int cachefiles_ondemand_init_close_req(struct cachefiles_req *req,
373+
void *private)
374+
{
375+
struct cachefiles_object *object = req->object;
376+
int object_id = object->ondemand_id;
377+
378+
/*
379+
* It's possible that object id is still 0 if the cookie looking up
380+
* phase failed before OPEN request has ever been sent. Also avoid
381+
* sending CLOSE request for CACHEFILES_ONDEMAND_ID_CLOSED, which means
382+
* anon_fd has already been closed.
383+
*/
384+
if (object_id <= 0)
385+
return -ENOENT;
386+
387+
req->msg.object_id = object_id;
388+
return 0;
389+
}
390+
359391
int cachefiles_ondemand_init_object(struct cachefiles_object *object)
360392
{
361393
struct fscache_cookie *cookie = object->cookie;
@@ -379,3 +411,9 @@ int cachefiles_ondemand_init_object(struct cachefiles_object *object)
379411
return cachefiles_ondemand_send_req(object, CACHEFILES_OP_OPEN,
380412
data_len, cachefiles_ondemand_init_open_req, NULL);
381413
}
414+
415+
void cachefiles_ondemand_clean_object(struct cachefiles_object *object)
416+
{
417+
cachefiles_ondemand_send_req(object, CACHEFILES_OP_CLOSE, 0,
418+
cachefiles_ondemand_init_close_req, NULL);
419+
}

include/uapi/linux/cachefiles.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
enum cachefiles_opcode {
1414
CACHEFILES_OP_OPEN,
15+
CACHEFILES_OP_CLOSE,
1516
};
1617

1718
/*

0 commit comments

Comments
 (0)