@@ -217,3 +217,310 @@ void cachefiles_put_directory(struct dentry *dir)
217217 dput (dir );
218218 }
219219}
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