Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Jeffle Xu and committed by
Gao Xiang
324b954a d11b0b04

+46
+2
fs/cachefiles/interface.c
··· 362 362 spin_unlock(&cache->object_list_lock); 363 363 } 364 364 365 + cachefiles_ondemand_clean_object(object); 366 + 365 367 if (object->file) { 366 368 cachefiles_begin_secure(cache, &saved_cred); 367 369 cachefiles_clean_up_object(object, cache);
+5
fs/cachefiles/internal.h
··· 290 290 char *args); 291 291 292 292 extern int cachefiles_ondemand_init_object(struct cachefiles_object *object); 293 + extern void cachefiles_ondemand_clean_object(struct cachefiles_object *object); 293 294 294 295 #else 295 296 static inline ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, ··· 302 301 static inline int cachefiles_ondemand_init_object(struct cachefiles_object *object) 303 302 { 304 303 return 0; 304 + } 305 + 306 + static inline void cachefiles_ondemand_clean_object(struct cachefiles_object *object) 307 + { 305 308 } 306 309 #endif 307 310
+38
fs/cachefiles/ondemand.c
··· 229 229 goto err_put_fd; 230 230 } 231 231 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 + 232 238 return n; 233 239 234 240 err_put_fd: ··· 306 300 /* coupled with the barrier in cachefiles_flush_reqs() */ 307 301 smp_mb(); 308 302 303 + if (opcode != CACHEFILES_OP_OPEN && object->ondemand_id <= 0) { 304 + WARN_ON_ONCE(object->ondemand_id == 0); 305 + xas_unlock(&xas); 306 + ret = -EIO; 307 + goto out; 308 + } 309 + 309 310 xas.xa_index = 0; 310 311 xas_find_marked(&xas, UINT_MAX, XA_FREE_MARK); 311 312 if (xas.xa_node == XAS_RESTART) ··· 369 356 return 0; 370 357 } 371 358 359 + static int cachefiles_ondemand_init_close_req(struct cachefiles_req *req, 360 + void *private) 361 + { 362 + struct cachefiles_object *object = req->object; 363 + int object_id = object->ondemand_id; 364 + 365 + /* 366 + * It's possible that object id is still 0 if the cookie looking up 367 + * phase failed before OPEN request has ever been sent. Also avoid 368 + * sending CLOSE request for CACHEFILES_ONDEMAND_ID_CLOSED, which means 369 + * anon_fd has already been closed. 370 + */ 371 + if (object_id <= 0) 372 + return -ENOENT; 373 + 374 + req->msg.object_id = object_id; 375 + return 0; 376 + } 377 + 372 378 int cachefiles_ondemand_init_object(struct cachefiles_object *object) 373 379 { 374 380 struct fscache_cookie *cookie = object->cookie; ··· 410 378 411 379 return cachefiles_ondemand_send_req(object, CACHEFILES_OP_OPEN, 412 380 data_len, cachefiles_ondemand_init_open_req, NULL); 381 + } 382 + 383 + void cachefiles_ondemand_clean_object(struct cachefiles_object *object) 384 + { 385 + cachefiles_ondemand_send_req(object, CACHEFILES_OP_CLOSE, 0, 386 + cachefiles_ondemand_init_close_req, NULL); 413 387 }
+1
include/uapi/linux/cachefiles.h
··· 12 12 13 13 enum cachefiles_opcode { 14 14 CACHEFILES_OP_OPEN, 15 + CACHEFILES_OP_CLOSE, 15 16 }; 16 17 17 18 /*