@@ -217,3 +217,310 @@ void cachefiles_put_directory(struct dentry *dir)
217
217
dput (dir );
218
218
}
219
219
}
220
+
221
+ /*
222
+ * Remove a regular file from the cache.
223
+ */
224
+ static int cachefiles_unlink (struct cachefiles_cache * cache ,
225
+ struct cachefiles_object * object ,
226
+ struct dentry * dir , struct dentry * dentry ,
227
+ enum fscache_why_object_killed why )
228
+ {
229
+ struct path path = {
230
+ .mnt = cache -> mnt ,
231
+ .dentry = dir ,
232
+ };
233
+ int ret ;
234
+
235
+ trace_cachefiles_unlink (object , dentry , why );
236
+ ret = security_path_unlink (& path , dentry );
237
+ if (ret < 0 ) {
238
+ cachefiles_io_error (cache , "Unlink security error" );
239
+ return ret ;
240
+ }
241
+
242
+ ret = cachefiles_inject_remove_error ();
243
+ if (ret == 0 ) {
244
+ ret = vfs_unlink (& init_user_ns , d_backing_inode (dir ), dentry , NULL );
245
+ if (ret == - EIO )
246
+ cachefiles_io_error (cache , "Unlink failed" );
247
+ }
248
+ if (ret != 0 )
249
+ trace_cachefiles_vfs_error (object , d_backing_inode (dir ), ret ,
250
+ cachefiles_trace_unlink_error );
251
+ return ret ;
252
+ }
253
+
254
+ /*
255
+ * Delete an object representation from the cache
256
+ * - File backed objects are unlinked
257
+ * - Directory backed objects are stuffed into the graveyard for userspace to
258
+ * delete
259
+ */
260
+ int cachefiles_bury_object (struct cachefiles_cache * cache ,
261
+ struct cachefiles_object * object ,
262
+ struct dentry * dir ,
263
+ struct dentry * rep ,
264
+ enum fscache_why_object_killed why )
265
+ {
266
+ struct dentry * grave , * trap ;
267
+ struct path path , path_to_graveyard ;
268
+ char nbuffer [8 + 8 + 1 ];
269
+ int ret ;
270
+
271
+ _enter (",'%pd','%pd'" , dir , rep );
272
+
273
+ if (rep -> d_parent != dir ) {
274
+ inode_unlock (d_inode (dir ));
275
+ _leave (" = -ESTALE" );
276
+ return - ESTALE ;
277
+ }
278
+
279
+ /* non-directories can just be unlinked */
280
+ if (!d_is_dir (rep )) {
281
+ dget (rep ); /* Stop the dentry being negated if it's only pinned
282
+ * by a file struct.
283
+ */
284
+ ret = cachefiles_unlink (cache , object , dir , rep , why );
285
+ dput (rep );
286
+
287
+ inode_unlock (d_inode (dir ));
288
+ _leave (" = %d" , ret );
289
+ return ret ;
290
+ }
291
+
292
+ /* directories have to be moved to the graveyard */
293
+ _debug ("move stale object to graveyard" );
294
+ inode_unlock (d_inode (dir ));
295
+
296
+ try_again :
297
+ /* first step is to make up a grave dentry in the graveyard */
298
+ sprintf (nbuffer , "%08x%08x" ,
299
+ (uint32_t ) ktime_get_real_seconds (),
300
+ (uint32_t ) atomic_inc_return (& cache -> gravecounter ));
301
+
302
+ /* do the multiway lock magic */
303
+ trap = lock_rename (cache -> graveyard , dir );
304
+
305
+ /* do some checks before getting the grave dentry */
306
+ if (rep -> d_parent != dir || IS_DEADDIR (d_inode (rep ))) {
307
+ /* the entry was probably culled when we dropped the parent dir
308
+ * lock */
309
+ unlock_rename (cache -> graveyard , dir );
310
+ _leave (" = 0 [culled?]" );
311
+ return 0 ;
312
+ }
313
+
314
+ if (!d_can_lookup (cache -> graveyard )) {
315
+ unlock_rename (cache -> graveyard , dir );
316
+ cachefiles_io_error (cache , "Graveyard no longer a directory" );
317
+ return - EIO ;
318
+ }
319
+
320
+ if (trap == rep ) {
321
+ unlock_rename (cache -> graveyard , dir );
322
+ cachefiles_io_error (cache , "May not make directory loop" );
323
+ return - EIO ;
324
+ }
325
+
326
+ if (d_mountpoint (rep )) {
327
+ unlock_rename (cache -> graveyard , dir );
328
+ cachefiles_io_error (cache , "Mountpoint in cache" );
329
+ return - EIO ;
330
+ }
331
+
332
+ grave = lookup_one_len (nbuffer , cache -> graveyard , strlen (nbuffer ));
333
+ if (IS_ERR (grave )) {
334
+ unlock_rename (cache -> graveyard , dir );
335
+ trace_cachefiles_vfs_error (object , d_inode (cache -> graveyard ),
336
+ PTR_ERR (grave ),
337
+ cachefiles_trace_lookup_error );
338
+
339
+ if (PTR_ERR (grave ) == - ENOMEM ) {
340
+ _leave (" = -ENOMEM" );
341
+ return - ENOMEM ;
342
+ }
343
+
344
+ cachefiles_io_error (cache , "Lookup error %ld" , PTR_ERR (grave ));
345
+ return - EIO ;
346
+ }
347
+
348
+ if (d_is_positive (grave )) {
349
+ unlock_rename (cache -> graveyard , dir );
350
+ dput (grave );
351
+ grave = NULL ;
352
+ cond_resched ();
353
+ goto try_again ;
354
+ }
355
+
356
+ if (d_mountpoint (grave )) {
357
+ unlock_rename (cache -> graveyard , dir );
358
+ dput (grave );
359
+ cachefiles_io_error (cache , "Mountpoint in graveyard" );
360
+ return - EIO ;
361
+ }
362
+
363
+ /* target should not be an ancestor of source */
364
+ if (trap == grave ) {
365
+ unlock_rename (cache -> graveyard , dir );
366
+ dput (grave );
367
+ cachefiles_io_error (cache , "May not make directory loop" );
368
+ return - EIO ;
369
+ }
370
+
371
+ /* attempt the rename */
372
+ path .mnt = cache -> mnt ;
373
+ path .dentry = dir ;
374
+ path_to_graveyard .mnt = cache -> mnt ;
375
+ path_to_graveyard .dentry = cache -> graveyard ;
376
+ ret = security_path_rename (& path , rep , & path_to_graveyard , grave , 0 );
377
+ if (ret < 0 ) {
378
+ cachefiles_io_error (cache , "Rename security error %d" , ret );
379
+ } else {
380
+ struct renamedata rd = {
381
+ .old_mnt_userns = & init_user_ns ,
382
+ .old_dir = d_inode (dir ),
383
+ .old_dentry = rep ,
384
+ .new_mnt_userns = & init_user_ns ,
385
+ .new_dir = d_inode (cache -> graveyard ),
386
+ .new_dentry = grave ,
387
+ };
388
+ trace_cachefiles_rename (object , rep , grave , why );
389
+ ret = cachefiles_inject_read_error ();
390
+ if (ret == 0 )
391
+ ret = vfs_rename (& rd );
392
+ if (ret != 0 )
393
+ trace_cachefiles_vfs_error (object , d_inode (dir ), ret ,
394
+ cachefiles_trace_rename_error );
395
+ if (ret != 0 && ret != - ENOMEM )
396
+ cachefiles_io_error (cache ,
397
+ "Rename failed with error %d" , ret );
398
+ }
399
+
400
+ __cachefiles_unmark_inode_in_use (object , rep );
401
+ unlock_rename (cache -> graveyard , dir );
402
+ dput (grave );
403
+ _leave (" = 0" );
404
+ return 0 ;
405
+ }
406
+
407
+ /*
408
+ * Look up an inode to be checked or culled. Return -EBUSY if the inode is
409
+ * marked in use.
410
+ */
411
+ static struct dentry * cachefiles_lookup_for_cull (struct cachefiles_cache * cache ,
412
+ struct dentry * dir ,
413
+ char * filename )
414
+ {
415
+ struct dentry * victim ;
416
+ int ret = - ENOENT ;
417
+
418
+ inode_lock_nested (d_inode (dir ), I_MUTEX_PARENT );
419
+
420
+ victim = lookup_one_len (filename , dir , strlen (filename ));
421
+ if (IS_ERR (victim ))
422
+ goto lookup_error ;
423
+ if (d_is_negative (victim ))
424
+ goto lookup_put ;
425
+ if (d_inode (victim )-> i_flags & S_KERNEL_FILE )
426
+ goto lookup_busy ;
427
+ return victim ;
428
+
429
+ lookup_busy :
430
+ ret = - EBUSY ;
431
+ lookup_put :
432
+ inode_unlock (d_inode (dir ));
433
+ dput (victim );
434
+ return ERR_PTR (ret );
435
+
436
+ lookup_error :
437
+ inode_unlock (d_inode (dir ));
438
+ ret = PTR_ERR (victim );
439
+ if (ret == - ENOENT )
440
+ return ERR_PTR (- ESTALE ); /* Probably got retired by the netfs */
441
+
442
+ if (ret == - EIO ) {
443
+ cachefiles_io_error (cache , "Lookup failed" );
444
+ } else if (ret != - ENOMEM ) {
445
+ pr_err ("Internal error: %d\n" , ret );
446
+ ret = - EIO ;
447
+ }
448
+
449
+ return ERR_PTR (ret );
450
+ }
451
+
452
+ /*
453
+ * Cull an object if it's not in use
454
+ * - called only by cache manager daemon
455
+ */
456
+ int cachefiles_cull (struct cachefiles_cache * cache , struct dentry * dir ,
457
+ char * filename )
458
+ {
459
+ struct dentry * victim ;
460
+ struct inode * inode ;
461
+ int ret ;
462
+
463
+ _enter (",%pd/,%s" , dir , filename );
464
+
465
+ victim = cachefiles_lookup_for_cull (cache , dir , filename );
466
+ if (IS_ERR (victim ))
467
+ return PTR_ERR (victim );
468
+
469
+ /* check to see if someone is using this object */
470
+ inode = d_inode (victim );
471
+ inode_lock (inode );
472
+ if (inode -> i_flags & S_KERNEL_FILE ) {
473
+ ret = - EBUSY ;
474
+ } else {
475
+ /* Stop the cache from picking it back up */
476
+ inode -> i_flags |= S_KERNEL_FILE ;
477
+ ret = 0 ;
478
+ }
479
+ inode_unlock (inode );
480
+ if (ret < 0 )
481
+ goto error_unlock ;
482
+
483
+ ret = cachefiles_bury_object (cache , NULL , dir , victim ,
484
+ FSCACHE_OBJECT_WAS_CULLED );
485
+ if (ret < 0 )
486
+ goto error ;
487
+
488
+ dput (victim );
489
+ _leave (" = 0" );
490
+ return 0 ;
491
+
492
+ error_unlock :
493
+ inode_unlock (d_inode (dir ));
494
+ error :
495
+ dput (victim );
496
+ if (ret == - ENOENT )
497
+ return - ESTALE ; /* Probably got retired by the netfs */
498
+
499
+ if (ret != - ENOMEM ) {
500
+ pr_err ("Internal error: %d\n" , ret );
501
+ ret = - EIO ;
502
+ }
503
+
504
+ _leave (" = %d" , ret );
505
+ return ret ;
506
+ }
507
+
508
+ /*
509
+ * Find out if an object is in use or not
510
+ * - called only by cache manager daemon
511
+ * - returns -EBUSY or 0 to indicate whether an object is in use or not
512
+ */
513
+ int cachefiles_check_in_use (struct cachefiles_cache * cache , struct dentry * dir ,
514
+ char * filename )
515
+ {
516
+ struct dentry * victim ;
517
+ int ret = 0 ;
518
+
519
+ victim = cachefiles_lookup_for_cull (cache , dir , filename );
520
+ if (IS_ERR (victim ))
521
+ return PTR_ERR (victim );
522
+
523
+ inode_unlock (d_inode (dir ));
524
+ dput (victim );
525
+ return ret ;
526
+ }
0 commit comments