1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2e9be9d5eSMiklos Szeredi /* 3e9be9d5eSMiklos Szeredi * 4e9be9d5eSMiklos Szeredi * Copyright (C) 2011 Novell Inc. 5e9be9d5eSMiklos Szeredi */ 6e9be9d5eSMiklos Szeredi 7fb5bb2c3SDavid Howells #include <linux/module.h> 8e9be9d5eSMiklos Szeredi #include <linux/fs.h> 9e9be9d5eSMiklos Szeredi #include <linux/slab.h> 10e9be9d5eSMiklos Szeredi #include <linux/file.h> 11e9be9d5eSMiklos Szeredi #include <linux/splice.h> 12e9be9d5eSMiklos Szeredi #include <linux/xattr.h> 13e9be9d5eSMiklos Szeredi #include <linux/security.h> 14e9be9d5eSMiklos Szeredi #include <linux/uaccess.h> 15174cd4b1SIngo Molnar #include <linux/sched/signal.h> 165b825c3aSIngo Molnar #include <linux/cred.h> 17e9be9d5eSMiklos Szeredi #include <linux/namei.h> 18fb5bb2c3SDavid Howells #include <linux/fdtable.h> 19fb5bb2c3SDavid Howells #include <linux/ratelimit.h> 203a1e819bSAmir Goldstein #include <linux/exportfs.h> 21e9be9d5eSMiklos Szeredi #include "overlayfs.h" 22e9be9d5eSMiklos Szeredi 23e9be9d5eSMiklos Szeredi #define OVL_COPY_UP_CHUNK_SIZE (1 << 20) 24e9be9d5eSMiklos Szeredi 25670c2324SMiklos Szeredi static int ovl_ccup_set(const char *buf, const struct kernel_param *param) 26fb5bb2c3SDavid Howells { 271bd0a3aeSlijiazi pr_warn("\"check_copy_up\" module option is obsolete\n"); 28fb5bb2c3SDavid Howells return 0; 29fb5bb2c3SDavid Howells } 30fb5bb2c3SDavid Howells 31670c2324SMiklos Szeredi static int ovl_ccup_get(char *buf, const struct kernel_param *param) 32fb5bb2c3SDavid Howells { 33670c2324SMiklos Szeredi return sprintf(buf, "N\n"); 34fb5bb2c3SDavid Howells } 35fb5bb2c3SDavid Howells 36670c2324SMiklos Szeredi module_param_call(check_copy_up, ovl_ccup_set, ovl_ccup_get, NULL, 0644); 37253e7483SNicolas Schier MODULE_PARM_DESC(check_copy_up, "Obsolete; does nothing"); 38670c2324SMiklos Szeredi 39c61ca557SMiklos Szeredi static bool ovl_must_copy_xattr(const char *name) 40c61ca557SMiklos Szeredi { 41c61ca557SMiklos Szeredi return !strcmp(name, XATTR_POSIX_ACL_ACCESS) || 42c61ca557SMiklos Szeredi !strcmp(name, XATTR_POSIX_ACL_DEFAULT) || 43c61ca557SMiklos Szeredi !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN); 44c61ca557SMiklos Szeredi } 45c61ca557SMiklos Szeredi 46610afc0bSMiklos Szeredi int ovl_copy_xattr(struct super_block *sb, struct dentry *old, 47610afc0bSMiklos Szeredi struct dentry *new) 48e9be9d5eSMiklos Szeredi { 49e4ad29faSVito Caputo ssize_t list_size, size, value_size = 0; 50e4ad29faSVito Caputo char *buf, *name, *value = NULL; 51520da69dSYuxuan Shui int error = 0; 528b326c61SMiklos Szeredi size_t slen; 53e9be9d5eSMiklos Szeredi 545d6c3191SAndreas Gruenbacher if (!(old->d_inode->i_opflags & IOP_XATTR) || 555d6c3191SAndreas Gruenbacher !(new->d_inode->i_opflags & IOP_XATTR)) 56e9be9d5eSMiklos Szeredi return 0; 57e9be9d5eSMiklos Szeredi 58e9be9d5eSMiklos Szeredi list_size = vfs_listxattr(old, NULL, 0); 59e9be9d5eSMiklos Szeredi if (list_size <= 0) { 60e9be9d5eSMiklos Szeredi if (list_size == -EOPNOTSUPP) 61e9be9d5eSMiklos Szeredi return 0; 62e9be9d5eSMiklos Szeredi return list_size; 63e9be9d5eSMiklos Szeredi } 64e9be9d5eSMiklos Szeredi 65e9be9d5eSMiklos Szeredi buf = kzalloc(list_size, GFP_KERNEL); 66e9be9d5eSMiklos Szeredi if (!buf) 67e9be9d5eSMiklos Szeredi return -ENOMEM; 68e9be9d5eSMiklos Szeredi 69e9be9d5eSMiklos Szeredi list_size = vfs_listxattr(old, buf, list_size); 70e9be9d5eSMiklos Szeredi if (list_size <= 0) { 71e9be9d5eSMiklos Szeredi error = list_size; 72e4ad29faSVito Caputo goto out; 73e9be9d5eSMiklos Szeredi } 74e9be9d5eSMiklos Szeredi 758b326c61SMiklos Szeredi for (name = buf; list_size; name += slen) { 768b326c61SMiklos Szeredi slen = strnlen(name, list_size) + 1; 778b326c61SMiklos Szeredi 788b326c61SMiklos Szeredi /* underlying fs providing us with an broken xattr list? */ 798b326c61SMiklos Szeredi if (WARN_ON(slen > list_size)) { 808b326c61SMiklos Szeredi error = -EIO; 818b326c61SMiklos Szeredi break; 828b326c61SMiklos Szeredi } 838b326c61SMiklos Szeredi list_size -= slen; 848b326c61SMiklos Szeredi 85610afc0bSMiklos Szeredi if (ovl_is_private_xattr(sb, name)) 860956254aSMiklos Szeredi continue; 87*03fedf93SAmir Goldstein 88*03fedf93SAmir Goldstein error = security_inode_copy_up_xattr(name); 89*03fedf93SAmir Goldstein if (error < 0 && error != -EOPNOTSUPP) 90*03fedf93SAmir Goldstein break; 91*03fedf93SAmir Goldstein if (error == 1) { 92*03fedf93SAmir Goldstein error = 0; 93*03fedf93SAmir Goldstein continue; /* Discard */ 94*03fedf93SAmir Goldstein } 95e4ad29faSVito Caputo retry: 96e4ad29faSVito Caputo size = vfs_getxattr(old, name, value, value_size); 97e4ad29faSVito Caputo if (size == -ERANGE) 98e4ad29faSVito Caputo size = vfs_getxattr(old, name, NULL, 0); 99e4ad29faSVito Caputo 10097daf8b9SMiklos Szeredi if (size < 0) { 101e9be9d5eSMiklos Szeredi error = size; 102e4ad29faSVito Caputo break; 103e9be9d5eSMiklos Szeredi } 104e9be9d5eSMiklos Szeredi 105e4ad29faSVito Caputo if (size > value_size) { 106e4ad29faSVito Caputo void *new; 107e4ad29faSVito Caputo 108e4ad29faSVito Caputo new = krealloc(value, size, GFP_KERNEL); 109e4ad29faSVito Caputo if (!new) { 110e4ad29faSVito Caputo error = -ENOMEM; 111e4ad29faSVito Caputo break; 112e4ad29faSVito Caputo } 113e4ad29faSVito Caputo value = new; 114e4ad29faSVito Caputo value_size = size; 115e4ad29faSVito Caputo goto retry; 116e4ad29faSVito Caputo } 117e4ad29faSVito Caputo 118e4ad29faSVito Caputo error = vfs_setxattr(new, name, value, size, 0); 119c61ca557SMiklos Szeredi if (error) { 120c61ca557SMiklos Szeredi if (error != -EOPNOTSUPP || ovl_must_copy_xattr(name)) 121e4ad29faSVito Caputo break; 122c61ca557SMiklos Szeredi 123c61ca557SMiklos Szeredi /* Ignore failure to copy unknown xattrs */ 124c61ca557SMiklos Szeredi error = 0; 125c61ca557SMiklos Szeredi } 126e4ad29faSVito Caputo } 127e9be9d5eSMiklos Szeredi kfree(value); 128e9be9d5eSMiklos Szeredi out: 129e9be9d5eSMiklos Szeredi kfree(buf); 130e9be9d5eSMiklos Szeredi return error; 131e9be9d5eSMiklos Szeredi } 132e9be9d5eSMiklos Szeredi 133c86243b0SVivek Goyal static int ovl_copy_up_data(struct ovl_fs *ofs, struct path *old, 134c86243b0SVivek Goyal struct path *new, loff_t len) 135e9be9d5eSMiklos Szeredi { 136e9be9d5eSMiklos Szeredi struct file *old_file; 137e9be9d5eSMiklos Szeredi struct file *new_file; 138e9be9d5eSMiklos Szeredi loff_t old_pos = 0; 139e9be9d5eSMiklos Szeredi loff_t new_pos = 0; 14042ec3d4cSDarrick J. Wong loff_t cloned; 141b504c654SChengguang Xu loff_t data_pos = -1; 142b504c654SChengguang Xu loff_t hole_len; 143b504c654SChengguang Xu bool skip_hole = false; 144e9be9d5eSMiklos Szeredi int error = 0; 145e9be9d5eSMiklos Szeredi 146e9be9d5eSMiklos Szeredi if (len == 0) 147e9be9d5eSMiklos Szeredi return 0; 148e9be9d5eSMiklos Szeredi 1490480334fSDavid Howells old_file = ovl_path_open(old, O_LARGEFILE | O_RDONLY); 150e9be9d5eSMiklos Szeredi if (IS_ERR(old_file)) 151e9be9d5eSMiklos Szeredi return PTR_ERR(old_file); 152e9be9d5eSMiklos Szeredi 1530480334fSDavid Howells new_file = ovl_path_open(new, O_LARGEFILE | O_WRONLY); 154e9be9d5eSMiklos Szeredi if (IS_ERR(new_file)) { 155e9be9d5eSMiklos Szeredi error = PTR_ERR(new_file); 156e9be9d5eSMiklos Szeredi goto out_fput; 157e9be9d5eSMiklos Szeredi } 158e9be9d5eSMiklos Szeredi 1592ea98466SAmir Goldstein /* Try to use clone_file_range to clone up within the same fs */ 160452ce659SDarrick J. Wong cloned = do_clone_file_range(old_file, 0, new_file, 0, len, 0); 16142ec3d4cSDarrick J. Wong if (cloned == len) 1622ea98466SAmir Goldstein goto out; 1632ea98466SAmir Goldstein /* Couldn't clone, so now we try to copy the data */ 1642ea98466SAmir Goldstein 165b504c654SChengguang Xu /* Check if lower fs supports seek operation */ 166b504c654SChengguang Xu if (old_file->f_mode & FMODE_LSEEK && 167b504c654SChengguang Xu old_file->f_op->llseek) 168b504c654SChengguang Xu skip_hole = true; 169b504c654SChengguang Xu 170e9be9d5eSMiklos Szeredi while (len) { 171e9be9d5eSMiklos Szeredi size_t this_len = OVL_COPY_UP_CHUNK_SIZE; 172e9be9d5eSMiklos Szeredi long bytes; 173e9be9d5eSMiklos Szeredi 174e9be9d5eSMiklos Szeredi if (len < this_len) 175e9be9d5eSMiklos Szeredi this_len = len; 176e9be9d5eSMiklos Szeredi 177e9be9d5eSMiklos Szeredi if (signal_pending_state(TASK_KILLABLE, current)) { 178e9be9d5eSMiklos Szeredi error = -EINTR; 179e9be9d5eSMiklos Szeredi break; 180e9be9d5eSMiklos Szeredi } 181e9be9d5eSMiklos Szeredi 182b504c654SChengguang Xu /* 183b504c654SChengguang Xu * Fill zero for hole will cost unnecessary disk space 184b504c654SChengguang Xu * and meanwhile slow down the copy-up speed, so we do 185b504c654SChengguang Xu * an optimization for hole during copy-up, it relies 186b504c654SChengguang Xu * on SEEK_DATA implementation in lower fs so if lower 187b504c654SChengguang Xu * fs does not support it, copy-up will behave as before. 188b504c654SChengguang Xu * 189b504c654SChengguang Xu * Detail logic of hole detection as below: 190b504c654SChengguang Xu * When we detect next data position is larger than current 191b504c654SChengguang Xu * position we will skip that hole, otherwise we copy 192b504c654SChengguang Xu * data in the size of OVL_COPY_UP_CHUNK_SIZE. Actually, 193b504c654SChengguang Xu * it may not recognize all kind of holes and sometimes 194b504c654SChengguang Xu * only skips partial of hole area. However, it will be 195b504c654SChengguang Xu * enough for most of the use cases. 196b504c654SChengguang Xu */ 197b504c654SChengguang Xu 198b504c654SChengguang Xu if (skip_hole && data_pos < old_pos) { 199b504c654SChengguang Xu data_pos = vfs_llseek(old_file, old_pos, SEEK_DATA); 200b504c654SChengguang Xu if (data_pos > old_pos) { 201b504c654SChengguang Xu hole_len = data_pos - old_pos; 202b504c654SChengguang Xu len -= hole_len; 203b504c654SChengguang Xu old_pos = new_pos = data_pos; 204b504c654SChengguang Xu continue; 205b504c654SChengguang Xu } else if (data_pos == -ENXIO) { 206b504c654SChengguang Xu break; 207b504c654SChengguang Xu } else if (data_pos < 0) { 208b504c654SChengguang Xu skip_hole = false; 209b504c654SChengguang Xu } 210b504c654SChengguang Xu } 211b504c654SChengguang Xu 212e9be9d5eSMiklos Szeredi bytes = do_splice_direct(old_file, &old_pos, 213e9be9d5eSMiklos Szeredi new_file, &new_pos, 214e9be9d5eSMiklos Szeredi this_len, SPLICE_F_MOVE); 215e9be9d5eSMiklos Szeredi if (bytes <= 0) { 216e9be9d5eSMiklos Szeredi error = bytes; 217e9be9d5eSMiklos Szeredi break; 218e9be9d5eSMiklos Szeredi } 219e9be9d5eSMiklos Szeredi WARN_ON(old_pos != new_pos); 220e9be9d5eSMiklos Szeredi 221e9be9d5eSMiklos Szeredi len -= bytes; 222e9be9d5eSMiklos Szeredi } 2232ea98466SAmir Goldstein out: 224c86243b0SVivek Goyal if (!error && ovl_should_sync(ofs)) 225641089c1SMiklos Szeredi error = vfs_fsync(new_file, 0); 226e9be9d5eSMiklos Szeredi fput(new_file); 227e9be9d5eSMiklos Szeredi out_fput: 228e9be9d5eSMiklos Szeredi fput(old_file); 229e9be9d5eSMiklos Szeredi return error; 230e9be9d5eSMiklos Szeredi } 231e9be9d5eSMiklos Szeredi 2320c288874SVivek Goyal static int ovl_set_size(struct dentry *upperdentry, struct kstat *stat) 2330c288874SVivek Goyal { 2340c288874SVivek Goyal struct iattr attr = { 2350c288874SVivek Goyal .ia_valid = ATTR_SIZE, 2360c288874SVivek Goyal .ia_size = stat->size, 2370c288874SVivek Goyal }; 2380c288874SVivek Goyal 2390c288874SVivek Goyal return notify_change(upperdentry, &attr, NULL); 2400c288874SVivek Goyal } 2410c288874SVivek Goyal 242e9be9d5eSMiklos Szeredi static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat) 243e9be9d5eSMiklos Szeredi { 244e9be9d5eSMiklos Szeredi struct iattr attr = { 245e9be9d5eSMiklos Szeredi .ia_valid = 246e9be9d5eSMiklos Szeredi ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, 247e9be9d5eSMiklos Szeredi .ia_atime = stat->atime, 248e9be9d5eSMiklos Szeredi .ia_mtime = stat->mtime, 249e9be9d5eSMiklos Szeredi }; 250e9be9d5eSMiklos Szeredi 251e9be9d5eSMiklos Szeredi return notify_change(upperdentry, &attr, NULL); 252e9be9d5eSMiklos Szeredi } 253e9be9d5eSMiklos Szeredi 254e9be9d5eSMiklos Szeredi int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat) 255e9be9d5eSMiklos Szeredi { 256e9be9d5eSMiklos Szeredi int err = 0; 257e9be9d5eSMiklos Szeredi 258e9be9d5eSMiklos Szeredi if (!S_ISLNK(stat->mode)) { 259e9be9d5eSMiklos Szeredi struct iattr attr = { 260e9be9d5eSMiklos Szeredi .ia_valid = ATTR_MODE, 261e9be9d5eSMiklos Szeredi .ia_mode = stat->mode, 262e9be9d5eSMiklos Szeredi }; 263e9be9d5eSMiklos Szeredi err = notify_change(upperdentry, &attr, NULL); 264e9be9d5eSMiklos Szeredi } 265e9be9d5eSMiklos Szeredi if (!err) { 266e9be9d5eSMiklos Szeredi struct iattr attr = { 267e9be9d5eSMiklos Szeredi .ia_valid = ATTR_UID | ATTR_GID, 268e9be9d5eSMiklos Szeredi .ia_uid = stat->uid, 269e9be9d5eSMiklos Szeredi .ia_gid = stat->gid, 270e9be9d5eSMiklos Szeredi }; 271e9be9d5eSMiklos Szeredi err = notify_change(upperdentry, &attr, NULL); 272e9be9d5eSMiklos Szeredi } 273e9be9d5eSMiklos Szeredi if (!err) 274e9be9d5eSMiklos Szeredi ovl_set_timestamps(upperdentry, stat); 275e9be9d5eSMiklos Szeredi 276e9be9d5eSMiklos Szeredi return err; 277e9be9d5eSMiklos Szeredi } 278e9be9d5eSMiklos Szeredi 2791cdb0cb6SPavel Tikhomirov struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, 2801cdb0cb6SPavel Tikhomirov bool is_upper) 2813a1e819bSAmir Goldstein { 2823a1e819bSAmir Goldstein struct ovl_fh *fh; 283ec7bbb53SAmir Goldstein int fh_type, dwords; 2843a1e819bSAmir Goldstein int buflen = MAX_HANDLE_SZ; 28505122443SAmir Goldstein uuid_t *uuid = &real->d_sb->s_uuid; 286ec7bbb53SAmir Goldstein int err; 2873a1e819bSAmir Goldstein 288ec7bbb53SAmir Goldstein /* Make sure the real fid stays 32bit aligned */ 289ec7bbb53SAmir Goldstein BUILD_BUG_ON(OVL_FH_FID_OFFSET % 4); 290ec7bbb53SAmir Goldstein BUILD_BUG_ON(MAX_HANDLE_SZ + OVL_FH_FID_OFFSET > 255); 291ec7bbb53SAmir Goldstein 292ec7bbb53SAmir Goldstein fh = kzalloc(buflen + OVL_FH_FID_OFFSET, GFP_KERNEL); 293ec7bbb53SAmir Goldstein if (!fh) 2943a1e819bSAmir Goldstein return ERR_PTR(-ENOMEM); 2953a1e819bSAmir Goldstein 2963a1e819bSAmir Goldstein /* 2973a1e819bSAmir Goldstein * We encode a non-connectable file handle for non-dir, because we 2983a1e819bSAmir Goldstein * only need to find the lower inode number and we don't want to pay 2993a1e819bSAmir Goldstein * the price or reconnecting the dentry. 3003a1e819bSAmir Goldstein */ 3013a1e819bSAmir Goldstein dwords = buflen >> 2; 302ec7bbb53SAmir Goldstein fh_type = exportfs_encode_fh(real, (void *)fh->fb.fid, &dwords, 0); 3033a1e819bSAmir Goldstein buflen = (dwords << 2); 3043a1e819bSAmir Goldstein 305ec7bbb53SAmir Goldstein err = -EIO; 3063a1e819bSAmir Goldstein if (WARN_ON(fh_type < 0) || 3073a1e819bSAmir Goldstein WARN_ON(buflen > MAX_HANDLE_SZ) || 3083a1e819bSAmir Goldstein WARN_ON(fh_type == FILEID_INVALID)) 309ec7bbb53SAmir Goldstein goto out_err; 3103a1e819bSAmir Goldstein 311cbe7fba8SAmir Goldstein fh->fb.version = OVL_FH_VERSION; 312cbe7fba8SAmir Goldstein fh->fb.magic = OVL_FH_MAGIC; 313cbe7fba8SAmir Goldstein fh->fb.type = fh_type; 314cbe7fba8SAmir Goldstein fh->fb.flags = OVL_FH_FLAG_CPU_ENDIAN; 31554fb347eSAmir Goldstein /* 31654fb347eSAmir Goldstein * When we will want to decode an overlay dentry from this handle 31754fb347eSAmir Goldstein * and all layers are on the same fs, if we get a disconncted real 31854fb347eSAmir Goldstein * dentry when we decode fid, the only way to tell if we should assign 31954fb347eSAmir Goldstein * it to upperdentry or to lowerstack is by checking this flag. 32054fb347eSAmir Goldstein */ 32154fb347eSAmir Goldstein if (is_upper) 322cbe7fba8SAmir Goldstein fh->fb.flags |= OVL_FH_FLAG_PATH_UPPER; 323ec7bbb53SAmir Goldstein fh->fb.len = sizeof(fh->fb) + buflen; 3245830fb6bSPavel Tikhomirov if (ofs->config.uuid) 325cbe7fba8SAmir Goldstein fh->fb.uuid = *uuid; 3263a1e819bSAmir Goldstein 3273a1e819bSAmir Goldstein return fh; 328ec7bbb53SAmir Goldstein 329ec7bbb53SAmir Goldstein out_err: 330ec7bbb53SAmir Goldstein kfree(fh); 331ec7bbb53SAmir Goldstein return ERR_PTR(err); 3323a1e819bSAmir Goldstein } 3333a1e819bSAmir Goldstein 3341cdb0cb6SPavel Tikhomirov int ovl_set_origin(struct ovl_fs *ofs, struct dentry *dentry, 3351cdb0cb6SPavel Tikhomirov struct dentry *lower, struct dentry *upper) 3363a1e819bSAmir Goldstein { 3373a1e819bSAmir Goldstein const struct ovl_fh *fh = NULL; 3383a1e819bSAmir Goldstein int err; 3393a1e819bSAmir Goldstein 3403a1e819bSAmir Goldstein /* 3413a1e819bSAmir Goldstein * When lower layer doesn't support export operations store a 'null' fh, 3423a1e819bSAmir Goldstein * so we can use the overlay.origin xattr to distignuish between a copy 3433a1e819bSAmir Goldstein * up and a pure upper inode. 3443a1e819bSAmir Goldstein */ 34502bcd157SAmir Goldstein if (ovl_can_decode_fh(lower->d_sb)) { 3461cdb0cb6SPavel Tikhomirov fh = ovl_encode_real_fh(ofs, lower, false); 3473a1e819bSAmir Goldstein if (IS_ERR(fh)) 3483a1e819bSAmir Goldstein return PTR_ERR(fh); 3493a1e819bSAmir Goldstein } 3503a1e819bSAmir Goldstein 3516266d465SMiklos Szeredi /* 3526266d465SMiklos Szeredi * Do not fail when upper doesn't support xattrs. 3536266d465SMiklos Szeredi */ 354cbe7fba8SAmir Goldstein err = ovl_check_setxattr(dentry, upper, OVL_XATTR_ORIGIN, fh->buf, 355cbe7fba8SAmir Goldstein fh ? fh->fb.len : 0, 0); 3563a1e819bSAmir Goldstein kfree(fh); 3573a1e819bSAmir Goldstein 3586939f977SMiklos Szeredi /* Ignore -EPERM from setting "user.*" on symlink/special */ 3596939f977SMiklos Szeredi return err == -EPERM ? 0 : err; 3603a1e819bSAmir Goldstein } 3613a1e819bSAmir Goldstein 362016b720fSAmir Goldstein /* Store file handle of @upper dir in @index dir entry */ 363610afc0bSMiklos Szeredi static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, 364610afc0bSMiklos Szeredi struct dentry *index) 365016b720fSAmir Goldstein { 366016b720fSAmir Goldstein const struct ovl_fh *fh; 367016b720fSAmir Goldstein int err; 368016b720fSAmir Goldstein 3691cdb0cb6SPavel Tikhomirov fh = ovl_encode_real_fh(ofs, upper, true); 370016b720fSAmir Goldstein if (IS_ERR(fh)) 371016b720fSAmir Goldstein return PTR_ERR(fh); 372016b720fSAmir Goldstein 373610afc0bSMiklos Szeredi err = ovl_do_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len); 374016b720fSAmir Goldstein 375016b720fSAmir Goldstein kfree(fh); 376016b720fSAmir Goldstein return err; 377016b720fSAmir Goldstein } 378016b720fSAmir Goldstein 379016b720fSAmir Goldstein /* 380016b720fSAmir Goldstein * Create and install index entry. 381016b720fSAmir Goldstein * 382016b720fSAmir Goldstein * Caller must hold i_mutex on indexdir. 383016b720fSAmir Goldstein */ 384016b720fSAmir Goldstein static int ovl_create_index(struct dentry *dentry, struct dentry *origin, 385016b720fSAmir Goldstein struct dentry *upper) 386016b720fSAmir Goldstein { 3871cdb0cb6SPavel Tikhomirov struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 388016b720fSAmir Goldstein struct dentry *indexdir = ovl_indexdir(dentry->d_sb); 389016b720fSAmir Goldstein struct inode *dir = d_inode(indexdir); 390016b720fSAmir Goldstein struct dentry *index = NULL; 391016b720fSAmir Goldstein struct dentry *temp = NULL; 392016b720fSAmir Goldstein struct qstr name = { }; 393016b720fSAmir Goldstein int err; 394016b720fSAmir Goldstein 395016b720fSAmir Goldstein /* 396016b720fSAmir Goldstein * For now this is only used for creating index entry for directories, 397016b720fSAmir Goldstein * because non-dir are copied up directly to index and then hardlinked 398016b720fSAmir Goldstein * to upper dir. 399016b720fSAmir Goldstein * 400016b720fSAmir Goldstein * TODO: implement create index for non-dir, so we can call it when 401016b720fSAmir Goldstein * encoding file handle for non-dir in case index does not exist. 402016b720fSAmir Goldstein */ 403016b720fSAmir Goldstein if (WARN_ON(!d_is_dir(dentry))) 404016b720fSAmir Goldstein return -EIO; 405016b720fSAmir Goldstein 406016b720fSAmir Goldstein /* Directory not expected to be indexed before copy up */ 407016b720fSAmir Goldstein if (WARN_ON(ovl_test_flag(OVL_INDEX, d_inode(dentry)))) 408016b720fSAmir Goldstein return -EIO; 409016b720fSAmir Goldstein 4101cdb0cb6SPavel Tikhomirov err = ovl_get_index_name(ofs, origin, &name); 411016b720fSAmir Goldstein if (err) 412016b720fSAmir Goldstein return err; 413016b720fSAmir Goldstein 414137ec526SAmir Goldstein temp = ovl_create_temp(indexdir, OVL_CATTR(S_IFDIR | 0)); 415b148cba4SMiklos Szeredi err = PTR_ERR(temp); 416016b720fSAmir Goldstein if (IS_ERR(temp)) 417b148cba4SMiklos Szeredi goto free_name; 418016b720fSAmir Goldstein 4191cdb0cb6SPavel Tikhomirov err = ovl_set_upper_fh(ofs, upper, temp); 420016b720fSAmir Goldstein if (err) 421b148cba4SMiklos Szeredi goto out; 422016b720fSAmir Goldstein 423016b720fSAmir Goldstein index = lookup_one_len(name.name, indexdir, name.len); 424016b720fSAmir Goldstein if (IS_ERR(index)) { 425016b720fSAmir Goldstein err = PTR_ERR(index); 426016b720fSAmir Goldstein } else { 427016b720fSAmir Goldstein err = ovl_do_rename(dir, temp, dir, index, 0); 428016b720fSAmir Goldstein dput(index); 429016b720fSAmir Goldstein } 430016b720fSAmir Goldstein out: 431b148cba4SMiklos Szeredi if (err) 432b148cba4SMiklos Szeredi ovl_cleanup(dir, temp); 433016b720fSAmir Goldstein dput(temp); 434b148cba4SMiklos Szeredi free_name: 435016b720fSAmir Goldstein kfree(name.name); 436016b720fSAmir Goldstein return err; 437016b720fSAmir Goldstein } 438016b720fSAmir Goldstein 43923f0ab13SMiklos Szeredi struct ovl_copy_up_ctx { 440a6fb235aSMiklos Szeredi struct dentry *parent; 44123f0ab13SMiklos Szeredi struct dentry *dentry; 44223f0ab13SMiklos Szeredi struct path lowerpath; 44323f0ab13SMiklos Szeredi struct kstat stat; 44423f0ab13SMiklos Szeredi struct kstat pstat; 44523f0ab13SMiklos Szeredi const char *link; 44659be0971SAmir Goldstein struct dentry *destdir; 44759be0971SAmir Goldstein struct qstr destname; 44823f0ab13SMiklos Szeredi struct dentry *workdir; 44959be0971SAmir Goldstein bool origin; 450016b720fSAmir Goldstein bool indexed; 45144d5bf10SVivek Goyal bool metacopy; 45223f0ab13SMiklos Szeredi }; 45323f0ab13SMiklos Szeredi 454f4439de1SAmir Goldstein static int ovl_link_up(struct ovl_copy_up_ctx *c) 455f4439de1SAmir Goldstein { 456f4439de1SAmir Goldstein int err; 457f4439de1SAmir Goldstein struct dentry *upper; 458f4439de1SAmir Goldstein struct dentry *upperdir = ovl_dentry_upper(c->parent); 459f4439de1SAmir Goldstein struct inode *udir = d_inode(upperdir); 460f4439de1SAmir Goldstein 461f4439de1SAmir Goldstein /* Mark parent "impure" because it may now contain non-pure upper */ 462f4439de1SAmir Goldstein err = ovl_set_impure(c->parent, upperdir); 463f4439de1SAmir Goldstein if (err) 464f4439de1SAmir Goldstein return err; 465f4439de1SAmir Goldstein 466f4439de1SAmir Goldstein err = ovl_set_nlink_lower(c->dentry); 467f4439de1SAmir Goldstein if (err) 468f4439de1SAmir Goldstein return err; 469f4439de1SAmir Goldstein 470f4439de1SAmir Goldstein inode_lock_nested(udir, I_MUTEX_PARENT); 471f4439de1SAmir Goldstein upper = lookup_one_len(c->dentry->d_name.name, upperdir, 472f4439de1SAmir Goldstein c->dentry->d_name.len); 473f4439de1SAmir Goldstein err = PTR_ERR(upper); 474f4439de1SAmir Goldstein if (!IS_ERR(upper)) { 4756cf00764SAmir Goldstein err = ovl_do_link(ovl_dentry_upper(c->dentry), udir, upper); 476f4439de1SAmir Goldstein dput(upper); 477f4439de1SAmir Goldstein 478f4439de1SAmir Goldstein if (!err) { 479f4439de1SAmir Goldstein /* Restore timestamps on parent (best effort) */ 480f4439de1SAmir Goldstein ovl_set_timestamps(upperdir, &c->pstat); 481f4439de1SAmir Goldstein ovl_dentry_set_upper_alias(c->dentry); 482f4439de1SAmir Goldstein } 483f4439de1SAmir Goldstein } 484f4439de1SAmir Goldstein inode_unlock(udir); 485aa3ff3c1SAmir Goldstein if (err) 486aa3ff3c1SAmir Goldstein return err; 487aa3ff3c1SAmir Goldstein 488aa3ff3c1SAmir Goldstein err = ovl_set_nlink_upper(c->dentry); 489f4439de1SAmir Goldstein 490f4439de1SAmir Goldstein return err; 491f4439de1SAmir Goldstein } 492f4439de1SAmir Goldstein 49323f0ab13SMiklos Szeredi static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp) 49402209d10SAmir Goldstein { 495c86243b0SVivek Goyal struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); 49602209d10SAmir Goldstein int err; 49702209d10SAmir Goldstein 4985f32879eSVivek Goyal /* 4995f32879eSVivek Goyal * Copy up data first and then xattrs. Writing data after 5005f32879eSVivek Goyal * xattrs will remove security.capability xattr automatically. 5015f32879eSVivek Goyal */ 5025f32879eSVivek Goyal if (S_ISREG(c->stat.mode) && !c->metacopy) { 5035f32879eSVivek Goyal struct path upperpath, datapath; 5045f32879eSVivek Goyal 5055f32879eSVivek Goyal ovl_path_upper(c->dentry, &upperpath); 5065f32879eSVivek Goyal if (WARN_ON(upperpath.dentry != NULL)) 5075f32879eSVivek Goyal return -EIO; 5085f32879eSVivek Goyal upperpath.dentry = temp; 5095f32879eSVivek Goyal 5105f32879eSVivek Goyal ovl_path_lowerdata(c->dentry, &datapath); 511c86243b0SVivek Goyal err = ovl_copy_up_data(ofs, &datapath, &upperpath, 512c86243b0SVivek Goyal c->stat.size); 5135f32879eSVivek Goyal if (err) 5145f32879eSVivek Goyal return err; 5155f32879eSVivek Goyal } 5165f32879eSVivek Goyal 517610afc0bSMiklos Szeredi err = ovl_copy_xattr(c->dentry->d_sb, c->lowerpath.dentry, temp); 51802209d10SAmir Goldstein if (err) 51902209d10SAmir Goldstein return err; 52002209d10SAmir Goldstein 52102209d10SAmir Goldstein /* 52202209d10SAmir Goldstein * Store identifier of lower inode in upper inode xattr to 52302209d10SAmir Goldstein * allow lookup of the copy up origin inode. 52402209d10SAmir Goldstein * 52502209d10SAmir Goldstein * Don't set origin when we are breaking the association with a lower 52602209d10SAmir Goldstein * hard link. 52702209d10SAmir Goldstein */ 52859be0971SAmir Goldstein if (c->origin) { 5291cdb0cb6SPavel Tikhomirov err = ovl_set_origin(ofs, c->dentry, c->lowerpath.dentry, temp); 53002209d10SAmir Goldstein if (err) 53102209d10SAmir Goldstein return err; 53202209d10SAmir Goldstein } 53302209d10SAmir Goldstein 5340c288874SVivek Goyal if (c->metacopy) { 5350c288874SVivek Goyal err = ovl_check_setxattr(c->dentry, temp, OVL_XATTR_METACOPY, 5360c288874SVivek Goyal NULL, 0, -EOPNOTSUPP); 5370c288874SVivek Goyal if (err) 5380c288874SVivek Goyal return err; 5390c288874SVivek Goyal } 5400c288874SVivek Goyal 541bd64e575SVivek Goyal inode_lock(temp->d_inode); 542b504c654SChengguang Xu if (S_ISREG(c->stat.mode)) 5430c288874SVivek Goyal err = ovl_set_size(temp, &c->stat); 5440c288874SVivek Goyal if (!err) 545bd64e575SVivek Goyal err = ovl_set_attr(temp, &c->stat); 546bd64e575SVivek Goyal inode_unlock(temp->d_inode); 547bd64e575SVivek Goyal 548bd64e575SVivek Goyal return err; 54902209d10SAmir Goldstein } 55002209d10SAmir Goldstein 5516b52243fSMiklos Szeredi struct ovl_cu_creds { 5526b52243fSMiklos Szeredi const struct cred *old; 5536b52243fSMiklos Szeredi struct cred *new; 554b10cdcdcSAmir Goldstein }; 555b10cdcdcSAmir Goldstein 5566b52243fSMiklos Szeredi static int ovl_prep_cu_creds(struct dentry *dentry, struct ovl_cu_creds *cc) 557b10cdcdcSAmir Goldstein { 558b10cdcdcSAmir Goldstein int err; 559b10cdcdcSAmir Goldstein 5606b52243fSMiklos Szeredi cc->old = cc->new = NULL; 5616b52243fSMiklos Szeredi err = security_inode_copy_up(dentry, &cc->new); 5626b52243fSMiklos Szeredi if (err < 0) 563b10cdcdcSAmir Goldstein return err; 5646b52243fSMiklos Szeredi 5656b52243fSMiklos Szeredi if (cc->new) 5666b52243fSMiklos Szeredi cc->old = override_creds(cc->new); 5676b52243fSMiklos Szeredi 5686b52243fSMiklos Szeredi return 0; 5696b52243fSMiklos Szeredi } 5706b52243fSMiklos Szeredi 5716b52243fSMiklos Szeredi static void ovl_revert_cu_creds(struct ovl_cu_creds *cc) 5726b52243fSMiklos Szeredi { 5736b52243fSMiklos Szeredi if (cc->new) { 5746b52243fSMiklos Szeredi revert_creds(cc->old); 5756b52243fSMiklos Szeredi put_cred(cc->new); 5766b52243fSMiklos Szeredi } 577b10cdcdcSAmir Goldstein } 578b10cdcdcSAmir Goldstein 579b10cdcdcSAmir Goldstein /* 580b10cdcdcSAmir Goldstein * Copyup using workdir to prepare temp file. Used when copying up directories, 581b10cdcdcSAmir Goldstein * special files or when upper fs doesn't support O_TMPFILE. 582b10cdcdcSAmir Goldstein */ 583b10cdcdcSAmir Goldstein static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) 584b10cdcdcSAmir Goldstein { 585b79e05aaSAmir Goldstein struct inode *inode; 5866b52243fSMiklos Szeredi struct inode *udir = d_inode(c->destdir), *wdir = d_inode(c->workdir); 5876b52243fSMiklos Szeredi struct dentry *temp, *upper; 5886b52243fSMiklos Szeredi struct ovl_cu_creds cc; 5897d90b853SMiklos Szeredi int err; 5906b52243fSMiklos Szeredi struct ovl_cattr cattr = { 5916b52243fSMiklos Szeredi /* Can't properly set mode on creation because of the umask */ 5926b52243fSMiklos Szeredi .mode = c->stat.mode & S_IFMT, 5936b52243fSMiklos Szeredi .rdev = c->stat.rdev, 5946b52243fSMiklos Szeredi .link = c->link 5956b52243fSMiklos Szeredi }; 5967d90b853SMiklos Szeredi 597773cb4c5SAmir Goldstein /* workdir and destdir could be the same when copying up to indexdir */ 598773cb4c5SAmir Goldstein err = -EIO; 599773cb4c5SAmir Goldstein if (lock_rename(c->workdir, c->destdir) != NULL) 600773cb4c5SAmir Goldstein goto unlock; 601b10cdcdcSAmir Goldstein 6026b52243fSMiklos Szeredi err = ovl_prep_cu_creds(c->dentry, &cc); 6036b52243fSMiklos Szeredi if (err) 6046b52243fSMiklos Szeredi goto unlock; 6056b52243fSMiklos Szeredi 6066b52243fSMiklos Szeredi temp = ovl_create_temp(c->workdir, &cattr); 6076b52243fSMiklos Szeredi ovl_revert_cu_creds(&cc); 6086b52243fSMiklos Szeredi 609b10cdcdcSAmir Goldstein err = PTR_ERR(temp); 610b10cdcdcSAmir Goldstein if (IS_ERR(temp)) 611b10cdcdcSAmir Goldstein goto unlock; 612b10cdcdcSAmir Goldstein 613b10cdcdcSAmir Goldstein err = ovl_copy_up_inode(c, temp); 614b10cdcdcSAmir Goldstein if (err) 615b10cdcdcSAmir Goldstein goto cleanup; 616b10cdcdcSAmir Goldstein 617b10cdcdcSAmir Goldstein if (S_ISDIR(c->stat.mode) && c->indexed) { 618b10cdcdcSAmir Goldstein err = ovl_create_index(c->dentry, c->lowerpath.dentry, temp); 619b10cdcdcSAmir Goldstein if (err) 620b10cdcdcSAmir Goldstein goto cleanup; 621b10cdcdcSAmir Goldstein } 622b10cdcdcSAmir Goldstein 6236b52243fSMiklos Szeredi upper = lookup_one_len(c->destname.name, c->destdir, c->destname.len); 6246b52243fSMiklos Szeredi err = PTR_ERR(upper); 6256b52243fSMiklos Szeredi if (IS_ERR(upper)) 6266b52243fSMiklos Szeredi goto cleanup; 6276b52243fSMiklos Szeredi 6286b52243fSMiklos Szeredi err = ovl_do_rename(wdir, temp, udir, upper, 0); 6296b52243fSMiklos Szeredi dput(upper); 630b10cdcdcSAmir Goldstein if (err) 631b10cdcdcSAmir Goldstein goto cleanup; 632b10cdcdcSAmir Goldstein 633b10cdcdcSAmir Goldstein if (!c->metacopy) 634b10cdcdcSAmir Goldstein ovl_set_upperdata(d_inode(c->dentry)); 635b10cdcdcSAmir Goldstein inode = d_inode(c->dentry); 6366b52243fSMiklos Szeredi ovl_inode_update(inode, temp); 637b10cdcdcSAmir Goldstein if (S_ISDIR(inode->i_mode)) 638b10cdcdcSAmir Goldstein ovl_set_flag(OVL_WHITEOUTS, inode); 639b10cdcdcSAmir Goldstein unlock: 640b10cdcdcSAmir Goldstein unlock_rename(c->workdir, c->destdir); 641b10cdcdcSAmir Goldstein 642b10cdcdcSAmir Goldstein return err; 643b10cdcdcSAmir Goldstein 644b10cdcdcSAmir Goldstein cleanup: 6456b52243fSMiklos Szeredi ovl_cleanup(wdir, temp); 6466b52243fSMiklos Szeredi dput(temp); 647b10cdcdcSAmir Goldstein goto unlock; 648b10cdcdcSAmir Goldstein } 649b10cdcdcSAmir Goldstein 650b10cdcdcSAmir Goldstein /* Copyup using O_TMPFILE which does not require cross dir locking */ 651b10cdcdcSAmir Goldstein static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) 652b10cdcdcSAmir Goldstein { 6536b52243fSMiklos Szeredi struct inode *udir = d_inode(c->destdir); 6546b52243fSMiklos Szeredi struct dentry *temp, *upper; 6556b52243fSMiklos Szeredi struct ovl_cu_creds cc; 656b10cdcdcSAmir Goldstein int err; 657b10cdcdcSAmir Goldstein 6586b52243fSMiklos Szeredi err = ovl_prep_cu_creds(c->dentry, &cc); 6596b52243fSMiklos Szeredi if (err) 6606b52243fSMiklos Szeredi return err; 6616b52243fSMiklos Szeredi 6626b52243fSMiklos Szeredi temp = ovl_do_tmpfile(c->workdir, c->stat.mode); 6636b52243fSMiklos Szeredi ovl_revert_cu_creds(&cc); 6646b52243fSMiklos Szeredi 665b148cba4SMiklos Szeredi if (IS_ERR(temp)) 666b148cba4SMiklos Szeredi return PTR_ERR(temp); 667e9be9d5eSMiklos Szeredi 66823f0ab13SMiklos Szeredi err = ovl_copy_up_inode(c, temp); 669e9be9d5eSMiklos Szeredi if (err) 6706b52243fSMiklos Szeredi goto out_dput; 6713a1e819bSAmir Goldstein 6726b52243fSMiklos Szeredi inode_lock_nested(udir, I_MUTEX_PARENT); 6736b52243fSMiklos Szeredi 6746b52243fSMiklos Szeredi upper = lookup_one_len(c->destname.name, c->destdir, c->destname.len); 6756b52243fSMiklos Szeredi err = PTR_ERR(upper); 6766b52243fSMiklos Szeredi if (!IS_ERR(upper)) { 6776b52243fSMiklos Szeredi err = ovl_do_link(temp, udir, upper); 6786b52243fSMiklos Szeredi dput(upper); 6796b52243fSMiklos Szeredi } 6806b52243fSMiklos Szeredi inode_unlock(udir); 6816b52243fSMiklos Szeredi 682e9be9d5eSMiklos Szeredi if (err) 6836b52243fSMiklos Szeredi goto out_dput; 684e9be9d5eSMiklos Szeredi 6850c288874SVivek Goyal if (!c->metacopy) 6860c288874SVivek Goyal ovl_set_upperdata(d_inode(c->dentry)); 6876b52243fSMiklos Szeredi ovl_inode_update(d_inode(c->dentry), temp); 688b79e05aaSAmir Goldstein 6896b52243fSMiklos Szeredi return 0; 6906b52243fSMiklos Szeredi 6916b52243fSMiklos Szeredi out_dput: 692e85f82ffSMiklos Szeredi dput(temp); 693e9be9d5eSMiklos Szeredi return err; 694e9be9d5eSMiklos Szeredi } 695e9be9d5eSMiklos Szeredi 696e9be9d5eSMiklos Szeredi /* 697e9be9d5eSMiklos Szeredi * Copy up a single dentry 698e9be9d5eSMiklos Szeredi * 699a6c60655SMiklos Szeredi * All renames start with copy up of source if necessary. The actual 700a6c60655SMiklos Szeredi * rename will only proceed once the copy up was successful. Copy up uses 701a6c60655SMiklos Szeredi * upper parent i_mutex for exclusion. Since rename can change d_parent it 702a6c60655SMiklos Szeredi * is possible that the copy up will lock the old parent. At that point 703a6c60655SMiklos Szeredi * the file will have already been copied up anyway. 704e9be9d5eSMiklos Szeredi */ 705a6fb235aSMiklos Szeredi static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) 706e9be9d5eSMiklos Szeredi { 707e9be9d5eSMiklos Szeredi int err; 7081cdb0cb6SPavel Tikhomirov struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); 709016b720fSAmir Goldstein bool to_index = false; 71059be0971SAmir Goldstein 711016b720fSAmir Goldstein /* 712016b720fSAmir Goldstein * Indexed non-dir is copied up directly to the index entry and then 713016b720fSAmir Goldstein * hardlinked to upper dir. Indexed dir is copied up to indexdir, 714016b720fSAmir Goldstein * then index entry is created and then copied up dir installed. 715016b720fSAmir Goldstein * Copying dir up to indexdir instead of workdir simplifies locking. 716016b720fSAmir Goldstein */ 717016b720fSAmir Goldstein if (ovl_need_index(c->dentry)) { 718016b720fSAmir Goldstein c->indexed = true; 719016b720fSAmir Goldstein if (S_ISDIR(c->stat.mode)) 720016b720fSAmir Goldstein c->workdir = ovl_indexdir(c->dentry->d_sb); 721016b720fSAmir Goldstein else 722016b720fSAmir Goldstein to_index = true; 723016b720fSAmir Goldstein } 724016b720fSAmir Goldstein 725016b720fSAmir Goldstein if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || to_index) 72659be0971SAmir Goldstein c->origin = true; 72759be0971SAmir Goldstein 728016b720fSAmir Goldstein if (to_index) { 72959be0971SAmir Goldstein c->destdir = ovl_indexdir(c->dentry->d_sb); 7301cdb0cb6SPavel Tikhomirov err = ovl_get_index_name(ofs, c->lowerpath.dentry, &c->destname); 731f3a15685SAmir Goldstein if (err) 732f3a15685SAmir Goldstein return err; 733aa3ff3c1SAmir Goldstein } else if (WARN_ON(!c->parent)) { 734aa3ff3c1SAmir Goldstein /* Disconnected dentry must be copied up to index dir */ 735aa3ff3c1SAmir Goldstein return -EIO; 73659be0971SAmir Goldstein } else { 73759be0971SAmir Goldstein /* 73859be0971SAmir Goldstein * Mark parent "impure" because it may now contain non-pure 73959be0971SAmir Goldstein * upper 74059be0971SAmir Goldstein */ 74159be0971SAmir Goldstein err = ovl_set_impure(c->parent, c->destdir); 74259be0971SAmir Goldstein if (err) 74359be0971SAmir Goldstein return err; 74459be0971SAmir Goldstein } 745f3a15685SAmir Goldstein 74601ad3eb8SAmir Goldstein /* Should we copyup with O_TMPFILE or with workdir? */ 747b10cdcdcSAmir Goldstein if (S_ISREG(c->stat.mode) && ofs->tmpfile) 748b10cdcdcSAmir Goldstein err = ovl_copy_up_tmpfile(c); 749b10cdcdcSAmir Goldstein else 750b10cdcdcSAmir Goldstein err = ovl_copy_up_workdir(c); 751aa3ff3c1SAmir Goldstein if (err) 752aa3ff3c1SAmir Goldstein goto out; 753aa3ff3c1SAmir Goldstein 754aa3ff3c1SAmir Goldstein if (c->indexed) 75559be0971SAmir Goldstein ovl_set_flag(OVL_INDEX, d_inode(c->dentry)); 756016b720fSAmir Goldstein 757016b720fSAmir Goldstein if (to_index) { 758aa3ff3c1SAmir Goldstein /* Initialize nlink for copy up of disconnected dentry */ 759aa3ff3c1SAmir Goldstein err = ovl_set_nlink_upper(c->dentry); 760aa3ff3c1SAmir Goldstein } else { 76159be0971SAmir Goldstein struct inode *udir = d_inode(c->destdir); 76259be0971SAmir Goldstein 76359be0971SAmir Goldstein /* Restore timestamps on parent (best effort) */ 76459be0971SAmir Goldstein inode_lock(udir); 76559be0971SAmir Goldstein ovl_set_timestamps(c->destdir, &c->pstat); 76659be0971SAmir Goldstein inode_unlock(udir); 76759be0971SAmir Goldstein 76859be0971SAmir Goldstein ovl_dentry_set_upper_alias(c->dentry); 769fd210b7dSMiklos Szeredi } 770a6fb235aSMiklos Szeredi 771aa3ff3c1SAmir Goldstein out: 772aa3ff3c1SAmir Goldstein if (to_index) 773aa3ff3c1SAmir Goldstein kfree(c->destname.name); 774a6fb235aSMiklos Szeredi return err; 775a6fb235aSMiklos Szeredi } 776a6fb235aSMiklos Szeredi 77744d5bf10SVivek Goyal static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode, 77844d5bf10SVivek Goyal int flags) 77944d5bf10SVivek Goyal { 78044d5bf10SVivek Goyal struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 78144d5bf10SVivek Goyal 78244d5bf10SVivek Goyal if (!ofs->config.metacopy) 78344d5bf10SVivek Goyal return false; 78444d5bf10SVivek Goyal 78544d5bf10SVivek Goyal if (!S_ISREG(mode)) 78644d5bf10SVivek Goyal return false; 78744d5bf10SVivek Goyal 78844d5bf10SVivek Goyal if (flags && ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC))) 78944d5bf10SVivek Goyal return false; 79044d5bf10SVivek Goyal 79144d5bf10SVivek Goyal return true; 79244d5bf10SVivek Goyal } 79344d5bf10SVivek Goyal 794de7a52c9SMiklos Szeredi static ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value) 795fee0f298SMiklos Szeredi { 796fee0f298SMiklos Szeredi ssize_t res; 797de7a52c9SMiklos Szeredi char *buf; 798fee0f298SMiklos Szeredi 799fee0f298SMiklos Szeredi res = vfs_getxattr(dentry, name, NULL, 0); 800fee0f298SMiklos Szeredi if (res == -ENODATA || res == -EOPNOTSUPP) 801de7a52c9SMiklos Szeredi res = 0; 802fee0f298SMiklos Szeredi 803de7a52c9SMiklos Szeredi if (res > 0) { 804de7a52c9SMiklos Szeredi buf = kzalloc(res, GFP_KERNEL); 805fee0f298SMiklos Szeredi if (!buf) 806fee0f298SMiklos Szeredi return -ENOMEM; 807fee0f298SMiklos Szeredi 808fee0f298SMiklos Szeredi res = vfs_getxattr(dentry, name, buf, res); 809fee0f298SMiklos Szeredi if (res < 0) 810fee0f298SMiklos Szeredi kfree(buf); 811de7a52c9SMiklos Szeredi else 812de7a52c9SMiklos Szeredi *value = buf; 813de7a52c9SMiklos Szeredi } 814fee0f298SMiklos Szeredi return res; 815fee0f298SMiklos Szeredi } 816fee0f298SMiklos Szeredi 8170c288874SVivek Goyal /* Copy up data of an inode which was copied up metadata only in the past. */ 8180c288874SVivek Goyal static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) 8190c288874SVivek Goyal { 820c86243b0SVivek Goyal struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); 8214f93b426SVivek Goyal struct path upperpath, datapath; 8220c288874SVivek Goyal int err; 823993a0b2aSVivek Goyal char *capability = NULL; 8243f649ab7SKees Cook ssize_t cap_size; 8250c288874SVivek Goyal 8260c288874SVivek Goyal ovl_path_upper(c->dentry, &upperpath); 8270c288874SVivek Goyal if (WARN_ON(upperpath.dentry == NULL)) 8280c288874SVivek Goyal return -EIO; 8290c288874SVivek Goyal 8304f93b426SVivek Goyal ovl_path_lowerdata(c->dentry, &datapath); 8314f93b426SVivek Goyal if (WARN_ON(datapath.dentry == NULL)) 8324f93b426SVivek Goyal return -EIO; 8334f93b426SVivek Goyal 834993a0b2aSVivek Goyal if (c->stat.size) { 835993a0b2aSVivek Goyal err = cap_size = ovl_getxattr(upperpath.dentry, XATTR_NAME_CAPS, 836de7a52c9SMiklos Szeredi &capability); 837de7a52c9SMiklos Szeredi if (cap_size < 0) 838993a0b2aSVivek Goyal goto out; 839993a0b2aSVivek Goyal } 840993a0b2aSVivek Goyal 841c86243b0SVivek Goyal err = ovl_copy_up_data(ofs, &datapath, &upperpath, c->stat.size); 8420c288874SVivek Goyal if (err) 843993a0b2aSVivek Goyal goto out_free; 844993a0b2aSVivek Goyal 845993a0b2aSVivek Goyal /* 846993a0b2aSVivek Goyal * Writing to upper file will clear security.capability xattr. We 847993a0b2aSVivek Goyal * don't want that to happen for normal copy-up operation. 848993a0b2aSVivek Goyal */ 849993a0b2aSVivek Goyal if (capability) { 85071097047SMiklos Szeredi err = vfs_setxattr(upperpath.dentry, XATTR_NAME_CAPS, 851993a0b2aSVivek Goyal capability, cap_size, 0); 852993a0b2aSVivek Goyal if (err) 853993a0b2aSVivek Goyal goto out_free; 854993a0b2aSVivek Goyal } 855993a0b2aSVivek Goyal 8560c288874SVivek Goyal 857610afc0bSMiklos Szeredi err = ovl_do_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY); 8580c288874SVivek Goyal if (err) 859993a0b2aSVivek Goyal goto out_free; 8600c288874SVivek Goyal 8610c288874SVivek Goyal ovl_set_upperdata(d_inode(c->dentry)); 862993a0b2aSVivek Goyal out_free: 863993a0b2aSVivek Goyal kfree(capability); 864993a0b2aSVivek Goyal out: 8650c288874SVivek Goyal return err; 8660c288874SVivek Goyal } 8670c288874SVivek Goyal 868a6fb235aSMiklos Szeredi static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, 869a6fb235aSMiklos Szeredi int flags) 870a6fb235aSMiklos Szeredi { 871a6fb235aSMiklos Szeredi int err; 872a6fb235aSMiklos Szeredi DEFINE_DELAYED_CALL(done); 873a6fb235aSMiklos Szeredi struct path parentpath; 874a6fb235aSMiklos Szeredi struct ovl_copy_up_ctx ctx = { 875a6fb235aSMiklos Szeredi .parent = parent, 876a6fb235aSMiklos Szeredi .dentry = dentry, 877a6fb235aSMiklos Szeredi .workdir = ovl_workdir(dentry), 878a6fb235aSMiklos Szeredi }; 879a6fb235aSMiklos Szeredi 880a6fb235aSMiklos Szeredi if (WARN_ON(!ctx.workdir)) 881a6fb235aSMiklos Szeredi return -EROFS; 882a6fb235aSMiklos Szeredi 883a6fb235aSMiklos Szeredi ovl_path_lower(dentry, &ctx.lowerpath); 884a6fb235aSMiklos Szeredi err = vfs_getattr(&ctx.lowerpath, &ctx.stat, 885a6fb235aSMiklos Szeredi STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); 886a6fb235aSMiklos Szeredi if (err) 887a6fb235aSMiklos Szeredi return err; 888a6fb235aSMiklos Szeredi 88944d5bf10SVivek Goyal ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags); 89044d5bf10SVivek Goyal 891aa3ff3c1SAmir Goldstein if (parent) { 892a6fb235aSMiklos Szeredi ovl_path_upper(parent, &parentpath); 89359be0971SAmir Goldstein ctx.destdir = parentpath.dentry; 89459be0971SAmir Goldstein ctx.destname = dentry->d_name; 895a6fb235aSMiklos Szeredi 896a6fb235aSMiklos Szeredi err = vfs_getattr(&parentpath, &ctx.pstat, 897aa3ff3c1SAmir Goldstein STATX_ATIME | STATX_MTIME, 898aa3ff3c1SAmir Goldstein AT_STATX_SYNC_AS_STAT); 899a6fb235aSMiklos Szeredi if (err) 900a6fb235aSMiklos Szeredi return err; 901aa3ff3c1SAmir Goldstein } 902a6fb235aSMiklos Szeredi 903a6fb235aSMiklos Szeredi /* maybe truncate regular file. this has no effect on dirs */ 904a6fb235aSMiklos Szeredi if (flags & O_TRUNC) 905a6fb235aSMiklos Szeredi ctx.stat.size = 0; 906a6fb235aSMiklos Szeredi 907a6fb235aSMiklos Szeredi if (S_ISLNK(ctx.stat.mode)) { 908a6fb235aSMiklos Szeredi ctx.link = vfs_get_link(ctx.lowerpath.dentry, &done); 909a6fb235aSMiklos Szeredi if (IS_ERR(ctx.link)) 910a6fb235aSMiklos Szeredi return PTR_ERR(ctx.link); 911a6fb235aSMiklos Szeredi } 912a6fb235aSMiklos Szeredi 9130c288874SVivek Goyal err = ovl_copy_up_start(dentry, flags); 914fd210b7dSMiklos Szeredi /* err < 0: interrupted, err > 0: raced with another copy-up */ 915fd210b7dSMiklos Szeredi if (unlikely(err)) { 916fd210b7dSMiklos Szeredi if (err > 0) 917fd210b7dSMiklos Szeredi err = 0; 918fd210b7dSMiklos Szeredi } else { 91959be0971SAmir Goldstein if (!ovl_dentry_upper(dentry)) 920a6fb235aSMiklos Szeredi err = ovl_do_copy_up(&ctx); 921aa3ff3c1SAmir Goldstein if (!err && parent && !ovl_dentry_has_upper_alias(dentry)) 922f4439de1SAmir Goldstein err = ovl_link_up(&ctx); 9230c288874SVivek Goyal if (!err && ovl_dentry_needs_data_copy_up_locked(dentry, flags)) 9240c288874SVivek Goyal err = ovl_copy_up_meta_inode_data(&ctx); 925fd210b7dSMiklos Szeredi ovl_copy_up_end(dentry); 926fd210b7dSMiklos Szeredi } 9277764235bSMiklos Szeredi do_delayed_call(&done); 928e9be9d5eSMiklos Szeredi 929e9be9d5eSMiklos Szeredi return err; 930e9be9d5eSMiklos Szeredi } 931e9be9d5eSMiklos Szeredi 9325ac8e802Syoungjun static int ovl_copy_up_flags(struct dentry *dentry, int flags) 933e9be9d5eSMiklos Szeredi { 9348eac98b8SVivek Goyal int err = 0; 9358eac98b8SVivek Goyal const struct cred *old_cred = ovl_override_creds(dentry->d_sb); 936aa3ff3c1SAmir Goldstein bool disconnected = (dentry->d_flags & DCACHE_DISCONNECTED); 937aa3ff3c1SAmir Goldstein 938aa3ff3c1SAmir Goldstein /* 939aa3ff3c1SAmir Goldstein * With NFS export, copy up can get called for a disconnected non-dir. 940aa3ff3c1SAmir Goldstein * In this case, we will copy up lower inode to index dir without 941aa3ff3c1SAmir Goldstein * linking it to upper dir. 942aa3ff3c1SAmir Goldstein */ 943aa3ff3c1SAmir Goldstein if (WARN_ON(disconnected && d_is_dir(dentry))) 944aa3ff3c1SAmir Goldstein return -EIO; 945e9be9d5eSMiklos Szeredi 946e9be9d5eSMiklos Szeredi while (!err) { 947e9be9d5eSMiklos Szeredi struct dentry *next; 948aa3ff3c1SAmir Goldstein struct dentry *parent = NULL; 949e9be9d5eSMiklos Szeredi 9500c288874SVivek Goyal if (ovl_already_copied_up(dentry, flags)) 951e9be9d5eSMiklos Szeredi break; 952e9be9d5eSMiklos Szeredi 953e9be9d5eSMiklos Szeredi next = dget(dentry); 954e9be9d5eSMiklos Szeredi /* find the topmost dentry not yet copied up */ 955aa3ff3c1SAmir Goldstein for (; !disconnected;) { 956e9be9d5eSMiklos Szeredi parent = dget_parent(next); 957e9be9d5eSMiklos Szeredi 95859be0971SAmir Goldstein if (ovl_dentry_upper(parent)) 959e9be9d5eSMiklos Szeredi break; 960e9be9d5eSMiklos Szeredi 961e9be9d5eSMiklos Szeredi dput(next); 962e9be9d5eSMiklos Szeredi next = parent; 963e9be9d5eSMiklos Szeredi } 964e9be9d5eSMiklos Szeredi 965a6fb235aSMiklos Szeredi err = ovl_copy_up_one(parent, next, flags); 966e9be9d5eSMiklos Szeredi 967e9be9d5eSMiklos Szeredi dput(parent); 968e9be9d5eSMiklos Szeredi dput(next); 969e9be9d5eSMiklos Szeredi } 9708eac98b8SVivek Goyal revert_creds(old_cred); 971e9be9d5eSMiklos Szeredi 972e9be9d5eSMiklos Szeredi return err; 973e9be9d5eSMiklos Szeredi } 9749aba6521SAmir Goldstein 975d6eac039SVivek Goyal static bool ovl_open_need_copy_up(struct dentry *dentry, int flags) 976d6eac039SVivek Goyal { 977d6eac039SVivek Goyal /* Copy up of disconnected dentry does not set upper alias */ 9780c288874SVivek Goyal if (ovl_already_copied_up(dentry, flags)) 979d6eac039SVivek Goyal return false; 980d6eac039SVivek Goyal 981d6eac039SVivek Goyal if (special_file(d_inode(dentry)->i_mode)) 982d6eac039SVivek Goyal return false; 983d6eac039SVivek Goyal 9840c288874SVivek Goyal if (!ovl_open_flags_need_copy_up(flags)) 985d6eac039SVivek Goyal return false; 986d6eac039SVivek Goyal 987d6eac039SVivek Goyal return true; 988d6eac039SVivek Goyal } 989d6eac039SVivek Goyal 9903428030dSAmir Goldstein int ovl_maybe_copy_up(struct dentry *dentry, int flags) 991d6eac039SVivek Goyal { 992d6eac039SVivek Goyal int err = 0; 993d6eac039SVivek Goyal 9943428030dSAmir Goldstein if (ovl_open_need_copy_up(dentry, flags)) { 995d6eac039SVivek Goyal err = ovl_want_write(dentry); 996d6eac039SVivek Goyal if (!err) { 9973428030dSAmir Goldstein err = ovl_copy_up_flags(dentry, flags); 998d6eac039SVivek Goyal ovl_drop_write(dentry); 999d6eac039SVivek Goyal } 1000d6eac039SVivek Goyal } 1001d6eac039SVivek Goyal 1002d6eac039SVivek Goyal return err; 1003d6eac039SVivek Goyal } 1004d6eac039SVivek Goyal 1005d1e6f6a9SVivek Goyal int ovl_copy_up_with_data(struct dentry *dentry) 1006d1e6f6a9SVivek Goyal { 1007d1e6f6a9SVivek Goyal return ovl_copy_up_flags(dentry, O_WRONLY); 1008d1e6f6a9SVivek Goyal } 1009d1e6f6a9SVivek Goyal 10109aba6521SAmir Goldstein int ovl_copy_up(struct dentry *dentry) 10119aba6521SAmir Goldstein { 10129aba6521SAmir Goldstein return ovl_copy_up_flags(dentry, 0); 10139aba6521SAmir Goldstein } 1014