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 >