linux/fs/overlayfs/inode.c
<<
>>
Prefs
   1/*
   2 *
   3 * Copyright (C) 2011 Novell Inc.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 as published by
   7 * the Free Software Foundation.
   8 */
   9
  10#include <linux/fs.h>
  11#include <linux/slab.h>
  12#include <linux/xattr.h>
  13#include "overlayfs.h"
  14
  15static int ovl_copy_up_truncate(struct dentry *dentry)
  16{
  17        int err;
  18        struct dentry *parent;
  19        struct kstat stat;
  20        struct path lowerpath;
  21
  22        parent = dget_parent(dentry);
  23        err = ovl_copy_up(parent);
  24        if (err)
  25                goto out_dput_parent;
  26
  27        ovl_path_lower(dentry, &lowerpath);
  28        err = vfs_getattr(&lowerpath, &stat);
  29        if (err)
  30                goto out_dput_parent;
  31
  32        stat.size = 0;
  33        err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
  34
  35out_dput_parent:
  36        dput(parent);
  37        return err;
  38}
  39
  40int ovl_setattr(struct dentry *dentry, struct iattr *attr)
  41{
  42        int err;
  43        struct dentry *upperdentry;
  44
  45        err = ovl_want_write(dentry);
  46        if (err)
  47                goto out;
  48
  49        err = ovl_copy_up(dentry);
  50        if (!err) {
  51                upperdentry = ovl_dentry_upper(dentry);
  52
  53                mutex_lock(&upperdentry->d_inode->i_mutex);
  54                err = notify_change(upperdentry, attr, NULL);
  55                mutex_unlock(&upperdentry->d_inode->i_mutex);
  56        }
  57        ovl_drop_write(dentry);
  58out:
  59        return err;
  60}
  61
  62static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry,
  63                         struct kstat *stat)
  64{
  65        struct path realpath;
  66
  67        ovl_path_real(dentry, &realpath);
  68        return vfs_getattr(&realpath, stat);
  69}
  70
  71int ovl_permission(struct inode *inode, int mask)
  72{
  73        struct ovl_entry *oe;
  74        struct dentry *alias = NULL;
  75        struct inode *realinode;
  76        struct dentry *realdentry;
  77        bool is_upper;
  78        int err;
  79
  80        if (S_ISDIR(inode->i_mode)) {
  81                oe = inode->i_private;
  82        } else if (mask & MAY_NOT_BLOCK) {
  83                return -ECHILD;
  84        } else {
  85                /*
  86                 * For non-directories find an alias and get the info
  87                 * from there.
  88                 */
  89                alias = d_find_any_alias(inode);
  90                if (WARN_ON(!alias))
  91                        return -ENOENT;
  92
  93                oe = alias->d_fsdata;
  94        }
  95
  96        realdentry = ovl_entry_real(oe, &is_upper);
  97
  98        /* Careful in RCU walk mode */
  99        realinode = ACCESS_ONCE(realdentry->d_inode);
 100        if (!realinode) {
 101                WARN_ON(!(mask & MAY_NOT_BLOCK));
 102                err = -ENOENT;
 103                goto out_dput;
 104        }
 105
 106        if (mask & MAY_WRITE) {
 107                umode_t mode = realinode->i_mode;
 108
 109                /*
 110                 * Writes will always be redirected to upper layer, so
 111                 * ignore lower layer being read-only.
 112                 *
 113                 * If the overlay itself is read-only then proceed
 114                 * with the permission check, don't return EROFS.
 115                 * This will only happen if this is the lower layer of
 116                 * another overlayfs.
 117                 *
 118                 * If upper fs becomes read-only after the overlay was
 119                 * constructed return EROFS to prevent modification of
 120                 * upper layer.
 121                 */
 122                err = -EROFS;
 123                if (is_upper && !IS_RDONLY(inode) && IS_RDONLY(realinode) &&
 124                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 125                        goto out_dput;
 126        }
 127
 128        err = __inode_permission(realinode, mask);
 129out_dput:
 130        dput(alias);
 131        return err;
 132}
 133
 134
 135struct ovl_link_data {
 136        struct dentry *realdentry;
 137        void *cookie;
 138};
 139
 140static const char *ovl_follow_link(struct dentry *dentry, void **cookie)
 141{
 142        struct dentry *realdentry;
 143        struct inode *realinode;
 144        struct ovl_link_data *data = NULL;
 145        const char *ret;
 146
 147        realdentry = ovl_dentry_real(dentry);
 148        realinode = realdentry->d_inode;
 149
 150        if (WARN_ON(!realinode->i_op->follow_link))
 151                return ERR_PTR(-EPERM);
 152
 153        if (realinode->i_op->put_link) {
 154                data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
 155                if (!data)
 156                        return ERR_PTR(-ENOMEM);
 157                data->realdentry = realdentry;
 158        }
 159
 160        ret = realinode->i_op->follow_link(realdentry, cookie);
 161        if (IS_ERR_OR_NULL(ret)) {
 162                kfree(data);
 163                return ret;
 164        }
 165
 166        if (data)
 167                data->cookie = *cookie;
 168
 169        *cookie = data;
 170
 171        return ret;
 172}
 173
 174static void ovl_put_link(struct inode *unused, void *c)
 175{
 176        struct inode *realinode;
 177        struct ovl_link_data *data = c;
 178
 179        if (!data)
 180                return;
 181
 182        realinode = data->realdentry->d_inode;
 183        realinode->i_op->put_link(realinode, data->cookie);
 184        kfree(data);
 185}
 186
 187static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
 188{
 189        struct path realpath;
 190        struct inode *realinode;
 191
 192        ovl_path_real(dentry, &realpath);
 193        realinode = realpath.dentry->d_inode;
 194
 195        if (!realinode->i_op->readlink)
 196                return -EINVAL;
 197
 198        touch_atime(&realpath);
 199
 200        return realinode->i_op->readlink(realpath.dentry, buf, bufsiz);
 201}
 202
 203
 204static bool ovl_is_private_xattr(const char *name)
 205{
 206        return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
 207}
 208
 209int ovl_setxattr(struct dentry *dentry, const char *name,
 210                 const void *value, size_t size, int flags)
 211{
 212        int err;
 213        struct dentry *upperdentry;
 214
 215        err = ovl_want_write(dentry);
 216        if (err)
 217                goto out;
 218
 219        err = -EPERM;
 220        if (ovl_is_private_xattr(name))
 221                goto out_drop_write;
 222
 223        err = ovl_copy_up(dentry);
 224        if (err)
 225                goto out_drop_write;
 226
 227        upperdentry = ovl_dentry_upper(dentry);
 228        err = vfs_setxattr(upperdentry, name, value, size, flags);
 229
 230out_drop_write:
 231        ovl_drop_write(dentry);
 232out:
 233        return err;
 234}
 235
 236static bool ovl_need_xattr_filter(struct dentry *dentry,
 237                                  enum ovl_path_type type)
 238{
 239        if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER)
 240                return S_ISDIR(dentry->d_inode->i_mode);
 241        else
 242                return false;
 243}
 244
 245ssize_t ovl_getxattr(struct dentry *dentry, const char *name,
 246                     void *value, size_t size)
 247{
 248        struct path realpath;
 249        enum ovl_path_type type = ovl_path_real(dentry, &realpath);
 250
 251        if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name))
 252                return -ENODATA;
 253
 254        return vfs_getxattr(realpath.dentry, name, value, size);
 255}
 256
 257ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
 258{
 259        struct path realpath;
 260        enum ovl_path_type type = ovl_path_real(dentry, &realpath);
 261        ssize_t res;
 262        int off;
 263
 264        res = vfs_listxattr(realpath.dentry, list, size);
 265        if (res <= 0 || size == 0)
 266                return res;
 267
 268        if (!ovl_need_xattr_filter(dentry, type))
 269                return res;
 270
 271        /* filter out private xattrs */
 272        for (off = 0; off < res;) {
 273                char *s = list + off;
 274                size_t slen = strlen(s) + 1;
 275
 276                BUG_ON(off + slen > res);
 277
 278                if (ovl_is_private_xattr(s)) {
 279                        res -= slen;
 280                        memmove(s, s + slen, res - off);
 281                } else {
 282                        off += slen;
 283                }
 284        }
 285
 286        return res;
 287}
 288
 289int ovl_removexattr(struct dentry *dentry, const char *name)
 290{
 291        int err;
 292        struct path realpath;
 293        enum ovl_path_type type = ovl_path_real(dentry, &realpath);
 294
 295        err = ovl_want_write(dentry);
 296        if (err)
 297                goto out;
 298
 299        err = -ENODATA;
 300        if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name))
 301                goto out_drop_write;
 302
 303        if (!OVL_TYPE_UPPER(type)) {
 304                err = vfs_getxattr(realpath.dentry, name, NULL, 0);
 305                if (err < 0)
 306                        goto out_drop_write;
 307
 308                err = ovl_copy_up(dentry);
 309                if (err)
 310                        goto out_drop_write;
 311
 312                ovl_path_upper(dentry, &realpath);
 313        }
 314
 315        err = vfs_removexattr(realpath.dentry, name);
 316out_drop_write:
 317        ovl_drop_write(dentry);
 318out:
 319        return err;
 320}
 321
 322static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type,
 323                                  struct dentry *realdentry)
 324{
 325        if (OVL_TYPE_UPPER(type))
 326                return false;
 327
 328        if (special_file(realdentry->d_inode->i_mode))
 329                return false;
 330
 331        if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
 332                return false;
 333
 334        return true;
 335}
 336
 337struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
 338{
 339        int err;
 340        struct path realpath;
 341        enum ovl_path_type type;
 342
 343        if (d_is_dir(dentry))
 344                return d_backing_inode(dentry);
 345
 346        type = ovl_path_real(dentry, &realpath);
 347        if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
 348                err = ovl_want_write(dentry);
 349                if (err)
 350                        return ERR_PTR(err);
 351
 352                if (file_flags & O_TRUNC)
 353                        err = ovl_copy_up_truncate(dentry);
 354                else
 355                        err = ovl_copy_up(dentry);
 356                ovl_drop_write(dentry);
 357                if (err)
 358                        return ERR_PTR(err);
 359
 360                ovl_path_upper(dentry, &realpath);
 361        }
 362
 363        if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
 364                return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);
 365
 366        return d_backing_inode(realpath.dentry);
 367}
 368
 369static const struct inode_operations ovl_file_inode_operations = {
 370        .setattr        = ovl_setattr,
 371        .permission     = ovl_permission,
 372        .getattr        = ovl_getattr,
 373        .setxattr       = ovl_setxattr,
 374        .getxattr       = ovl_getxattr,
 375        .listxattr      = ovl_listxattr,
 376        .removexattr    = ovl_removexattr,
 377};
 378
 379static const struct inode_operations ovl_symlink_inode_operations = {
 380        .setattr        = ovl_setattr,
 381        .follow_link    = ovl_follow_link,
 382        .put_link       = ovl_put_link,
 383        .readlink       = ovl_readlink,
 384        .getattr        = ovl_getattr,
 385        .setxattr       = ovl_setxattr,
 386        .getxattr       = ovl_getxattr,
 387        .listxattr      = ovl_listxattr,
 388        .removexattr    = ovl_removexattr,
 389};
 390
 391struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
 392                            struct ovl_entry *oe)
 393{
 394        struct inode *inode;
 395
 396        inode = new_inode(sb);
 397        if (!inode)
 398                return NULL;
 399
 400        mode &= S_IFMT;
 401
 402        inode->i_ino = get_next_ino();
 403        inode->i_mode = mode;
 404        inode->i_flags |= S_NOATIME | S_NOCMTIME;
 405
 406        switch (mode) {
 407        case S_IFDIR:
 408                inode->i_private = oe;
 409                inode->i_op = &ovl_dir_inode_operations;
 410                inode->i_fop = &ovl_dir_operations;
 411                break;
 412
 413        case S_IFLNK:
 414                inode->i_op = &ovl_symlink_inode_operations;
 415                break;
 416
 417        case S_IFREG:
 418        case S_IFSOCK:
 419        case S_IFBLK:
 420        case S_IFCHR:
 421        case S_IFIFO:
 422                inode->i_op = &ovl_file_inode_operations;
 423                break;
 424
 425        default:
 426                WARN(1, "illegal file type: %i\n", mode);
 427                iput(inode);
 428                inode = NULL;
 429        }
 430
 431        return inode;
 432}
 433