README.md
Rendering markdown...
15c15,16
< static int ovl_copy_up_truncate(struct dentry *dentry)
---
> static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr,
> bool no_data)
32,33c33,36
< stat.size = 0;
< err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
---
> if (no_data)
> stat.size = 0;
>
> err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat, attr);
45,57d47
< /*
< * Check for permissions before trying to copy-up. This is redundant
< * since it will be rechecked later by ->setattr() on upper dentry. But
< * without this, copy-up can be triggered by just about anybody.
< *
< * We don't initialize inode->size, which just means that
< * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
< * check for a swapfile (which this won't be anyway).
< */
< err = inode_change_ok(dentry->d_inode, attr);
< if (err)
< return err;
<
62,66c52,54
< err = ovl_copy_up(dentry);
< if (!err) {
< upperdentry = ovl_dentry_upper(dentry);
<
< inode_lock(upperdentry->d_inode);
---
> upperdentry = ovl_dentry_upper(dentry);
> if (upperdentry) {
> mutex_lock(&upperdentry->d_inode->i_mutex);
68,70c56,58
< if (!err)
< ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
< inode_unlock(upperdentry->d_inode);
---
> mutex_unlock(&upperdentry->d_inode->i_mutex);
> } else {
> err = ovl_copy_up_last(dentry, attr, false);
113,135d100
< if (ovl_is_default_permissions(inode)) {
< struct kstat stat;
< struct path realpath = { .dentry = realdentry };
<
< if (mask & MAY_NOT_BLOCK)
< return -ECHILD;
<
< realpath.mnt = ovl_entry_mnt_real(oe, inode, is_upper);
<
< err = vfs_getattr(&realpath, &stat);
< if (err)
< return err;
<
< if ((stat.mode ^ inode->i_mode) & S_IFMT)
< return -ESTALE;
<
< inode->i_mode = stat.mode;
< inode->i_uid = stat.uid;
< inode->i_gid = stat.gid;
<
< return generic_permission(inode, mask);
< }
<
172,174c137,143
< static const char *ovl_get_link(struct dentry *dentry,
< struct inode *inode,
< struct delayed_call *done)
---
>
> struct ovl_link_data {
> struct dentry *realdentry;
> void *cookie;
> };
>
> static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
175a145
> void *ret;
179,181d148
< if (!dentry)
< return ERR_PTR(-ECHILD);
<
185c152
< if (WARN_ON(!realinode->i_op->get_link))
---
> if (WARN_ON(!realinode->i_op->follow_link))
188c155,186
< return realinode->i_op->get_link(realdentry, realinode, done);
---
> ret = realinode->i_op->follow_link(realdentry, nd);
> if (IS_ERR(ret))
> return ret;
>
> if (realinode->i_op->put_link) {
> struct ovl_link_data *data;
>
> data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
> if (!data) {
> realinode->i_op->put_link(realdentry, nd, ret);
> return ERR_PTR(-ENOMEM);
> }
> data->realdentry = realdentry;
> data->cookie = ret;
>
> return data;
> } else {
> return NULL;
> }
> }
>
> static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
> {
> struct inode *realinode;
> struct ovl_link_data *data = c;
>
> if (!data)
> return;
>
> realinode = data->realdentry->d_inode;
> realinode->i_op->put_link(data->realdentry, nd, data->cookie);
> kfree(data);
210c208
< return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
---
> return strncmp(name, "trusted.overlay.", 14) == 0;
243,246c241
< if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER)
< return S_ISDIR(dentry->d_inode->i_mode);
< else
< return false;
---
> return type == OVL_PATH_UPPER && S_ISDIR(dentry->d_inode->i_mode);
307c302
< if (!OVL_TYPE_UPPER(type)) {
---
> if (type == OVL_PATH_LOWER) {
329c324
< if (OVL_TYPE_UPPER(type))
---
> if (type != OVL_PATH_LOWER)
341c336,337
< struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
---
> static int ovl_dentry_open(struct dentry *dentry, struct file *file,
> const struct cred *cred)
346,348c342
<
< if (d_is_dir(dentry))
< return d_backing_inode(dentry);
---
> bool want_write = false;
351c345,346
< if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
---
> if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) {
> want_write = true;
354c349
< return ERR_PTR(err);
---
> goto out;
356,357c351,352
< if (file_flags & O_TRUNC)
< err = ovl_copy_up_truncate(dentry);
---
> if (file->f_flags & O_TRUNC)
> err = ovl_copy_up_last(dentry, NULL, true);
360d354
< ovl_drop_write(dentry);
362c356
< return ERR_PTR(err);
---
> goto out_drop_write;
367,370c361,366
< if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
< return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);
<
< return d_backing_inode(realpath.dentry);
---
> err = vfs_open(&realpath, file, cred);
> out_drop_write:
> if (want_write)
> ovl_drop_write(dentry);
> out:
> return err;
380a377
> .dentry_open = ovl_dentry_open,
385c382,383
< .get_link = ovl_get_link,
---
> .follow_link = ovl_follow_link,
> .put_link = ovl_put_link,
434a433
>