linux/fs/cachefiles/daemon.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* Daemon interface
   3 *
   4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/init.h>
  10#include <linux/sched.h>
  11#include <linux/completion.h>
  12#include <linux/slab.h>
  13#include <linux/fs.h>
  14#include <linux/file.h>
  15#include <linux/namei.h>
  16#include <linux/poll.h>
  17#include <linux/mount.h>
  18#include <linux/statfs.h>
  19#include <linux/ctype.h>
  20#include <linux/string.h>
  21#include <linux/fs_struct.h>
  22#include "internal.h"
  23
  24static int cachefiles_daemon_open(struct inode *, struct file *);
  25static int cachefiles_daemon_release(struct inode *, struct file *);
  26static ssize_t cachefiles_daemon_read(struct file *, char __user *, size_t,
  27                                      loff_t *);
  28static ssize_t cachefiles_daemon_write(struct file *, const char __user *,
  29                                       size_t, loff_t *);
  30static __poll_t cachefiles_daemon_poll(struct file *,
  31                                           struct poll_table_struct *);
  32static int cachefiles_daemon_frun(struct cachefiles_cache *, char *);
  33static int cachefiles_daemon_fcull(struct cachefiles_cache *, char *);
  34static int cachefiles_daemon_fstop(struct cachefiles_cache *, char *);
  35static int cachefiles_daemon_brun(struct cachefiles_cache *, char *);
  36static int cachefiles_daemon_bcull(struct cachefiles_cache *, char *);
  37static int cachefiles_daemon_bstop(struct cachefiles_cache *, char *);
  38static int cachefiles_daemon_cull(struct cachefiles_cache *, char *);
  39static int cachefiles_daemon_debug(struct cachefiles_cache *, char *);
  40static int cachefiles_daemon_dir(struct cachefiles_cache *, char *);
  41static int cachefiles_daemon_inuse(struct cachefiles_cache *, char *);
  42static int cachefiles_daemon_secctx(struct cachefiles_cache *, char *);
  43static int cachefiles_daemon_tag(struct cachefiles_cache *, char *);
  44
  45static unsigned long cachefiles_open;
  46
  47const struct file_operations cachefiles_daemon_fops = {
  48        .owner          = THIS_MODULE,
  49        .open           = cachefiles_daemon_open,
  50        .release        = cachefiles_daemon_release,
  51        .read           = cachefiles_daemon_read,
  52        .write          = cachefiles_daemon_write,
  53        .poll           = cachefiles_daemon_poll,
  54        .llseek         = noop_llseek,
  55};
  56
  57struct cachefiles_daemon_cmd {
  58        char name[8];
  59        int (*handler)(struct cachefiles_cache *cache, char *args);
  60};
  61
  62static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = {
  63        { "bind",       cachefiles_daemon_bind          },
  64        { "brun",       cachefiles_daemon_brun          },
  65        { "bcull",      cachefiles_daemon_bcull         },
  66        { "bstop",      cachefiles_daemon_bstop         },
  67        { "cull",       cachefiles_daemon_cull          },
  68        { "debug",      cachefiles_daemon_debug         },
  69        { "dir",        cachefiles_daemon_dir           },
  70        { "frun",       cachefiles_daemon_frun          },
  71        { "fcull",      cachefiles_daemon_fcull         },
  72        { "fstop",      cachefiles_daemon_fstop         },
  73        { "inuse",      cachefiles_daemon_inuse         },
  74        { "secctx",     cachefiles_daemon_secctx        },
  75        { "tag",        cachefiles_daemon_tag           },
  76        { "",           NULL                            }
  77};
  78
  79
  80/*
  81 * do various checks
  82 */
  83static int cachefiles_daemon_open(struct inode *inode, struct file *file)
  84{
  85        struct cachefiles_cache *cache;
  86
  87        _enter("");
  88
  89        /* only the superuser may do this */
  90        if (!capable(CAP_SYS_ADMIN))
  91                return -EPERM;
  92
  93        /* the cachefiles device may only be open once at a time */
  94        if (xchg(&cachefiles_open, 1) == 1)
  95                return -EBUSY;
  96
  97        /* allocate a cache record */
  98        cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL);
  99        if (!cache) {
 100                cachefiles_open = 0;
 101                return -ENOMEM;
 102        }
 103
 104        mutex_init(&cache->daemon_mutex);
 105        cache->active_nodes = RB_ROOT;
 106        rwlock_init(&cache->active_lock);
 107        init_waitqueue_head(&cache->daemon_pollwq);
 108
 109        /* set default caching limits
 110         * - limit at 1% free space and/or free files
 111         * - cull below 5% free space and/or free files
 112         * - cease culling above 7% free space and/or free files
 113         */
 114        cache->frun_percent = 7;
 115        cache->fcull_percent = 5;
 116        cache->fstop_percent = 1;
 117        cache->brun_percent = 7;
 118        cache->bcull_percent = 5;
 119        cache->bstop_percent = 1;
 120
 121        file->private_data = cache;
 122        cache->cachefilesd = file;
 123        return 0;
 124}
 125
 126/*
 127 * release a cache
 128 */
 129static int cachefiles_daemon_release(struct inode *inode, struct file *file)
 130{
 131        struct cachefiles_cache *cache = file->private_data;
 132
 133        _enter("");
 134
 135        ASSERT(cache);
 136
 137        set_bit(CACHEFILES_DEAD, &cache->flags);
 138
 139        cachefiles_daemon_unbind(cache);
 140
 141        ASSERT(!cache->active_nodes.rb_node);
 142
 143        /* clean up the control file interface */
 144        cache->cachefilesd = NULL;
 145        file->private_data = NULL;
 146        cachefiles_open = 0;
 147
 148        kfree(cache);
 149
 150        _leave("");
 151        return 0;
 152}
 153
 154/*
 155 * read the cache state
 156 */
 157static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer,
 158                                      size_t buflen, loff_t *pos)
 159{
 160        struct cachefiles_cache *cache = file->private_data;
 161        unsigned long long b_released;
 162        unsigned f_released;
 163        char buffer[256];
 164        int n;
 165
 166        //_enter(",,%zu,", buflen);
 167
 168        if (!test_bit(CACHEFILES_READY, &cache->flags))
 169                return 0;
 170
 171        /* check how much space the cache has */
 172        cachefiles_has_space(cache, 0, 0);
 173
 174        /* summarise */
 175        f_released = atomic_xchg(&cache->f_released, 0);
 176        b_released = atomic_long_xchg(&cache->b_released, 0);
 177        clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
 178
 179        n = snprintf(buffer, sizeof(buffer),
 180                     "cull=%c"
 181                     " frun=%llx"
 182                     " fcull=%llx"
 183                     " fstop=%llx"
 184                     " brun=%llx"
 185                     " bcull=%llx"
 186                     " bstop=%llx"
 187                     " freleased=%x"
 188                     " breleased=%llx",
 189                     test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0',
 190                     (unsigned long long) cache->frun,
 191                     (unsigned long long) cache->fcull,
 192                     (unsigned long long) cache->fstop,
 193                     (unsigned long long) cache->brun,
 194                     (unsigned long long) cache->bcull,
 195                     (unsigned long long) cache->bstop,
 196                     f_released,
 197                     b_released);
 198
 199        if (n > buflen)
 200                return -EMSGSIZE;
 201
 202        if (copy_to_user(_buffer, buffer, n) != 0)
 203                return -EFAULT;
 204
 205        return n;
 206}
 207
 208/*
 209 * command the cache
 210 */
 211static ssize_t cachefiles_daemon_write(struct file *file,
 212                                       const char __user *_data,
 213                                       size_t datalen,
 214                                       loff_t *pos)
 215{
 216        const struct cachefiles_daemon_cmd *cmd;
 217        struct cachefiles_cache *cache = file->private_data;
 218        ssize_t ret;
 219        char *data, *args, *cp;
 220
 221        //_enter(",,%zu,", datalen);
 222
 223        ASSERT(cache);
 224
 225        if (test_bit(CACHEFILES_DEAD, &cache->flags))
 226                return -EIO;
 227
 228        if (datalen < 0 || datalen > PAGE_SIZE - 1)
 229                return -EOPNOTSUPP;
 230
 231        /* drag the command string into the kernel so we can parse it */
 232        data = memdup_user_nul(_data, datalen);
 233        if (IS_ERR(data))
 234                return PTR_ERR(data);
 235
 236        ret = -EINVAL;
 237        if (memchr(data, '\0', datalen))
 238                goto error;
 239
 240        /* strip any newline */
 241        cp = memchr(data, '\n', datalen);
 242        if (cp) {
 243                if (cp == data)
 244                        goto error;
 245
 246                *cp = '\0';
 247        }
 248
 249        /* parse the command */
 250        ret = -EOPNOTSUPP;
 251
 252        for (args = data; *args; args++)
 253                if (isspace(*args))
 254                        break;
 255        if (*args) {
 256                if (args == data)
 257                        goto error;
 258                *args = '\0';
 259                args = skip_spaces(++args);
 260        }
 261
 262        /* run the appropriate command handler */
 263        for (cmd = cachefiles_daemon_cmds; cmd->name[0]; cmd++)
 264                if (strcmp(cmd->name, data) == 0)
 265                        goto found_command;
 266
 267error:
 268        kfree(data);
 269        //_leave(" = %zd", ret);
 270        return ret;
 271
 272found_command:
 273        mutex_lock(&cache->daemon_mutex);
 274
 275        ret = -EIO;
 276        if (!test_bit(CACHEFILES_DEAD, &cache->flags))
 277                ret = cmd->handler(cache, args);
 278
 279        mutex_unlock(&cache->daemon_mutex);
 280
 281        if (ret == 0)
 282                ret = datalen;
 283        goto error;
 284}
 285
 286/*
 287 * poll for culling state
 288 * - use EPOLLOUT to indicate culling state
 289 */
 290static __poll_t cachefiles_daemon_poll(struct file *file,
 291                                           struct poll_table_struct *poll)
 292{
 293        struct cachefiles_cache *cache = file->private_data;
 294        __poll_t mask;
 295
 296        poll_wait(file, &cache->daemon_pollwq, poll);
 297        mask = 0;
 298
 299        if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags))
 300                mask |= EPOLLIN;
 301
 302        if (test_bit(CACHEFILES_CULLING, &cache->flags))
 303                mask |= EPOLLOUT;
 304
 305        return mask;
 306}
 307
 308/*
 309 * give a range error for cache space constraints
 310 * - can be tail-called
 311 */
 312static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
 313                                         char *args)
 314{
 315        pr_err("Free space limits must be in range 0%%<=stop<cull<run<100%%\n");
 316
 317        return -EINVAL;
 318}
 319
 320/*
 321 * set the percentage of files at which to stop culling
 322 * - command: "frun <N>%"
 323 */
 324static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
 325{
 326        unsigned long frun;
 327
 328        _enter(",%s", args);
 329
 330        if (!*args)
 331                return -EINVAL;
 332
 333        frun = simple_strtoul(args, &args, 10);
 334        if (args[0] != '%' || args[1] != '\0')
 335                return -EINVAL;
 336
 337        if (frun <= cache->fcull_percent || frun >= 100)
 338                return cachefiles_daemon_range_error(cache, args);
 339
 340        cache->frun_percent = frun;
 341        return 0;
 342}
 343
 344/*
 345 * set the percentage of files at which to start culling
 346 * - command: "fcull <N>%"
 347 */
 348static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
 349{
 350        unsigned long fcull;
 351
 352        _enter(",%s", args);
 353
 354        if (!*args)
 355                return -EINVAL;
 356
 357        fcull = simple_strtoul(args, &args, 10);
 358        if (args[0] != '%' || args[1] != '\0')
 359                return -EINVAL;
 360
 361        if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent)
 362                return cachefiles_daemon_range_error(cache, args);
 363
 364        cache->fcull_percent = fcull;
 365        return 0;
 366}
 367
 368/*
 369 * set the percentage of files at which to stop allocating
 370 * - command: "fstop <N>%"
 371 */
 372static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
 373{
 374        unsigned long fstop;
 375
 376        _enter(",%s", args);
 377
 378        if (!*args)
 379                return -EINVAL;
 380
 381        fstop = simple_strtoul(args, &args, 10);
 382        if (args[0] != '%' || args[1] != '\0')
 383                return -EINVAL;
 384
 385        if (fstop < 0 || fstop >= cache->fcull_percent)
 386                return cachefiles_daemon_range_error(cache, args);
 387
 388        cache->fstop_percent = fstop;
 389        return 0;
 390}
 391
 392/*
 393 * set the percentage of blocks at which to stop culling
 394 * - command: "brun <N>%"
 395 */
 396static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
 397{
 398        unsigned long brun;
 399
 400        _enter(",%s", args);
 401
 402        if (!*args)
 403                return -EINVAL;
 404
 405        brun = simple_strtoul(args, &args, 10);
 406        if (args[0] != '%' || args[1] != '\0')
 407                return -EINVAL;
 408
 409        if (brun <= cache->bcull_percent || brun >= 100)
 410                return cachefiles_daemon_range_error(cache, args);
 411
 412        cache->brun_percent = brun;
 413        return 0;
 414}
 415
 416/*
 417 * set the percentage of blocks at which to start culling
 418 * - command: "bcull <N>%"
 419 */
 420static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
 421{
 422        unsigned long bcull;
 423
 424        _enter(",%s", args);
 425
 426        if (!*args)
 427                return -EINVAL;
 428
 429        bcull = simple_strtoul(args, &args, 10);
 430        if (args[0] != '%' || args[1] != '\0')
 431                return -EINVAL;
 432
 433        if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
 434                return cachefiles_daemon_range_error(cache, args);
 435
 436        cache->bcull_percent = bcull;
 437        return 0;
 438}
 439
 440/*
 441 * set the percentage of blocks at which to stop allocating
 442 * - command: "bstop <N>%"
 443 */
 444static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args)
 445{
 446        unsigned long bstop;
 447
 448        _enter(",%s", args);
 449
 450        if (!*args)
 451                return -EINVAL;
 452
 453        bstop = simple_strtoul(args, &args, 10);
 454        if (args[0] != '%' || args[1] != '\0')
 455                return -EINVAL;
 456
 457        if (bstop < 0 || bstop >= cache->bcull_percent)
 458                return cachefiles_daemon_range_error(cache, args);
 459
 460        cache->bstop_percent = bstop;
 461        return 0;
 462}
 463
 464/*
 465 * set the cache directory
 466 * - command: "dir <name>"
 467 */
 468static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
 469{
 470        char *dir;
 471
 472        _enter(",%s", args);
 473
 474        if (!*args) {
 475                pr_err("Empty directory specified\n");
 476                return -EINVAL;
 477        }
 478
 479        if (cache->rootdirname) {
 480                pr_err("Second cache directory specified\n");
 481                return -EEXIST;
 482        }
 483
 484        dir = kstrdup(args, GFP_KERNEL);
 485        if (!dir)
 486                return -ENOMEM;
 487
 488        cache->rootdirname = dir;
 489        return 0;
 490}
 491
 492/*
 493 * set the cache security context
 494 * - command: "secctx <ctx>"
 495 */
 496static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
 497{
 498        char *secctx;
 499
 500        _enter(",%s", args);
 501
 502        if (!*args) {
 503                pr_err("Empty security context specified\n");
 504                return -EINVAL;
 505        }
 506
 507        if (cache->secctx) {
 508                pr_err("Second security context specified\n");
 509                return -EINVAL;
 510        }
 511
 512        secctx = kstrdup(args, GFP_KERNEL);
 513        if (!secctx)
 514                return -ENOMEM;
 515
 516        cache->secctx = secctx;
 517        return 0;
 518}
 519
 520/*
 521 * set the cache tag
 522 * - command: "tag <name>"
 523 */
 524static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
 525{
 526        char *tag;
 527
 528        _enter(",%s", args);
 529
 530        if (!*args) {
 531                pr_err("Empty tag specified\n");
 532                return -EINVAL;
 533        }
 534
 535        if (cache->tag)
 536                return -EEXIST;
 537
 538        tag = kstrdup(args, GFP_KERNEL);
 539        if (!tag)
 540                return -ENOMEM;
 541
 542        cache->tag = tag;
 543        return 0;
 544}
 545
 546/*
 547 * request a node in the cache be culled from the current working directory
 548 * - command: "cull <name>"
 549 */
 550static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
 551{
 552        struct path path;
 553        const struct cred *saved_cred;
 554        int ret;
 555
 556        _enter(",%s", args);
 557
 558        if (strchr(args, '/'))
 559                goto inval;
 560
 561        if (!test_bit(CACHEFILES_READY, &cache->flags)) {
 562                pr_err("cull applied to unready cache\n");
 563                return -EIO;
 564        }
 565
 566        if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
 567                pr_err("cull applied to dead cache\n");
 568                return -EIO;
 569        }
 570
 571        /* extract the directory dentry from the cwd */
 572        get_fs_pwd(current->fs, &path);
 573
 574        if (!d_can_lookup(path.dentry))
 575                goto notdir;
 576
 577        cachefiles_begin_secure(cache, &saved_cred);
 578        ret = cachefiles_cull(cache, path.dentry, args);
 579        cachefiles_end_secure(cache, saved_cred);
 580
 581        path_put(&path);
 582        _leave(" = %d", ret);
 583        return ret;
 584
 585notdir:
 586        path_put(&path);
 587        pr_err("cull command requires dirfd to be a directory\n");
 588        return -ENOTDIR;
 589
 590inval:
 591        pr_err("cull command requires dirfd and filename\n");
 592        return -EINVAL;
 593}
 594
 595/*
 596 * set debugging mode
 597 * - command: "debug <mask>"
 598 */
 599static int cachefiles_daemon_debug(struct cachefiles_cache *cache, char *args)
 600{
 601        unsigned long mask;
 602
 603        _enter(",%s", args);
 604
 605        mask = simple_strtoul(args, &args, 0);
 606        if (args[0] != '\0')
 607                goto inval;
 608
 609        cachefiles_debug = mask;
 610        _leave(" = 0");
 611        return 0;
 612
 613inval:
 614        pr_err("debug command requires mask\n");
 615        return -EINVAL;
 616}
 617
 618/*
 619 * find out whether an object in the current working directory is in use or not
 620 * - command: "inuse <name>"
 621 */
 622static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
 623{
 624        struct path path;
 625        const struct cred *saved_cred;
 626        int ret;
 627
 628        //_enter(",%s", args);
 629
 630        if (strchr(args, '/'))
 631                goto inval;
 632
 633        if (!test_bit(CACHEFILES_READY, &cache->flags)) {
 634                pr_err("inuse applied to unready cache\n");
 635                return -EIO;
 636        }
 637
 638        if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
 639                pr_err("inuse applied to dead cache\n");
 640                return -EIO;
 641        }
 642
 643        /* extract the directory dentry from the cwd */
 644        get_fs_pwd(current->fs, &path);
 645
 646        if (!d_can_lookup(path.dentry))
 647                goto notdir;
 648
 649        cachefiles_begin_secure(cache, &saved_cred);
 650        ret = cachefiles_check_in_use(cache, path.dentry, args);
 651        cachefiles_end_secure(cache, saved_cred);
 652
 653        path_put(&path);
 654        //_leave(" = %d", ret);
 655        return ret;
 656
 657notdir:
 658        path_put(&path);
 659        pr_err("inuse command requires dirfd to be a directory\n");
 660        return -ENOTDIR;
 661
 662inval:
 663        pr_err("inuse command requires dirfd and filename\n");
 664        return -EINVAL;
 665}
 666
 667/*
 668 * see if we have space for a number of pages and/or a number of files in the
 669 * cache
 670 */
 671int cachefiles_has_space(struct cachefiles_cache *cache,
 672                         unsigned fnr, unsigned bnr)
 673{
 674        struct kstatfs stats;
 675        struct path path = {
 676                .mnt    = cache->mnt,
 677                .dentry = cache->mnt->mnt_root,
 678        };
 679        int ret;
 680
 681        //_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u",
 682        //       (unsigned long long) cache->frun,
 683        //       (unsigned long long) cache->fcull,
 684        //       (unsigned long long) cache->fstop,
 685        //       (unsigned long long) cache->brun,
 686        //       (unsigned long long) cache->bcull,
 687        //       (unsigned long long) cache->bstop,
 688        //       fnr, bnr);
 689
 690        /* find out how many pages of blockdev are available */
 691        memset(&stats, 0, sizeof(stats));
 692
 693        ret = vfs_statfs(&path, &stats);
 694        if (ret < 0) {
 695                if (ret == -EIO)
 696                        cachefiles_io_error(cache, "statfs failed");
 697                _leave(" = %d", ret);
 698                return ret;
 699        }
 700
 701        stats.f_bavail >>= cache->bshift;
 702
 703        //_debug("avail %llu,%llu",
 704        //       (unsigned long long) stats.f_ffree,
 705        //       (unsigned long long) stats.f_bavail);
 706
 707        /* see if there is sufficient space */
 708        if (stats.f_ffree > fnr)
 709                stats.f_ffree -= fnr;
 710        else
 711                stats.f_ffree = 0;
 712
 713        if (stats.f_bavail > bnr)
 714                stats.f_bavail -= bnr;
 715        else
 716                stats.f_bavail = 0;
 717
 718        ret = -ENOBUFS;
 719        if (stats.f_ffree < cache->fstop ||
 720            stats.f_bavail < cache->bstop)
 721                goto begin_cull;
 722
 723        ret = 0;
 724        if (stats.f_ffree < cache->fcull ||
 725            stats.f_bavail < cache->bcull)
 726                goto begin_cull;
 727
 728        if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
 729            stats.f_ffree >= cache->frun &&
 730            stats.f_bavail >= cache->brun &&
 731            test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)
 732            ) {
 733                _debug("cease culling");
 734                cachefiles_state_changed(cache);
 735        }
 736
 737        //_leave(" = 0");
 738        return 0;
 739
 740begin_cull:
 741        if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
 742                _debug("### CULL CACHE ###");
 743                cachefiles_state_changed(cache);
 744        }
 745
 746        _leave(" = %d", ret);
 747        return ret;
 748}
 749