@@ -404,6 +404,324 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
404
404
return 0 ;
405
405
}
406
406
407
+ /*
408
+ * Delete a cache file.
409
+ */
410
+ int cachefiles_delete_object (struct cachefiles_object * object ,
411
+ enum fscache_why_object_killed why )
412
+ {
413
+ struct cachefiles_volume * volume = object -> volume ;
414
+ struct dentry * dentry = object -> file -> f_path .dentry ;
415
+ struct dentry * fan = volume -> fanout [(u8 )object -> cookie -> key_hash ];
416
+ int ret ;
417
+
418
+ _enter (",OBJ%x{%pD}" , object -> debug_id , object -> file );
419
+
420
+ /* Stop the dentry being negated if it's only pinned by a file struct. */
421
+ dget (dentry );
422
+
423
+ inode_lock_nested (d_backing_inode (fan ), I_MUTEX_PARENT );
424
+ ret = cachefiles_unlink (volume -> cache , object , fan , dentry , why );
425
+ inode_unlock (d_backing_inode (fan ));
426
+ dput (dentry );
427
+ return ret ;
428
+ }
429
+
430
+ /*
431
+ * Create a temporary file and leave it unattached and un-xattr'd until the
432
+ * time comes to discard the object from memory.
433
+ */
434
+ struct file * cachefiles_create_tmpfile (struct cachefiles_object * object )
435
+ {
436
+ struct cachefiles_volume * volume = object -> volume ;
437
+ struct cachefiles_cache * cache = volume -> cache ;
438
+ const struct cred * saved_cred ;
439
+ struct dentry * fan = volume -> fanout [(u8 )object -> cookie -> key_hash ];
440
+ struct file * file ;
441
+ struct path path ;
442
+ uint64_t ni_size = object -> cookie -> object_size ;
443
+ long ret ;
444
+
445
+ ni_size = round_up (ni_size , CACHEFILES_DIO_BLOCK_SIZE );
446
+
447
+ cachefiles_begin_secure (cache , & saved_cred );
448
+
449
+ path .mnt = cache -> mnt ;
450
+ ret = cachefiles_inject_write_error ();
451
+ if (ret == 0 )
452
+ path .dentry = vfs_tmpfile (& init_user_ns , fan , S_IFREG , O_RDWR );
453
+ else
454
+ path .dentry = ERR_PTR (ret );
455
+ if (IS_ERR (path .dentry )) {
456
+ trace_cachefiles_vfs_error (object , d_inode (fan ), PTR_ERR (path .dentry ),
457
+ cachefiles_trace_tmpfile_error );
458
+ if (PTR_ERR (path .dentry ) == - EIO )
459
+ cachefiles_io_error_obj (object , "Failed to create tmpfile" );
460
+ file = ERR_CAST (path .dentry );
461
+ goto out ;
462
+ }
463
+
464
+ trace_cachefiles_tmpfile (object , d_backing_inode (path .dentry ));
465
+
466
+ if (!cachefiles_mark_inode_in_use (object , path .dentry )) {
467
+ file = ERR_PTR (- EBUSY );
468
+ goto out_dput ;
469
+ }
470
+
471
+ if (ni_size > 0 ) {
472
+ trace_cachefiles_trunc (object , d_backing_inode (path .dentry ), 0 , ni_size ,
473
+ cachefiles_trunc_expand_tmpfile );
474
+ ret = cachefiles_inject_write_error ();
475
+ if (ret == 0 )
476
+ ret = vfs_truncate (& path , ni_size );
477
+ if (ret < 0 ) {
478
+ trace_cachefiles_vfs_error (
479
+ object , d_backing_inode (path .dentry ), ret ,
480
+ cachefiles_trace_trunc_error );
481
+ file = ERR_PTR (ret );
482
+ goto out_dput ;
483
+ }
484
+ }
485
+
486
+ file = open_with_fake_path (& path , O_RDWR | O_LARGEFILE | O_DIRECT ,
487
+ d_backing_inode (path .dentry ), cache -> cache_cred );
488
+ if (IS_ERR (file )) {
489
+ trace_cachefiles_vfs_error (object , d_backing_inode (path .dentry ),
490
+ PTR_ERR (file ),
491
+ cachefiles_trace_open_error );
492
+ goto out_dput ;
493
+ }
494
+ if (unlikely (!file -> f_op -> read_iter ) ||
495
+ unlikely (!file -> f_op -> write_iter )) {
496
+ fput (file );
497
+ pr_notice ("Cache does not support read_iter and write_iter\n" );
498
+ file = ERR_PTR (- EINVAL );
499
+ }
500
+
501
+ out_dput :
502
+ dput (path .dentry );
503
+ out :
504
+ cachefiles_end_secure (cache , saved_cred );
505
+ return file ;
506
+ }
507
+
508
+ /*
509
+ * Create a new file.
510
+ */
511
+ static bool cachefiles_create_file (struct cachefiles_object * object )
512
+ {
513
+ struct file * file ;
514
+ int ret ;
515
+
516
+ ret = cachefiles_has_space (object -> volume -> cache , 1 , 0 );
517
+ if (ret < 0 )
518
+ return false;
519
+
520
+ file = cachefiles_create_tmpfile (object );
521
+ if (IS_ERR (file ))
522
+ return false;
523
+
524
+ set_bit (FSCACHE_COOKIE_NEEDS_UPDATE , & object -> cookie -> flags );
525
+ set_bit (CACHEFILES_OBJECT_USING_TMPFILE , & object -> flags );
526
+ _debug ("create -> %pD{ino=%lu}" , file , file_inode (file )-> i_ino );
527
+ object -> file = file ;
528
+ return true;
529
+ }
530
+
531
+ /*
532
+ * Open an existing file, checking its attributes and replacing it if it is
533
+ * stale.
534
+ */
535
+ static bool cachefiles_open_file (struct cachefiles_object * object ,
536
+ struct dentry * dentry )
537
+ {
538
+ struct cachefiles_cache * cache = object -> volume -> cache ;
539
+ struct file * file ;
540
+ struct path path ;
541
+ int ret ;
542
+
543
+ _enter ("%pd" , dentry );
544
+
545
+ if (!cachefiles_mark_inode_in_use (object , dentry ))
546
+ return false;
547
+
548
+ /* We need to open a file interface onto a data file now as we can't do
549
+ * it on demand because writeback called from do_exit() sees
550
+ * current->fs == NULL - which breaks d_path() called from ext4 open.
551
+ */
552
+ path .mnt = cache -> mnt ;
553
+ path .dentry = dentry ;
554
+ file = open_with_fake_path (& path , O_RDWR | O_LARGEFILE | O_DIRECT ,
555
+ d_backing_inode (dentry ), cache -> cache_cred );
556
+ if (IS_ERR (file )) {
557
+ trace_cachefiles_vfs_error (object , d_backing_inode (dentry ),
558
+ PTR_ERR (file ),
559
+ cachefiles_trace_open_error );
560
+ goto error ;
561
+ }
562
+
563
+ if (unlikely (!file -> f_op -> read_iter ) ||
564
+ unlikely (!file -> f_op -> write_iter )) {
565
+ pr_notice ("Cache does not support read_iter and write_iter\n" );
566
+ goto error_fput ;
567
+ }
568
+ _debug ("file -> %pd positive" , dentry );
569
+
570
+ ret = cachefiles_check_auxdata (object , file );
571
+ if (ret < 0 )
572
+ goto check_failed ;
573
+
574
+ object -> file = file ;
575
+
576
+ /* Always update the atime on an object we've just looked up (this is
577
+ * used to keep track of culling, and atimes are only updated by read,
578
+ * write and readdir but not lookup or open).
579
+ */
580
+ touch_atime (& file -> f_path );
581
+ dput (dentry );
582
+ return true;
583
+
584
+ check_failed :
585
+ fscache_cookie_lookup_negative (object -> cookie );
586
+ cachefiles_unmark_inode_in_use (object , file );
587
+ if (ret == - ESTALE ) {
588
+ fput (file );
589
+ dput (dentry );
590
+ return cachefiles_create_file (object );
591
+ }
592
+ error_fput :
593
+ fput (file );
594
+ error :
595
+ dput (dentry );
596
+ return false;
597
+ }
598
+
599
+ /*
600
+ * walk from the parent object to the child object through the backing
601
+ * filesystem, creating directories as we go
602
+ */
603
+ bool cachefiles_look_up_object (struct cachefiles_object * object )
604
+ {
605
+ struct cachefiles_volume * volume = object -> volume ;
606
+ struct dentry * dentry , * fan = volume -> fanout [(u8 )object -> cookie -> key_hash ];
607
+ int ret ;
608
+
609
+ _enter ("OBJ%x,%s," , object -> debug_id , object -> d_name );
610
+
611
+ /* Look up path "cache/vol/fanout/file". */
612
+ ret = cachefiles_inject_read_error ();
613
+ if (ret == 0 )
614
+ dentry = lookup_positive_unlocked (object -> d_name , fan ,
615
+ object -> d_name_len );
616
+ else
617
+ dentry = ERR_PTR (ret );
618
+ trace_cachefiles_lookup (object , dentry );
619
+ if (IS_ERR (dentry )) {
620
+ if (dentry == ERR_PTR (- ENOENT ))
621
+ goto new_file ;
622
+ if (dentry == ERR_PTR (- EIO ))
623
+ cachefiles_io_error_obj (object , "Lookup failed" );
624
+ return false;
625
+ }
626
+
627
+ if (!d_is_reg (dentry )) {
628
+ pr_err ("%pd is not a file\n" , dentry );
629
+ inode_lock_nested (d_inode (fan ), I_MUTEX_PARENT );
630
+ ret = cachefiles_bury_object (volume -> cache , object , fan , dentry ,
631
+ FSCACHE_OBJECT_IS_WEIRD );
632
+ dput (dentry );
633
+ if (ret < 0 )
634
+ return false;
635
+ goto new_file ;
636
+ }
637
+
638
+ if (!cachefiles_open_file (object , dentry ))
639
+ return false;
640
+
641
+ _leave (" = t [%lu]" , file_inode (object -> file )-> i_ino );
642
+ return true;
643
+
644
+ new_file :
645
+ fscache_cookie_lookup_negative (object -> cookie );
646
+ return cachefiles_create_file (object );
647
+ }
648
+
649
+ /*
650
+ * Attempt to link a temporary file into its rightful place in the cache.
651
+ */
652
+ bool cachefiles_commit_tmpfile (struct cachefiles_cache * cache ,
653
+ struct cachefiles_object * object )
654
+ {
655
+ struct cachefiles_volume * volume = object -> volume ;
656
+ struct dentry * dentry , * fan = volume -> fanout [(u8 )object -> cookie -> key_hash ];
657
+ bool success = false;
658
+ int ret ;
659
+
660
+ _enter (",%pD" , object -> file );
661
+
662
+ inode_lock_nested (d_inode (fan ), I_MUTEX_PARENT );
663
+ ret = cachefiles_inject_read_error ();
664
+ if (ret == 0 )
665
+ dentry = lookup_one_len (object -> d_name , fan , object -> d_name_len );
666
+ else
667
+ dentry = ERR_PTR (ret );
668
+ if (IS_ERR (dentry )) {
669
+ trace_cachefiles_vfs_error (object , d_inode (fan ), PTR_ERR (dentry ),
670
+ cachefiles_trace_lookup_error );
671
+ _debug ("lookup fail %ld" , PTR_ERR (dentry ));
672
+ goto out_unlock ;
673
+ }
674
+
675
+ if (!d_is_negative (dentry )) {
676
+ if (d_backing_inode (dentry ) == file_inode (object -> file )) {
677
+ success = true;
678
+ goto out_dput ;
679
+ }
680
+
681
+ ret = cachefiles_unlink (volume -> cache , object , fan , dentry ,
682
+ FSCACHE_OBJECT_IS_STALE );
683
+ if (ret < 0 )
684
+ goto out_dput ;
685
+
686
+ dput (dentry );
687
+ ret = cachefiles_inject_read_error ();
688
+ if (ret == 0 )
689
+ dentry = lookup_one_len (object -> d_name , fan , object -> d_name_len );
690
+ else
691
+ dentry = ERR_PTR (ret );
692
+ if (IS_ERR (dentry )) {
693
+ trace_cachefiles_vfs_error (object , d_inode (fan ), PTR_ERR (dentry ),
694
+ cachefiles_trace_lookup_error );
695
+ _debug ("lookup fail %ld" , PTR_ERR (dentry ));
696
+ goto out_unlock ;
697
+ }
698
+ }
699
+
700
+ ret = cachefiles_inject_read_error ();
701
+ if (ret == 0 )
702
+ ret = vfs_link (object -> file -> f_path .dentry , & init_user_ns ,
703
+ d_inode (fan ), dentry , NULL );
704
+ if (ret < 0 ) {
705
+ trace_cachefiles_vfs_error (object , d_inode (fan ), ret ,
706
+ cachefiles_trace_link_error );
707
+ _debug ("link fail %d" , ret );
708
+ } else {
709
+ trace_cachefiles_link (object , file_inode (object -> file ));
710
+ spin_lock (& object -> lock );
711
+ /* TODO: Do we want to switch the file pointer to the new dentry? */
712
+ clear_bit (CACHEFILES_OBJECT_USING_TMPFILE , & object -> flags );
713
+ spin_unlock (& object -> lock );
714
+ success = true;
715
+ }
716
+
717
+ out_dput :
718
+ dput (dentry );
719
+ out_unlock :
720
+ inode_unlock (d_inode (fan ));
721
+ _leave (" = %u" , success );
722
+ return success ;
723
+ }
724
+
407
725
/*
408
726
* Look up an inode to be checked or culled. Return -EBUSY if the inode is
409
727
* marked in use.
0 commit comments