source: trunk/target/linux/generic/patches-3.0/100-overlayfs_v10.patch @ 27300

Last change on this file since 27300 was 27300, checked in by hauke, 5 years ago

kernel: refresh patches for kernel 3.0-rc5

File size: 75.0 KB
  • fs/open.c

    a b static inline int __get_file_write_acces 
    666666        return error; 
    667667} 
    668668 
    669 static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 
    670                                         struct file *f, 
     669static struct file *__dentry_open(struct path *path, struct file *f, 
    671670                                        int (*open)(struct inode *, struct file *), 
    672671                                        const struct cred *cred) 
    673672{ 
    static struct file *__dentry_open(struct 
    675674        struct inode *inode; 
    676675        int error; 
    677676 
     677        path_get(path); 
    678678        f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | 
    679679                                FMODE_PREAD | FMODE_PWRITE; 
    680680 
    681681        if (unlikely(f->f_flags & O_PATH)) 
    682682                f->f_mode = FMODE_PATH; 
    683683 
    684         inode = dentry->d_inode; 
     684        inode = path->dentry->d_inode; 
    685685        if (f->f_mode & FMODE_WRITE) { 
    686                 error = __get_file_write_access(inode, mnt); 
     686                error = __get_file_write_access(inode, path->mnt); 
    687687                if (error) 
    688688                        goto cleanup_file; 
    689689                if (!special_file(inode->i_mode)) 
    static struct file *__dentry_open(struct 
    691691        } 
    692692 
    693693        f->f_mapping = inode->i_mapping; 
    694         f->f_path.dentry = dentry; 
    695         f->f_path.mnt = mnt; 
     694        f->f_path = *path; 
    696695        f->f_pos = 0; 
    697696        file_sb_list_add(f, inode->i_sb); 
    698697 
    cleanup_all: 
    745744                         * here, so just reset the state. 
    746745                         */ 
    747746                        file_reset_write(f); 
    748                         mnt_drop_write(mnt); 
     747                        mnt_drop_write(path->mnt); 
    749748                } 
    750749        } 
    751750        file_sb_list_del(f); 
    cleanup_all: 
    753752        f->f_path.mnt = NULL; 
    754753cleanup_file: 
    755754        put_filp(f); 
    756         dput(dentry); 
    757         mntput(mnt); 
     755        path_put(path); 
    758756        return ERR_PTR(error); 
    759757} 
    760758 
    cleanup_file: 
    780778struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, 
    781779                int (*open)(struct inode *, struct file *)) 
    782780{ 
     781        struct path path = { .dentry = dentry, .mnt = nd->path.mnt }; 
    783782        const struct cred *cred = current_cred(); 
    784783 
    785784        if (IS_ERR(nd->intent.open.file)) 
    786785                goto out; 
    787786        if (IS_ERR(dentry)) 
    788787                goto out_err; 
    789         nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), 
    790                                              nd->intent.open.file, 
     788        nd->intent.open.file = __dentry_open(&path, nd->intent.open.file, 
    791789                                             open, cred); 
    792790out: 
    793791        return nd->intent.open.file; 
    struct file *nameidata_to_filp(struct na 
    816814 
    817815        /* Has the filesystem initialised the file for us? */ 
    818816        if (filp->f_path.dentry == NULL) { 
    819                 path_get(&nd->path); 
    820                 filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, 
    821                                      NULL, cred); 
     817                struct inode *inode = nd->path.dentry->d_inode; 
     818 
     819                if (inode->i_op->open) { 
     820                        int flags = filp->f_flags; 
     821                        put_filp(filp); 
     822                        filp = inode->i_op->open(nd->path.dentry, flags, cred); 
     823                } else { 
     824                        filp = __dentry_open(&nd->path, filp, NULL, cred); 
     825                } 
    822826        } 
     827 
    823828        return filp; 
    824829} 
    825830 
    struct file *nameidata_to_filp(struct na 
    830835struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, 
    831836                         const struct cred *cred) 
    832837{ 
    833         int error; 
    834         struct file *f; 
    835  
    836         validate_creds(cred); 
     838        struct path path = { .dentry = dentry, .mnt = mnt }; 
     839        struct file *ret; 
    837840 
    838841        /* We must always pass in a valid mount pointer. */ 
    839842        BUG_ON(!mnt); 
    840843 
    841         error = -ENFILE; 
     844        ret = vfs_open(&path, flags, cred); 
     845        path_put(&path); 
     846 
     847        return ret; 
     848} 
     849EXPORT_SYMBOL(dentry_open); 
     850 
     851/** 
     852 * vfs_open - open the file at the given path 
     853 * @path: path to open 
     854 * @flags: open flags 
     855 * @cred: credentials to use 
     856 * 
     857 * Open the file.  If successful, the returned file will have acquired 
     858 * an additional reference for path. 
     859 */ 
     860struct file *vfs_open(struct path *path, int flags, const struct cred *cred) 
     861{ 
     862        struct file *f; 
     863        struct inode *inode = path->dentry->d_inode; 
     864 
     865        validate_creds(cred); 
     866 
     867        if (inode->i_op->open) 
     868                return inode->i_op->open(path->dentry, flags, cred); 
    842869        f = get_empty_filp(); 
    843         if (f == NULL) { 
    844                 dput(dentry); 
    845                 mntput(mnt); 
    846                 return ERR_PTR(error); 
    847         } 
     870        if (f == NULL) 
     871                return ERR_PTR(-ENFILE); 
    848872 
    849873        f->f_flags = flags; 
    850         return __dentry_open(dentry, mnt, f, NULL, cred); 
     874        return __dentry_open(path, f, NULL, cred); 
    851875} 
    852 EXPORT_SYMBOL(dentry_open); 
     876EXPORT_SYMBOL(vfs_open); 
    853877 
    854878static void __put_unused_fd(struct files_struct *files, unsigned int fd) 
    855879{ 
  • include/linux/fs.h

    a b struct inode_operations { 
    16031603        void (*truncate_range)(struct inode *, loff_t, loff_t); 
    16041604        int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, 
    16051605                      u64 len); 
     1606        struct file *(*open)(struct dentry *, int flags, const struct cred *); 
    16061607} ____cacheline_aligned; 
    16071608 
    16081609struct seq_file; 
    extern long do_sys_open(int dfd, const c 
    19971998extern struct file *filp_open(const char *, int, int); 
    19981999extern struct file *file_open_root(struct dentry *, struct vfsmount *, 
    19992000                                   const char *, int); 
     2001extern struct file *vfs_open(struct path *, int flags, const struct cred *); 
    20002002extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, 
    20012003                                 const struct cred *); 
    20022004extern int filp_close(struct file *, fl_owner_t id); 
  • fs/splice.c

    a b long do_splice_direct(struct file *in, l 
    13001300 
    13011301        return ret; 
    13021302} 
     1303EXPORT_SYMBOL(do_splice_direct); 
    13031304 
    13041305static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, 
    13051306                               struct pipe_inode_info *opipe, 
  • fs/namespace.c

    a b void drop_collected_mounts(struct vfsmou 
    14941494        release_mounts(&umount_list); 
    14951495} 
    14961496 
     1497struct vfsmount *clone_private_mount(struct path *path) 
     1498{ 
     1499        struct vfsmount *mnt; 
     1500 
     1501        if (IS_MNT_UNBINDABLE(path->mnt)) 
     1502                return ERR_PTR(-EINVAL); 
     1503 
     1504        down_read(&namespace_sem); 
     1505        mnt = clone_mnt(path->mnt, path->dentry, CL_PRIVATE); 
     1506        up_read(&namespace_sem); 
     1507        if (!mnt) 
     1508                return ERR_PTR(-ENOMEM); 
     1509 
     1510        return mnt; 
     1511} 
     1512EXPORT_SYMBOL_GPL(clone_private_mount); 
     1513 
    14971514int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, 
    14981515                   struct vfsmount *root) 
    14991516{ 
  • include/linux/mount.h

    a b extern void mnt_pin(struct vfsmount *mnt 
    100100extern void mnt_unpin(struct vfsmount *mnt); 
    101101extern int __mnt_is_readonly(struct vfsmount *mnt); 
    102102 
     103struct path; 
     104extern struct vfsmount *clone_private_mount(struct path *path); 
     105 
    103106extern struct vfsmount *do_kern_mount(const char *fstype, int flags, 
    104107                                      const char *name, void *data); 
    105108 
  • fs/Kconfig

    a b source "fs/quota/Kconfig" 
    6363 
    6464source "fs/autofs4/Kconfig" 
    6565source "fs/fuse/Kconfig" 
     66source "fs/overlayfs/Kconfig" 
    6667 
    6768config CUSE 
    6869        tristate "Character device in Userspace support" 
  • fs/Makefile

    a b obj-$(CONFIG_QNX4FS_FS) += qnx4/ 
    105105obj-$(CONFIG_AUTOFS4_FS)        += autofs4/ 
    106106obj-$(CONFIG_ADFS_FS)           += adfs/ 
    107107obj-$(CONFIG_FUSE_FS)           += fuse/ 
     108obj-$(CONFIG_OVERLAYFS_FS)      += overlayfs/ 
    108109obj-$(CONFIG_UDF_FS)            += udf/ 
    109110obj-$(CONFIG_SUN_OPENPROMFS)    += openpromfs/ 
    110111obj-$(CONFIG_OMFS_FS)           += omfs/ 
  • new file fs/overlayfs/Kconfig

    - +  
     1config OVERLAYFS_FS 
     2        tristate "Overlay filesystem support" 
     3        help 
     4          Add support for overlay filesystem. 
  • new file fs/overlayfs/Makefile

    - +  
     1# 
     2# Makefile for the overlay filesystem. 
     3# 
     4 
     5obj-$(CONFIG_OVERLAYFS_FS) += overlayfs.o 
     6 
     7overlayfs-objs := super.o inode.o dir.o readdir.o copy_up.o 
  • new file fs/overlayfs/copy_up.c

    - +  
     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/file.h> 
     13#include <linux/splice.h> 
     14#include <linux/xattr.h> 
     15#include <linux/security.h> 
     16#include <linux/uaccess.h> 
     17#include "overlayfs.h" 
     18 
     19#define OVL_COPY_UP_CHUNK_SIZE (1 << 20) 
     20 
     21static int ovl_copy_up_xattr(struct dentry *old, struct dentry *new) 
     22{ 
     23        ssize_t list_size, size; 
     24        char *buf, *name, *value; 
     25        int error; 
     26 
     27        if (!old->d_inode->i_op->getxattr || 
     28            !new->d_inode->i_op->getxattr) 
     29                return 0; 
     30 
     31        list_size = vfs_listxattr(old, NULL, 0); 
     32        if (list_size <= 0) { 
     33                if (list_size == -EOPNOTSUPP) 
     34                        return 0; 
     35                return list_size; 
     36        } 
     37 
     38        buf = kzalloc(list_size, GFP_KERNEL); 
     39        if (!buf) 
     40                return -ENOMEM; 
     41 
     42        error = -ENOMEM; 
     43        value = kmalloc(XATTR_SIZE_MAX, GFP_KERNEL); 
     44        if (!value) 
     45                goto out; 
     46 
     47        list_size = vfs_listxattr(old, buf, list_size); 
     48        if (list_size <= 0) { 
     49                error = list_size; 
     50                goto out_free_value; 
     51        } 
     52 
     53        for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { 
     54                size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX); 
     55                if (size <= 0) { 
     56                        error = size; 
     57                        goto out_free_value; 
     58                } 
     59                error = vfs_setxattr(new, name, value, size, 0); 
     60                if (error) 
     61                        goto out_free_value; 
     62        } 
     63 
     64out_free_value: 
     65        kfree(value); 
     66out: 
     67        kfree(buf); 
     68        return error; 
     69} 
     70 
     71static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) 
     72{ 
     73        struct file *old_file; 
     74        struct file *new_file; 
     75        int error = 0; 
     76 
     77        if (len == 0) 
     78                return 0; 
     79 
     80        old_file = vfs_open(old, O_RDONLY, current_cred()); 
     81        if (IS_ERR(old_file)) 
     82                return PTR_ERR(old_file); 
     83 
     84        new_file = vfs_open(new, O_WRONLY, current_cred()); 
     85        if (IS_ERR(new_file)) { 
     86                error = PTR_ERR(new_file); 
     87                goto out_fput; 
     88        } 
     89 
     90        /* FIXME: copy up sparse files efficiently */ 
     91        while (len) { 
     92                loff_t offset = new_file->f_pos; 
     93                size_t this_len = OVL_COPY_UP_CHUNK_SIZE; 
     94                long bytes; 
     95 
     96                if (len < this_len) 
     97                        this_len = len; 
     98 
     99                if (signal_pending_state(TASK_KILLABLE, current)) { 
     100                        error = -EINTR; 
     101                        break; 
     102                } 
     103 
     104                bytes = do_splice_direct(old_file, &offset, new_file, this_len, 
     105                                 SPLICE_F_MOVE); 
     106                if (bytes <= 0) { 
     107                        error = bytes; 
     108                        break; 
     109                } 
     110 
     111                len -= bytes; 
     112        } 
     113 
     114        fput(new_file); 
     115out_fput: 
     116        fput(old_file); 
     117        return error; 
     118} 
     119 
     120static char *ovl_read_symlink(struct dentry *realdentry) 
     121{ 
     122        int res; 
     123        char *buf; 
     124        struct inode *inode = realdentry->d_inode; 
     125        mm_segment_t old_fs; 
     126 
     127        res = -EINVAL; 
     128        if (!inode->i_op->readlink) 
     129                goto err; 
     130 
     131        res = -ENOMEM; 
     132        buf = (char *) __get_free_page(GFP_KERNEL); 
     133        if (!buf) 
     134                goto err; 
     135 
     136        old_fs = get_fs(); 
     137        set_fs(get_ds()); 
     138        /* The cast to a user pointer is valid due to the set_fs() */ 
     139        res = inode->i_op->readlink(realdentry, 
     140                                    (char __user *)buf, PAGE_SIZE - 1); 
     141        set_fs(old_fs); 
     142        if (res < 0) { 
     143                free_page((unsigned long) buf); 
     144                goto err; 
     145        } 
     146        buf[res] = '\0'; 
     147 
     148        return buf; 
     149 
     150err: 
     151        return ERR_PTR(res); 
     152} 
     153 
     154static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat) 
     155{ 
     156        struct iattr attr = { 
     157                .ia_valid = ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, 
     158                .ia_atime = stat->atime, 
     159                .ia_mtime = stat->mtime, 
     160        }; 
     161 
     162        return notify_change(upperdentry, &attr); 
     163} 
     164 
     165static int ovl_set_mode(struct dentry *upperdentry, umode_t mode) 
     166{ 
     167        struct iattr attr = { 
     168                .ia_valid = ATTR_MODE, 
     169                .ia_mode = mode, 
     170        }; 
     171 
     172        return notify_change(upperdentry, &attr); 
     173} 
     174 
     175static int ovl_copy_up_locked(struct dentry *upperdir, struct dentry *dentry, 
     176                              struct path *lowerpath, struct kstat *stat, 
     177                              const char *link) 
     178{ 
     179        int err; 
     180        struct path newpath; 
     181        umode_t mode = stat->mode; 
     182 
     183        /* Can't properly set mode on creation because of the umask */ 
     184        stat->mode &= S_IFMT; 
     185 
     186        ovl_path_upper(dentry, &newpath); 
     187        WARN_ON(newpath.dentry); 
     188        newpath.dentry = ovl_upper_create(upperdir, dentry, stat, link); 
     189        if (IS_ERR(newpath.dentry)) 
     190                return PTR_ERR(newpath.dentry); 
     191 
     192        if (S_ISREG(stat->mode)) { 
     193                err = ovl_copy_up_data(lowerpath, &newpath, stat->size); 
     194                if (err) 
     195                        goto err_remove; 
     196        } 
     197 
     198        err = ovl_copy_up_xattr(lowerpath->dentry, newpath.dentry); 
     199        if (err) 
     200                goto err_remove; 
     201 
     202        mutex_lock(&newpath.dentry->d_inode->i_mutex); 
     203        if (!S_ISLNK(stat->mode)) 
     204                err = ovl_set_mode(newpath.dentry, mode); 
     205        if (!err) 
     206                err = ovl_set_timestamps(newpath.dentry, stat); 
     207        mutex_unlock(&newpath.dentry->d_inode->i_mutex); 
     208        if (err) 
     209                goto err_remove; 
     210 
     211        ovl_dentry_update(dentry, newpath.dentry); 
     212 
     213        /* 
     214         * Easiest way to get rid of the lower dentry reference is to 
     215         * drop this dentry.  This is neither needed nor possible for 
     216         * directories. 
     217         */ 
     218        if (!S_ISDIR(stat->mode)) 
     219                d_drop(dentry); 
     220 
     221        return 0; 
     222 
     223err_remove: 
     224        if (S_ISDIR(stat->mode)) 
     225                vfs_rmdir(upperdir->d_inode, newpath.dentry); 
     226        else 
     227                vfs_unlink(upperdir->d_inode, newpath.dentry); 
     228 
     229        dput(newpath.dentry); 
     230 
     231        return err; 
     232} 
     233 
     234/* 
     235 * Copy up a single dentry 
     236 * 
     237 * Directory renames only allowed on "pure upper" (already created on 
     238 * upper filesystem, never copied up).  Directories which are on lower or 
     239 * are merged may not be renamed.  For these -EXDEV is returned and 
     240 * userspace has to deal with it.  This means, when copying up a 
     241 * directory we can rely on it and ancestors being stable. 
     242 * 
     243 * Non-directory renames start with copy up of source if necessary.  The 
     244 * actual rename will only proceed once the copy up was successful.  Copy 
     245 * up uses upper parent i_mutex for exclusion.  Since rename can change 
     246 * d_parent it is possible that the copy up will lock the old parent.  At 
     247 * that point the file will have already been copied up anyway. 
     248 */ 
     249static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, 
     250                           struct path *lowerpath, struct kstat *stat) 
     251{ 
     252        int err; 
     253        struct kstat pstat; 
     254        struct path parentpath; 
     255        struct dentry *upperdir; 
     256        const struct cred *old_cred; 
     257        struct cred *override_cred; 
     258        char *link = NULL; 
     259 
     260        ovl_path_upper(parent, &parentpath); 
     261        upperdir = parentpath.dentry; 
     262 
     263        err = vfs_getattr(parentpath.mnt, parentpath.dentry, &pstat); 
     264        if (err) 
     265                return err; 
     266 
     267        if (S_ISLNK(stat->mode)) { 
     268                link = ovl_read_symlink(lowerpath->dentry); 
     269                if (IS_ERR(link)) 
     270                        return PTR_ERR(link); 
     271        } 
     272 
     273        err = -ENOMEM; 
     274        override_cred = prepare_creds(); 
     275        if (!override_cred) 
     276                goto out_free_link; 
     277 
     278        override_cred->fsuid = stat->uid; 
     279        override_cred->fsgid = stat->gid; 
     280        /* 
     281         * CAP_SYS_ADMIN for copying up extended attributes 
     282         * CAP_DAC_OVERRIDE for create 
     283         * CAP_FOWNER for chmod, timestamp update 
     284         * CAP_FSETID for chmod 
     285         * CAP_MKNOD for mknod 
     286         */ 
     287        cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     288        cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); 
     289        cap_raise(override_cred->cap_effective, CAP_FOWNER); 
     290        cap_raise(override_cred->cap_effective, CAP_FSETID); 
     291        cap_raise(override_cred->cap_effective, CAP_MKNOD); 
     292        old_cred = override_creds(override_cred); 
     293 
     294        mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); 
     295        if (ovl_path_type(dentry) != OVL_PATH_LOWER) { 
     296                err = 0; 
     297        } else { 
     298                err = ovl_copy_up_locked(upperdir, dentry, lowerpath, 
     299                                         stat, link); 
     300                if (!err) { 
     301                        /* Restore timestamps on parent (best effort) */ 
     302                        ovl_set_timestamps(upperdir, &pstat); 
     303                } 
     304        } 
     305 
     306        mutex_unlock(&upperdir->d_inode->i_mutex); 
     307 
     308        revert_creds(old_cred); 
     309        put_cred(override_cred); 
     310 
     311out_free_link: 
     312        if (link) 
     313                free_page((unsigned long) link); 
     314 
     315        return err; 
     316} 
     317 
     318int ovl_copy_up(struct dentry *dentry) 
     319{ 
     320        int err; 
     321 
     322        err = 0; 
     323        while (!err) { 
     324                struct dentry *next; 
     325                struct dentry *parent; 
     326                struct path lowerpath; 
     327                struct kstat stat; 
     328                enum ovl_path_type type = ovl_path_type(dentry); 
     329 
     330                if (type != OVL_PATH_LOWER) 
     331                        break; 
     332 
     333                next = dget(dentry); 
     334                /* find the topmost dentry not yet copied up */ 
     335                for (;;) { 
     336                        parent = dget_parent(next); 
     337 
     338                        type = ovl_path_type(parent); 
     339                        if (type != OVL_PATH_LOWER) 
     340                                break; 
     341 
     342                        dput(next); 
     343                        next = parent; 
     344                } 
     345 
     346                ovl_path_lower(next, &lowerpath); 
     347                err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat); 
     348                if (!err) 
     349                        err = ovl_copy_up_one(parent, next, &lowerpath, &stat); 
     350 
     351                dput(parent); 
     352                dput(next); 
     353        } 
     354 
     355        return err; 
     356} 
     357 
     358/* Optimize by not copying up the file first and truncating later */ 
     359int ovl_copy_up_truncate(struct dentry *dentry, loff_t size) 
     360{ 
     361        int err; 
     362        struct kstat stat; 
     363        struct path lowerpath; 
     364        struct dentry *parent = dget_parent(dentry); 
     365 
     366        err = ovl_copy_up(parent); 
     367        if (err) 
     368                goto out_dput_parent; 
     369 
     370        ovl_path_lower(dentry, &lowerpath); 
     371        err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat); 
     372        if (err) 
     373                goto out_dput_parent; 
     374 
     375        if (size < stat.size) 
     376                stat.size = size; 
     377 
     378        err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat); 
     379 
     380out_dput_parent: 
     381        dput(parent); 
     382        return err; 
     383} 
  • new file fs/overlayfs/dir.c

    - +  
     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/namei.h> 
     12#include <linux/xattr.h> 
     13#include <linux/security.h> 
     14#include "overlayfs.h" 
     15 
     16static const char *ovl_whiteout_symlink = "(overlay-whiteout)"; 
     17 
     18static struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, 
     19                                 struct nameidata *nd) 
     20{ 
     21        int err = ovl_do_lookup(dentry); 
     22 
     23        if (err) 
     24                return ERR_PTR(err); 
     25 
     26        return NULL; 
     27} 
     28 
     29static int ovl_whiteout(struct dentry *upperdir, struct dentry *dentry) 
     30{ 
     31        int err; 
     32        struct dentry *newdentry; 
     33        const struct cred *old_cred; 
     34        struct cred *override_cred; 
     35 
     36        /* FIXME: recheck lower dentry to see if whiteout is really needed */ 
     37 
     38        err = -ENOMEM; 
     39        override_cred = prepare_creds(); 
     40        if (!override_cred) 
     41                goto out; 
     42 
     43        /* 
     44         * CAP_SYS_ADMIN for setxattr 
     45         * CAP_DAC_OVERRIDE for symlink creation 
     46         * CAP_FOWNER for unlink in sticky directory 
     47         */ 
     48        cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     49        cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); 
     50        cap_raise(override_cred->cap_effective, CAP_FOWNER); 
     51        override_cred->fsuid = 0; 
     52        override_cred->fsgid = 0; 
     53        old_cred = override_creds(override_cred); 
     54 
     55        newdentry = lookup_one_len(dentry->d_name.name, upperdir, 
     56                                   dentry->d_name.len); 
     57        err = PTR_ERR(newdentry); 
     58        if (IS_ERR(newdentry)) 
     59                goto out_put_cred; 
     60 
     61        /* Just been removed within the same locked region */ 
     62        WARN_ON(newdentry->d_inode); 
     63 
     64        err = vfs_symlink(upperdir->d_inode, newdentry, ovl_whiteout_symlink); 
     65        if (err) 
     66                goto out_dput; 
     67 
     68        ovl_dentry_version_inc(dentry->d_parent); 
     69 
     70        err = vfs_setxattr(newdentry, ovl_whiteout_xattr, "y", 1, 0); 
     71        if (err) 
     72                vfs_unlink(upperdir->d_inode, newdentry); 
     73 
     74out_dput: 
     75        dput(newdentry); 
     76out_put_cred: 
     77        revert_creds(old_cred); 
     78        put_cred(override_cred); 
     79out: 
     80        if (err) { 
     81                /* 
     82                 * There's no way to recover from failure to whiteout. 
     83                 * What should we do?  Log a big fat error and... ? 
     84                 */ 
     85                printk(KERN_ERR "overlayfs: ERROR - failed to whiteout '%s'\n", 
     86                       dentry->d_name.name); 
     87        } 
     88 
     89        return err; 
     90} 
     91 
     92static struct dentry *ovl_lookup_create(struct dentry *upperdir, 
     93                                        struct dentry *template) 
     94{ 
     95        int err; 
     96        struct dentry *newdentry; 
     97        struct qstr *name = &template->d_name; 
     98 
     99        newdentry = lookup_one_len(name->name, upperdir, name->len); 
     100        if (IS_ERR(newdentry)) 
     101                return newdentry; 
     102 
     103        if (newdentry->d_inode) { 
     104                const struct cred *old_cred; 
     105                struct cred *override_cred; 
     106 
     107                /* No need to check whiteout if lower parent is non-existent */ 
     108                err = -EEXIST; 
     109                if (!ovl_dentry_lower(template->d_parent)) 
     110                        goto out_dput; 
     111 
     112                if (!S_ISLNK(newdentry->d_inode->i_mode)) 
     113                        goto out_dput; 
     114 
     115                err = -ENOMEM; 
     116                override_cred = prepare_creds(); 
     117                if (!override_cred) 
     118                        goto out_dput; 
     119 
     120                /* 
     121                 * CAP_SYS_ADMIN for getxattr 
     122                 * CAP_FOWNER for unlink in sticky directory 
     123                 */ 
     124                cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     125                cap_raise(override_cred->cap_effective, CAP_FOWNER); 
     126                old_cred = override_creds(override_cred); 
     127 
     128                err = -EEXIST; 
     129                if (ovl_is_whiteout(newdentry)) 
     130                        err = vfs_unlink(upperdir->d_inode, newdentry); 
     131 
     132                revert_creds(old_cred); 
     133                put_cred(override_cred); 
     134                if (err) 
     135                        goto out_dput; 
     136 
     137                dput(newdentry); 
     138                newdentry = lookup_one_len(name->name, upperdir, name->len); 
     139                if (IS_ERR(newdentry)) { 
     140                        ovl_whiteout(upperdir, template); 
     141                        return newdentry; 
     142                } 
     143 
     144                /* 
     145                 * Whiteout just been successfully removed, parent 
     146                 * i_mutex is still held, there's no way the lookup 
     147                 * could return positive. 
     148                 */ 
     149                WARN_ON(newdentry->d_inode); 
     150        } 
     151 
     152        return newdentry; 
     153 
     154out_dput: 
     155        dput(newdentry); 
     156        return ERR_PTR(err); 
     157} 
     158 
     159struct dentry *ovl_upper_create(struct dentry *upperdir, struct dentry *dentry, 
     160                                struct kstat *stat, const char *link) 
     161{ 
     162        int err; 
     163        struct dentry *newdentry; 
     164        struct inode *dir = upperdir->d_inode; 
     165 
     166        newdentry = ovl_lookup_create(upperdir, dentry); 
     167        if (IS_ERR(newdentry)) 
     168                goto out; 
     169 
     170        switch (stat->mode & S_IFMT) { 
     171        case S_IFREG: 
     172                err = vfs_create(dir, newdentry, stat->mode, NULL); 
     173                break; 
     174 
     175        case S_IFDIR: 
     176                err = vfs_mkdir(dir, newdentry, stat->mode); 
     177                break; 
     178 
     179        case S_IFCHR: 
     180        case S_IFBLK: 
     181        case S_IFIFO: 
     182        case S_IFSOCK: 
     183                err = vfs_mknod(dir, newdentry, stat->mode, stat->rdev); 
     184                break; 
     185 
     186        case S_IFLNK: 
     187                err = vfs_symlink(dir, newdentry, link); 
     188                break; 
     189 
     190        default: 
     191                err = -EPERM; 
     192        } 
     193        if (err) { 
     194                if (ovl_dentry_is_opaque(dentry)) 
     195                        ovl_whiteout(upperdir, dentry); 
     196                dput(newdentry); 
     197                newdentry = ERR_PTR(err); 
     198        } else if (WARN_ON(!newdentry->d_inode)) { 
     199                /* 
     200                 * Not quite sure if non-instantiated dentry is legal or not. 
     201                 * VFS doesn't seem to care so check and warn here. 
     202                 */ 
     203                dput(newdentry); 
     204                newdentry = ERR_PTR(-ENOENT); 
     205        } 
     206 
     207out: 
     208        return newdentry; 
     209 
     210} 
     211 
     212static int ovl_set_opaque(struct dentry *upperdentry) 
     213{ 
     214        int err; 
     215        const struct cred *old_cred; 
     216        struct cred *override_cred; 
     217 
     218        override_cred = prepare_creds(); 
     219        if (!override_cred) 
     220                return -ENOMEM; 
     221 
     222        /* CAP_SYS_ADMIN for setxattr of "trusted" namespace */ 
     223        cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     224        old_cred = override_creds(override_cred); 
     225        err = vfs_setxattr(upperdentry, ovl_opaque_xattr, "y", 1, 0); 
     226        revert_creds(old_cred); 
     227        put_cred(override_cred); 
     228 
     229        return err; 
     230} 
     231 
     232static int ovl_remove_opaque(struct dentry *upperdentry) 
     233{ 
     234        int err; 
     235        const struct cred *old_cred; 
     236        struct cred *override_cred; 
     237 
     238        override_cred = prepare_creds(); 
     239        if (!override_cred) 
     240                return -ENOMEM; 
     241 
     242        /* CAP_SYS_ADMIN for removexattr of "trusted" namespace */ 
     243        cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     244        old_cred = override_creds(override_cred); 
     245        err = vfs_removexattr(upperdentry, ovl_opaque_xattr); 
     246        revert_creds(old_cred); 
     247        put_cred(override_cred); 
     248 
     249        return err; 
     250} 
     251 
     252static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, 
     253                         struct kstat *stat) 
     254{ 
     255        int err; 
     256        enum ovl_path_type type; 
     257        struct path realpath; 
     258 
     259        type = ovl_path_real(dentry, &realpath); 
     260        err = vfs_getattr(realpath.mnt, realpath.dentry, stat); 
     261        if (err) 
     262                return err; 
     263 
     264        stat->dev = dentry->d_sb->s_dev; 
     265        stat->ino = dentry->d_inode->i_ino; 
     266 
     267        /* 
     268         * It's probably not worth it to count subdirs to get the 
     269         * correct link count.  nlink=1 seems to pacify 'find' and 
     270         * other utilities. 
     271         */ 
     272        if (type == OVL_PATH_MERGE) 
     273                stat->nlink = 1; 
     274 
     275        return 0; 
     276} 
     277 
     278static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev, 
     279                             const char *link) 
     280{ 
     281        int err; 
     282        struct dentry *newdentry; 
     283        struct dentry *upperdir; 
     284        struct inode *inode; 
     285        struct kstat stat = { 
     286                .mode = mode, 
     287                .rdev = rdev, 
     288        }; 
     289 
     290        err = -ENOMEM; 
     291        inode = ovl_new_inode(dentry->d_sb, mode, dentry->d_fsdata); 
     292        if (!inode) 
     293                goto out; 
     294 
     295        err = ovl_copy_up(dentry->d_parent); 
     296        if (err) 
     297                goto out_iput; 
     298 
     299        upperdir = ovl_dentry_upper(dentry->d_parent); 
     300        mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); 
     301 
     302        newdentry = ovl_upper_create(upperdir, dentry, &stat, link); 
     303        err = PTR_ERR(newdentry); 
     304        if (IS_ERR(newdentry)) 
     305                goto out_unlock; 
     306 
     307        ovl_dentry_version_inc(dentry->d_parent); 
     308        if (ovl_dentry_is_opaque(dentry) && S_ISDIR(mode)) { 
     309                err = ovl_set_opaque(newdentry); 
     310                if (err) { 
     311                        vfs_rmdir(upperdir->d_inode, newdentry); 
     312                        ovl_whiteout(upperdir, dentry); 
     313                        goto out_dput; 
     314                } 
     315        } 
     316        ovl_dentry_update(dentry, newdentry); 
     317        d_instantiate(dentry, inode); 
     318        inode = NULL; 
     319        newdentry = NULL; 
     320        err = 0; 
     321 
     322out_dput: 
     323        dput(newdentry); 
     324out_unlock: 
     325        mutex_unlock(&upperdir->d_inode->i_mutex); 
     326out_iput: 
     327        iput(inode); 
     328out: 
     329        return err; 
     330} 
     331 
     332static int ovl_create(struct inode *dir, struct dentry *dentry, int mode, 
     333                        struct nameidata *nd) 
     334{ 
     335        return ovl_create_object(dentry, (mode & 07777) | S_IFREG, 0, NULL); 
     336} 
     337 
     338static int ovl_mkdir(struct inode *dir, struct dentry *dentry, int mode) 
     339{ 
     340        return ovl_create_object(dentry, (mode & 07777) | S_IFDIR, 0, NULL); 
     341} 
     342 
     343static int ovl_mknod(struct inode *dir, struct dentry *dentry, int mode, 
     344                       dev_t rdev) 
     345{ 
     346        return ovl_create_object(dentry, mode, rdev, NULL); 
     347} 
     348 
     349static int ovl_symlink(struct inode *dir, struct dentry *dentry, 
     350                         const char *link) 
     351{ 
     352        return ovl_create_object(dentry, S_IFLNK, 0, link); 
     353} 
     354 
     355static int ovl_do_remove(struct dentry *dentry, bool is_dir) 
     356{ 
     357        int err; 
     358        enum ovl_path_type type; 
     359        struct path realpath; 
     360        struct dentry *upperdir; 
     361 
     362        err = ovl_copy_up(dentry->d_parent); 
     363        if (err) 
     364                return err; 
     365 
     366        upperdir = ovl_dentry_upper(dentry->d_parent); 
     367        mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); 
     368        type = ovl_path_real(dentry, &realpath); 
     369        if (type != OVL_PATH_LOWER) { 
     370                err = -ESTALE; 
     371                if (realpath.dentry->d_parent != upperdir) 
     372                        goto out_d_drop; 
     373 
     374                /* FIXME: create whiteout up front and rename to target */ 
     375 
     376                if (is_dir) 
     377                        err = vfs_rmdir(upperdir->d_inode, realpath.dentry); 
     378                else 
     379                        err = vfs_unlink(upperdir->d_inode, realpath.dentry); 
     380                if (err) 
     381                        goto out_d_drop; 
     382 
     383                ovl_dentry_version_inc(dentry->d_parent); 
     384        } 
     385 
     386        if (type != OVL_PATH_UPPER || ovl_dentry_is_opaque(dentry)) 
     387                err = ovl_whiteout(upperdir, dentry); 
     388 
     389        /* 
     390         * Keeping this dentry hashed would mean having to release 
     391         * upperpath/lowerpath, which could only be done if we are the 
     392         * sole user of this dentry.  Too tricky...  Just unhash for 
     393         * now. 
     394         */ 
     395out_d_drop: 
     396        d_drop(dentry); 
     397        mutex_unlock(&upperdir->d_inode->i_mutex); 
     398 
     399        return err; 
     400} 
     401 
     402static int ovl_unlink(struct inode *dir, struct dentry *dentry) 
     403{ 
     404        return ovl_do_remove(dentry, false); 
     405} 
     406 
     407 
     408static int ovl_rmdir(struct inode *dir, struct dentry *dentry) 
     409{ 
     410        int err; 
     411        enum ovl_path_type type; 
     412 
     413        type = ovl_path_type(dentry); 
     414        if (type != OVL_PATH_UPPER) { 
     415                err = ovl_check_empty_and_clear(dentry, type); 
     416                if (err) 
     417                        return err; 
     418        } 
     419 
     420        return ovl_do_remove(dentry, true); 
     421} 
     422 
     423static int ovl_link(struct dentry *old, struct inode *newdir, 
     424                    struct dentry *new) 
     425{ 
     426        int err; 
     427        struct dentry *olddentry; 
     428        struct dentry *newdentry; 
     429        struct dentry *upperdir; 
     430 
     431        err = ovl_copy_up(old); 
     432        if (err) 
     433                goto out; 
     434 
     435        err = ovl_copy_up(new->d_parent); 
     436        if (err) 
     437                goto out; 
     438 
     439        upperdir = ovl_dentry_upper(new->d_parent); 
     440        mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); 
     441        newdentry = ovl_lookup_create(upperdir, new); 
     442        err = PTR_ERR(newdentry); 
     443        if (IS_ERR(newdentry)) 
     444                goto out_unlock; 
     445 
     446        olddentry = ovl_dentry_upper(old); 
     447        err = vfs_link(olddentry, upperdir->d_inode, newdentry); 
     448        if (!err) { 
     449                if (WARN_ON(!newdentry->d_inode)) { 
     450                        dput(newdentry); 
     451                        err = -ENOENT; 
     452                        goto out_unlock; 
     453                } 
     454 
     455                ovl_dentry_version_inc(new->d_parent); 
     456                ovl_dentry_update(new, newdentry); 
     457 
     458                ihold(old->d_inode); 
     459                d_instantiate(new, old->d_inode); 
     460        } else { 
     461                if (ovl_dentry_is_opaque(new)) 
     462                        ovl_whiteout(upperdir, new); 
     463                dput(newdentry); 
     464        } 
     465out_unlock: 
     466        mutex_unlock(&upperdir->d_inode->i_mutex); 
     467out: 
     468        return err; 
     469 
     470} 
     471 
     472static int ovl_rename(struct inode *olddir, struct dentry *old, 
     473                        struct inode *newdir, struct dentry *new) 
     474{ 
     475        int err; 
     476        enum ovl_path_type old_type; 
     477        enum ovl_path_type new_type; 
     478        struct dentry *old_upperdir; 
     479        struct dentry *new_upperdir; 
     480        struct dentry *olddentry; 
     481        struct dentry *newdentry; 
     482        struct dentry *trap; 
     483        bool old_opaque; 
     484        bool new_opaque; 
     485        bool new_create = false; 
     486        bool is_dir = S_ISDIR(old->d_inode->i_mode); 
     487 
     488        /* Don't copy up directory trees */ 
     489        old_type = ovl_path_type(old); 
     490        if (old_type != OVL_PATH_UPPER && is_dir) 
     491                return -EXDEV; 
     492 
     493        if (new->d_inode) { 
     494                new_type = ovl_path_type(new); 
     495 
     496                if (new_type == OVL_PATH_LOWER && old_type == OVL_PATH_LOWER) { 
     497                        if (ovl_dentry_lower(old)->d_inode == 
     498                            ovl_dentry_lower(new)->d_inode) 
     499                                return 0; 
     500                } 
     501                if (new_type != OVL_PATH_LOWER && old_type != OVL_PATH_LOWER) { 
     502                        if (ovl_dentry_upper(old)->d_inode == 
     503                            ovl_dentry_upper(new)->d_inode) 
     504                                return 0; 
     505                } 
     506 
     507                if (new_type != OVL_PATH_UPPER && 
     508                    S_ISDIR(new->d_inode->i_mode)) { 
     509                        err = ovl_check_empty_and_clear(new, new_type); 
     510                        if (err) 
     511                                return err; 
     512                } 
     513        } else { 
     514                new_type = OVL_PATH_UPPER; 
     515        } 
     516 
     517        err = ovl_copy_up(old); 
     518        if (err) 
     519                return err; 
     520 
     521        err = ovl_copy_up(new->d_parent); 
     522        if (err) 
     523                return err; 
     524 
     525        old_upperdir = ovl_dentry_upper(old->d_parent); 
     526        new_upperdir = ovl_dentry_upper(new->d_parent); 
     527 
     528        trap = lock_rename(new_upperdir, old_upperdir); 
     529 
     530        olddentry = ovl_dentry_upper(old); 
     531        newdentry = ovl_dentry_upper(new); 
     532        if (newdentry) { 
     533                dget(newdentry); 
     534        } else { 
     535                new_create = true; 
     536                newdentry = ovl_lookup_create(new_upperdir, new); 
     537                err = PTR_ERR(newdentry); 
     538                if (IS_ERR(newdentry)) 
     539                        goto out_unlock; 
     540        } 
     541 
     542        err = -ESTALE; 
     543        if (olddentry->d_parent != old_upperdir) 
     544                goto out_dput; 
     545        if (newdentry->d_parent != new_upperdir) 
     546                goto out_dput; 
     547        if (olddentry == trap) 
     548                goto out_dput; 
     549        if (newdentry == trap) 
     550                goto out_dput; 
     551 
     552        old_opaque = ovl_dentry_is_opaque(old); 
     553        new_opaque = ovl_dentry_is_opaque(new) || new_type != OVL_PATH_UPPER; 
     554 
     555        if (is_dir && !old_opaque && new_opaque) { 
     556                err = ovl_set_opaque(olddentry); 
     557                if (err) 
     558                        goto out_dput; 
     559        } 
     560 
     561        err = vfs_rename(old_upperdir->d_inode, olddentry, 
     562                         new_upperdir->d_inode, newdentry); 
     563 
     564        if (err) { 
     565                if (new_create && ovl_dentry_is_opaque(new)) 
     566                        ovl_whiteout(new_upperdir, new); 
     567                if (is_dir && !old_opaque && new_opaque) 
     568                        ovl_remove_opaque(olddentry); 
     569                goto out_dput; 
     570        } 
     571 
     572        if (old_type != OVL_PATH_UPPER || old_opaque) 
     573                err = ovl_whiteout(old_upperdir, old); 
     574        if (is_dir && old_opaque && !new_opaque) 
     575                ovl_remove_opaque(olddentry); 
     576 
     577        if (old_opaque != new_opaque) 
     578                ovl_dentry_set_opaque(old, new_opaque); 
     579 
     580        ovl_dentry_version_inc(old->d_parent); 
     581        ovl_dentry_version_inc(new->d_parent); 
     582 
     583out_dput: 
     584        dput(newdentry); 
     585out_unlock: 
     586        unlock_rename(new_upperdir, old_upperdir); 
     587        return err; 
     588} 
     589 
     590const struct inode_operations ovl_dir_inode_operations = { 
     591        .lookup         = ovl_lookup, 
     592        .mkdir          = ovl_mkdir, 
     593        .symlink        = ovl_symlink, 
     594        .unlink         = ovl_unlink, 
     595        .rmdir          = ovl_rmdir, 
     596        .rename         = ovl_rename, 
     597        .link           = ovl_link, 
     598        .setattr        = ovl_setattr, 
     599        .create         = ovl_create, 
     600        .mknod          = ovl_mknod, 
     601        .permission     = ovl_permission, 
     602        .getattr        = ovl_dir_getattr, 
     603        .setxattr       = ovl_setxattr, 
     604        .getxattr       = ovl_getxattr, 
     605        .listxattr      = ovl_listxattr, 
     606        .removexattr    = ovl_removexattr, 
     607}; 
  • new file fs/overlayfs/inode.c

    - +  
     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 
     15int ovl_setattr(struct dentry *dentry, struct iattr *attr) 
     16{ 
     17        struct dentry *upperdentry; 
     18        int err; 
     19 
     20        if ((attr->ia_valid & ATTR_SIZE) && !ovl_dentry_upper(dentry)) 
     21                err = ovl_copy_up_truncate(dentry, attr->ia_size); 
     22        else 
     23                err = ovl_copy_up(dentry); 
     24        if (err) 
     25                return err; 
     26 
     27        upperdentry = ovl_dentry_upper(dentry); 
     28 
     29        if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) 
     30                attr->ia_valid &= ~ATTR_MODE; 
     31 
     32        mutex_lock(&upperdentry->d_inode->i_mutex); 
     33        err = notify_change(upperdentry, attr); 
     34        mutex_unlock(&upperdentry->d_inode->i_mutex); 
     35 
     36        return err; 
     37} 
     38 
     39static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry, 
     40                         struct kstat *stat) 
     41{ 
     42        struct path realpath; 
     43 
     44        ovl_path_real(dentry, &realpath); 
     45        return vfs_getattr(realpath.mnt, realpath.dentry, stat); 
     46} 
     47 
     48int ovl_permission(struct inode *inode, int mask, unsigned int flags) 
     49{ 
     50        struct ovl_entry *oe; 
     51        struct dentry *alias = NULL; 
     52        struct inode *realinode; 
     53        struct dentry *realdentry; 
     54        bool is_upper; 
     55        int err; 
     56 
     57        if (S_ISDIR(inode->i_mode)) { 
     58                oe = inode->i_private; 
     59        } else if (flags & IPERM_FLAG_RCU) { 
     60                return -ECHILD; 
     61        } else { 
     62                /* 
     63                 * For non-directories find an alias and get the info 
     64                 * from there. 
     65                 */ 
     66                spin_lock(&inode->i_lock); 
     67                if (WARN_ON(list_empty(&inode->i_dentry))) { 
     68                        spin_unlock(&inode->i_lock); 
     69                        return -ENOENT; 
     70                } 
     71                alias = list_entry(inode->i_dentry.next, struct dentry, d_alias); 
     72                dget(alias); 
     73                spin_unlock(&inode->i_lock); 
     74                oe = alias->d_fsdata; 
     75        } 
     76 
     77        realdentry = ovl_entry_real(oe, &is_upper); 
     78 
     79        /* Careful in RCU walk mode */ 
     80        realinode = ACCESS_ONCE(realdentry->d_inode); 
     81        if (!realinode) { 
     82                WARN_ON(!(flags & IPERM_FLAG_RCU)); 
     83                err = -ENOENT; 
     84                goto out_dput; 
     85        } 
     86 
     87        if (mask & MAY_WRITE) { 
     88                umode_t mode = realinode->i_mode; 
     89 
     90                /* 
     91                 * Writes will always be redirected to upper layer, so 
     92                 * ignore lower layer being read-only. 
     93                 */ 
     94                err = -EROFS; 
     95                if (is_upper && IS_RDONLY(realinode) && 
     96                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) 
     97                        goto out_dput; 
     98 
     99                /* 
     100                 * Nobody gets write access to an immutable file. 
     101                 */ 
     102                err = -EACCES; 
     103                if (IS_IMMUTABLE(realinode)) 
     104                        goto out_dput; 
     105        } 
     106 
     107        if (realinode->i_op->permission) 
     108                err = realinode->i_op->permission(realinode, mask, flags); 
     109        else 
     110                err = generic_permission(realinode, mask, flags, 
     111                                         realinode->i_op->check_acl); 
     112out_dput: 
     113        dput(alias); 
     114        return err; 
     115} 
     116 
     117 
     118struct ovl_link_data { 
     119        struct dentry *realdentry; 
     120        void *cookie; 
     121}; 
     122 
     123static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd) 
     124{ 
     125        void *ret; 
     126        struct dentry *realdentry; 
     127        struct inode *realinode; 
     128 
     129        realdentry = ovl_dentry_real(dentry); 
     130        realinode = realdentry->d_inode; 
     131 
     132        if (WARN_ON(!realinode->i_op->follow_link)) 
     133                return ERR_PTR(-EPERM); 
     134 
     135        ret = realinode->i_op->follow_link(realdentry, nd); 
     136        if (IS_ERR(ret)) 
     137                return ret; 
     138 
     139        if (realinode->i_op->put_link) { 
     140                struct ovl_link_data *data; 
     141 
     142                data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL); 
     143                if (!data) { 
     144                        realinode->i_op->put_link(realdentry, nd, ret); 
     145                        return ERR_PTR(-ENOMEM); 
     146                } 
     147                data->realdentry = realdentry; 
     148                data->cookie = ret; 
     149 
     150                return data; 
     151        } else { 
     152                return NULL; 
     153        } 
     154} 
     155 
     156static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c) 
     157{ 
     158        struct inode *realinode; 
     159        struct ovl_link_data *data = c; 
     160 
     161        if (!data) 
     162                return; 
     163 
     164        realinode = data->realdentry->d_inode; 
     165        realinode->i_op->put_link(data->realdentry, nd, data->cookie); 
     166        kfree(data); 
     167} 
     168 
     169static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) 
     170{ 
     171        struct path realpath; 
     172        struct inode *realinode; 
     173 
     174        ovl_path_real(dentry, &realpath); 
     175        realinode = realpath.dentry->d_inode; 
     176 
     177        if (!realinode->i_op->readlink) 
     178                return -EINVAL; 
     179 
     180        touch_atime(realpath.mnt, realpath.dentry); 
     181 
     182        return realinode->i_op->readlink(realpath.dentry, buf, bufsiz); 
     183} 
     184 
     185 
     186static bool ovl_is_private_xattr(const char *name) 
     187{ 
     188        return strncmp(name, "trusted.overlay.", 14) == 0; 
     189} 
     190 
     191int ovl_setxattr(struct dentry *dentry, const char *name, 
     192                 const void *value, size_t size, int flags) 
     193{ 
     194        int err; 
     195        struct dentry *upperdentry; 
     196 
     197        if (ovl_is_private_xattr(name)) 
     198                return -EPERM; 
     199 
     200        err = ovl_copy_up(dentry); 
     201        if (err) 
     202                return err; 
     203 
     204        upperdentry = ovl_dentry_upper(dentry); 
     205        return  vfs_setxattr(upperdentry, name, value, size, flags); 
     206} 
     207 
     208ssize_t ovl_getxattr(struct dentry *dentry, const char *name, 
     209                     void *value, size_t size) 
     210{ 
     211        if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE && 
     212            ovl_is_private_xattr(name)) 
     213                return -ENODATA; 
     214 
     215        return vfs_getxattr(ovl_dentry_real(dentry), name, value, size); 
     216} 
     217 
     218ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) 
     219{ 
     220        ssize_t res; 
     221        int off; 
     222 
     223        res = vfs_listxattr(ovl_dentry_real(dentry), list, size); 
     224        if (res <= 0 || size == 0) 
     225                return res; 
     226 
     227        if (ovl_path_type(dentry->d_parent) != OVL_PATH_MERGE) 
     228                return res; 
     229 
     230        /* filter out private xattrs */ 
     231        for (off = 0; off < res;) { 
     232                char *s = list + off; 
     233                size_t slen = strlen(s) + 1; 
     234 
     235                BUG_ON(off + slen > res); 
     236 
     237                if (ovl_is_private_xattr(s)) { 
     238                        res -= slen; 
     239                        memmove(s, s + slen, res - off); 
     240                } else { 
     241                        off += slen; 
     242                } 
     243        } 
     244 
     245        return res; 
     246} 
     247 
     248int ovl_removexattr(struct dentry *dentry, const char *name) 
     249{ 
     250        int err; 
     251        struct path realpath; 
     252        enum ovl_path_type type; 
     253 
     254        if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE && 
     255            ovl_is_private_xattr(name)) 
     256                return -ENODATA; 
     257 
     258        type = ovl_path_real(dentry, &realpath); 
     259        if (type == OVL_PATH_LOWER) { 
     260                err = vfs_getxattr(realpath.dentry, name, NULL, 0); 
     261                if (err < 0) 
     262                        return err; 
     263 
     264                err = ovl_copy_up(dentry); 
     265                if (err) 
     266                        return err; 
     267 
     268                ovl_path_upper(dentry, &realpath); 
     269        } 
     270 
     271        return vfs_removexattr(realpath.dentry, name); 
     272} 
     273 
     274static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, 
     275                                  struct dentry *realdentry) 
     276{ 
     277        if (type != OVL_PATH_LOWER) 
     278                return false; 
     279 
     280        if (special_file(realdentry->d_inode->i_mode)) 
     281                return false; 
     282 
     283        if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC)) 
     284                return false; 
     285 
     286        return true; 
     287} 
     288 
     289static struct file *ovl_open(struct dentry *dentry, int flags, 
     290                             const struct cred *cred) 
     291{ 
     292        int err; 
     293        struct path realpath; 
     294        enum ovl_path_type type; 
     295 
     296        type = ovl_path_real(dentry, &realpath); 
     297        if (ovl_open_need_copy_up(flags, type, realpath.dentry)) { 
     298                if (flags & O_TRUNC) 
     299                        err = ovl_copy_up_truncate(dentry, 0); 
     300                else 
     301                        err = ovl_copy_up(dentry); 
     302                if (err) 
     303                        return ERR_PTR(err); 
     304 
     305                ovl_path_upper(dentry, &realpath); 
     306        } 
     307 
     308        return vfs_open(&realpath, flags, cred); 
     309} 
     310 
     311static const struct inode_operations ovl_file_inode_operations = { 
     312        .setattr        = ovl_setattr, 
     313        .permission     = ovl_permission, 
     314        .getattr        = ovl_getattr, 
     315        .setxattr       = ovl_setxattr, 
     316        .getxattr       = ovl_getxattr, 
     317        .listxattr      = ovl_listxattr, 
     318        .removexattr    = ovl_removexattr, 
     319        .open           = ovl_open, 
     320}; 
     321 
     322static const struct inode_operations ovl_symlink_inode_operations = { 
     323        .setattr        = ovl_setattr, 
     324        .follow_link    = ovl_follow_link, 
     325        .put_link       = ovl_put_link, 
     326        .readlink       = ovl_readlink, 
     327        .getattr        = ovl_getattr, 
     328        .setxattr       = ovl_setxattr, 
     329        .getxattr       = ovl_getxattr, 
     330        .listxattr      = ovl_listxattr, 
     331        .removexattr    = ovl_removexattr, 
     332}; 
     333 
     334struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, 
     335                            struct ovl_entry *oe) 
     336{ 
     337        struct inode *inode; 
     338 
     339        inode = new_inode(sb); 
     340        if (!inode) 
     341                return NULL; 
     342 
     343        mode &= S_IFMT; 
     344 
     345        inode->i_ino = get_next_ino(); 
     346        inode->i_mode = mode; 
     347        inode->i_flags |= S_NOATIME | S_NOCMTIME; 
     348 
     349        switch (mode) { 
     350        case S_IFDIR: 
     351                inode->i_private = oe; 
     352                inode->i_op = &ovl_dir_inode_operations; 
     353                inode->i_fop = &ovl_dir_operations; 
     354                break; 
     355 
     356        case S_IFLNK: 
     357                inode->i_op = &ovl_symlink_inode_operations; 
     358                break; 
     359 
     360        case S_IFREG: 
     361        case S_IFSOCK: 
     362        case S_IFBLK: 
     363        case S_IFCHR: 
     364        case S_IFIFO: 
     365                inode->i_op = &ovl_file_inode_operations; 
     366                break; 
     367 
     368        default: 
     369                WARN(1, "illegal file type: %i\n", mode); 
     370                inode = NULL; 
     371        } 
     372 
     373        return inode; 
     374 
     375} 
  • new file fs/overlayfs/overlayfs.h

    - +  
     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 
     10struct ovl_entry; 
     11 
     12enum ovl_path_type { 
     13        OVL_PATH_UPPER, 
     14        OVL_PATH_MERGE, 
     15        OVL_PATH_LOWER, 
     16}; 
     17 
     18extern const char *ovl_opaque_xattr; 
     19extern const char *ovl_whiteout_xattr; 
     20extern const struct dentry_operations ovl_dentry_operations; 
     21 
     22enum ovl_path_type ovl_path_type(struct dentry *dentry); 
     23u64 ovl_dentry_version_get(struct dentry *dentry); 
     24void ovl_dentry_version_inc(struct dentry *dentry); 
     25void ovl_path_upper(struct dentry *dentry, struct path *path); 
     26void ovl_path_lower(struct dentry *dentry, struct path *path); 
     27enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); 
     28struct dentry *ovl_dentry_upper(struct dentry *dentry); 
     29struct dentry *ovl_dentry_lower(struct dentry *dentry); 
     30struct dentry *ovl_dentry_real(struct dentry *dentry); 
     31struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper); 
     32bool ovl_dentry_is_opaque(struct dentry *dentry); 
     33void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque); 
     34bool ovl_is_whiteout(struct dentry *dentry); 
     35void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry); 
     36int ovl_do_lookup(struct dentry *dentry); 
     37 
     38struct dentry *ovl_upper_create(struct dentry *upperdir, struct dentry *dentry, 
     39                                struct kstat *stat, const char *link); 
     40 
     41/* readdir.c */ 
     42extern const struct file_operations ovl_dir_operations; 
     43int ovl_check_empty_and_clear(struct dentry *dentry, enum ovl_path_type type); 
     44 
     45/* inode.c */ 
     46int ovl_setattr(struct dentry *dentry, struct iattr *attr); 
     47int ovl_permission(struct inode *inode, int mask, unsigned int flags); 
     48int ovl_setxattr(struct dentry *dentry, const char *name, 
     49                 const void *value, size_t size, int flags); 
     50ssize_t ovl_getxattr(struct dentry *dentry, const char *name, 
     51                     void *value, size_t size); 
     52ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); 
     53int ovl_removexattr(struct dentry *dentry, const char *name); 
     54 
     55struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, 
     56                            struct ovl_entry *oe); 
     57/* dir.c */ 
     58extern const struct inode_operations ovl_dir_inode_operations; 
     59 
     60/* copy_up.c */ 
     61int ovl_copy_up(struct dentry *dentry); 
     62int ovl_copy_up_truncate(struct dentry *dentry, loff_t size); 
  • new file fs/overlayfs/readdir.c

    - +  
     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/namei.h> 
     13#include <linux/file.h> 
     14#include <linux/xattr.h> 
     15#include <linux/rbtree.h> 
     16#include <linux/security.h> 
     17#include "overlayfs.h" 
     18 
     19struct ovl_cache_entry { 
     20        const char *name; 
     21        unsigned int len; 
     22        unsigned int type; 
     23        u64 ino; 
     24        bool is_whiteout; 
     25        struct list_head l_node; 
     26        struct rb_node node; 
     27}; 
     28 
     29struct ovl_readdir_data { 
     30        struct rb_root *root; 
     31        struct list_head *list; 
     32        struct list_head *middle; 
     33        struct dentry *dir; 
     34        int count; 
     35        int err; 
     36}; 
     37 
     38struct ovl_dir_file { 
     39        bool is_real; 
     40        bool is_cached; 
     41        struct list_head cursor; 
     42        u64 cache_version; 
     43        struct list_head cache; 
     44        struct file *realfile; 
     45}; 
     46 
     47static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n) 
     48{ 
     49        return container_of(n, struct ovl_cache_entry, node); 
     50} 
     51 
     52static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root, 
     53                                                    const char *name, int len) 
     54{ 
     55        struct rb_node *node = root->rb_node; 
     56        int cmp; 
     57 
     58        while (node) { 
     59                struct ovl_cache_entry *p = ovl_cache_entry_from_node(node); 
     60 
     61                cmp = strncmp(name, p->name, len); 
     62                if (cmp > 0) 
     63                        node = p->node.rb_right; 
     64                else if (cmp < 0 || len < p->len) 
     65                        node = p->node.rb_left; 
     66                else 
     67                        return p; 
     68        } 
     69 
     70        return NULL; 
     71} 
     72 
     73static struct ovl_cache_entry *ovl_cache_entry_new(const char *name, int len, 
     74                                                   u64 ino, unsigned int d_type) 
     75{ 
     76        struct ovl_cache_entry *p; 
     77 
     78        p = kmalloc(sizeof(*p) + len + 1, GFP_KERNEL); 
     79        if (p) { 
     80                char *name_copy = (char *) (p + 1); 
     81                memcpy(name_copy, name, len); 
     82                name_copy[len] = '\0'; 
     83                p->name = name_copy; 
     84                p->len = len; 
     85                p->type = d_type; 
     86                p->ino = ino; 
     87                p->is_whiteout = false; 
     88        } 
     89 
     90        return p; 
     91} 
     92 
     93static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd, 
     94                                  const char *name, int len, u64 ino, 
     95                                  unsigned int d_type) 
     96{ 
     97        struct rb_node **newp = &rdd->root->rb_node; 
     98        struct rb_node *parent = NULL; 
     99        struct ovl_cache_entry *p; 
     100 
     101        while (*newp) { 
     102                int cmp; 
     103                struct ovl_cache_entry *tmp; 
     104 
     105                parent = *newp; 
     106                tmp = ovl_cache_entry_from_node(*newp); 
     107                cmp = strncmp(name, tmp->name, len); 
     108                if (cmp > 0) 
     109                        newp = &tmp->node.rb_right; 
     110                else if (cmp < 0 || len < tmp->len) 
     111                        newp = &tmp->node.rb_left; 
     112                else 
     113                        return 0; 
     114        } 
     115 
     116        p = ovl_cache_entry_new(name, len, ino, d_type); 
     117        if (p == NULL) 
     118                return -ENOMEM; 
     119 
     120        list_add_tail(&p->l_node, rdd->list); 
     121        rb_link_node(&p->node, parent, newp); 
     122        rb_insert_color(&p->node, rdd->root); 
     123 
     124        return 0; 
     125} 
     126 
     127static int ovl_fill_lower(void *buf, const char *name, int namelen, 
     128                            loff_t offset, u64 ino, unsigned int d_type) 
     129{ 
     130        struct ovl_readdir_data *rdd = buf; 
     131        struct ovl_cache_entry *p; 
     132 
     133        rdd->count++; 
     134        p = ovl_cache_entry_find(rdd->root, name, namelen); 
     135        if (p) { 
     136                list_move_tail(&p->l_node, rdd->middle); 
     137        } else { 
     138                p = ovl_cache_entry_new(name, namelen, ino, d_type); 
     139                if (p == NULL) 
     140                        rdd->err = -ENOMEM; 
     141                else 
     142                        list_add_tail(&p->l_node, rdd->middle); 
     143        } 
     144 
     145        return rdd->err; 
     146} 
     147 
     148static void ovl_cache_free(struct list_head *list) 
     149{ 
     150        struct ovl_cache_entry *p; 
     151        struct ovl_cache_entry *n; 
     152 
     153        list_for_each_entry_safe(p, n, list, l_node) 
     154                kfree(p); 
     155 
     156        INIT_LIST_HEAD(list); 
     157} 
     158 
     159static int ovl_fill_upper(void *buf, const char *name, int namelen, 
     160                          loff_t offset, u64 ino, unsigned int d_type) 
     161{ 
     162        struct ovl_readdir_data *rdd = buf; 
     163 
     164        rdd->count++; 
     165        return ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type); 
     166} 
     167 
     168static int ovl_dir_read(struct path *realpath, struct ovl_readdir_data *rdd, 
     169                          filldir_t filler) 
     170{ 
     171        struct file *realfile; 
     172        int err; 
     173 
     174        realfile = vfs_open(realpath, O_RDONLY | O_DIRECTORY, current_cred()); 
     175        if (IS_ERR(realfile)) 
     176                return PTR_ERR(realfile); 
     177 
     178        do { 
     179                rdd->count = 0; 
     180                rdd->err = 0; 
     181                err = vfs_readdir(realfile, filler, rdd); 
     182                if (err >= 0) 
     183                        err = rdd->err; 
     184        } while (!err && rdd->count); 
     185        fput(realfile); 
     186 
     187        return 0; 
     188} 
     189 
     190static void ovl_dir_reset(struct file *file) 
     191{ 
     192        struct ovl_dir_file *od = file->private_data; 
     193        enum ovl_path_type type = ovl_path_type(file->f_path.dentry); 
     194 
     195        if (ovl_dentry_version_get(file->f_path.dentry) != od->cache_version) { 
     196                list_del_init(&od->cursor); 
     197                ovl_cache_free(&od->cache); 
     198                od->is_cached = false; 
     199        } 
     200        WARN_ON(!od->is_real && type != OVL_PATH_MERGE); 
     201        if (od->is_real && type == OVL_PATH_MERGE) { 
     202                fput(od->realfile); 
     203                od->realfile = NULL; 
     204                od->is_real = false; 
     205        } 
     206} 
     207 
     208static int ovl_dir_mark_whiteouts(struct ovl_readdir_data *rdd) 
     209{ 
     210        struct ovl_cache_entry *p; 
     211        struct dentry *dentry; 
     212        const struct cred *old_cred; 
     213        struct cred *override_cred; 
     214 
     215        override_cred = prepare_creds(); 
     216        if (!override_cred) { 
     217                ovl_cache_free(rdd->list); 
     218                return -ENOMEM; 
     219        } 
     220 
     221        /* 
     222         * CAP_SYS_ADMIN for getxattr 
     223         * CAP_DAC_OVERRIDE for lookup 
     224         */ 
     225        cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     226        cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); 
     227        old_cred = override_creds(override_cred); 
     228 
     229        mutex_lock(&rdd->dir->d_inode->i_mutex); 
     230        list_for_each_entry(p, rdd->list, l_node) { 
     231                if (p->type != DT_LNK) 
     232                        continue; 
     233 
     234                dentry = lookup_one_len(p->name, rdd->dir, p->len); 
     235                if (IS_ERR(dentry)) 
     236                        continue; 
     237 
     238                p->is_whiteout = ovl_is_whiteout(dentry); 
     239                dput(dentry); 
     240        } 
     241        mutex_unlock(&rdd->dir->d_inode->i_mutex); 
     242 
     243        revert_creds(old_cred); 
     244        put_cred(override_cred); 
     245 
     246        return 0; 
     247} 
     248 
     249static int ovl_dir_read_merged(struct path *upperpath, struct path *lowerpath, 
     250                               struct ovl_readdir_data *rdd) 
     251{ 
     252        int err; 
     253        struct rb_root root = RB_ROOT; 
     254        struct list_head middle; 
     255 
     256        rdd->root = &root; 
     257        if (upperpath->dentry) { 
     258                rdd->dir = upperpath->dentry; 
     259                err = ovl_dir_read(upperpath, rdd, ovl_fill_upper); 
     260                if (err) 
     261                        goto out; 
     262 
     263                err = ovl_dir_mark_whiteouts(rdd); 
     264                if (err) 
     265                        goto out; 
     266        } 
     267        /* 
     268         * Insert lowerpath entries before upperpath ones, this allows 
     269         * offsets to be reasonably constant 
     270         */ 
     271        list_add(&middle, rdd->list); 
     272        rdd->middle = &middle; 
     273        err = ovl_dir_read(lowerpath, rdd, ovl_fill_lower); 
     274        list_del(&middle); 
     275out: 
     276        rdd->root = NULL; 
     277 
     278        return err; 
     279} 
     280 
     281static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos) 
     282{ 
     283        struct list_head *l; 
     284        loff_t off; 
     285 
     286        l = od->cache.next; 
     287        for (off = 0; off < pos; off++) { 
     288                if (l == &od->cache) 
     289                        break; 
     290                l = l->next; 
     291        } 
     292        list_move_tail(&od->cursor, l); 
     293} 
     294 
     295static int ovl_readdir(struct file *file, void *buf, filldir_t filler) 
     296{ 
     297        struct ovl_dir_file *od = file->private_data; 
     298        int res; 
     299 
     300        if (!file->f_pos) 
     301                ovl_dir_reset(file); 
     302 
     303        if (od->is_real) { 
     304                res = vfs_readdir(od->realfile, filler, buf); 
     305                file->f_pos = od->realfile->f_pos; 
     306 
     307                return res; 
     308        } 
     309 
     310        if (!od->is_cached) { 
     311                struct path lowerpath; 
     312                struct path upperpath; 
     313                struct ovl_readdir_data rdd = { .list = &od->cache }; 
     314 
     315                ovl_path_lower(file->f_path.dentry, &lowerpath); 
     316                ovl_path_upper(file->f_path.dentry, &upperpath); 
     317 
     318                res = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd); 
     319                if (res) { 
     320                        ovl_cache_free(rdd.list); 
     321                        return res; 
     322                } 
     323 
     324                od->cache_version = ovl_dentry_version_get(file->f_path.dentry); 
     325                od->is_cached = true; 
     326 
     327                ovl_seek_cursor(od, file->f_pos); 
     328        } 
     329 
     330        while (od->cursor.next != &od->cache) { 
     331                int over; 
     332                loff_t off; 
     333                struct ovl_cache_entry *p; 
     334 
     335                p = list_entry(od->cursor.next, struct ovl_cache_entry, l_node); 
     336                off = file->f_pos; 
     337                if (!p->is_whiteout) { 
     338                        over = filler(buf, p->name, p->len, off, p->ino, p->type); 
     339                        if (over) 
     340                                break; 
     341                } 
     342                file->f_pos++; 
     343                list_move(&od->cursor, &p->l_node); 
     344        } 
     345 
     346        return 0; 
     347} 
     348 
     349static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin) 
     350{ 
     351        loff_t res; 
     352        struct ovl_dir_file *od = file->private_data; 
     353 
     354        mutex_lock(&file->f_dentry->d_inode->i_mutex); 
     355        if (!file->f_pos) 
     356                ovl_dir_reset(file); 
     357 
     358        if (od->is_real) { 
     359                res = vfs_llseek(od->realfile, offset, origin); 
     360                file->f_pos = od->realfile->f_pos; 
     361        } else { 
     362                res = -EINVAL; 
     363 
     364                switch (origin) { 
     365                case SEEK_CUR: 
     366                        offset += file->f_pos; 
     367                        break; 
     368                case SEEK_SET: 
     369                        break; 
     370                default: 
     371                        goto out_unlock; 
     372                } 
     373                if (offset < 0) 
     374                        goto out_unlock; 
     375 
     376                if (offset != file->f_pos) { 
     377                        file->f_pos = offset; 
     378                        if (od->is_cached) 
     379                                ovl_seek_cursor(od, offset); 
     380                } 
     381                res = offset; 
     382        } 
     383out_unlock: 
     384        mutex_unlock(&file->f_dentry->d_inode->i_mutex); 
     385 
     386        return res; 
     387} 
     388 
     389static int ovl_dir_fsync(struct file *file, int datasync) 
     390{ 
     391        struct ovl_dir_file *od = file->private_data; 
     392 
     393        /* May need to reopen directory if it got copied up */ 
     394        if (!od->realfile) { 
     395                struct path upperpath; 
     396 
     397                ovl_path_upper(file->f_path.dentry, &upperpath); 
     398                od->realfile = vfs_open(&upperpath, O_RDONLY, current_cred()); 
     399                if (IS_ERR(od->realfile)) 
     400                        return PTR_ERR(od->realfile); 
     401        } 
     402 
     403        return vfs_fsync(od->realfile, datasync); 
     404} 
     405 
     406static int ovl_dir_release(struct inode *inode, struct file *file) 
     407{ 
     408        struct ovl_dir_file *od = file->private_data; 
     409 
     410        list_del(&od->cursor); 
     411        ovl_cache_free(&od->cache); 
     412        if (od->realfile) 
     413                fput(od->realfile); 
     414        kfree(od); 
     415 
     416        return 0; 
     417} 
     418 
     419static int ovl_dir_open(struct inode *inode, struct file *file) 
     420{ 
     421        struct path realpath; 
     422        struct file *realfile; 
     423        struct ovl_dir_file *od; 
     424        enum ovl_path_type type; 
     425 
     426        od = kzalloc(sizeof(struct ovl_dir_file), GFP_KERNEL); 
     427        if (!od) 
     428                return -ENOMEM; 
     429 
     430        type = ovl_path_real(file->f_path.dentry, &realpath); 
     431        realfile = vfs_open(&realpath, file->f_flags, current_cred()); 
     432        if (IS_ERR(realfile)) { 
     433                kfree(od); 
     434                return PTR_ERR(realfile); 
     435        } 
     436        INIT_LIST_HEAD(&od->cache); 
     437        INIT_LIST_HEAD(&od->cursor); 
     438        od->is_cached = false; 
     439        od->realfile = realfile; 
     440        od->is_real = (type != OVL_PATH_MERGE); 
     441        file->private_data = od; 
     442 
     443        return 0; 
     444} 
     445 
     446const struct file_operations ovl_dir_operations = { 
     447        .read           = generic_read_dir, 
     448        .open           = ovl_dir_open, 
     449        .readdir        = ovl_readdir, 
     450        .llseek         = ovl_dir_llseek, 
     451        .fsync          = ovl_dir_fsync, 
     452        .release        = ovl_dir_release, 
     453}; 
     454 
     455static int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) 
     456{ 
     457        int err; 
     458        struct path lowerpath; 
     459        struct path upperpath; 
     460        struct ovl_cache_entry *p; 
     461        struct ovl_readdir_data rdd = { .list = list }; 
     462 
     463        ovl_path_upper(dentry, &upperpath); 
     464        ovl_path_lower(dentry, &lowerpath); 
     465 
     466        err = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd); 
     467        if (err) 
     468                return err; 
     469 
     470        err = 0; 
     471 
     472        list_for_each_entry(p, list, l_node) { 
     473                if (p->is_whiteout) 
     474                        continue; 
     475 
     476                if (p->name[0] == '.') { 
     477                        if (p->len == 1) 
     478                                continue; 
     479                        if (p->len == 2 && p->name[1] == '.') 
     480                                continue; 
     481                } 
     482                err = -ENOTEMPTY; 
     483                break; 
     484        } 
     485 
     486        return err; 
     487} 
     488 
     489static int ovl_remove_whiteouts(struct dentry *dir, struct list_head *list) 
     490{ 
     491        struct path upperpath; 
     492        struct dentry *upperdir; 
     493        struct ovl_cache_entry *p; 
     494        const struct cred *old_cred; 
     495        struct cred *override_cred; 
     496        int err; 
     497 
     498        ovl_path_upper(dir, &upperpath); 
     499        upperdir = upperpath.dentry; 
     500 
     501        override_cred = prepare_creds(); 
     502        if (!override_cred) 
     503                return -ENOMEM; 
     504 
     505        /* 
     506         * CAP_DAC_OVERRIDE for lookup and unlink 
     507         * CAP_SYS_ADMIN for setxattr of "trusted" namespace 
     508         * CAP_FOWNER for unlink in sticky directory 
     509         */ 
     510        cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); 
     511        cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     512        cap_raise(override_cred->cap_effective, CAP_FOWNER); 
     513        old_cred = override_creds(override_cred); 
     514 
     515        err = vfs_setxattr(upperdir, ovl_opaque_xattr, "y", 1, 0); 
     516        if (err) 
     517                goto out_revert_creds; 
     518 
     519        mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); 
     520        list_for_each_entry(p, list, l_node) { 
     521                struct dentry *dentry; 
     522                int ret; 
     523 
     524                if (!p->is_whiteout) 
     525                        continue; 
     526 
     527                dentry = lookup_one_len(p->name, upperdir, p->len); 
     528                if (IS_ERR(dentry)) { 
     529                        printk(KERN_WARNING "overlayfs: failed to lookup whiteout %.*s: %li\n", p->len, p->name, PTR_ERR(dentry)); 
     530                        continue; 
     531                } 
     532                ret = vfs_unlink(upperdir->d_inode, dentry); 
     533                dput(dentry); 
     534                if (ret) 
     535                        printk(KERN_WARNING "overlayfs: failed to unlink whiteout %.*s: %i\n", p->len, p->name, ret); 
     536        } 
     537        mutex_unlock(&upperdir->d_inode->i_mutex); 
     538 
     539out_revert_creds: 
     540        revert_creds(old_cred); 
     541        put_cred(override_cred); 
     542 
     543        return err; 
     544} 
     545 
     546int ovl_check_empty_and_clear(struct dentry *dentry, enum ovl_path_type type) 
     547{ 
     548        int err; 
     549        LIST_HEAD(list); 
     550 
     551        err = ovl_check_empty_dir(dentry, &list); 
     552        if (!err && type == OVL_PATH_MERGE) 
     553                err = ovl_remove_whiteouts(dentry, &list); 
     554 
     555        ovl_cache_free(&list); 
     556 
     557        return err; 
     558} 
  • new file fs/overlayfs/super.c

    - +  
     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/namei.h> 
     12#include <linux/xattr.h> 
     13#include <linux/security.h> 
     14#include <linux/mount.h> 
     15#include <linux/slab.h> 
     16#include <linux/parser.h> 
     17#include <linux/module.h> 
     18#include <linux/seq_file.h> 
     19#include "overlayfs.h" 
     20 
     21MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); 
     22MODULE_DESCRIPTION("Overlay filesystem"); 
     23MODULE_LICENSE("GPL"); 
     24 
     25struct ovl_config { 
     26        char *lowerdir; 
     27        char *upperdir; 
     28}; 
     29 
     30/* private information held for overlayfs's superblock */ 
     31struct ovl_fs { 
     32        struct vfsmount *upper_mnt; 
     33        struct vfsmount *lower_mnt; 
     34        /* pathnames of lower and upper dirs, for show_options */ 
     35        struct ovl_config config; 
     36}; 
     37 
     38/* private information held for every overlayfs dentry */ 
     39struct ovl_entry { 
     40        /* 
     41         * Keep "double reference" on upper dentries, so that 
     42         * d_delete() doesn't think it's OK to reset d_inode to NULL. 
     43         */ 
     44        struct dentry *__upperdentry; 
     45        struct dentry *lowerdentry; 
     46        union { 
     47                struct { 
     48                        u64 version; 
     49                        bool opaque; 
     50                }; 
     51                struct rcu_head rcu; 
     52        }; 
     53}; 
     54 
     55const char *ovl_whiteout_xattr = "trusted.overlay.whiteout"; 
     56const char *ovl_opaque_xattr = "trusted.overlay.opaque"; 
     57 
     58 
     59enum ovl_path_type ovl_path_type(struct dentry *dentry) 
     60{ 
     61        struct ovl_entry *oe = dentry->d_fsdata; 
     62 
     63        if (oe->__upperdentry) { 
     64                if (oe->lowerdentry && S_ISDIR(dentry->d_inode->i_mode)) 
     65                        return OVL_PATH_MERGE; 
     66                else 
     67                        return OVL_PATH_UPPER; 
     68        } else { 
     69                return OVL_PATH_LOWER; 
     70        } 
     71} 
     72 
     73static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) 
     74{ 
     75        struct dentry *upperdentry = ACCESS_ONCE(oe->__upperdentry); 
     76        smp_read_barrier_depends(); 
     77        return upperdentry; 
     78} 
     79 
     80void ovl_path_upper(struct dentry *dentry, struct path *path) 
     81{ 
     82        struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 
     83        struct ovl_entry *oe = dentry->d_fsdata; 
     84 
     85        path->mnt = ofs->upper_mnt; 
     86        path->dentry = ovl_upperdentry_dereference(oe); 
     87} 
     88 
     89void ovl_path_lower(struct dentry *dentry, struct path *path) 
     90{ 
     91        struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 
     92        struct ovl_entry *oe = dentry->d_fsdata; 
     93 
     94        path->mnt = ofs->lower_mnt; 
     95        path->dentry = oe->lowerdentry; 
     96} 
     97 
     98enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path) 
     99{ 
     100 
     101        enum ovl_path_type type = ovl_path_type(dentry); 
     102 
     103        if (type == OVL_PATH_LOWER) 
     104                ovl_path_lower(dentry, path); 
     105        else 
     106                ovl_path_upper(dentry, path); 
     107 
     108        return type; 
     109} 
     110 
     111struct dentry *ovl_dentry_upper(struct dentry *dentry) 
     112{ 
     113        struct ovl_entry *oe = dentry->d_fsdata; 
     114 
     115        return ovl_upperdentry_dereference(oe); 
     116} 
     117 
     118struct dentry *ovl_dentry_lower(struct dentry *dentry) 
     119{ 
     120        struct ovl_entry *oe = dentry->d_fsdata; 
     121 
     122        return oe->lowerdentry; 
     123} 
     124 
     125struct dentry *ovl_dentry_real(struct dentry *dentry) 
     126{ 
     127        struct ovl_entry *oe = dentry->d_fsdata; 
     128        struct dentry *realdentry; 
     129 
     130        realdentry = ovl_upperdentry_dereference(oe); 
     131        if (!realdentry) 
     132                realdentry = oe->lowerdentry; 
     133 
     134        return realdentry; 
     135} 
     136 
     137struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper) 
     138{ 
     139        struct dentry *realdentry; 
     140 
     141        realdentry = ovl_upperdentry_dereference(oe); 
     142        if (realdentry) { 
     143                *is_upper = true; 
     144        } else { 
     145                realdentry = oe->lowerdentry; 
     146                *is_upper = false; 
     147        } 
     148        return realdentry; 
     149} 
     150 
     151bool ovl_dentry_is_opaque(struct dentry *dentry) 
     152{ 
     153        struct ovl_entry *oe = dentry->d_fsdata; 
     154        return oe->opaque; 
     155} 
     156 
     157void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque) 
     158{ 
     159        struct ovl_entry *oe = dentry->d_fsdata; 
     160        oe->opaque = opaque; 
     161} 
     162 
     163void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) 
     164{ 
     165        struct ovl_entry *oe = dentry->d_fsdata; 
     166 
     167        WARN_ON(!mutex_is_locked(&upperdentry->d_parent->d_inode->i_mutex)); 
     168        WARN_ON(oe->__upperdentry); 
     169        BUG_ON(!upperdentry->d_inode); 
     170        smp_wmb(); 
     171        oe->__upperdentry = dget(upperdentry); 
     172} 
     173 
     174void ovl_dentry_version_inc(struct dentry *dentry) 
     175{ 
     176        struct ovl_entry *oe = dentry->d_fsdata; 
     177 
     178        WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); 
     179        oe->version++; 
     180} 
     181 
     182u64 ovl_dentry_version_get(struct dentry *dentry) 
     183{ 
     184        struct ovl_entry *oe = dentry->d_fsdata; 
     185 
     186        WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); 
     187        return oe->version; 
     188} 
     189 
     190bool ovl_is_whiteout(struct dentry *dentry) 
     191{ 
     192        int res; 
     193        char val; 
     194 
     195        if (!dentry) 
     196                return false; 
     197        if (!dentry->d_inode) 
     198                return false; 
     199        if (!S_ISLNK(dentry->d_inode->i_mode)) 
     200                return false; 
     201 
     202        res = vfs_getxattr(dentry, ovl_whiteout_xattr, &val, 1); 
     203        if (res == 1 && val == 'y') 
     204                return true; 
     205 
     206        return false; 
     207} 
     208 
     209static bool ovl_is_opaquedir(struct dentry *dentry) 
     210{ 
     211        int res; 
     212        char val; 
     213 
     214        if (!S_ISDIR(dentry->d_inode->i_mode)) 
     215                return false; 
     216 
     217        res = vfs_getxattr(dentry, ovl_opaque_xattr, &val, 1); 
     218        if (res == 1 && val == 'y') 
     219                return true; 
     220 
     221        return false; 
     222} 
     223 
     224static void ovl_entry_free(struct rcu_head *head) 
     225{ 
     226        struct ovl_entry *oe = container_of(head, struct ovl_entry, rcu); 
     227        kfree(oe); 
     228} 
     229 
     230static void ovl_dentry_release(struct dentry *dentry) 
     231{ 
     232        struct ovl_entry *oe = dentry->d_fsdata; 
     233 
     234        if (oe) { 
     235                dput(oe->__upperdentry); 
     236                dput(oe->__upperdentry); 
     237                dput(oe->lowerdentry); 
     238                call_rcu(&oe->rcu, ovl_entry_free); 
     239        } 
     240} 
     241 
     242const struct dentry_operations ovl_dentry_operations = { 
     243        .d_release = ovl_dentry_release, 
     244}; 
     245 
     246static struct ovl_entry *ovl_alloc_entry(void) 
     247{ 
     248        return kzalloc(sizeof(struct ovl_entry), GFP_KERNEL); 
     249} 
     250 
     251static struct dentry *ovl_lookup_real(struct dentry *dir, struct qstr *name) 
     252{ 
     253        struct dentry *dentry; 
     254 
     255        mutex_lock(&dir->d_inode->i_mutex); 
     256        dentry = lookup_one_len(name->name, dir, name->len); 
     257        mutex_unlock(&dir->d_inode->i_mutex); 
     258 
     259        if (IS_ERR(dentry)) { 
     260                if (PTR_ERR(dentry) == -ENOENT) 
     261                        dentry = NULL; 
     262        } else if (!dentry->d_inode) { 
     263                dput(dentry); 
     264                dentry = NULL; 
     265        } 
     266        return dentry; 
     267} 
     268 
     269int ovl_do_lookup(struct dentry *dentry) 
     270{ 
     271        struct ovl_entry *oe; 
     272        struct dentry *upperdir; 
     273        struct dentry *lowerdir; 
     274        struct dentry *upperdentry = NULL; 
     275        struct dentry *lowerdentry = NULL; 
     276        struct inode *inode = NULL; 
     277        int err; 
     278 
     279        err = -ENOMEM; 
     280        oe = ovl_alloc_entry(); 
     281        if (!oe) 
     282                goto out; 
     283 
     284        upperdir = ovl_dentry_upper(dentry->d_parent); 
     285        lowerdir = ovl_dentry_lower(dentry->d_parent); 
     286 
     287        if (upperdir) { 
     288                upperdentry = ovl_lookup_real(upperdir, &dentry->d_name); 
     289                err = PTR_ERR(upperdentry); 
     290                if (IS_ERR(upperdentry)) 
     291                        goto out_put_dir; 
     292 
     293                if (lowerdir && upperdentry && 
     294                    (S_ISLNK(upperdentry->d_inode->i_mode) || 
     295                     S_ISDIR(upperdentry->d_inode->i_mode))) { 
     296                        const struct cred *old_cred; 
     297                        struct cred *override_cred; 
     298 
     299                        err = -ENOMEM; 
     300                        override_cred = prepare_creds(); 
     301                        if (!override_cred) 
     302                                goto out_dput_upper; 
     303 
     304                        /* CAP_SYS_ADMIN needed for getxattr */ 
     305                        cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); 
     306                        old_cred = override_creds(override_cred); 
     307 
     308                        if (ovl_is_opaquedir(upperdentry)) { 
     309                                oe->opaque = true; 
     310                        } else if (ovl_is_whiteout(upperdentry)) { 
     311                                dput(upperdentry); 
     312                                upperdentry = NULL; 
     313                                oe->opaque = true; 
     314                        } 
     315                        revert_creds(old_cred); 
     316                        put_cred(override_cred); 
     317                } 
     318        } 
     319        if (lowerdir && !oe->opaque) { 
     320                lowerdentry = ovl_lookup_real(lowerdir, &dentry->d_name); 
     321                err = PTR_ERR(lowerdentry); 
     322                if (IS_ERR(lowerdentry)) 
     323                        goto out_dput_upper; 
     324        } 
     325 
     326        if (lowerdentry && upperdentry && 
     327            (!S_ISDIR(upperdentry->d_inode->i_mode) || 
     328             !S_ISDIR(lowerdentry->d_inode->i_mode))) { 
     329                dput(lowerdentry); 
     330                lowerdentry = NULL; 
     331                oe->opaque = true; 
     332        } 
     333 
     334        if (lowerdentry || upperdentry) { 
     335                struct dentry *realdentry; 
     336 
     337                realdentry = upperdentry ? upperdentry : lowerdentry; 
     338                err = -ENOMEM; 
     339                inode = ovl_new_inode(dentry->d_sb, realdentry->d_inode->i_mode, oe); 
     340                if (!inode) 
     341                        goto out_dput; 
     342        } 
     343 
     344        if (upperdentry) 
     345                oe->__upperdentry = dget(upperdentry); 
     346 
     347        if (lowerdentry) 
     348                oe->lowerdentry = lowerdentry; 
     349 
     350        dentry->d_fsdata = oe; 
     351        dentry->d_op = &ovl_dentry_operations; 
     352        d_add(dentry, inode); 
     353 
     354        return 0; 
     355 
     356out_dput: 
     357        dput(lowerdentry); 
     358out_dput_upper: 
     359        dput(upperdentry); 
     360out_put_dir: 
     361        kfree(oe); 
     362out: 
     363        return err; 
     364} 
     365 
     366static void ovl_put_super(struct super_block *sb) 
     367{ 
     368        struct ovl_fs *ufs = sb->s_fs_info; 
     369 
     370        if (!(sb->s_flags & MS_RDONLY)) 
     371                mnt_drop_write(ufs->upper_mnt); 
     372 
     373        mntput(ufs->upper_mnt); 
     374        mntput(ufs->lower_mnt); 
     375 
     376        kfree(ufs->config.lowerdir); 
     377        kfree(ufs->config.upperdir); 
     378        kfree(ufs); 
     379} 
     380 
     381static int ovl_remount_fs(struct super_block *sb, int *flagsp, char *data) 
     382{ 
     383        int flags = *flagsp; 
     384        struct ovl_fs *ufs = sb->s_fs_info; 
     385 
     386        /* When remounting rw or ro, we need to adjust the write access to the 
     387         * upper fs. 
     388         */ 
     389        if (((flags ^ sb->s_flags) & MS_RDONLY) == 0) 
     390                /* No change to readonly status */ 
     391                return 0; 
     392 
     393        if (flags & MS_RDONLY) { 
     394                mnt_drop_write(ufs->upper_mnt); 
     395                return 0; 
     396        } else 
     397                return mnt_want_write(ufs->upper_mnt); 
     398} 
     399 
     400/** 
     401 * ovl_statfs 
     402 * @sb: The overlayfs super block 
     403 * @buf: The struct kstatfs to fill in with stats 
     404 * 
     405 * Get the filesystem statistics.  As writes always target the upper layer 
     406 * filesystem pass the statfs to the same filesystem. 
     407 */ 
     408static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) 
     409{ 
     410        struct dentry *root_dentry = dentry->d_sb->s_root; 
     411        struct path path; 
     412        ovl_path_upper(root_dentry, &path); 
     413 
     414        if (!path.dentry->d_sb->s_op->statfs) 
     415                return -ENOSYS; 
     416        return path.dentry->d_sb->s_op->statfs(path.dentry, buf); 
     417} 
     418 
     419/** 
     420 * ovl_show_options 
     421 * 
     422 * Prints the mount options for a given superblock. 
     423 * Returns zero; does not fail. 
     424 */ 
     425static int ovl_show_options(struct seq_file *m, struct vfsmount *mnt) 
     426{ 
     427        struct super_block *sb = mnt->mnt_sb; 
     428        struct ovl_fs *ufs = sb->s_fs_info; 
     429 
     430        seq_printf(m, ",lowerdir=%s", ufs->config.lowerdir); 
     431        seq_printf(m, ",upperdir=%s", ufs->config.upperdir); 
     432        return 0; 
     433} 
     434 
     435static const struct super_operations ovl_super_operations = { 
     436        .put_super      = ovl_put_super, 
     437        .remount_fs     = ovl_remount_fs, 
     438        .statfs         = ovl_statfs, 
     439        .show_options   = ovl_show_options, 
     440}; 
     441 
     442enum { 
     443        Opt_lowerdir, 
     444        Opt_upperdir, 
     445        Opt_err, 
     446}; 
     447 
     448static const match_table_t ovl_tokens = { 
     449        {Opt_lowerdir,                  "lowerdir=%s"}, 
     450        {Opt_upperdir,                  "upperdir=%s"}, 
     451        {Opt_err,                       NULL} 
     452}; 
     453 
     454static int ovl_parse_opt(char *opt, struct ovl_config *config) 
     455{ 
     456        char *p; 
     457 
     458        config->upperdir = NULL; 
     459        config->lowerdir = NULL; 
     460 
     461        while ((p = strsep(&opt, ",")) != NULL) { 
     462                int token; 
     463                substring_t args[MAX_OPT_ARGS]; 
     464 
     465                if (!*p) 
     466                        continue; 
     467 
     468                token = match_token(p, ovl_tokens, args); 
     469                switch (token) { 
     470                case Opt_upperdir: 
     471                        kfree(config->upperdir); 
     472                        config->upperdir = match_strdup(&args[0]); 
     473                        if (!config->upperdir) 
     474                                return -ENOMEM; 
     475                        break; 
     476 
     477                case Opt_lowerdir: 
     478                        kfree(config->lowerdir); 
     479                        config->lowerdir = match_strdup(&args[0]); 
     480                        if (!config->lowerdir) 
     481                                return -ENOMEM; 
     482                        break; 
     483 
     484                default: 
     485                        return -EINVAL; 
     486                } 
     487        } 
     488        return 0; 
     489} 
     490 
     491static int ovl_fill_super(struct super_block *sb, void *data, int silent) 
     492{ 
     493        struct path lowerpath; 
     494        struct path upperpath; 
     495        struct inode *root_inode; 
     496        struct dentry *root_dentry; 
     497        struct ovl_entry *oe; 
     498        struct ovl_fs *ufs; 
     499        int err; 
     500 
     501        err = -ENOMEM; 
     502        ufs = kmalloc(sizeof(struct ovl_fs), GFP_KERNEL); 
     503        if (!ufs) 
     504                goto out; 
     505 
     506        err = ovl_parse_opt((char *) data, &ufs->config); 
     507        if (err) 
     508                goto out_free_ufs; 
     509 
     510        err = -EINVAL; 
     511        if (!ufs->config.upperdir || !ufs->config.lowerdir) { 
     512                printk(KERN_ERR "overlayfs: missing upperdir or lowerdir\n"); 
     513                goto out_free_config; 
     514        } 
     515 
     516        oe = ovl_alloc_entry(); 
     517        if (oe == NULL) 
     518                goto out_free_config; 
     519 
     520        root_inode = ovl_new_inode(sb, S_IFDIR, oe); 
     521        if (!root_inode) 
     522                goto out_free_oe; 
     523 
     524        err = kern_path(ufs->config.upperdir, LOOKUP_FOLLOW, &upperpath); 
     525        if (err) 
     526                goto out_put_root; 
     527 
     528        err = kern_path(ufs->config.lowerdir, LOOKUP_FOLLOW, &lowerpath); 
     529        if (err) 
     530                goto out_put_upperpath; 
     531 
     532        err = -ENOTDIR; 
     533        if (!S_ISDIR(upperpath.dentry->d_inode->i_mode) || 
     534            !S_ISDIR(lowerpath.dentry->d_inode->i_mode)) 
     535                goto out_put_lowerpath; 
     536 
     537        ufs->upper_mnt = clone_private_mount(&upperpath); 
     538        err = PTR_ERR(ufs->upper_mnt); 
     539        if (IS_ERR(ufs->upper_mnt)) { 
     540                printk(KERN_ERR "overlayfs: failed to clone upperpath\n"); 
     541                goto out_put_lowerpath; 
     542        } 
     543 
     544        ufs->lower_mnt = clone_private_mount(&lowerpath); 
     545        err = PTR_ERR(ufs->lower_mnt); 
     546        if (IS_ERR(ufs->lower_mnt)) { 
     547                printk(KERN_ERR "overlayfs: failed to clone lowerpath\n"); 
     548                goto out_put_upper_mnt; 
     549        } 
     550 
     551        if (!(sb->s_flags & MS_RDONLY)) { 
     552                err = mnt_want_write(ufs->upper_mnt); 
     553                if (err) 
     554                        goto out_put_lower_mnt; 
     555        } 
     556 
     557        err = -ENOMEM; 
     558        root_dentry = d_alloc_root(root_inode); 
     559        if (!root_dentry) 
     560                goto out_drop_write; 
     561 
     562        mntput(upperpath.mnt); 
     563        mntput(lowerpath.mnt); 
     564 
     565        oe->__upperdentry = dget(upperpath.dentry); 
     566        oe->lowerdentry = lowerpath.dentry; 
     567 
     568        root_dentry->d_fsdata = oe; 
     569        root_dentry->d_op = &ovl_dentry_operations; 
     570 
     571        sb->s_op = &ovl_super_operations; 
     572        sb->s_root = root_dentry; 
     573        sb->s_fs_info = ufs; 
     574 
     575        return 0; 
     576 
     577out_drop_write: 
     578        if (!(sb->s_flags & MS_RDONLY)) 
     579                mnt_drop_write(ufs->upper_mnt); 
     580out_put_lower_mnt: 
     581        mntput(ufs->lower_mnt); 
     582out_put_upper_mnt: 
     583        mntput(ufs->upper_mnt); 
     584out_put_lowerpath: 
     585        path_put(&lowerpath); 
     586out_put_upperpath: 
     587        path_put(&upperpath); 
     588out_put_root: 
     589        iput(root_inode); 
     590out_free_oe: 
     591        kfree(oe); 
     592out_free_config: 
     593        kfree(ufs->config.lowerdir); 
     594        kfree(ufs->config.upperdir); 
     595out_free_ufs: 
     596        kfree(ufs); 
     597out: 
     598        return err; 
     599} 
     600 
     601static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags, 
     602                                const char *dev_name, void *raw_data) 
     603{ 
     604        return mount_nodev(fs_type, flags, raw_data, ovl_fill_super); 
     605} 
     606 
     607static struct file_system_type ovl_fs_type = { 
     608        .owner          = THIS_MODULE, 
     609        .name           = "overlayfs", 
     610        .mount          = ovl_mount, 
     611        .kill_sb        = kill_anon_super, 
     612}; 
     613 
     614static int __init ovl_init(void) 
     615{ 
     616        return register_filesystem(&ovl_fs_type); 
     617} 
     618 
     619static void __exit ovl_exit(void) 
     620{ 
     621        unregister_filesystem(&ovl_fs_type); 
     622} 
     623 
     624module_init(ovl_init); 
     625module_exit(ovl_exit); 
  • new file Documentation/filesystems/overlayfs.txt

    - +  
     1Written by: Neil Brown <neilb@suse.de> 
     2 
     3Overlay Filesystem 
     4================== 
     5 
     6This document describes a prototype for a new approach to providing 
     7overlay-filesystem functionality in Linux (sometimes referred to as 
     8union-filesystems).  An overlay-filesystem tries to present a 
     9filesystem which is the result over overlaying one filesystem on top 
     10of the other. 
     11 
     12The result will inevitably fail to look exactly like a normal 
     13filesystem for various technical reasons.  The expectation is that 
     14many use cases will be able to ignore these differences. 
     15 
     16This approach is 'hybrid' because the objects that appear in the 
     17filesystem do not all appear to belong to that filesystem.  In many 
     18cases an object accessed in the union will be indistinguishable 
     19from accessing the corresponding object from the original filesystem. 
     20This is most obvious from the 'st_dev' field returned by stat(2). 
     21 
     22While directories will report an st_dev from the overlay-filesystem, 
     23all non-directory objects will report an st_dev from the lower or 
     24upper filesystem that is providing the object.  Similarly st_ino will 
     25only be unique when combined with st_dev, and both of these can change 
     26over the lifetime of a non-directory object.  Many applications and 
     27tools ignore these values and will not be affected. 
     28 
     29Upper and Lower 
     30--------------- 
     31 
     32An overlay filesystem combines two filesystems - an 'upper' filesystem 
     33and a 'lower' filesystem.  When a name exists in both filesystems, the 
     34object in the 'upper' filesystem is visible while the object in the 
     35'lower' filesystem is either hidden or, in the case of directories, 
     36merged with the 'upper' object. 
     37 
     38It would be more correct to refer to an upper and lower 'directory 
     39tree' rather than 'filesystem' as it is quite possible for both 
     40directory trees to be in the same filesystem and there is no 
     41requirement that the root of a filesystem be given for either upper or 
     42lower. 
     43 
     44The lower filesystem can be any filesystem supported by Linux and does 
     45not need to be writable.  The lower filesystem can even be another 
     46overlayfs.  The upper filesystem will normally be writable and if it 
     47is it must support the creation of trusted.* extended attributes, and 
     48must provide valid d_type in readdir responses, at least for symbolic 
     49links - so NFS is not suitable. 
     50 
     51A read-only overlay of two read-only filesystems may use any 
     52filesystem type. 
     53 
     54Directories 
     55----------- 
     56 
     57Overlaying mainly involved directories.  If a given name appears in both 
     58upper and lower filesystems and refers to a non-directory in either, 
     59then the lower object is hidden - the name refers only to the upper 
     60object. 
     61 
     62Where both upper and lower objects are directories, a merged directory 
     63is formed. 
     64 
     65At mount time, the two directories given as mount options are combined 
     66into a merged directory: 
     67 
     68  mount -t overlayfs overlayfs -olowerdir=/lower,upperdir=/upper /overlay 
     69 
     70Then whenever a lookup is requested in such a merged directory, the 
     71lookup is performed in each actual directory and the combined result 
     72is cached in the dentry belonging to the overlay filesystem.  If both 
     73actual lookups find directories, both are stored and a merged 
     74directory is created, otherwise only one is stored: the upper if it 
     75exists, else the lower. 
     76 
     77Only the lists of names from directories are merged.  Other content 
     78such as metadata and extended attributes are reported for the upper 
     79directory only.  These attributes of the lower directory are hidden. 
     80 
     81whiteouts and opaque directories 
     82-------------------------------- 
     83 
     84In order to support rm and rmdir without changing the lower 
     85filesystem, an overlay filesystem needs to record in the upper filesystem 
     86that files have been removed.  This is done using whiteouts and opaque 
     87directories (non-directories are always opaque). 
     88 
     89The overlay filesystem uses extended attributes with a 
     90"trusted.overlay."  prefix to record these details. 
     91 
     92A whiteout is created as a symbolic link with target 
     93"(overlay-whiteout)" and with xattr "trusted.overlay.whiteout" set to "y". 
     94When a whiteout is found in the upper level of a merged directory, any 
     95matching name in the lower level is ignored, and the whiteout itself 
     96is also hidden. 
     97 
     98A directory is made opaque by setting the xattr "trusted.overlay.opaque" 
     99to "y".  Where the upper filesystem contains an opaque directory, any 
     100directory in the lower filesystem with the same name is ignored. 
     101 
     102readdir 
     103------- 
     104 
     105When a 'readdir' request is made on a merged directory, the upper and 
     106lower directories are each read and the name lists merged in the 
     107obvious way (upper is read first, then lower - entries that already 
     108exist are not re-added).  This merged name list is cached in the 
     109'struct file' and so remains as long as the file is kept open.  If the 
     110directory is opened and read by two processes at the same time, they 
     111will each have separate caches.  A seekdir to the start of the 
     112directory (offset 0) followed by a readdir will cause the cache to be 
     113discarded and rebuilt. 
     114 
     115This means that changes to the merged directory do not appear while a 
     116directory is being read.  This is unlikely to be noticed by many 
     117programs. 
     118 
     119seek offsets are assigned sequentially when the directories are read. 
     120Thus if 
     121  - read part of a directory 
     122  - remember an offset, and close the directory 
     123  - re-open the directory some time later 
     124  - seek to the remembered offset 
     125 
     126there may be little correlation between the old and new locations in 
     127the list of filenames, particularly if anything has changed in the 
     128directory. 
     129 
     130Readdir on directories that are not merged is simply handled by the 
     131underlying directory (upper or lower). 
     132 
     133 
     134Non-directories 
     135--------------- 
     136 
     137Objects that are not directories (files, symlinks, device-special 
     138files etc.) are presented either from the upper or lower filesystem as 
     139appropriate.  When a file in the lower filesystem is accessed in a way 
     140the requires write-access, such as opening for write access, changing 
     141some metadata etc., the file is first copied from the lower filesystem 
     142to the upper filesystem (copy_up).  Note that creating a hard-link 
     143also requires copy_up, though of course creation of a symlink does 
     144not. 
     145 
     146The copy_up process first makes sure that the containing directory 
     147exists in the upper filesystem - creating it and any parents as 
     148necessary.  It then creates the object with the same metadata (owner, 
     149mode, mtime, symlink-target etc.) and then if the object is a file, the 
     150data is copied from the lower to the upper filesystem.  Finally any 
     151extended attributes are copied up. 
     152 
     153Once the copy_up is complete, the overlay filesystem simply 
     154provides direct access to the newly created file in the upper 
     155filesystem - future operations on the file are barely noticed by the 
     156overlay filesystem (though an operation on the name of the file such as 
     157rename or unlink will of course be noticed and handled). 
     158 
     159Changes to underlying filesystems 
     160--------------------------------- 
     161 
     162Offline changes, when the overlay is not mounted, are allowed to either 
     163the upper or the lower trees. 
     164 
     165Changes to the underlying filesystems while part of a mounted overlay 
     166filesystem are not allowed.  This is not yet enforced, but will be in 
     167the future. 
  • MAINTAINERS

    a b F: drivers/scsi/osd/ 
    47174717F:      include/scsi/osd_* 
    47184718F:      fs/exofs/ 
    47194719 
     4720OVERLAYFS FILESYSTEM 
     4721M:      Miklos Szeredi <miklos@szeredi.hu> 
     4722L:      linux-fsdevel@vger.kernel.org 
     4723S:      Supported 
     4724F:      fs/overlayfs/* 
     4725F:      Documentation/filesystems/overlayfs.txt 
     4726 
    47204727P54 WIRELESS DRIVER 
    47214728M:      Christian Lamparter <chunkeey@googlemail.com> 
    47224729L:      linux-wireless@vger.kernel.org 
Note: See TracBrowser for help on using the repository browser.