xref: /openbmc/linux/fs/overlayfs/super.c (revision 37ebf056)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2e9be9d5eSMiklos Szeredi /*
3e9be9d5eSMiklos Szeredi  *
4e9be9d5eSMiklos Szeredi  * Copyright (C) 2011 Novell Inc.
5e9be9d5eSMiklos Szeredi  */
6e9be9d5eSMiklos Szeredi 
75b825c3aSIngo Molnar #include <uapi/linux/magic.h>
8e9be9d5eSMiklos Szeredi #include <linux/fs.h>
9e9be9d5eSMiklos Szeredi #include <linux/namei.h>
10e9be9d5eSMiklos Szeredi #include <linux/xattr.h>
11e9be9d5eSMiklos Szeredi #include <linux/mount.h>
12e9be9d5eSMiklos Szeredi #include <linux/parser.h>
13e9be9d5eSMiklos Szeredi #include <linux/module.h>
14cc259639SAndy Whitcroft #include <linux/statfs.h>
15f45827e8SErez Zadok #include <linux/seq_file.h>
16d837a49bSMiklos Szeredi #include <linux/posix_acl_xattr.h>
17e487d889SAmir Goldstein #include <linux/exportfs.h>
182b1a7746SMiklos Szeredi #include <linux/file.h>
19e9be9d5eSMiklos Szeredi #include "overlayfs.h"
20e9be9d5eSMiklos Szeredi 
21e9be9d5eSMiklos Szeredi MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
22e9be9d5eSMiklos Szeredi MODULE_DESCRIPTION("Overlay filesystem");
23e9be9d5eSMiklos Szeredi MODULE_LICENSE("GPL");
24e9be9d5eSMiklos Szeredi 
25e9be9d5eSMiklos Szeredi 
26e9be9d5eSMiklos Szeredi struct ovl_dir_cache;
27e9be9d5eSMiklos Szeredi 
28a78d9f0dSMiklos Szeredi #define OVL_MAX_STACK 500
29a78d9f0dSMiklos Szeredi 
30688ea0e5SMiklos Szeredi static bool ovl_redirect_dir_def = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR);
31688ea0e5SMiklos Szeredi module_param_named(redirect_dir, ovl_redirect_dir_def, bool, 0644);
32253e7483SNicolas Schier MODULE_PARM_DESC(redirect_dir,
33688ea0e5SMiklos Szeredi 		 "Default to on or off for the redirect_dir feature");
34e9be9d5eSMiklos Szeredi 
35438c84c2SMiklos Szeredi static bool ovl_redirect_always_follow =
36438c84c2SMiklos Szeredi 	IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW);
37438c84c2SMiklos Szeredi module_param_named(redirect_always_follow, ovl_redirect_always_follow,
38438c84c2SMiklos Szeredi 		   bool, 0644);
39253e7483SNicolas Schier MODULE_PARM_DESC(redirect_always_follow,
40438c84c2SMiklos Szeredi 		 "Follow redirects even if redirect_dir feature is turned off");
41438c84c2SMiklos Szeredi 
4202bcd157SAmir Goldstein static bool ovl_index_def = IS_ENABLED(CONFIG_OVERLAY_FS_INDEX);
4302bcd157SAmir Goldstein module_param_named(index, ovl_index_def, bool, 0644);
44253e7483SNicolas Schier MODULE_PARM_DESC(index,
4502bcd157SAmir Goldstein 		 "Default to on or off for the inodes index feature");
4602bcd157SAmir Goldstein 
47f168f109SAmir Goldstein static bool ovl_nfs_export_def = IS_ENABLED(CONFIG_OVERLAY_FS_NFS_EXPORT);
48f168f109SAmir Goldstein module_param_named(nfs_export, ovl_nfs_export_def, bool, 0644);
49253e7483SNicolas Schier MODULE_PARM_DESC(nfs_export,
50f168f109SAmir Goldstein 		 "Default to on or off for the NFS export feature");
51f168f109SAmir Goldstein 
52795939a9SAmir Goldstein static bool ovl_xino_auto_def = IS_ENABLED(CONFIG_OVERLAY_FS_XINO_AUTO);
53795939a9SAmir Goldstein module_param_named(xino_auto, ovl_xino_auto_def, bool, 0644);
54253e7483SNicolas Schier MODULE_PARM_DESC(xino_auto,
55795939a9SAmir Goldstein 		 "Auto enable xino feature");
56795939a9SAmir Goldstein 
57d5791044SVivek Goyal static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY);
58d5791044SVivek Goyal module_param_named(metacopy, ovl_metacopy_def, bool, 0644);
59253e7483SNicolas Schier MODULE_PARM_DESC(metacopy,
60d5791044SVivek Goyal 		 "Default to on or off for the metadata only copy up feature");
61d5791044SVivek Goyal 
622d902671SMiklos Szeredi static struct dentry *ovl_d_real(struct dentry *dentry,
63fb16043bSMiklos Szeredi 				 const struct inode *inode)
64d101a125SMiklos Szeredi {
65cef4cbffSMiklos Szeredi 	struct dentry *real = NULL, *lower;
66d101a125SMiklos Szeredi 
67e8c985baSMiklos Szeredi 	/* It's an overlay file */
68e8c985baSMiklos Szeredi 	if (inode && d_inode(dentry) == inode)
69e8c985baSMiklos Szeredi 		return dentry;
70e8c985baSMiklos Szeredi 
71ca4c8a3aSMiklos Szeredi 	if (!d_is_reg(dentry)) {
72d101a125SMiklos Szeredi 		if (!inode || inode == d_inode(dentry))
73d101a125SMiklos Szeredi 			return dentry;
74d101a125SMiklos Szeredi 		goto bug;
75d101a125SMiklos Szeredi 	}
76d101a125SMiklos Szeredi 
77d101a125SMiklos Szeredi 	real = ovl_dentry_upper(dentry);
782c3d7358SVivek Goyal 	if (real && (inode == d_inode(real)))
79d101a125SMiklos Szeredi 		return real;
80d101a125SMiklos Szeredi 
812c3d7358SVivek Goyal 	if (real && !inode && ovl_has_upperdata(d_inode(dentry)))
822c3d7358SVivek Goyal 		return real;
832c3d7358SVivek Goyal 
84cef4cbffSMiklos Szeredi 	lower = ovl_dentry_lowerdata(dentry);
85cef4cbffSMiklos Szeredi 	if (!lower)
86d101a125SMiklos Szeredi 		goto bug;
87cef4cbffSMiklos Szeredi 	real = lower;
88d101a125SMiklos Szeredi 
89c4fcfc16SMiklos Szeredi 	/* Handle recursion */
90fb16043bSMiklos Szeredi 	real = d_real(real, inode);
91c4fcfc16SMiklos Szeredi 
92d101a125SMiklos Szeredi 	if (!inode || inode == d_inode(real))
93d101a125SMiklos Szeredi 		return real;
94d101a125SMiklos Szeredi bug:
95cef4cbffSMiklos Szeredi 	WARN(1, "%s(%pd4, %s:%lu): real dentry (%p/%lu) not found\n",
96cef4cbffSMiklos Szeredi 	     __func__, dentry, inode ? inode->i_sb->s_id : "NULL",
97cef4cbffSMiklos Szeredi 	     inode ? inode->i_ino : 0, real,
98cef4cbffSMiklos Szeredi 	     real && d_inode(real) ? d_inode(real)->i_ino : 0);
99d101a125SMiklos Szeredi 	return dentry;
100d101a125SMiklos Szeredi }
101d101a125SMiklos Szeredi 
1023bb7df92SMiklos Szeredi static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak)
1033bb7df92SMiklos Szeredi {
1043bb7df92SMiklos Szeredi 	int ret = 1;
1053bb7df92SMiklos Szeredi 
1063bb7df92SMiklos Szeredi 	if (weak) {
1073bb7df92SMiklos Szeredi 		if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE)
1083bb7df92SMiklos Szeredi 			ret =  d->d_op->d_weak_revalidate(d, flags);
1093bb7df92SMiklos Szeredi 	} else if (d->d_flags & DCACHE_OP_REVALIDATE) {
1103bb7df92SMiklos Szeredi 		ret = d->d_op->d_revalidate(d, flags);
1113bb7df92SMiklos Szeredi 		if (!ret) {
1123bb7df92SMiklos Szeredi 			if (!(flags & LOOKUP_RCU))
1133bb7df92SMiklos Szeredi 				d_invalidate(d);
1143bb7df92SMiklos Szeredi 			ret = -ESTALE;
1153bb7df92SMiklos Szeredi 		}
1163bb7df92SMiklos Szeredi 	}
1173bb7df92SMiklos Szeredi 	return ret;
1183bb7df92SMiklos Szeredi }
1193bb7df92SMiklos Szeredi 
1203bb7df92SMiklos Szeredi static int ovl_dentry_revalidate_common(struct dentry *dentry,
1213bb7df92SMiklos Szeredi 					unsigned int flags, bool weak)
1227c03b5d4SMiklos Szeredi {
123a6ff2bc0SAmir Goldstein 	struct ovl_entry *oe = OVL_E(dentry);
1245522c9c7SAmir Goldstein 	struct ovl_path *lowerstack = ovl_lowerstack(oe);
125672e4268SChen Zhongjin 	struct inode *inode = d_inode_rcu(dentry);
126bccece1eSMiklos Szeredi 	struct dentry *upper;
1277c03b5d4SMiklos Szeredi 	unsigned int i;
1287c03b5d4SMiklos Szeredi 	int ret = 1;
1297c03b5d4SMiklos Szeredi 
130672e4268SChen Zhongjin 	/* Careful in RCU mode */
131672e4268SChen Zhongjin 	if (!inode)
132672e4268SChen Zhongjin 		return -ECHILD;
133672e4268SChen Zhongjin 
134672e4268SChen Zhongjin 	upper = ovl_i_dentry_upper(inode);
135bccece1eSMiklos Szeredi 	if (upper)
136bccece1eSMiklos Szeredi 		ret = ovl_revalidate_real(upper, flags, weak);
137bccece1eSMiklos Szeredi 
1385522c9c7SAmir Goldstein 	for (i = 0; ret > 0 && i < ovl_numlower(oe); i++)
1395522c9c7SAmir Goldstein 		ret = ovl_revalidate_real(lowerstack[i].dentry, flags, weak);
1405522c9c7SAmir Goldstein 
1417c03b5d4SMiklos Szeredi 	return ret;
1427c03b5d4SMiklos Szeredi }
1433bb7df92SMiklos Szeredi 
1443bb7df92SMiklos Szeredi static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags)
1453bb7df92SMiklos Szeredi {
1463bb7df92SMiklos Szeredi 	return ovl_dentry_revalidate_common(dentry, flags, false);
1477c03b5d4SMiklos Szeredi }
1487c03b5d4SMiklos Szeredi 
1497c03b5d4SMiklos Szeredi static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
1507c03b5d4SMiklos Szeredi {
1513bb7df92SMiklos Szeredi 	return ovl_dentry_revalidate_common(dentry, flags, true);
1527c03b5d4SMiklos Szeredi }
1537c03b5d4SMiklos Szeredi 
154e9be9d5eSMiklos Szeredi static const struct dentry_operations ovl_dentry_operations = {
155d101a125SMiklos Szeredi 	.d_real = ovl_d_real,
1567c03b5d4SMiklos Szeredi 	.d_revalidate = ovl_dentry_revalidate,
1577c03b5d4SMiklos Szeredi 	.d_weak_revalidate = ovl_dentry_weak_revalidate,
1587c03b5d4SMiklos Szeredi };
1597c03b5d4SMiklos Szeredi 
16013cf199dSAmir Goldstein static struct kmem_cache *ovl_inode_cachep;
16113cf199dSAmir Goldstein 
16213cf199dSAmir Goldstein static struct inode *ovl_alloc_inode(struct super_block *sb)
16313cf199dSAmir Goldstein {
164fd60b288SMuchun Song 	struct ovl_inode *oi = alloc_inode_sb(sb, ovl_inode_cachep, GFP_KERNEL);
16513cf199dSAmir Goldstein 
166b3885bd6SHirofumi Nakagawa 	if (!oi)
167b3885bd6SHirofumi Nakagawa 		return NULL;
168b3885bd6SHirofumi Nakagawa 
16904a01ac7SMiklos Szeredi 	oi->cache = NULL;
170cf31c463SMiklos Szeredi 	oi->redirect = NULL;
17104a01ac7SMiklos Szeredi 	oi->version = 0;
17213c72075SMiklos Szeredi 	oi->flags = 0;
17309d8b586SMiklos Szeredi 	oi->__upperdentry = NULL;
1740af950f5SAmir Goldstein 	oi->oe = NULL;
175a015dafcSAmir Goldstein 	mutex_init(&oi->lock);
17625b7713aSMiklos Szeredi 
17713cf199dSAmir Goldstein 	return &oi->vfs_inode;
17813cf199dSAmir Goldstein }
17913cf199dSAmir Goldstein 
1800b269dedSAl Viro static void ovl_free_inode(struct inode *inode)
18113cf199dSAmir Goldstein {
1820b269dedSAl Viro 	struct ovl_inode *oi = OVL_I(inode);
18313cf199dSAmir Goldstein 
1840b269dedSAl Viro 	kfree(oi->redirect);
1850b269dedSAl Viro 	mutex_destroy(&oi->lock);
1860b269dedSAl Viro 	kmem_cache_free(ovl_inode_cachep, oi);
18713cf199dSAmir Goldstein }
18813cf199dSAmir Goldstein 
18913cf199dSAmir Goldstein static void ovl_destroy_inode(struct inode *inode)
19013cf199dSAmir Goldstein {
19109d8b586SMiklos Szeredi 	struct ovl_inode *oi = OVL_I(inode);
19209d8b586SMiklos Szeredi 
19309d8b586SMiklos Szeredi 	dput(oi->__upperdentry);
1940af950f5SAmir Goldstein 	ovl_free_entry(oi->oe);
1952664bd08SVivek Goyal 	if (S_ISDIR(inode->i_mode))
1964edb83bbSMiklos Szeredi 		ovl_dir_cache_free(inode);
19713cf199dSAmir Goldstein }
19813cf199dSAmir Goldstein 
199ad204488SMiklos Szeredi static void ovl_free_fs(struct ovl_fs *ofs)
200e9be9d5eSMiklos Szeredi {
201df820f8dSMiklos Szeredi 	struct vfsmount **mounts;
202dd662667SMiklos Szeredi 	unsigned i;
203e9be9d5eSMiklos Szeredi 
2040be0bfd2SAmir Goldstein 	iput(ofs->workbasedir_trap);
205146d62e5SAmir Goldstein 	iput(ofs->indexdir_trap);
206146d62e5SAmir Goldstein 	iput(ofs->workdir_trap);
207c21c839bSChengguang Xu 	dput(ofs->whiteout);
208ad204488SMiklos Szeredi 	dput(ofs->indexdir);
209ad204488SMiklos Szeredi 	dput(ofs->workdir);
210ad204488SMiklos Szeredi 	if (ofs->workdir_locked)
211ad204488SMiklos Szeredi 		ovl_inuse_unlock(ofs->workbasedir);
212ad204488SMiklos Szeredi 	dput(ofs->workbasedir);
213ad204488SMiklos Szeredi 	if (ofs->upperdir_locked)
21408f4c7c8SMiklos Szeredi 		ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root);
215df820f8dSMiklos Szeredi 
216df820f8dSMiklos Szeredi 	/* Hack!  Reuse ofs->layers as a vfsmount array before freeing it */
217df820f8dSMiklos Szeredi 	mounts = (struct vfsmount **) ofs->layers;
218b8e42a65SMiklos Szeredi 	for (i = 0; i < ofs->numlayer; i++) {
21994375f9dSAmir Goldstein 		iput(ofs->layers[i].trap);
220df820f8dSMiklos Szeredi 		mounts[i] = ofs->layers[i].mnt;
221146d62e5SAmir Goldstein 	}
222df820f8dSMiklos Szeredi 	kern_unmount_array(mounts, ofs->numlayer);
22394375f9dSAmir Goldstein 	kfree(ofs->layers);
224b7bf9908SAmir Goldstein 	for (i = 0; i < ofs->numfs; i++)
22507f1e596SAmir Goldstein 		free_anon_bdev(ofs->fs[i].pseudo_dev);
22607f1e596SAmir Goldstein 	kfree(ofs->fs);
227e9be9d5eSMiklos Szeredi 
228ad204488SMiklos Szeredi 	kfree(ofs->config.lowerdir);
229ad204488SMiklos Szeredi 	kfree(ofs->config.upperdir);
230ad204488SMiklos Szeredi 	kfree(ofs->config.workdir);
231438c84c2SMiklos Szeredi 	kfree(ofs->config.redirect_mode);
232ad204488SMiklos Szeredi 	if (ofs->creator_cred)
233ad204488SMiklos Szeredi 		put_cred(ofs->creator_cred);
234ad204488SMiklos Szeredi 	kfree(ofs);
235e9be9d5eSMiklos Szeredi }
236e9be9d5eSMiklos Szeredi 
237a9075cdbSMiklos Szeredi static void ovl_put_super(struct super_block *sb)
238a9075cdbSMiklos Szeredi {
239a9075cdbSMiklos Szeredi 	struct ovl_fs *ofs = sb->s_fs_info;
240a9075cdbSMiklos Szeredi 
241a9075cdbSMiklos Szeredi 	ovl_free_fs(ofs);
242a9075cdbSMiklos Szeredi }
243a9075cdbSMiklos Szeredi 
244e8d4bfe3SChengguang Xu /* Sync real dirty inodes in upper filesystem (if it exists) */
245e593b2bfSAmir Goldstein static int ovl_sync_fs(struct super_block *sb, int wait)
246e593b2bfSAmir Goldstein {
247ad204488SMiklos Szeredi 	struct ovl_fs *ofs = sb->s_fs_info;
248e593b2bfSAmir Goldstein 	struct super_block *upper_sb;
249e593b2bfSAmir Goldstein 	int ret;
250e593b2bfSAmir Goldstein 
251335d3fc5SSargun Dhillon 	ret = ovl_sync_status(ofs);
252335d3fc5SSargun Dhillon 	/*
253335d3fc5SSargun Dhillon 	 * We have to always set the err, because the return value isn't
254335d3fc5SSargun Dhillon 	 * checked in syncfs, and instead indirectly return an error via
255335d3fc5SSargun Dhillon 	 * the sb's writeback errseq, which VFS inspects after this call.
256335d3fc5SSargun Dhillon 	 */
257335d3fc5SSargun Dhillon 	if (ret < 0) {
258335d3fc5SSargun Dhillon 		errseq_set(&sb->s_wb_err, -EIO);
259335d3fc5SSargun Dhillon 		return -EIO;
260335d3fc5SSargun Dhillon 	}
261e8d4bfe3SChengguang Xu 
262335d3fc5SSargun Dhillon 	if (!ret)
263335d3fc5SSargun Dhillon 		return ret;
264335d3fc5SSargun Dhillon 
265e8d4bfe3SChengguang Xu 	/*
26632b1924bSKonstantin Khlebnikov 	 * Not called for sync(2) call or an emergency sync (SB_I_SKIP_SYNC).
26732b1924bSKonstantin Khlebnikov 	 * All the super blocks will be iterated, including upper_sb.
268e8d4bfe3SChengguang Xu 	 *
269e8d4bfe3SChengguang Xu 	 * If this is a syncfs(2) call, then we do need to call
270e8d4bfe3SChengguang Xu 	 * sync_filesystem() on upper_sb, but enough if we do it when being
271e8d4bfe3SChengguang Xu 	 * called with wait == 1.
272e8d4bfe3SChengguang Xu 	 */
273e8d4bfe3SChengguang Xu 	if (!wait)
274e593b2bfSAmir Goldstein 		return 0;
275e593b2bfSAmir Goldstein 
27608f4c7c8SMiklos Szeredi 	upper_sb = ovl_upper_mnt(ofs)->mnt_sb;
277e8d4bfe3SChengguang Xu 
278e593b2bfSAmir Goldstein 	down_read(&upper_sb->s_umount);
279e8d4bfe3SChengguang Xu 	ret = sync_filesystem(upper_sb);
280e593b2bfSAmir Goldstein 	up_read(&upper_sb->s_umount);
281e8d4bfe3SChengguang Xu 
282e593b2bfSAmir Goldstein 	return ret;
283e593b2bfSAmir Goldstein }
284e593b2bfSAmir Goldstein 
285cc259639SAndy Whitcroft /**
286cc259639SAndy Whitcroft  * ovl_statfs
2879c5dd803SYang Li  * @dentry: The dentry to query
288cc259639SAndy Whitcroft  * @buf: The struct kstatfs to fill in with stats
289cc259639SAndy Whitcroft  *
290cc259639SAndy Whitcroft  * Get the filesystem statistics.  As writes always target the upper layer
2914ebc5818SMiklos Szeredi  * filesystem pass the statfs to the upper filesystem (if it exists)
292cc259639SAndy Whitcroft  */
293cc259639SAndy Whitcroft static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf)
294cc259639SAndy Whitcroft {
295cc259639SAndy Whitcroft 	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
296cc259639SAndy Whitcroft 	struct dentry *root_dentry = dentry->d_sb->s_root;
297cc259639SAndy Whitcroft 	struct path path;
298cc259639SAndy Whitcroft 	int err;
299cc259639SAndy Whitcroft 
3004ebc5818SMiklos Szeredi 	ovl_path_real(root_dentry, &path);
301cc259639SAndy Whitcroft 
302cc259639SAndy Whitcroft 	err = vfs_statfs(&path, buf);
303cc259639SAndy Whitcroft 	if (!err) {
3046b2d5fe4SMiklos Szeredi 		buf->f_namelen = ofs->namelen;
305cc259639SAndy Whitcroft 		buf->f_type = OVERLAYFS_SUPER_MAGIC;
306cc259639SAndy Whitcroft 	}
307cc259639SAndy Whitcroft 
308cc259639SAndy Whitcroft 	return err;
309cc259639SAndy Whitcroft }
310cc259639SAndy Whitcroft 
31102bcd157SAmir Goldstein /* Will this overlay be forced to mount/remount ro? */
312ad204488SMiklos Szeredi static bool ovl_force_readonly(struct ovl_fs *ofs)
31302bcd157SAmir Goldstein {
31408f4c7c8SMiklos Szeredi 	return (!ovl_upper_mnt(ofs) || !ofs->workdir);
31502bcd157SAmir Goldstein }
31602bcd157SAmir Goldstein 
317438c84c2SMiklos Szeredi static const char *ovl_redirect_mode_def(void)
318438c84c2SMiklos Szeredi {
319438c84c2SMiklos Szeredi 	return ovl_redirect_dir_def ? "on" : "off";
320438c84c2SMiklos Szeredi }
321438c84c2SMiklos Szeredi 
322795939a9SAmir Goldstein static const char * const ovl_xino_str[] = {
323795939a9SAmir Goldstein 	"off",
324795939a9SAmir Goldstein 	"auto",
325795939a9SAmir Goldstein 	"on",
326795939a9SAmir Goldstein };
327795939a9SAmir Goldstein 
328795939a9SAmir Goldstein static inline int ovl_xino_def(void)
329795939a9SAmir Goldstein {
330795939a9SAmir Goldstein 	return ovl_xino_auto_def ? OVL_XINO_AUTO : OVL_XINO_OFF;
331795939a9SAmir Goldstein }
332795939a9SAmir Goldstein 
333f45827e8SErez Zadok /**
334f45827e8SErez Zadok  * ovl_show_options
3359c5dd803SYang Li  * @m: the seq_file handle
3369c5dd803SYang Li  * @dentry: The dentry to query
337f45827e8SErez Zadok  *
338f45827e8SErez Zadok  * Prints the mount options for a given superblock.
339f45827e8SErez Zadok  * Returns zero; does not fail.
340f45827e8SErez Zadok  */
341f45827e8SErez Zadok static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
342f45827e8SErez Zadok {
343f45827e8SErez Zadok 	struct super_block *sb = dentry->d_sb;
344ad204488SMiklos Szeredi 	struct ovl_fs *ofs = sb->s_fs_info;
345f45827e8SErez Zadok 
346ad204488SMiklos Szeredi 	seq_show_option(m, "lowerdir", ofs->config.lowerdir);
347ad204488SMiklos Szeredi 	if (ofs->config.upperdir) {
348ad204488SMiklos Szeredi 		seq_show_option(m, "upperdir", ofs->config.upperdir);
349ad204488SMiklos Szeredi 		seq_show_option(m, "workdir", ofs->config.workdir);
35053a08cb9SMiklos Szeredi 	}
351ad204488SMiklos Szeredi 	if (ofs->config.default_permissions)
3528d3095f4SMiklos Szeredi 		seq_puts(m, ",default_permissions");
353438c84c2SMiklos Szeredi 	if (strcmp(ofs->config.redirect_mode, ovl_redirect_mode_def()) != 0)
354438c84c2SMiklos Szeredi 		seq_printf(m, ",redirect_dir=%s", ofs->config.redirect_mode);
355ad204488SMiklos Szeredi 	if (ofs->config.index != ovl_index_def)
356438c84c2SMiklos Szeredi 		seq_printf(m, ",index=%s", ofs->config.index ? "on" : "off");
3575830fb6bSPavel Tikhomirov 	if (!ofs->config.uuid)
3585830fb6bSPavel Tikhomirov 		seq_puts(m, ",uuid=off");
359f168f109SAmir Goldstein 	if (ofs->config.nfs_export != ovl_nfs_export_def)
360f168f109SAmir Goldstein 		seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ?
361f168f109SAmir Goldstein 						"on" : "off");
3620f831ec8SAmir Goldstein 	if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(sb))
363795939a9SAmir Goldstein 		seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]);
364d5791044SVivek Goyal 	if (ofs->config.metacopy != ovl_metacopy_def)
365d5791044SVivek Goyal 		seq_printf(m, ",metacopy=%s",
366d5791044SVivek Goyal 			   ofs->config.metacopy ? "on" : "off");
367c86243b0SVivek Goyal 	if (ofs->config.ovl_volatile)
368c86243b0SVivek Goyal 		seq_puts(m, ",volatile");
369321b46b9SGiuseppe Scrivano 	if (ofs->config.userxattr)
370321b46b9SGiuseppe Scrivano 		seq_puts(m, ",userxattr");
371f45827e8SErez Zadok 	return 0;
372f45827e8SErez Zadok }
373f45827e8SErez Zadok 
3743cdf6fe9SSeunghun Lee static int ovl_remount(struct super_block *sb, int *flags, char *data)
3753cdf6fe9SSeunghun Lee {
376ad204488SMiklos Szeredi 	struct ovl_fs *ofs = sb->s_fs_info;
377399c109dSChengguang Xu 	struct super_block *upper_sb;
378399c109dSChengguang Xu 	int ret = 0;
3793cdf6fe9SSeunghun Lee 
3801751e8a6SLinus Torvalds 	if (!(*flags & SB_RDONLY) && ovl_force_readonly(ofs))
3813cdf6fe9SSeunghun Lee 		return -EROFS;
3823cdf6fe9SSeunghun Lee 
383399c109dSChengguang Xu 	if (*flags & SB_RDONLY && !sb_rdonly(sb)) {
38408f4c7c8SMiklos Szeredi 		upper_sb = ovl_upper_mnt(ofs)->mnt_sb;
385c86243b0SVivek Goyal 		if (ovl_should_sync(ofs)) {
386399c109dSChengguang Xu 			down_read(&upper_sb->s_umount);
387399c109dSChengguang Xu 			ret = sync_filesystem(upper_sb);
388399c109dSChengguang Xu 			up_read(&upper_sb->s_umount);
389399c109dSChengguang Xu 		}
390c86243b0SVivek Goyal 	}
391399c109dSChengguang Xu 
392399c109dSChengguang Xu 	return ret;
3933cdf6fe9SSeunghun Lee }
3943cdf6fe9SSeunghun Lee 
395e9be9d5eSMiklos Szeredi static const struct super_operations ovl_super_operations = {
39613cf199dSAmir Goldstein 	.alloc_inode	= ovl_alloc_inode,
3970b269dedSAl Viro 	.free_inode	= ovl_free_inode,
39813cf199dSAmir Goldstein 	.destroy_inode	= ovl_destroy_inode,
39913cf199dSAmir Goldstein 	.drop_inode	= generic_delete_inode,
400e9be9d5eSMiklos Szeredi 	.put_super	= ovl_put_super,
401e593b2bfSAmir Goldstein 	.sync_fs	= ovl_sync_fs,
402cc259639SAndy Whitcroft 	.statfs		= ovl_statfs,
403f45827e8SErez Zadok 	.show_options	= ovl_show_options,
4043cdf6fe9SSeunghun Lee 	.remount_fs	= ovl_remount,
405e9be9d5eSMiklos Szeredi };
406e9be9d5eSMiklos Szeredi 
407e9be9d5eSMiklos Szeredi enum {
408e9be9d5eSMiklos Szeredi 	OPT_LOWERDIR,
409e9be9d5eSMiklos Szeredi 	OPT_UPPERDIR,
410e9be9d5eSMiklos Szeredi 	OPT_WORKDIR,
4118d3095f4SMiklos Szeredi 	OPT_DEFAULT_PERMISSIONS,
412438c84c2SMiklos Szeredi 	OPT_REDIRECT_DIR,
41302bcd157SAmir Goldstein 	OPT_INDEX_ON,
41402bcd157SAmir Goldstein 	OPT_INDEX_OFF,
4155830fb6bSPavel Tikhomirov 	OPT_UUID_ON,
4165830fb6bSPavel Tikhomirov 	OPT_UUID_OFF,
417f168f109SAmir Goldstein 	OPT_NFS_EXPORT_ON,
4182d2f2d73SMiklos Szeredi 	OPT_USERXATTR,
419f168f109SAmir Goldstein 	OPT_NFS_EXPORT_OFF,
420795939a9SAmir Goldstein 	OPT_XINO_ON,
421795939a9SAmir Goldstein 	OPT_XINO_OFF,
422795939a9SAmir Goldstein 	OPT_XINO_AUTO,
423d5791044SVivek Goyal 	OPT_METACOPY_ON,
424d5791044SVivek Goyal 	OPT_METACOPY_OFF,
425c86243b0SVivek Goyal 	OPT_VOLATILE,
426e9be9d5eSMiklos Szeredi 	OPT_ERR,
427e9be9d5eSMiklos Szeredi };
428e9be9d5eSMiklos Szeredi 
429e9be9d5eSMiklos Szeredi static const match_table_t ovl_tokens = {
430e9be9d5eSMiklos Szeredi 	{OPT_LOWERDIR,			"lowerdir=%s"},
431e9be9d5eSMiklos Szeredi 	{OPT_UPPERDIR,			"upperdir=%s"},
432e9be9d5eSMiklos Szeredi 	{OPT_WORKDIR,			"workdir=%s"},
4338d3095f4SMiklos Szeredi 	{OPT_DEFAULT_PERMISSIONS,	"default_permissions"},
434438c84c2SMiklos Szeredi 	{OPT_REDIRECT_DIR,		"redirect_dir=%s"},
43502bcd157SAmir Goldstein 	{OPT_INDEX_ON,			"index=on"},
43602bcd157SAmir Goldstein 	{OPT_INDEX_OFF,			"index=off"},
4372d2f2d73SMiklos Szeredi 	{OPT_USERXATTR,			"userxattr"},
4385830fb6bSPavel Tikhomirov 	{OPT_UUID_ON,			"uuid=on"},
4395830fb6bSPavel Tikhomirov 	{OPT_UUID_OFF,			"uuid=off"},
440f168f109SAmir Goldstein 	{OPT_NFS_EXPORT_ON,		"nfs_export=on"},
441f168f109SAmir Goldstein 	{OPT_NFS_EXPORT_OFF,		"nfs_export=off"},
442795939a9SAmir Goldstein 	{OPT_XINO_ON,			"xino=on"},
443795939a9SAmir Goldstein 	{OPT_XINO_OFF,			"xino=off"},
444795939a9SAmir Goldstein 	{OPT_XINO_AUTO,			"xino=auto"},
445d5791044SVivek Goyal 	{OPT_METACOPY_ON,		"metacopy=on"},
446d5791044SVivek Goyal 	{OPT_METACOPY_OFF,		"metacopy=off"},
447c86243b0SVivek Goyal 	{OPT_VOLATILE,			"volatile"},
448e9be9d5eSMiklos Szeredi 	{OPT_ERR,			NULL}
449e9be9d5eSMiklos Szeredi };
450e9be9d5eSMiklos Szeredi 
45191c77947SMiklos Szeredi static char *ovl_next_opt(char **s)
45291c77947SMiklos Szeredi {
45391c77947SMiklos Szeredi 	char *sbegin = *s;
45491c77947SMiklos Szeredi 	char *p;
45591c77947SMiklos Szeredi 
45691c77947SMiklos Szeredi 	if (sbegin == NULL)
45791c77947SMiklos Szeredi 		return NULL;
45891c77947SMiklos Szeredi 
45991c77947SMiklos Szeredi 	for (p = sbegin; *p; p++) {
46091c77947SMiklos Szeredi 		if (*p == '\\') {
46191c77947SMiklos Szeredi 			p++;
46291c77947SMiklos Szeredi 			if (!*p)
46391c77947SMiklos Szeredi 				break;
46491c77947SMiklos Szeredi 		} else if (*p == ',') {
46591c77947SMiklos Szeredi 			*p = '\0';
46691c77947SMiklos Szeredi 			*s = p + 1;
46791c77947SMiklos Szeredi 			return sbegin;
46891c77947SMiklos Szeredi 		}
46991c77947SMiklos Szeredi 	}
47091c77947SMiklos Szeredi 	*s = NULL;
47191c77947SMiklos Szeredi 	return sbegin;
47291c77947SMiklos Szeredi }
47391c77947SMiklos Szeredi 
474438c84c2SMiklos Szeredi static int ovl_parse_redirect_mode(struct ovl_config *config, const char *mode)
475438c84c2SMiklos Szeredi {
476438c84c2SMiklos Szeredi 	if (strcmp(mode, "on") == 0) {
477438c84c2SMiklos Szeredi 		config->redirect_dir = true;
478438c84c2SMiklos Szeredi 		/*
479438c84c2SMiklos Szeredi 		 * Does not make sense to have redirect creation without
480438c84c2SMiklos Szeredi 		 * redirect following.
481438c84c2SMiklos Szeredi 		 */
482438c84c2SMiklos Szeredi 		config->redirect_follow = true;
483438c84c2SMiklos Szeredi 	} else if (strcmp(mode, "follow") == 0) {
484438c84c2SMiklos Szeredi 		config->redirect_follow = true;
485438c84c2SMiklos Szeredi 	} else if (strcmp(mode, "off") == 0) {
486438c84c2SMiklos Szeredi 		if (ovl_redirect_always_follow)
487438c84c2SMiklos Szeredi 			config->redirect_follow = true;
488438c84c2SMiklos Szeredi 	} else if (strcmp(mode, "nofollow") != 0) {
4891bd0a3aeSlijiazi 		pr_err("bad mount option \"redirect_dir=%s\"\n",
490438c84c2SMiklos Szeredi 		       mode);
491438c84c2SMiklos Szeredi 		return -EINVAL;
492438c84c2SMiklos Szeredi 	}
493438c84c2SMiklos Szeredi 
494438c84c2SMiklos Szeredi 	return 0;
495438c84c2SMiklos Szeredi }
496438c84c2SMiklos Szeredi 
497e9be9d5eSMiklos Szeredi static int ovl_parse_opt(char *opt, struct ovl_config *config)
498e9be9d5eSMiklos Szeredi {
499e9be9d5eSMiklos Szeredi 	char *p;
500d5791044SVivek Goyal 	int err;
501d47748e5SMiklos Szeredi 	bool metacopy_opt = false, redirect_opt = false;
502b0def88dSAmir Goldstein 	bool nfs_export_opt = false, index_opt = false;
503e9be9d5eSMiklos Szeredi 
504438c84c2SMiklos Szeredi 	config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
505438c84c2SMiklos Szeredi 	if (!config->redirect_mode)
506438c84c2SMiklos Szeredi 		return -ENOMEM;
507438c84c2SMiklos Szeredi 
50891c77947SMiklos Szeredi 	while ((p = ovl_next_opt(&opt)) != NULL) {
509e9be9d5eSMiklos Szeredi 		int token;
510e9be9d5eSMiklos Szeredi 		substring_t args[MAX_OPT_ARGS];
511e9be9d5eSMiklos Szeredi 
512e9be9d5eSMiklos Szeredi 		if (!*p)
513e9be9d5eSMiklos Szeredi 			continue;
514e9be9d5eSMiklos Szeredi 
515e9be9d5eSMiklos Szeredi 		token = match_token(p, ovl_tokens, args);
516e9be9d5eSMiklos Szeredi 		switch (token) {
517e9be9d5eSMiklos Szeredi 		case OPT_UPPERDIR:
518e9be9d5eSMiklos Szeredi 			kfree(config->upperdir);
519e9be9d5eSMiklos Szeredi 			config->upperdir = match_strdup(&args[0]);
520e9be9d5eSMiklos Szeredi 			if (!config->upperdir)
521e9be9d5eSMiklos Szeredi 				return -ENOMEM;
522e9be9d5eSMiklos Szeredi 			break;
523e9be9d5eSMiklos Szeredi 
524e9be9d5eSMiklos Szeredi 		case OPT_LOWERDIR:
525e9be9d5eSMiklos Szeredi 			kfree(config->lowerdir);
526e9be9d5eSMiklos Szeredi 			config->lowerdir = match_strdup(&args[0]);
527e9be9d5eSMiklos Szeredi 			if (!config->lowerdir)
528e9be9d5eSMiklos Szeredi 				return -ENOMEM;
529e9be9d5eSMiklos Szeredi 			break;
530e9be9d5eSMiklos Szeredi 
531e9be9d5eSMiklos Szeredi 		case OPT_WORKDIR:
532e9be9d5eSMiklos Szeredi 			kfree(config->workdir);
533e9be9d5eSMiklos Szeredi 			config->workdir = match_strdup(&args[0]);
534e9be9d5eSMiklos Szeredi 			if (!config->workdir)
535e9be9d5eSMiklos Szeredi 				return -ENOMEM;
536e9be9d5eSMiklos Szeredi 			break;
537e9be9d5eSMiklos Szeredi 
5388d3095f4SMiklos Szeredi 		case OPT_DEFAULT_PERMISSIONS:
5398d3095f4SMiklos Szeredi 			config->default_permissions = true;
5408d3095f4SMiklos Szeredi 			break;
5418d3095f4SMiklos Szeredi 
542438c84c2SMiklos Szeredi 		case OPT_REDIRECT_DIR:
543438c84c2SMiklos Szeredi 			kfree(config->redirect_mode);
544438c84c2SMiklos Szeredi 			config->redirect_mode = match_strdup(&args[0]);
545438c84c2SMiklos Szeredi 			if (!config->redirect_mode)
546438c84c2SMiklos Szeredi 				return -ENOMEM;
547d47748e5SMiklos Szeredi 			redirect_opt = true;
548a6c60655SMiklos Szeredi 			break;
549a6c60655SMiklos Szeredi 
55002bcd157SAmir Goldstein 		case OPT_INDEX_ON:
55102bcd157SAmir Goldstein 			config->index = true;
552b0def88dSAmir Goldstein 			index_opt = true;
55302bcd157SAmir Goldstein 			break;
55402bcd157SAmir Goldstein 
55502bcd157SAmir Goldstein 		case OPT_INDEX_OFF:
55602bcd157SAmir Goldstein 			config->index = false;
557b0def88dSAmir Goldstein 			index_opt = true;
55802bcd157SAmir Goldstein 			break;
55902bcd157SAmir Goldstein 
5605830fb6bSPavel Tikhomirov 		case OPT_UUID_ON:
5615830fb6bSPavel Tikhomirov 			config->uuid = true;
5625830fb6bSPavel Tikhomirov 			break;
5635830fb6bSPavel Tikhomirov 
5645830fb6bSPavel Tikhomirov 		case OPT_UUID_OFF:
5655830fb6bSPavel Tikhomirov 			config->uuid = false;
5665830fb6bSPavel Tikhomirov 			break;
5675830fb6bSPavel Tikhomirov 
568f168f109SAmir Goldstein 		case OPT_NFS_EXPORT_ON:
569f168f109SAmir Goldstein 			config->nfs_export = true;
570b0def88dSAmir Goldstein 			nfs_export_opt = true;
571f168f109SAmir Goldstein 			break;
572f168f109SAmir Goldstein 
573f168f109SAmir Goldstein 		case OPT_NFS_EXPORT_OFF:
574f168f109SAmir Goldstein 			config->nfs_export = false;
575b0def88dSAmir Goldstein 			nfs_export_opt = true;
576f168f109SAmir Goldstein 			break;
577f168f109SAmir Goldstein 
578795939a9SAmir Goldstein 		case OPT_XINO_ON:
579795939a9SAmir Goldstein 			config->xino = OVL_XINO_ON;
580795939a9SAmir Goldstein 			break;
581795939a9SAmir Goldstein 
582795939a9SAmir Goldstein 		case OPT_XINO_OFF:
583795939a9SAmir Goldstein 			config->xino = OVL_XINO_OFF;
584795939a9SAmir Goldstein 			break;
585795939a9SAmir Goldstein 
586795939a9SAmir Goldstein 		case OPT_XINO_AUTO:
587795939a9SAmir Goldstein 			config->xino = OVL_XINO_AUTO;
588795939a9SAmir Goldstein 			break;
589795939a9SAmir Goldstein 
590d5791044SVivek Goyal 		case OPT_METACOPY_ON:
591d5791044SVivek Goyal 			config->metacopy = true;
592d47748e5SMiklos Szeredi 			metacopy_opt = true;
593d5791044SVivek Goyal 			break;
594d5791044SVivek Goyal 
595d5791044SVivek Goyal 		case OPT_METACOPY_OFF:
596d5791044SVivek Goyal 			config->metacopy = false;
597b0def88dSAmir Goldstein 			metacopy_opt = true;
598d5791044SVivek Goyal 			break;
599d5791044SVivek Goyal 
600c86243b0SVivek Goyal 		case OPT_VOLATILE:
601c86243b0SVivek Goyal 			config->ovl_volatile = true;
602c86243b0SVivek Goyal 			break;
603c86243b0SVivek Goyal 
6042d2f2d73SMiklos Szeredi 		case OPT_USERXATTR:
6052d2f2d73SMiklos Szeredi 			config->userxattr = true;
6062d2f2d73SMiklos Szeredi 			break;
6072d2f2d73SMiklos Szeredi 
608e9be9d5eSMiklos Szeredi 		default:
6091bd0a3aeSlijiazi 			pr_err("unrecognized mount option \"%s\" or missing value\n",
6101bd0a3aeSlijiazi 					p);
611e9be9d5eSMiklos Szeredi 			return -EINVAL;
612e9be9d5eSMiklos Szeredi 		}
613e9be9d5eSMiklos Szeredi 	}
61471cbad7eShujianyang 
615f0e1266eSAmir Goldstein 	/* Workdir/index are useless in non-upper mount */
616f0e1266eSAmir Goldstein 	if (!config->upperdir) {
617f0e1266eSAmir Goldstein 		if (config->workdir) {
6181bd0a3aeSlijiazi 			pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
61971cbad7eShujianyang 				config->workdir);
62071cbad7eShujianyang 			kfree(config->workdir);
62171cbad7eShujianyang 			config->workdir = NULL;
62271cbad7eShujianyang 		}
623f0e1266eSAmir Goldstein 		if (config->index && index_opt) {
624f0e1266eSAmir Goldstein 			pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n");
625f0e1266eSAmir Goldstein 			index_opt = false;
626f0e1266eSAmir Goldstein 		}
627f0e1266eSAmir Goldstein 		config->index = false;
628f0e1266eSAmir Goldstein 	}
62971cbad7eShujianyang 
630c86243b0SVivek Goyal 	if (!config->upperdir && config->ovl_volatile) {
631c86243b0SVivek Goyal 		pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n");
632c86243b0SVivek Goyal 		config->ovl_volatile = false;
633c86243b0SVivek Goyal 	}
634c86243b0SVivek Goyal 
635d5791044SVivek Goyal 	err = ovl_parse_redirect_mode(config, config->redirect_mode);
636d5791044SVivek Goyal 	if (err)
637d5791044SVivek Goyal 		return err;
638d5791044SVivek Goyal 
639d47748e5SMiklos Szeredi 	/*
640d47748e5SMiklos Szeredi 	 * This is to make the logic below simpler.  It doesn't make any other
641d47748e5SMiklos Szeredi 	 * difference, since config->redirect_dir is only used for upper.
642d47748e5SMiklos Szeredi 	 */
643d47748e5SMiklos Szeredi 	if (!config->upperdir && config->redirect_follow)
644d47748e5SMiklos Szeredi 		config->redirect_dir = true;
645d47748e5SMiklos Szeredi 
646d47748e5SMiklos Szeredi 	/* Resolve metacopy -> redirect_dir dependency */
647d47748e5SMiklos Szeredi 	if (config->metacopy && !config->redirect_dir) {
648d47748e5SMiklos Szeredi 		if (metacopy_opt && redirect_opt) {
6491bd0a3aeSlijiazi 			pr_err("conflicting options: metacopy=on,redirect_dir=%s\n",
650d47748e5SMiklos Szeredi 			       config->redirect_mode);
651d47748e5SMiklos Szeredi 			return -EINVAL;
652d47748e5SMiklos Szeredi 		}
653d47748e5SMiklos Szeredi 		if (redirect_opt) {
654d47748e5SMiklos Szeredi 			/*
655d47748e5SMiklos Szeredi 			 * There was an explicit redirect_dir=... that resulted
656d47748e5SMiklos Szeredi 			 * in this conflict.
657d47748e5SMiklos Szeredi 			 */
6581bd0a3aeSlijiazi 			pr_info("disabling metacopy due to redirect_dir=%s\n",
659d47748e5SMiklos Szeredi 				config->redirect_mode);
660d5791044SVivek Goyal 			config->metacopy = false;
661d47748e5SMiklos Szeredi 		} else {
662d47748e5SMiklos Szeredi 			/* Automatically enable redirect otherwise. */
663d47748e5SMiklos Szeredi 			config->redirect_follow = config->redirect_dir = true;
664d47748e5SMiklos Szeredi 		}
665d5791044SVivek Goyal 	}
666d5791044SVivek Goyal 
667b0def88dSAmir Goldstein 	/* Resolve nfs_export -> index dependency */
668b0def88dSAmir Goldstein 	if (config->nfs_export && !config->index) {
669f0e1266eSAmir Goldstein 		if (!config->upperdir && config->redirect_follow) {
670f0e1266eSAmir Goldstein 			pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
671f0e1266eSAmir Goldstein 			config->nfs_export = false;
672f0e1266eSAmir Goldstein 		} else if (nfs_export_opt && index_opt) {
673b0def88dSAmir Goldstein 			pr_err("conflicting options: nfs_export=on,index=off\n");
674b0def88dSAmir Goldstein 			return -EINVAL;
675f0e1266eSAmir Goldstein 		} else if (index_opt) {
676b0def88dSAmir Goldstein 			/*
677b0def88dSAmir Goldstein 			 * There was an explicit index=off that resulted
678b0def88dSAmir Goldstein 			 * in this conflict.
679b0def88dSAmir Goldstein 			 */
680b0def88dSAmir Goldstein 			pr_info("disabling nfs_export due to index=off\n");
681b0def88dSAmir Goldstein 			config->nfs_export = false;
682b0def88dSAmir Goldstein 		} else {
683b0def88dSAmir Goldstein 			/* Automatically enable index otherwise. */
684b0def88dSAmir Goldstein 			config->index = true;
685b0def88dSAmir Goldstein 		}
686b0def88dSAmir Goldstein 	}
687b0def88dSAmir Goldstein 
688b0def88dSAmir Goldstein 	/* Resolve nfs_export -> !metacopy dependency */
689b0def88dSAmir Goldstein 	if (config->nfs_export && config->metacopy) {
690b0def88dSAmir Goldstein 		if (nfs_export_opt && metacopy_opt) {
691b0def88dSAmir Goldstein 			pr_err("conflicting options: nfs_export=on,metacopy=on\n");
692b0def88dSAmir Goldstein 			return -EINVAL;
693b0def88dSAmir Goldstein 		}
694b0def88dSAmir Goldstein 		if (metacopy_opt) {
695b0def88dSAmir Goldstein 			/*
696b0def88dSAmir Goldstein 			 * There was an explicit metacopy=on that resulted
697b0def88dSAmir Goldstein 			 * in this conflict.
698b0def88dSAmir Goldstein 			 */
699b0def88dSAmir Goldstein 			pr_info("disabling nfs_export due to metacopy=on\n");
700b0def88dSAmir Goldstein 			config->nfs_export = false;
701b0def88dSAmir Goldstein 		} else {
702b0def88dSAmir Goldstein 			/*
703b0def88dSAmir Goldstein 			 * There was an explicit nfs_export=on that resulted
704b0def88dSAmir Goldstein 			 * in this conflict.
705b0def88dSAmir Goldstein 			 */
706b0def88dSAmir Goldstein 			pr_info("disabling metacopy due to nfs_export=on\n");
707b0def88dSAmir Goldstein 			config->metacopy = false;
708b0def88dSAmir Goldstein 		}
709b0def88dSAmir Goldstein 	}
710b0def88dSAmir Goldstein 
7112d2f2d73SMiklos Szeredi 
7122d2f2d73SMiklos Szeredi 	/* Resolve userxattr -> !redirect && !metacopy dependency */
7132d2f2d73SMiklos Szeredi 	if (config->userxattr) {
7142d2f2d73SMiklos Szeredi 		if (config->redirect_follow && redirect_opt) {
7152d2f2d73SMiklos Szeredi 			pr_err("conflicting options: userxattr,redirect_dir=%s\n",
7162d2f2d73SMiklos Szeredi 			       config->redirect_mode);
7172d2f2d73SMiklos Szeredi 			return -EINVAL;
7182d2f2d73SMiklos Szeredi 		}
7192d2f2d73SMiklos Szeredi 		if (config->metacopy && metacopy_opt) {
7202d2f2d73SMiklos Szeredi 			pr_err("conflicting options: userxattr,metacopy=on\n");
7212d2f2d73SMiklos Szeredi 			return -EINVAL;
7222d2f2d73SMiklos Szeredi 		}
7232d2f2d73SMiklos Szeredi 		/*
7242d2f2d73SMiklos Szeredi 		 * Silently disable default setting of redirect and metacopy.
7252d2f2d73SMiklos Szeredi 		 * This shall be the default in the future as well: these
7262d2f2d73SMiklos Szeredi 		 * options must be explicitly enabled if used together with
7272d2f2d73SMiklos Szeredi 		 * userxattr.
7282d2f2d73SMiklos Szeredi 		 */
7292d2f2d73SMiklos Szeredi 		config->redirect_dir = config->redirect_follow = false;
7302d2f2d73SMiklos Szeredi 		config->metacopy = false;
7312d2f2d73SMiklos Szeredi 	}
7322d2f2d73SMiklos Szeredi 
733d5791044SVivek Goyal 	return 0;
734e9be9d5eSMiklos Szeredi }
735e9be9d5eSMiklos Szeredi 
736e9be9d5eSMiklos Szeredi #define OVL_WORKDIR_NAME "work"
73702bcd157SAmir Goldstein #define OVL_INDEXDIR_NAME "index"
738e9be9d5eSMiklos Szeredi 
739ad204488SMiklos Szeredi static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
7406b8aa129SAmir Goldstein 					 const char *name, bool persist)
741e9be9d5eSMiklos Szeredi {
742ad204488SMiklos Szeredi 	struct inode *dir =  ofs->workbasedir->d_inode;
74308f4c7c8SMiklos Szeredi 	struct vfsmount *mnt = ovl_upper_mnt(ofs);
744e9be9d5eSMiklos Szeredi 	struct dentry *work;
745e9be9d5eSMiklos Szeredi 	int err;
746e9be9d5eSMiklos Szeredi 	bool retried = false;
747e9be9d5eSMiklos Szeredi 
7485955102cSAl Viro 	inode_lock_nested(dir, I_MUTEX_PARENT);
749e9be9d5eSMiklos Szeredi retry:
75022f289ceSChristian Brauner 	work = ovl_lookup_upper(ofs, name, ofs->workbasedir, strlen(name));
751e9be9d5eSMiklos Szeredi 
752e9be9d5eSMiklos Szeredi 	if (!IS_ERR(work)) {
753c11b9fddSMiklos Szeredi 		struct iattr attr = {
754c11b9fddSMiklos Szeredi 			.ia_valid = ATTR_MODE,
75532a3d848SAl Viro 			.ia_mode = S_IFDIR | 0,
756c11b9fddSMiklos Szeredi 		};
757e9be9d5eSMiklos Szeredi 
758e9be9d5eSMiklos Szeredi 		if (work->d_inode) {
759e9be9d5eSMiklos Szeredi 			err = -EEXIST;
760e9be9d5eSMiklos Szeredi 			if (retried)
761e9be9d5eSMiklos Szeredi 				goto out_dput;
762e9be9d5eSMiklos Szeredi 
7636b8aa129SAmir Goldstein 			if (persist)
7646b8aa129SAmir Goldstein 				goto out_unlock;
7656b8aa129SAmir Goldstein 
766e9be9d5eSMiklos Szeredi 			retried = true;
767576bb263SChristian Brauner 			err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0);
768e9be9d5eSMiklos Szeredi 			dput(work);
769235ce9edSAmir Goldstein 			if (err == -EINVAL) {
770235ce9edSAmir Goldstein 				work = ERR_PTR(err);
771235ce9edSAmir Goldstein 				goto out_unlock;
772235ce9edSAmir Goldstein 			}
773e9be9d5eSMiklos Szeredi 			goto retry;
774e9be9d5eSMiklos Szeredi 		}
775e9be9d5eSMiklos Szeredi 
776576bb263SChristian Brauner 		err = ovl_mkdir_real(ofs, dir, &work, attr.ia_mode);
7771f5573cfSMiklos Szeredi 		if (err)
7781f5573cfSMiklos Szeredi 			goto out_dput;
7791f5573cfSMiklos Szeredi 
7801f5573cfSMiklos Szeredi 		/* Weird filesystem returning with hashed negative (kernfs)? */
7811f5573cfSMiklos Szeredi 		err = -EINVAL;
7821f5573cfSMiklos Szeredi 		if (d_really_is_negative(work))
7831f5573cfSMiklos Szeredi 			goto out_dput;
784c11b9fddSMiklos Szeredi 
785cb348edbSMiklos Szeredi 		/*
786cb348edbSMiklos Szeredi 		 * Try to remove POSIX ACL xattrs from workdir.  We are good if:
787cb348edbSMiklos Szeredi 		 *
788cb348edbSMiklos Szeredi 		 * a) success (there was a POSIX ACL xattr and was removed)
789cb348edbSMiklos Szeredi 		 * b) -ENODATA (there was no POSIX ACL xattr)
790cb348edbSMiklos Szeredi 		 * c) -EOPNOTSUPP (POSIX ACL xattrs are not supported)
791cb348edbSMiklos Szeredi 		 *
792cb348edbSMiklos Szeredi 		 * There are various other error values that could effectively
793cb348edbSMiklos Szeredi 		 * mean that the xattr doesn't exist (e.g. -ERANGE is returned
794cb348edbSMiklos Szeredi 		 * if the xattr name is too long), but the set of filesystems
795cb348edbSMiklos Szeredi 		 * allowed as upper are limited to "normal" ones, where checking
796cb348edbSMiklos Szeredi 		 * for the above two errors is sufficient.
797cb348edbSMiklos Szeredi 		 */
79831acceb9SChristian Brauner 		err = ovl_do_remove_acl(ofs, work, XATTR_NAME_POSIX_ACL_DEFAULT);
799e1ff3dd1SMiklos Szeredi 		if (err && err != -ENODATA && err != -EOPNOTSUPP)
800c11b9fddSMiklos Szeredi 			goto out_dput;
801c11b9fddSMiklos Szeredi 
80231acceb9SChristian Brauner 		err = ovl_do_remove_acl(ofs, work, XATTR_NAME_POSIX_ACL_ACCESS);
803e1ff3dd1SMiklos Szeredi 		if (err && err != -ENODATA && err != -EOPNOTSUPP)
804c11b9fddSMiklos Szeredi 			goto out_dput;
805c11b9fddSMiklos Szeredi 
806c11b9fddSMiklos Szeredi 		/* Clear any inherited mode bits */
807c11b9fddSMiklos Szeredi 		inode_lock(work->d_inode);
808a15506eaSChristian Brauner 		err = ovl_do_notify_change(ofs, work, &attr);
809c11b9fddSMiklos Szeredi 		inode_unlock(work->d_inode);
810c11b9fddSMiklos Szeredi 		if (err)
811c11b9fddSMiklos Szeredi 			goto out_dput;
8126b8aa129SAmir Goldstein 	} else {
8136b8aa129SAmir Goldstein 		err = PTR_ERR(work);
8146b8aa129SAmir Goldstein 		goto out_err;
815e9be9d5eSMiklos Szeredi 	}
816e9be9d5eSMiklos Szeredi out_unlock:
8176b8aa129SAmir Goldstein 	inode_unlock(dir);
818e9be9d5eSMiklos Szeredi 	return work;
819e9be9d5eSMiklos Szeredi 
820e9be9d5eSMiklos Szeredi out_dput:
821e9be9d5eSMiklos Szeredi 	dput(work);
8226b8aa129SAmir Goldstein out_err:
8231bd0a3aeSlijiazi 	pr_warn("failed to create directory %s/%s (errno: %i); mounting read-only\n",
824ad204488SMiklos Szeredi 		ofs->config.workdir, name, -err);
8256b8aa129SAmir Goldstein 	work = NULL;
826e9be9d5eSMiklos Szeredi 	goto out_unlock;
827e9be9d5eSMiklos Szeredi }
828e9be9d5eSMiklos Szeredi 
82991c77947SMiklos Szeredi static void ovl_unescape(char *s)
83091c77947SMiklos Szeredi {
83191c77947SMiklos Szeredi 	char *d = s;
83291c77947SMiklos Szeredi 
83391c77947SMiklos Szeredi 	for (;; s++, d++) {
83491c77947SMiklos Szeredi 		if (*s == '\\')
83591c77947SMiklos Szeredi 			s++;
83691c77947SMiklos Szeredi 		*d = *s;
83791c77947SMiklos Szeredi 		if (!*s)
83891c77947SMiklos Szeredi 			break;
83991c77947SMiklos Szeredi 	}
84091c77947SMiklos Szeredi }
84191c77947SMiklos Szeredi 
842ab508822SMiklos Szeredi static int ovl_mount_dir_noesc(const char *name, struct path *path)
843ab508822SMiklos Szeredi {
844a78d9f0dSMiklos Szeredi 	int err = -EINVAL;
845ab508822SMiklos Szeredi 
846a78d9f0dSMiklos Szeredi 	if (!*name) {
8471bd0a3aeSlijiazi 		pr_err("empty lowerdir\n");
848a78d9f0dSMiklos Szeredi 		goto out;
849a78d9f0dSMiklos Szeredi 	}
850ab508822SMiklos Szeredi 	err = kern_path(name, LOOKUP_FOLLOW, path);
851ab508822SMiklos Szeredi 	if (err) {
8521bd0a3aeSlijiazi 		pr_err("failed to resolve '%s': %i\n", name, err);
853ab508822SMiklos Szeredi 		goto out;
854ab508822SMiklos Szeredi 	}
855ab508822SMiklos Szeredi 	err = -EINVAL;
8567c03b5d4SMiklos Szeredi 	if (ovl_dentry_weird(path->dentry)) {
8571bd0a3aeSlijiazi 		pr_err("filesystem on '%s' not supported\n", name);
858ab508822SMiklos Szeredi 		goto out_put;
859ab508822SMiklos Szeredi 	}
8602b8c30e9SMiklos Szeredi 	if (!d_is_dir(path->dentry)) {
8611bd0a3aeSlijiazi 		pr_err("'%s' not a directory\n", name);
862ab508822SMiklos Szeredi 		goto out_put;
863ab508822SMiklos Szeredi 	}
864ab508822SMiklos Szeredi 	return 0;
865ab508822SMiklos Szeredi 
866ab508822SMiklos Szeredi out_put:
8678aafcb59SMiklos Szeredi 	path_put_init(path);
868ab508822SMiklos Szeredi out:
869ab508822SMiklos Szeredi 	return err;
870ab508822SMiklos Szeredi }
871ab508822SMiklos Szeredi 
872ab508822SMiklos Szeredi static int ovl_mount_dir(const char *name, struct path *path)
873ab508822SMiklos Szeredi {
874ab508822SMiklos Szeredi 	int err = -ENOMEM;
875ab508822SMiklos Szeredi 	char *tmp = kstrdup(name, GFP_KERNEL);
876ab508822SMiklos Szeredi 
877ab508822SMiklos Szeredi 	if (tmp) {
878ab508822SMiklos Szeredi 		ovl_unescape(tmp);
879ab508822SMiklos Szeredi 		err = ovl_mount_dir_noesc(tmp, path);
8807c03b5d4SMiklos Szeredi 
881bccece1eSMiklos Szeredi 		if (!err && path->dentry->d_flags & DCACHE_OP_REAL) {
8821bd0a3aeSlijiazi 			pr_err("filesystem on '%s' not supported as upperdir\n",
8837c03b5d4SMiklos Szeredi 			       tmp);
8848aafcb59SMiklos Szeredi 			path_put_init(path);
8857c03b5d4SMiklos Szeredi 			err = -EINVAL;
8867c03b5d4SMiklos Szeredi 		}
887ab508822SMiklos Szeredi 		kfree(tmp);
888ab508822SMiklos Szeredi 	}
889ab508822SMiklos Szeredi 	return err;
890ab508822SMiklos Szeredi }
891ab508822SMiklos Szeredi 
8922d343087SAl Viro static int ovl_check_namelen(const struct path *path, struct ovl_fs *ofs,
8936b2d5fe4SMiklos Szeredi 			     const char *name)
8946b2d5fe4SMiklos Szeredi {
8956b2d5fe4SMiklos Szeredi 	struct kstatfs statfs;
8966b2d5fe4SMiklos Szeredi 	int err = vfs_statfs(path, &statfs);
8976b2d5fe4SMiklos Szeredi 
8986b2d5fe4SMiklos Szeredi 	if (err)
8991bd0a3aeSlijiazi 		pr_err("statfs failed on '%s'\n", name);
9006b2d5fe4SMiklos Szeredi 	else
9016b2d5fe4SMiklos Szeredi 		ofs->namelen = max(ofs->namelen, statfs.f_namelen);
9026b2d5fe4SMiklos Szeredi 
9036b2d5fe4SMiklos Szeredi 	return err;
9046b2d5fe4SMiklos Szeredi }
9056b2d5fe4SMiklos Szeredi 
9066b2d5fe4SMiklos Szeredi static int ovl_lower_dir(const char *name, struct path *path,
907f4288844SMiklos Szeredi 			 struct ovl_fs *ofs, int *stack_depth)
908ab508822SMiklos Szeredi {
909e487d889SAmir Goldstein 	int fh_type;
910ab508822SMiklos Szeredi 	int err;
911ab508822SMiklos Szeredi 
912a78d9f0dSMiklos Szeredi 	err = ovl_mount_dir_noesc(name, path);
913ab508822SMiklos Szeredi 	if (err)
914b8e42a65SMiklos Szeredi 		return err;
915ab508822SMiklos Szeredi 
9166b2d5fe4SMiklos Szeredi 	err = ovl_check_namelen(path, ofs, name);
9176b2d5fe4SMiklos Szeredi 	if (err)
918b8e42a65SMiklos Szeredi 		return err;
9196b2d5fe4SMiklos Szeredi 
920ab508822SMiklos Szeredi 	*stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth);
921ab508822SMiklos Szeredi 
92202bcd157SAmir Goldstein 	/*
923f168f109SAmir Goldstein 	 * The inodes index feature and NFS export need to encode and decode
924f168f109SAmir Goldstein 	 * file handles, so they require that all layers support them.
92502bcd157SAmir Goldstein 	 */
926e487d889SAmir Goldstein 	fh_type = ovl_can_decode_fh(path->dentry->d_sb);
927f168f109SAmir Goldstein 	if ((ofs->config.nfs_export ||
928e487d889SAmir Goldstein 	     (ofs->config.index && ofs->config.upperdir)) && !fh_type) {
92902bcd157SAmir Goldstein 		ofs->config.index = false;
930f168f109SAmir Goldstein 		ofs->config.nfs_export = false;
9311bd0a3aeSlijiazi 		pr_warn("fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
932f168f109SAmir Goldstein 			name);
93302bcd157SAmir Goldstein 	}
934b0e0f697SAmir Goldstein 	/*
935b0e0f697SAmir Goldstein 	 * Decoding origin file handle is required for persistent st_ino.
936b0e0f697SAmir Goldstein 	 * Without persistent st_ino, xino=auto falls back to xino=off.
937b0e0f697SAmir Goldstein 	 */
938b0e0f697SAmir Goldstein 	if (ofs->config.xino == OVL_XINO_AUTO &&
939b0e0f697SAmir Goldstein 	    ofs->config.upperdir && !fh_type) {
940b0e0f697SAmir Goldstein 		ofs->config.xino = OVL_XINO_OFF;
941b0e0f697SAmir Goldstein 		pr_warn("fs on '%s' does not support file handles, falling back to xino=off.\n",
942b0e0f697SAmir Goldstein 			name);
943b0e0f697SAmir Goldstein 	}
94402bcd157SAmir Goldstein 
945e487d889SAmir Goldstein 	/* Check if lower fs has 32bit inode numbers */
946e487d889SAmir Goldstein 	if (fh_type != FILEID_INO32_GEN)
9470f831ec8SAmir Goldstein 		ofs->xino_mode = -1;
948e487d889SAmir Goldstein 
949ab508822SMiklos Szeredi 	return 0;
950ab508822SMiklos Szeredi }
951ab508822SMiklos Szeredi 
952e9be9d5eSMiklos Szeredi /* Workdir should not be subdir of upperdir and vice versa */
953e9be9d5eSMiklos Szeredi static bool ovl_workdir_ok(struct dentry *workdir, struct dentry *upperdir)
954e9be9d5eSMiklos Szeredi {
955e9be9d5eSMiklos Szeredi 	bool ok = false;
956e9be9d5eSMiklos Szeredi 
957e9be9d5eSMiklos Szeredi 	if (workdir != upperdir) {
958e9be9d5eSMiklos Szeredi 		ok = (lock_rename(workdir, upperdir) == NULL);
959e9be9d5eSMiklos Szeredi 		unlock_rename(workdir, upperdir);
960e9be9d5eSMiklos Szeredi 	}
961e9be9d5eSMiklos Szeredi 	return ok;
962e9be9d5eSMiklos Szeredi }
963e9be9d5eSMiklos Szeredi 
964a78d9f0dSMiklos Szeredi static unsigned int ovl_split_lowerdirs(char *str)
965a78d9f0dSMiklos Szeredi {
966a78d9f0dSMiklos Szeredi 	unsigned int ctr = 1;
967a78d9f0dSMiklos Szeredi 	char *s, *d;
968a78d9f0dSMiklos Szeredi 
969a78d9f0dSMiklos Szeredi 	for (s = d = str;; s++, d++) {
970a78d9f0dSMiklos Szeredi 		if (*s == '\\') {
971a78d9f0dSMiklos Szeredi 			s++;
972a78d9f0dSMiklos Szeredi 		} else if (*s == ':') {
973a78d9f0dSMiklos Szeredi 			*d = '\0';
974a78d9f0dSMiklos Szeredi 			ctr++;
975a78d9f0dSMiklos Szeredi 			continue;
976a78d9f0dSMiklos Szeredi 		}
977a78d9f0dSMiklos Szeredi 		*d = *s;
978a78d9f0dSMiklos Szeredi 		if (!*s)
979a78d9f0dSMiklos Szeredi 			break;
980a78d9f0dSMiklos Szeredi 	}
981a78d9f0dSMiklos Szeredi 	return ctr;
982a78d9f0dSMiklos Szeredi }
983a78d9f0dSMiklos Szeredi 
9840eb45fc3SAndreas Gruenbacher static int ovl_own_xattr_get(const struct xattr_handler *handler,
9850eb45fc3SAndreas Gruenbacher 			     struct dentry *dentry, struct inode *inode,
9860eb45fc3SAndreas Gruenbacher 			     const char *name, void *buffer, size_t size)
9870eb45fc3SAndreas Gruenbacher {
98848fab5d7SAmir Goldstein 	return -EOPNOTSUPP;
9890eb45fc3SAndreas Gruenbacher }
9900eb45fc3SAndreas Gruenbacher 
991d837a49bSMiklos Szeredi static int ovl_own_xattr_set(const struct xattr_handler *handler,
99239f60c1cSChristian Brauner 			     struct mnt_idmap *idmap,
993d837a49bSMiklos Szeredi 			     struct dentry *dentry, struct inode *inode,
994d837a49bSMiklos Szeredi 			     const char *name, const void *value,
995d837a49bSMiklos Szeredi 			     size_t size, int flags)
996d837a49bSMiklos Szeredi {
99748fab5d7SAmir Goldstein 	return -EOPNOTSUPP;
998d837a49bSMiklos Szeredi }
999d837a49bSMiklos Szeredi 
10000eb45fc3SAndreas Gruenbacher static int ovl_other_xattr_get(const struct xattr_handler *handler,
10010eb45fc3SAndreas Gruenbacher 			       struct dentry *dentry, struct inode *inode,
10020eb45fc3SAndreas Gruenbacher 			       const char *name, void *buffer, size_t size)
10030eb45fc3SAndreas Gruenbacher {
10041d88f183SMiklos Szeredi 	return ovl_xattr_get(dentry, inode, name, buffer, size);
10050eb45fc3SAndreas Gruenbacher }
10060eb45fc3SAndreas Gruenbacher 
10070e585cccSAndreas Gruenbacher static int ovl_other_xattr_set(const struct xattr_handler *handler,
100839f60c1cSChristian Brauner 			       struct mnt_idmap *idmap,
10090e585cccSAndreas Gruenbacher 			       struct dentry *dentry, struct inode *inode,
10100e585cccSAndreas Gruenbacher 			       const char *name, const void *value,
10110e585cccSAndreas Gruenbacher 			       size_t size, int flags)
10120e585cccSAndreas Gruenbacher {
10131d88f183SMiklos Szeredi 	return ovl_xattr_set(dentry, inode, name, value, size, flags);
10140e585cccSAndreas Gruenbacher }
10150e585cccSAndreas Gruenbacher 
10162d2f2d73SMiklos Szeredi static const struct xattr_handler ovl_own_trusted_xattr_handler = {
10172d2f2d73SMiklos Szeredi 	.prefix	= OVL_XATTR_TRUSTED_PREFIX,
10182d2f2d73SMiklos Szeredi 	.get = ovl_own_xattr_get,
10192d2f2d73SMiklos Szeredi 	.set = ovl_own_xattr_set,
10202d2f2d73SMiklos Szeredi };
10212d2f2d73SMiklos Szeredi 
10222d2f2d73SMiklos Szeredi static const struct xattr_handler ovl_own_user_xattr_handler = {
10232d2f2d73SMiklos Szeredi 	.prefix	= OVL_XATTR_USER_PREFIX,
10240eb45fc3SAndreas Gruenbacher 	.get = ovl_own_xattr_get,
1025d837a49bSMiklos Szeredi 	.set = ovl_own_xattr_set,
1026d837a49bSMiklos Szeredi };
1027d837a49bSMiklos Szeredi 
1028d837a49bSMiklos Szeredi static const struct xattr_handler ovl_other_xattr_handler = {
1029d837a49bSMiklos Szeredi 	.prefix	= "", /* catch all */
10300eb45fc3SAndreas Gruenbacher 	.get = ovl_other_xattr_get,
1031d837a49bSMiklos Szeredi 	.set = ovl_other_xattr_set,
1032d837a49bSMiklos Szeredi };
1033d837a49bSMiklos Szeredi 
10342d2f2d73SMiklos Szeredi static const struct xattr_handler *ovl_trusted_xattr_handlers[] = {
10352d2f2d73SMiklos Szeredi 	&ovl_own_trusted_xattr_handler,
10362d2f2d73SMiklos Szeredi 	&ovl_other_xattr_handler,
10372d2f2d73SMiklos Szeredi 	NULL
10382d2f2d73SMiklos Szeredi };
10392d2f2d73SMiklos Szeredi 
10402d2f2d73SMiklos Szeredi static const struct xattr_handler *ovl_user_xattr_handlers[] = {
10412d2f2d73SMiklos Szeredi 	&ovl_own_user_xattr_handler,
1042d837a49bSMiklos Szeredi 	&ovl_other_xattr_handler,
1043d837a49bSMiklos Szeredi 	NULL
1044d837a49bSMiklos Szeredi };
1045d837a49bSMiklos Szeredi 
1046146d62e5SAmir Goldstein static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
1047146d62e5SAmir Goldstein 			  struct inode **ptrap, const char *name)
1048146d62e5SAmir Goldstein {
1049146d62e5SAmir Goldstein 	struct inode *trap;
1050146d62e5SAmir Goldstein 	int err;
1051146d62e5SAmir Goldstein 
1052146d62e5SAmir Goldstein 	trap = ovl_get_trap_inode(sb, dir);
10531dac6f5bSArnd Bergmann 	err = PTR_ERR_OR_ZERO(trap);
10541dac6f5bSArnd Bergmann 	if (err) {
1055146d62e5SAmir Goldstein 		if (err == -ELOOP)
10561bd0a3aeSlijiazi 			pr_err("conflicting %s path\n", name);
1057146d62e5SAmir Goldstein 		return err;
1058146d62e5SAmir Goldstein 	}
1059146d62e5SAmir Goldstein 
1060146d62e5SAmir Goldstein 	*ptrap = trap;
1061146d62e5SAmir Goldstein 	return 0;
1062146d62e5SAmir Goldstein }
1063146d62e5SAmir Goldstein 
10640be0bfd2SAmir Goldstein /*
10650be0bfd2SAmir Goldstein  * Determine how we treat concurrent use of upperdir/workdir based on the
10660be0bfd2SAmir Goldstein  * index feature. This is papering over mount leaks of container runtimes,
10670be0bfd2SAmir Goldstein  * for example, an old overlay mount is leaked and now its upperdir is
10680be0bfd2SAmir Goldstein  * attempted to be used as a lower layer in a new overlay mount.
10690be0bfd2SAmir Goldstein  */
10700be0bfd2SAmir Goldstein static int ovl_report_in_use(struct ovl_fs *ofs, const char *name)
10710be0bfd2SAmir Goldstein {
10720be0bfd2SAmir Goldstein 	if (ofs->config.index) {
10731bd0a3aeSlijiazi 		pr_err("%s is in-use as upperdir/workdir of another mount, mount with '-o index=off' to override exclusive upperdir protection.\n",
10740be0bfd2SAmir Goldstein 		       name);
10750be0bfd2SAmir Goldstein 		return -EBUSY;
10760be0bfd2SAmir Goldstein 	} else {
10771bd0a3aeSlijiazi 		pr_warn("%s is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.\n",
10780be0bfd2SAmir Goldstein 			name);
10790be0bfd2SAmir Goldstein 		return 0;
10800be0bfd2SAmir Goldstein 	}
10810be0bfd2SAmir Goldstein }
10820be0bfd2SAmir Goldstein 
1083146d62e5SAmir Goldstein static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
1084b8e42a65SMiklos Szeredi 			 struct ovl_layer *upper_layer, struct path *upperpath)
10856ee8acf0SMiklos Szeredi {
10865064975eSMiklos Szeredi 	struct vfsmount *upper_mnt;
10876ee8acf0SMiklos Szeredi 	int err;
10886ee8acf0SMiklos Szeredi 
1089ad204488SMiklos Szeredi 	err = ovl_mount_dir(ofs->config.upperdir, upperpath);
10906ee8acf0SMiklos Szeredi 	if (err)
10916ee8acf0SMiklos Szeredi 		goto out;
10926ee8acf0SMiklos Szeredi 
1093e21a6c57SAmir Goldstein 	/* Upperdir path should not be r/o */
1094e21a6c57SAmir Goldstein 	if (__mnt_is_readonly(upperpath->mnt)) {
10951bd0a3aeSlijiazi 		pr_err("upper fs is r/o, try multi-lower layers mount\n");
10966ee8acf0SMiklos Szeredi 		err = -EINVAL;
10976ee8acf0SMiklos Szeredi 		goto out;
10986ee8acf0SMiklos Szeredi 	}
10996ee8acf0SMiklos Szeredi 
1100ad204488SMiklos Szeredi 	err = ovl_check_namelen(upperpath, ofs, ofs->config.upperdir);
11016ee8acf0SMiklos Szeredi 	if (err)
11026ee8acf0SMiklos Szeredi 		goto out;
11036ee8acf0SMiklos Szeredi 
1104b8e42a65SMiklos Szeredi 	err = ovl_setup_trap(sb, upperpath->dentry, &upper_layer->trap,
1105146d62e5SAmir Goldstein 			     "upperdir");
1106146d62e5SAmir Goldstein 	if (err)
1107146d62e5SAmir Goldstein 		goto out;
1108146d62e5SAmir Goldstein 
11095064975eSMiklos Szeredi 	upper_mnt = clone_private_mount(upperpath);
11105064975eSMiklos Szeredi 	err = PTR_ERR(upper_mnt);
11115064975eSMiklos Szeredi 	if (IS_ERR(upper_mnt)) {
11121bd0a3aeSlijiazi 		pr_err("failed to clone upperpath\n");
11135064975eSMiklos Szeredi 		goto out;
11145064975eSMiklos Szeredi 	}
11155064975eSMiklos Szeredi 
11165064975eSMiklos Szeredi 	/* Don't inherit atime flags */
11175064975eSMiklos Szeredi 	upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME);
1118b8e42a65SMiklos Szeredi 	upper_layer->mnt = upper_mnt;
1119b8e42a65SMiklos Szeredi 	upper_layer->idx = 0;
1120b8e42a65SMiklos Szeredi 	upper_layer->fsid = 0;
11218c25741aSMiklos Szeredi 
1122654255faSJeffle Xu 	/*
1123654255faSJeffle Xu 	 * Inherit SB_NOSEC flag from upperdir.
1124654255faSJeffle Xu 	 *
1125654255faSJeffle Xu 	 * This optimization changes behavior when a security related attribute
1126654255faSJeffle Xu 	 * (suid/sgid/security.*) is changed on an underlying layer.  This is
1127654255faSJeffle Xu 	 * okay because we don't yet have guarantees in that case, but it will
1128654255faSJeffle Xu 	 * need careful treatment once we want to honour changes to underlying
1129654255faSJeffle Xu 	 * filesystems.
1130654255faSJeffle Xu 	 */
1131654255faSJeffle Xu 	if (upper_mnt->mnt_sb->s_flags & SB_NOSEC)
1132654255faSJeffle Xu 		sb->s_flags |= SB_NOSEC;
1133654255faSJeffle Xu 
113408f4c7c8SMiklos Szeredi 	if (ovl_inuse_trylock(ovl_upper_mnt(ofs)->mnt_root)) {
11358c25741aSMiklos Szeredi 		ofs->upperdir_locked = true;
11368c25741aSMiklos Szeredi 	} else {
11370be0bfd2SAmir Goldstein 		err = ovl_report_in_use(ofs, "upperdir");
11380be0bfd2SAmir Goldstein 		if (err)
11390be0bfd2SAmir Goldstein 			goto out;
11408c25741aSMiklos Szeredi 	}
11418c25741aSMiklos Szeredi 
11426ee8acf0SMiklos Szeredi 	err = 0;
11436ee8acf0SMiklos Szeredi out:
11446ee8acf0SMiklos Szeredi 	return err;
11456ee8acf0SMiklos Szeredi }
11466ee8acf0SMiklos Szeredi 
1147cad218abSAmir Goldstein /*
1148cad218abSAmir Goldstein  * Returns 1 if RENAME_WHITEOUT is supported, 0 if not supported and
1149cad218abSAmir Goldstein  * negative values if error is encountered.
1150cad218abSAmir Goldstein  */
1151576bb263SChristian Brauner static int ovl_check_rename_whiteout(struct ovl_fs *ofs)
1152cad218abSAmir Goldstein {
1153576bb263SChristian Brauner 	struct dentry *workdir = ofs->workdir;
1154cad218abSAmir Goldstein 	struct inode *dir = d_inode(workdir);
1155cad218abSAmir Goldstein 	struct dentry *temp;
1156cad218abSAmir Goldstein 	struct dentry *dest;
1157cad218abSAmir Goldstein 	struct dentry *whiteout;
1158cad218abSAmir Goldstein 	struct name_snapshot name;
1159cad218abSAmir Goldstein 	int err;
1160cad218abSAmir Goldstein 
1161cad218abSAmir Goldstein 	inode_lock_nested(dir, I_MUTEX_PARENT);
1162cad218abSAmir Goldstein 
1163576bb263SChristian Brauner 	temp = ovl_create_temp(ofs, workdir, OVL_CATTR(S_IFREG | 0));
1164cad218abSAmir Goldstein 	err = PTR_ERR(temp);
1165cad218abSAmir Goldstein 	if (IS_ERR(temp))
1166cad218abSAmir Goldstein 		goto out_unlock;
1167cad218abSAmir Goldstein 
1168576bb263SChristian Brauner 	dest = ovl_lookup_temp(ofs, workdir);
1169cad218abSAmir Goldstein 	err = PTR_ERR(dest);
1170cad218abSAmir Goldstein 	if (IS_ERR(dest)) {
1171cad218abSAmir Goldstein 		dput(temp);
1172cad218abSAmir Goldstein 		goto out_unlock;
1173cad218abSAmir Goldstein 	}
1174cad218abSAmir Goldstein 
1175cad218abSAmir Goldstein 	/* Name is inline and stable - using snapshot as a copy helper */
1176cad218abSAmir Goldstein 	take_dentry_name_snapshot(&name, temp);
1177576bb263SChristian Brauner 	err = ovl_do_rename(ofs, dir, temp, dir, dest, RENAME_WHITEOUT);
1178cad218abSAmir Goldstein 	if (err) {
1179cad218abSAmir Goldstein 		if (err == -EINVAL)
1180cad218abSAmir Goldstein 			err = 0;
1181cad218abSAmir Goldstein 		goto cleanup_temp;
1182cad218abSAmir Goldstein 	}
1183cad218abSAmir Goldstein 
118422f289ceSChristian Brauner 	whiteout = ovl_lookup_upper(ofs, name.name.name, workdir, name.name.len);
1185cad218abSAmir Goldstein 	err = PTR_ERR(whiteout);
1186cad218abSAmir Goldstein 	if (IS_ERR(whiteout))
1187cad218abSAmir Goldstein 		goto cleanup_temp;
1188cad218abSAmir Goldstein 
1189cad218abSAmir Goldstein 	err = ovl_is_whiteout(whiteout);
1190cad218abSAmir Goldstein 
1191cad218abSAmir Goldstein 	/* Best effort cleanup of whiteout and temp file */
1192cad218abSAmir Goldstein 	if (err)
1193576bb263SChristian Brauner 		ovl_cleanup(ofs, dir, whiteout);
1194cad218abSAmir Goldstein 	dput(whiteout);
1195cad218abSAmir Goldstein 
1196cad218abSAmir Goldstein cleanup_temp:
1197576bb263SChristian Brauner 	ovl_cleanup(ofs, dir, temp);
1198cad218abSAmir Goldstein 	release_dentry_name_snapshot(&name);
1199cad218abSAmir Goldstein 	dput(temp);
1200cad218abSAmir Goldstein 	dput(dest);
1201cad218abSAmir Goldstein 
1202cad218abSAmir Goldstein out_unlock:
1203cad218abSAmir Goldstein 	inode_unlock(dir);
1204cad218abSAmir Goldstein 
1205cad218abSAmir Goldstein 	return err;
1206cad218abSAmir Goldstein }
1207cad218abSAmir Goldstein 
1208576bb263SChristian Brauner static struct dentry *ovl_lookup_or_create(struct ovl_fs *ofs,
1209576bb263SChristian Brauner 					   struct dentry *parent,
1210c86243b0SVivek Goyal 					   const char *name, umode_t mode)
1211c86243b0SVivek Goyal {
1212c86243b0SVivek Goyal 	size_t len = strlen(name);
1213c86243b0SVivek Goyal 	struct dentry *child;
1214c86243b0SVivek Goyal 
1215c86243b0SVivek Goyal 	inode_lock_nested(parent->d_inode, I_MUTEX_PARENT);
121622f289ceSChristian Brauner 	child = ovl_lookup_upper(ofs, name, parent, len);
1217c86243b0SVivek Goyal 	if (!IS_ERR(child) && !child->d_inode)
1218576bb263SChristian Brauner 		child = ovl_create_real(ofs, parent->d_inode, child,
1219c86243b0SVivek Goyal 					OVL_CATTR(mode));
1220c86243b0SVivek Goyal 	inode_unlock(parent->d_inode);
1221c86243b0SVivek Goyal 	dput(parent);
1222c86243b0SVivek Goyal 
1223c86243b0SVivek Goyal 	return child;
1224c86243b0SVivek Goyal }
1225c86243b0SVivek Goyal 
1226c86243b0SVivek Goyal /*
1227c86243b0SVivek Goyal  * Creates $workdir/work/incompat/volatile/dirty file if it is not already
1228c86243b0SVivek Goyal  * present.
1229c86243b0SVivek Goyal  */
1230c86243b0SVivek Goyal static int ovl_create_volatile_dirty(struct ovl_fs *ofs)
1231c86243b0SVivek Goyal {
1232c86243b0SVivek Goyal 	unsigned int ctr;
1233c86243b0SVivek Goyal 	struct dentry *d = dget(ofs->workbasedir);
1234c86243b0SVivek Goyal 	static const char *const volatile_path[] = {
1235c86243b0SVivek Goyal 		OVL_WORKDIR_NAME, "incompat", "volatile", "dirty"
1236c86243b0SVivek Goyal 	};
1237c86243b0SVivek Goyal 	const char *const *name = volatile_path;
1238c86243b0SVivek Goyal 
1239c86243b0SVivek Goyal 	for (ctr = ARRAY_SIZE(volatile_path); ctr; ctr--, name++) {
1240576bb263SChristian Brauner 		d = ovl_lookup_or_create(ofs, d, *name, ctr > 1 ? S_IFDIR : S_IFREG);
1241c86243b0SVivek Goyal 		if (IS_ERR(d))
1242c86243b0SVivek Goyal 			return PTR_ERR(d);
1243c86243b0SVivek Goyal 	}
1244c86243b0SVivek Goyal 	dput(d);
1245c86243b0SVivek Goyal 	return 0;
1246c86243b0SVivek Goyal }
1247c86243b0SVivek Goyal 
1248146d62e5SAmir Goldstein static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
12492d343087SAl Viro 			    const struct path *workpath)
12508ed61dc3SMiklos Szeredi {
125108f4c7c8SMiklos Szeredi 	struct vfsmount *mnt = ovl_upper_mnt(ofs);
12522b1a7746SMiklos Szeredi 	struct dentry *workdir;
12532b1a7746SMiklos Szeredi 	struct file *tmpfile;
1254d80172c2SAmir Goldstein 	bool rename_whiteout;
1255d80172c2SAmir Goldstein 	bool d_type;
1256e487d889SAmir Goldstein 	int fh_type;
12578ed61dc3SMiklos Szeredi 	int err;
12588ed61dc3SMiklos Szeredi 
12592ba9d57eSAmir Goldstein 	err = mnt_want_write(mnt);
12602ba9d57eSAmir Goldstein 	if (err)
12612ba9d57eSAmir Goldstein 		return err;
12622ba9d57eSAmir Goldstein 
1263235ce9edSAmir Goldstein 	workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false);
1264235ce9edSAmir Goldstein 	err = PTR_ERR(workdir);
1265235ce9edSAmir Goldstein 	if (IS_ERR_OR_NULL(workdir))
12662ba9d57eSAmir Goldstein 		goto out;
12678ed61dc3SMiklos Szeredi 
1268235ce9edSAmir Goldstein 	ofs->workdir = workdir;
1269235ce9edSAmir Goldstein 
1270146d62e5SAmir Goldstein 	err = ovl_setup_trap(sb, ofs->workdir, &ofs->workdir_trap, "workdir");
1271146d62e5SAmir Goldstein 	if (err)
1272146d62e5SAmir Goldstein 		goto out;
1273146d62e5SAmir Goldstein 
12748ed61dc3SMiklos Szeredi 	/*
12758ed61dc3SMiklos Szeredi 	 * Upper should support d_type, else whiteouts are visible.  Given
12768ed61dc3SMiklos Szeredi 	 * workdir and upper are on same fs, we can do iterate_dir() on
12778ed61dc3SMiklos Szeredi 	 * workdir. This check requires successful creation of workdir in
12788ed61dc3SMiklos Szeredi 	 * previous step.
12798ed61dc3SMiklos Szeredi 	 */
12808ed61dc3SMiklos Szeredi 	err = ovl_check_d_type_supported(workpath);
12818ed61dc3SMiklos Szeredi 	if (err < 0)
12822ba9d57eSAmir Goldstein 		goto out;
12838ed61dc3SMiklos Szeredi 
1284d80172c2SAmir Goldstein 	d_type = err;
1285d80172c2SAmir Goldstein 	if (!d_type)
12861bd0a3aeSlijiazi 		pr_warn("upper fs needs to support d_type.\n");
12878ed61dc3SMiklos Szeredi 
12888ed61dc3SMiklos Szeredi 	/* Check if upper/work fs supports O_TMPFILE */
12892b1a7746SMiklos Szeredi 	tmpfile = ovl_do_tmpfile(ofs, ofs->workdir, S_IFREG | 0);
12902b1a7746SMiklos Szeredi 	ofs->tmpfile = !IS_ERR(tmpfile);
1291ad204488SMiklos Szeredi 	if (ofs->tmpfile)
12922b1a7746SMiklos Szeredi 		fput(tmpfile);
12938ed61dc3SMiklos Szeredi 	else
12941bd0a3aeSlijiazi 		pr_warn("upper fs does not support tmpfile.\n");
12958ed61dc3SMiklos Szeredi 
1296cad218abSAmir Goldstein 
1297cad218abSAmir Goldstein 	/* Check if upper/work fs supports RENAME_WHITEOUT */
1298576bb263SChristian Brauner 	err = ovl_check_rename_whiteout(ofs);
1299cad218abSAmir Goldstein 	if (err < 0)
1300cad218abSAmir Goldstein 		goto out;
1301cad218abSAmir Goldstein 
1302d80172c2SAmir Goldstein 	rename_whiteout = err;
1303d80172c2SAmir Goldstein 	if (!rename_whiteout)
1304cad218abSAmir Goldstein 		pr_warn("upper fs does not support RENAME_WHITEOUT.\n");
1305cad218abSAmir Goldstein 
13068ed61dc3SMiklos Szeredi 	/*
13072d2f2d73SMiklos Szeredi 	 * Check if upper/work fs supports (trusted|user).overlay.* xattr
13088ed61dc3SMiklos Szeredi 	 */
1309c914c0e2SAmir Goldstein 	err = ovl_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1);
13108ed61dc3SMiklos Szeredi 	if (err) {
1311b10b85feSMiklos Szeredi 		pr_warn("failed to set xattr on upper\n");
1312ad204488SMiklos Szeredi 		ofs->noxattr = true;
1313b0e0f697SAmir Goldstein 		if (ofs->config.index || ofs->config.metacopy) {
1314a683737bSAmir Goldstein 			ofs->config.index = false;
1315d5791044SVivek Goyal 			ofs->config.metacopy = false;
1316b10b85feSMiklos Szeredi 			pr_warn("...falling back to index=off,metacopy=off.\n");
1317b0e0f697SAmir Goldstein 		}
1318b0e0f697SAmir Goldstein 		/*
1319b0e0f697SAmir Goldstein 		 * xattr support is required for persistent st_ino.
1320b0e0f697SAmir Goldstein 		 * Without persistent st_ino, xino=auto falls back to xino=off.
1321b0e0f697SAmir Goldstein 		 */
1322b0e0f697SAmir Goldstein 		if (ofs->config.xino == OVL_XINO_AUTO) {
1323b0e0f697SAmir Goldstein 			ofs->config.xino = OVL_XINO_OFF;
1324b10b85feSMiklos Szeredi 			pr_warn("...falling back to xino=off.\n");
1325b0e0f697SAmir Goldstein 		}
1326b10b85feSMiklos Szeredi 		if (err == -EPERM && !ofs->config.userxattr)
1327b10b85feSMiklos Szeredi 			pr_info("try mounting with 'userxattr' option\n");
13282ba9d57eSAmir Goldstein 		err = 0;
13298ed61dc3SMiklos Szeredi 	} else {
1330c914c0e2SAmir Goldstein 		ovl_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE);
13318ed61dc3SMiklos Szeredi 	}
13328ed61dc3SMiklos Szeredi 
1333d80172c2SAmir Goldstein 	/*
1334d80172c2SAmir Goldstein 	 * We allowed sub-optimal upper fs configuration and don't want to break
1335d80172c2SAmir Goldstein 	 * users over kernel upgrade, but we never allowed remote upper fs, so
1336d80172c2SAmir Goldstein 	 * we can enforce strict requirements for remote upper fs.
1337d80172c2SAmir Goldstein 	 */
1338d80172c2SAmir Goldstein 	if (ovl_dentry_remote(ofs->workdir) &&
1339d80172c2SAmir Goldstein 	    (!d_type || !rename_whiteout || ofs->noxattr)) {
1340d80172c2SAmir Goldstein 		pr_err("upper fs missing required features.\n");
1341d80172c2SAmir Goldstein 		err = -EINVAL;
1342d80172c2SAmir Goldstein 		goto out;
1343d80172c2SAmir Goldstein 	}
1344d80172c2SAmir Goldstein 
1345c86243b0SVivek Goyal 	/*
1346c86243b0SVivek Goyal 	 * For volatile mount, create a incompat/volatile/dirty file to keep
1347c86243b0SVivek Goyal 	 * track of it.
1348c86243b0SVivek Goyal 	 */
1349c86243b0SVivek Goyal 	if (ofs->config.ovl_volatile) {
1350c86243b0SVivek Goyal 		err = ovl_create_volatile_dirty(ofs);
1351c86243b0SVivek Goyal 		if (err < 0) {
1352c86243b0SVivek Goyal 			pr_err("Failed to create volatile/dirty file.\n");
1353c86243b0SVivek Goyal 			goto out;
1354c86243b0SVivek Goyal 		}
1355c86243b0SVivek Goyal 	}
1356c86243b0SVivek Goyal 
13578ed61dc3SMiklos Szeredi 	/* Check if upper/work fs supports file handles */
1358e487d889SAmir Goldstein 	fh_type = ovl_can_decode_fh(ofs->workdir->d_sb);
1359e487d889SAmir Goldstein 	if (ofs->config.index && !fh_type) {
1360ad204488SMiklos Szeredi 		ofs->config.index = false;
13611bd0a3aeSlijiazi 		pr_warn("upper fs does not support file handles, falling back to index=off.\n");
13628ed61dc3SMiklos Szeredi 	}
13638ed61dc3SMiklos Szeredi 
1364e487d889SAmir Goldstein 	/* Check if upper fs has 32bit inode numbers */
1365e487d889SAmir Goldstein 	if (fh_type != FILEID_INO32_GEN)
13660f831ec8SAmir Goldstein 		ofs->xino_mode = -1;
1367e487d889SAmir Goldstein 
1368f168f109SAmir Goldstein 	/* NFS export of r/w mount depends on index */
1369f168f109SAmir Goldstein 	if (ofs->config.nfs_export && !ofs->config.index) {
13701bd0a3aeSlijiazi 		pr_warn("NFS export requires \"index=on\", falling back to nfs_export=off.\n");
1371f168f109SAmir Goldstein 		ofs->config.nfs_export = false;
1372f168f109SAmir Goldstein 	}
13732ba9d57eSAmir Goldstein out:
13742ba9d57eSAmir Goldstein 	mnt_drop_write(mnt);
13752ba9d57eSAmir Goldstein 	return err;
13768ed61dc3SMiklos Szeredi }
13778ed61dc3SMiklos Szeredi 
1378146d62e5SAmir Goldstein static int ovl_get_workdir(struct super_block *sb, struct ovl_fs *ofs,
13792d343087SAl Viro 			   const struct path *upperpath)
1380520d7c86SMiklos Szeredi {
1381520d7c86SMiklos Szeredi 	int err;
1382bca44b52SMiklos Szeredi 	struct path workpath = { };
1383520d7c86SMiklos Szeredi 
1384ad204488SMiklos Szeredi 	err = ovl_mount_dir(ofs->config.workdir, &workpath);
1385520d7c86SMiklos Szeredi 	if (err)
1386520d7c86SMiklos Szeredi 		goto out;
1387520d7c86SMiklos Szeredi 
1388520d7c86SMiklos Szeredi 	err = -EINVAL;
1389bca44b52SMiklos Szeredi 	if (upperpath->mnt != workpath.mnt) {
13901bd0a3aeSlijiazi 		pr_err("workdir and upperdir must reside under the same mount\n");
1391520d7c86SMiklos Szeredi 		goto out;
1392520d7c86SMiklos Szeredi 	}
1393bca44b52SMiklos Szeredi 	if (!ovl_workdir_ok(workpath.dentry, upperpath->dentry)) {
13941bd0a3aeSlijiazi 		pr_err("workdir and upperdir must be separate subtrees\n");
1395520d7c86SMiklos Szeredi 		goto out;
1396520d7c86SMiklos Szeredi 	}
1397520d7c86SMiklos Szeredi 
13988c25741aSMiklos Szeredi 	ofs->workbasedir = dget(workpath.dentry);
13998c25741aSMiklos Szeredi 
14008c25741aSMiklos Szeredi 	if (ovl_inuse_trylock(ofs->workbasedir)) {
1401ad204488SMiklos Szeredi 		ofs->workdir_locked = true;
1402520d7c86SMiklos Szeredi 	} else {
14030be0bfd2SAmir Goldstein 		err = ovl_report_in_use(ofs, "workdir");
14040be0bfd2SAmir Goldstein 		if (err)
14050be0bfd2SAmir Goldstein 			goto out;
1406520d7c86SMiklos Szeredi 	}
1407520d7c86SMiklos Szeredi 
14080be0bfd2SAmir Goldstein 	err = ovl_setup_trap(sb, ofs->workbasedir, &ofs->workbasedir_trap,
14090be0bfd2SAmir Goldstein 			     "workdir");
14100be0bfd2SAmir Goldstein 	if (err)
14110be0bfd2SAmir Goldstein 		goto out;
14120be0bfd2SAmir Goldstein 
1413146d62e5SAmir Goldstein 	err = ovl_make_workdir(sb, ofs, &workpath);
1414bca44b52SMiklos Szeredi 
1415520d7c86SMiklos Szeredi out:
1416bca44b52SMiklos Szeredi 	path_put(&workpath);
1417bca44b52SMiklos Szeredi 
1418520d7c86SMiklos Szeredi 	return err;
1419520d7c86SMiklos Szeredi }
1420520d7c86SMiklos Szeredi 
1421146d62e5SAmir Goldstein static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
14222d343087SAl Viro 			    struct ovl_entry *oe, const struct path *upperpath)
1423f7e3a7d9SMiklos Szeredi {
142408f4c7c8SMiklos Szeredi 	struct vfsmount *mnt = ovl_upper_mnt(ofs);
1425235ce9edSAmir Goldstein 	struct dentry *indexdir;
1426f7e3a7d9SMiklos Szeredi 	int err;
1427f7e3a7d9SMiklos Szeredi 
14282ba9d57eSAmir Goldstein 	err = mnt_want_write(mnt);
14292ba9d57eSAmir Goldstein 	if (err)
14302ba9d57eSAmir Goldstein 		return err;
14312ba9d57eSAmir Goldstein 
1432f7e3a7d9SMiklos Szeredi 	/* Verify lower root is upper root origin */
1433610afc0bSMiklos Szeredi 	err = ovl_verify_origin(ofs, upperpath->dentry,
14345522c9c7SAmir Goldstein 				ovl_lowerstack(oe)->dentry, true);
1435f7e3a7d9SMiklos Szeredi 	if (err) {
14361bd0a3aeSlijiazi 		pr_err("failed to verify upper root origin\n");
1437f7e3a7d9SMiklos Szeredi 		goto out;
1438f7e3a7d9SMiklos Szeredi 	}
1439f7e3a7d9SMiklos Szeredi 
144020396365SAmir Goldstein 	/* index dir will act also as workdir */
144120396365SAmir Goldstein 	iput(ofs->workdir_trap);
144220396365SAmir Goldstein 	ofs->workdir_trap = NULL;
144320396365SAmir Goldstein 	dput(ofs->workdir);
1444470c1563SAmir Goldstein 	ofs->workdir = NULL;
1445235ce9edSAmir Goldstein 	indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true);
1446235ce9edSAmir Goldstein 	if (IS_ERR(indexdir)) {
1447235ce9edSAmir Goldstein 		err = PTR_ERR(indexdir);
1448235ce9edSAmir Goldstein 	} else if (indexdir) {
1449235ce9edSAmir Goldstein 		ofs->indexdir = indexdir;
1450235ce9edSAmir Goldstein 		ofs->workdir = dget(indexdir);
145120396365SAmir Goldstein 
1452146d62e5SAmir Goldstein 		err = ovl_setup_trap(sb, ofs->indexdir, &ofs->indexdir_trap,
1453146d62e5SAmir Goldstein 				     "indexdir");
1454146d62e5SAmir Goldstein 		if (err)
1455146d62e5SAmir Goldstein 			goto out;
1456146d62e5SAmir Goldstein 
1457ad1d615cSAmir Goldstein 		/*
1458ad1d615cSAmir Goldstein 		 * Verify upper root is exclusively associated with index dir.
14592d2f2d73SMiklos Szeredi 		 * Older kernels stored upper fh in ".overlay.origin"
1460ad1d615cSAmir Goldstein 		 * xattr. If that xattr exists, verify that it is a match to
1461ad1d615cSAmir Goldstein 		 * upper dir file handle. In any case, verify or set xattr
14622d2f2d73SMiklos Szeredi 		 * ".overlay.upper" to indicate that index may have
1463ad1d615cSAmir Goldstein 		 * directory entries.
1464ad1d615cSAmir Goldstein 		 */
1465610afc0bSMiklos Szeredi 		if (ovl_check_origin_xattr(ofs, ofs->indexdir)) {
1466610afc0bSMiklos Szeredi 			err = ovl_verify_set_fh(ofs, ofs->indexdir,
1467610afc0bSMiklos Szeredi 						OVL_XATTR_ORIGIN,
1468ad1d615cSAmir Goldstein 						upperpath->dentry, true, false);
1469f7e3a7d9SMiklos Szeredi 			if (err)
14701bd0a3aeSlijiazi 				pr_err("failed to verify index dir 'origin' xattr\n");
1471ad1d615cSAmir Goldstein 		}
1472610afc0bSMiklos Szeredi 		err = ovl_verify_upper(ofs, ofs->indexdir, upperpath->dentry,
1473610afc0bSMiklos Szeredi 				       true);
1474ad1d615cSAmir Goldstein 		if (err)
14751bd0a3aeSlijiazi 			pr_err("failed to verify index dir 'upper' xattr\n");
1476f7e3a7d9SMiklos Szeredi 
1477f7e3a7d9SMiklos Szeredi 		/* Cleanup bad/stale/orphan index entries */
1478f7e3a7d9SMiklos Szeredi 		if (!err)
14791eff1a1dSAmir Goldstein 			err = ovl_indexdir_cleanup(ofs);
1480f7e3a7d9SMiklos Szeredi 	}
1481ad204488SMiklos Szeredi 	if (err || !ofs->indexdir)
14821bd0a3aeSlijiazi 		pr_warn("try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
1483f7e3a7d9SMiklos Szeredi 
1484f7e3a7d9SMiklos Szeredi out:
14852ba9d57eSAmir Goldstein 	mnt_drop_write(mnt);
1486f7e3a7d9SMiklos Szeredi 	return err;
1487f7e3a7d9SMiklos Szeredi }
1488f7e3a7d9SMiklos Szeredi 
14899df085f3SAmir Goldstein static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid)
14905148626bSAmir Goldstein {
14915148626bSAmir Goldstein 	unsigned int i;
14929df085f3SAmir Goldstein 
149308f4c7c8SMiklos Szeredi 	if (!ofs->config.nfs_export && !ovl_upper_mnt(ofs))
14949df085f3SAmir Goldstein 		return true;
14959df085f3SAmir Goldstein 
1496a888db31SAmir Goldstein 	/*
1497a888db31SAmir Goldstein 	 * We allow using single lower with null uuid for index and nfs_export
1498a888db31SAmir Goldstein 	 * for example to support those features with single lower squashfs.
1499a888db31SAmir Goldstein 	 * To avoid regressions in setups of overlay with re-formatted lower
1500a888db31SAmir Goldstein 	 * squashfs, do not allow decoding origin with lower null uuid unless
1501a888db31SAmir Goldstein 	 * user opted-in to one of the new features that require following the
1502a888db31SAmir Goldstein 	 * lower inode of non-dir upper.
1503a888db31SAmir Goldstein 	 */
1504ca45275cSVyacheslav Yurkov 	if (ovl_allow_offline_changes(ofs) && uuid_is_null(uuid))
1505a888db31SAmir Goldstein 		return false;
1506a888db31SAmir Goldstein 
15071b81ddddSAmir Goldstein 	for (i = 0; i < ofs->numfs; i++) {
15089df085f3SAmir Goldstein 		/*
15099df085f3SAmir Goldstein 		 * We use uuid to associate an overlay lower file handle with a
15109df085f3SAmir Goldstein 		 * lower layer, so we can accept lower fs with null uuid as long
15119df085f3SAmir Goldstein 		 * as all lower layers with null uuid are on the same fs.
15127e63c87fSAmir Goldstein 		 * if we detect multiple lower fs with the same uuid, we
15137e63c87fSAmir Goldstein 		 * disable lower file handle decoding on all of them.
15149df085f3SAmir Goldstein 		 */
15151b81ddddSAmir Goldstein 		if (ofs->fs[i].is_lower &&
15161b81ddddSAmir Goldstein 		    uuid_equal(&ofs->fs[i].sb->s_uuid, uuid)) {
151707f1e596SAmir Goldstein 			ofs->fs[i].bad_uuid = true;
15189df085f3SAmir Goldstein 			return false;
15199df085f3SAmir Goldstein 		}
15207e63c87fSAmir Goldstein 	}
15219df085f3SAmir Goldstein 	return true;
15229df085f3SAmir Goldstein }
15239df085f3SAmir Goldstein 
15249df085f3SAmir Goldstein /* Get a unique fsid for the layer */
15259df085f3SAmir Goldstein static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
15269df085f3SAmir Goldstein {
15279df085f3SAmir Goldstein 	struct super_block *sb = path->mnt->mnt_sb;
15289df085f3SAmir Goldstein 	unsigned int i;
15295148626bSAmir Goldstein 	dev_t dev;
15305148626bSAmir Goldstein 	int err;
15317e63c87fSAmir Goldstein 	bool bad_uuid = false;
1532b0e0f697SAmir Goldstein 	bool warn = false;
15335148626bSAmir Goldstein 
153407f1e596SAmir Goldstein 	for (i = 0; i < ofs->numfs; i++) {
153507f1e596SAmir Goldstein 		if (ofs->fs[i].sb == sb)
153607f1e596SAmir Goldstein 			return i;
15375148626bSAmir Goldstein 	}
15385148626bSAmir Goldstein 
15399df085f3SAmir Goldstein 	if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) {
15407e63c87fSAmir Goldstein 		bad_uuid = true;
1541b0e0f697SAmir Goldstein 		if (ofs->config.xino == OVL_XINO_AUTO) {
1542b0e0f697SAmir Goldstein 			ofs->config.xino = OVL_XINO_OFF;
1543b0e0f697SAmir Goldstein 			warn = true;
1544b0e0f697SAmir Goldstein 		}
15457e63c87fSAmir Goldstein 		if (ofs->config.index || ofs->config.nfs_export) {
15469df085f3SAmir Goldstein 			ofs->config.index = false;
15479df085f3SAmir Goldstein 			ofs->config.nfs_export = false;
1548b0e0f697SAmir Goldstein 			warn = true;
1549b0e0f697SAmir Goldstein 		}
1550b0e0f697SAmir Goldstein 		if (warn) {
1551b0e0f697SAmir Goldstein 			pr_warn("%s uuid detected in lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n",
15527e63c87fSAmir Goldstein 				uuid_is_null(&sb->s_uuid) ? "null" :
15537e63c87fSAmir Goldstein 							    "conflicting",
1554b0e0f697SAmir Goldstein 				path->dentry, ovl_xino_str[ofs->config.xino]);
15559df085f3SAmir Goldstein 		}
15567e63c87fSAmir Goldstein 	}
15579df085f3SAmir Goldstein 
15585148626bSAmir Goldstein 	err = get_anon_bdev(&dev);
15595148626bSAmir Goldstein 	if (err) {
15601bd0a3aeSlijiazi 		pr_err("failed to get anonymous bdev for lowerpath\n");
15615148626bSAmir Goldstein 		return err;
15625148626bSAmir Goldstein 	}
15635148626bSAmir Goldstein 
156407f1e596SAmir Goldstein 	ofs->fs[ofs->numfs].sb = sb;
156507f1e596SAmir Goldstein 	ofs->fs[ofs->numfs].pseudo_dev = dev;
156607f1e596SAmir Goldstein 	ofs->fs[ofs->numfs].bad_uuid = bad_uuid;
15675148626bSAmir Goldstein 
156807f1e596SAmir Goldstein 	return ofs->numfs++;
15695148626bSAmir Goldstein }
15705148626bSAmir Goldstein 
1571*37ebf056SAmir Goldstein /*
1572*37ebf056SAmir Goldstein  * The fsid after the last lower fsid is used for the data layers.
1573*37ebf056SAmir Goldstein  * It is a "null fs" with a null sb, null uuid, and no pseudo dev.
1574*37ebf056SAmir Goldstein  */
1575*37ebf056SAmir Goldstein static int ovl_get_data_fsid(struct ovl_fs *ofs)
1576*37ebf056SAmir Goldstein {
1577*37ebf056SAmir Goldstein 	return ofs->numfs;
1578*37ebf056SAmir Goldstein }
1579*37ebf056SAmir Goldstein 
1580*37ebf056SAmir Goldstein 
158194375f9dSAmir Goldstein static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
1582b8e42a65SMiklos Szeredi 			  struct path *stack, unsigned int numlower,
1583b8e42a65SMiklos Szeredi 			  struct ovl_layer *layers)
1584520d7c86SMiklos Szeredi {
1585520d7c86SMiklos Szeredi 	int err;
1586520d7c86SMiklos Szeredi 	unsigned int i;
1587520d7c86SMiklos Szeredi 
1588*37ebf056SAmir Goldstein 	ofs->fs = kcalloc(numlower + 2, sizeof(struct ovl_sb), GFP_KERNEL);
158907f1e596SAmir Goldstein 	if (ofs->fs == NULL)
15909e88f905SAmir Goldstein 		return -ENOMEM;
15915148626bSAmir Goldstein 
1592*37ebf056SAmir Goldstein 	/*
1593*37ebf056SAmir Goldstein 	 * idx/fsid 0 are reserved for upper fs even with lower only overlay
1594*37ebf056SAmir Goldstein 	 * and the last fsid is reserved for "null fs" of the data layers.
1595*37ebf056SAmir Goldstein 	 */
159607f1e596SAmir Goldstein 	ofs->numfs++;
159707f1e596SAmir Goldstein 
159807f1e596SAmir Goldstein 	/*
1599b7bf9908SAmir Goldstein 	 * All lower layers that share the same fs as upper layer, use the same
1600b7bf9908SAmir Goldstein 	 * pseudo_dev as upper layer.  Allocate fs[0].pseudo_dev even for lower
1601b7bf9908SAmir Goldstein 	 * only overlay to simplify ovl_fs_free().
16021b81ddddSAmir Goldstein 	 * is_lower will be set if upper fs is shared with a lower layer.
160307f1e596SAmir Goldstein 	 */
1604b7bf9908SAmir Goldstein 	err = get_anon_bdev(&ofs->fs[0].pseudo_dev);
1605b7bf9908SAmir Goldstein 	if (err) {
1606b7bf9908SAmir Goldstein 		pr_err("failed to get anonymous bdev for upper fs\n");
16079e88f905SAmir Goldstein 		return err;
1608b7bf9908SAmir Goldstein 	}
1609b7bf9908SAmir Goldstein 
161008f4c7c8SMiklos Szeredi 	if (ovl_upper_mnt(ofs)) {
161108f4c7c8SMiklos Szeredi 		ofs->fs[0].sb = ovl_upper_mnt(ofs)->mnt_sb;
16121b81ddddSAmir Goldstein 		ofs->fs[0].is_lower = false;
161307f1e596SAmir Goldstein 	}
161407f1e596SAmir Goldstein 
1615520d7c86SMiklos Szeredi 	for (i = 0; i < numlower; i++) {
1616520d7c86SMiklos Szeredi 		struct vfsmount *mnt;
1617146d62e5SAmir Goldstein 		struct inode *trap;
16185148626bSAmir Goldstein 		int fsid;
1619520d7c86SMiklos Szeredi 
1620*37ebf056SAmir Goldstein 		if (i < numlower - ofs->numdatalayer)
16219e88f905SAmir Goldstein 			fsid = ovl_get_fsid(ofs, &stack[i]);
1622*37ebf056SAmir Goldstein 		else
1623*37ebf056SAmir Goldstein 			fsid = ovl_get_data_fsid(ofs);
16249e88f905SAmir Goldstein 		if (fsid < 0)
16259e88f905SAmir Goldstein 			return fsid;
1626520d7c86SMiklos Szeredi 
162724f14009Syoungjun 		/*
162824f14009Syoungjun 		 * Check if lower root conflicts with this overlay layers before
162924f14009Syoungjun 		 * checking if it is in-use as upperdir/workdir of "another"
163024f14009Syoungjun 		 * mount, because we do not bother to check in ovl_is_inuse() if
163124f14009Syoungjun 		 * the upperdir/workdir is in fact in-use by our
163224f14009Syoungjun 		 * upperdir/workdir.
163324f14009Syoungjun 		 */
1634146d62e5SAmir Goldstein 		err = ovl_setup_trap(sb, stack[i].dentry, &trap, "lowerdir");
1635146d62e5SAmir Goldstein 		if (err)
16369e88f905SAmir Goldstein 			return err;
1637146d62e5SAmir Goldstein 
16380be0bfd2SAmir Goldstein 		if (ovl_is_inuse(stack[i].dentry)) {
16390be0bfd2SAmir Goldstein 			err = ovl_report_in_use(ofs, "lowerdir");
164024f14009Syoungjun 			if (err) {
164124f14009Syoungjun 				iput(trap);
16429e88f905SAmir Goldstein 				return err;
16430be0bfd2SAmir Goldstein 			}
164424f14009Syoungjun 		}
16450be0bfd2SAmir Goldstein 
1646520d7c86SMiklos Szeredi 		mnt = clone_private_mount(&stack[i]);
1647520d7c86SMiklos Szeredi 		err = PTR_ERR(mnt);
1648520d7c86SMiklos Szeredi 		if (IS_ERR(mnt)) {
16491bd0a3aeSlijiazi 			pr_err("failed to clone lowerpath\n");
1650146d62e5SAmir Goldstein 			iput(trap);
16519e88f905SAmir Goldstein 			return err;
1652520d7c86SMiklos Szeredi 		}
16535148626bSAmir Goldstein 
1654520d7c86SMiklos Szeredi 		/*
1655520d7c86SMiklos Szeredi 		 * Make lower layers R/O.  That way fchmod/fchown on lower file
1656520d7c86SMiklos Szeredi 		 * will fail instead of modifying lower fs.
1657520d7c86SMiklos Szeredi 		 */
1658520d7c86SMiklos Szeredi 		mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
1659520d7c86SMiklos Szeredi 
166013464165SMiklos Szeredi 		layers[ofs->numlayer].trap = trap;
166113464165SMiklos Szeredi 		layers[ofs->numlayer].mnt = mnt;
166213464165SMiklos Szeredi 		layers[ofs->numlayer].idx = ofs->numlayer;
166313464165SMiklos Szeredi 		layers[ofs->numlayer].fsid = fsid;
166413464165SMiklos Szeredi 		layers[ofs->numlayer].fs = &ofs->fs[fsid];
166594375f9dSAmir Goldstein 		ofs->numlayer++;
16661b81ddddSAmir Goldstein 		ofs->fs[fsid].is_lower = true;
1667520d7c86SMiklos Szeredi 	}
1668e487d889SAmir Goldstein 
1669795939a9SAmir Goldstein 	/*
1670795939a9SAmir Goldstein 	 * When all layers on same fs, overlay can use real inode numbers.
1671926e94d7SAmir Goldstein 	 * With mount option "xino=<on|auto>", mounter declares that there are
1672926e94d7SAmir Goldstein 	 * enough free high bits in underlying fs to hold the unique fsid.
1673795939a9SAmir Goldstein 	 * If overlayfs does encounter underlying inodes using the high xino
1674795939a9SAmir Goldstein 	 * bits reserved for fsid, it emits a warning and uses the original
1675dfe51d47SAmir Goldstein 	 * inode number or a non persistent inode number allocated from a
1676dfe51d47SAmir Goldstein 	 * dedicated range.
1677795939a9SAmir Goldstein 	 */
167808f4c7c8SMiklos Szeredi 	if (ofs->numfs - !ovl_upper_mnt(ofs) == 1) {
16790f831ec8SAmir Goldstein 		if (ofs->config.xino == OVL_XINO_ON)
16800f831ec8SAmir Goldstein 			pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n");
16810f831ec8SAmir Goldstein 		ofs->xino_mode = 0;
168253afcd31SAmir Goldstein 	} else if (ofs->config.xino == OVL_XINO_OFF) {
168353afcd31SAmir Goldstein 		ofs->xino_mode = -1;
1684926e94d7SAmir Goldstein 	} else if (ofs->xino_mode < 0) {
1685795939a9SAmir Goldstein 		/*
168607f1e596SAmir Goldstein 		 * This is a roundup of number of bits needed for encoding
1687dfe51d47SAmir Goldstein 		 * fsid, where fsid 0 is reserved for upper fs (even with
1688dfe51d47SAmir Goldstein 		 * lower only overlay) +1 extra bit is reserved for the non
1689dfe51d47SAmir Goldstein 		 * persistent inode number range that is used for resolving
1690dfe51d47SAmir Goldstein 		 * xino lower bits overflow.
1691795939a9SAmir Goldstein 		 */
1692dfe51d47SAmir Goldstein 		BUILD_BUG_ON(ilog2(OVL_MAX_STACK) > 30);
1693dfe51d47SAmir Goldstein 		ofs->xino_mode = ilog2(ofs->numfs - 1) + 2;
1694795939a9SAmir Goldstein 	}
1695795939a9SAmir Goldstein 
16960f831ec8SAmir Goldstein 	if (ofs->xino_mode > 0) {
16971bd0a3aeSlijiazi 		pr_info("\"xino\" feature enabled using %d upper inode bits.\n",
16980f831ec8SAmir Goldstein 			ofs->xino_mode);
1699795939a9SAmir Goldstein 	}
1700e487d889SAmir Goldstein 
17019e88f905SAmir Goldstein 	return 0;
1702520d7c86SMiklos Szeredi }
1703520d7c86SMiklos Szeredi 
17044155c10aSMiklos Szeredi static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
1705b8e42a65SMiklos Szeredi 				const char *lower, unsigned int numlower,
1706b8e42a65SMiklos Szeredi 				struct ovl_fs *ofs, struct ovl_layer *layers)
170753dbb0b4SMiklos Szeredi {
170853dbb0b4SMiklos Szeredi 	int err;
17094155c10aSMiklos Szeredi 	struct path *stack = NULL;
17105522c9c7SAmir Goldstein 	struct ovl_path *lowerstack;
1711*37ebf056SAmir Goldstein 	unsigned int numlowerdata = 0;
1712b8e42a65SMiklos Szeredi 	unsigned int i;
17134155c10aSMiklos Szeredi 	struct ovl_entry *oe;
171453dbb0b4SMiklos Szeredi 
1715b8e42a65SMiklos Szeredi 	if (!ofs->config.upperdir && numlower == 1) {
17161bd0a3aeSlijiazi 		pr_err("at least 2 lowerdir are needed while upperdir nonexistent\n");
1717b8e42a65SMiklos Szeredi 		return ERR_PTR(-EINVAL);
171853dbb0b4SMiklos Szeredi 	}
171953dbb0b4SMiklos Szeredi 
1720b8e42a65SMiklos Szeredi 	stack = kcalloc(numlower, sizeof(struct path), GFP_KERNEL);
172153dbb0b4SMiklos Szeredi 	if (!stack)
1722b8e42a65SMiklos Szeredi 		return ERR_PTR(-ENOMEM);
172353dbb0b4SMiklos Szeredi 
1724*37ebf056SAmir Goldstein 	for (i = 0; i < numlower;) {
1725b8e42a65SMiklos Szeredi 		err = ovl_lower_dir(lower, &stack[i], ofs, &sb->s_stack_depth);
172653dbb0b4SMiklos Szeredi 		if (err)
17274155c10aSMiklos Szeredi 			goto out_err;
172853dbb0b4SMiklos Szeredi 
172953dbb0b4SMiklos Szeredi 		lower = strchr(lower, '\0') + 1;
1730*37ebf056SAmir Goldstein 
1731*37ebf056SAmir Goldstein 		i++;
1732*37ebf056SAmir Goldstein 		if (i == numlower)
1733*37ebf056SAmir Goldstein 			break;
1734*37ebf056SAmir Goldstein 
1735*37ebf056SAmir Goldstein 		err = -EINVAL;
1736*37ebf056SAmir Goldstein 		/*
1737*37ebf056SAmir Goldstein 		 * Empty lower layer path could mean :: separator that indicates
1738*37ebf056SAmir Goldstein 		 * a data-only lower data.
1739*37ebf056SAmir Goldstein 		 * Several data-only layers are allowed, but they all need to be
1740*37ebf056SAmir Goldstein 		 * at the bottom of the stack.
1741*37ebf056SAmir Goldstein 		 */
1742*37ebf056SAmir Goldstein 		if (*lower) {
1743*37ebf056SAmir Goldstein 			/* normal lower dir */
1744*37ebf056SAmir Goldstein 			if (numlowerdata) {
1745*37ebf056SAmir Goldstein 				pr_err("lower data-only dirs must be at the bottom of the stack.\n");
1746*37ebf056SAmir Goldstein 				goto out_err;
1747*37ebf056SAmir Goldstein 			}
1748*37ebf056SAmir Goldstein 		} else {
1749*37ebf056SAmir Goldstein 			/* data-only lower dir */
1750*37ebf056SAmir Goldstein 			if (!ofs->config.metacopy) {
1751*37ebf056SAmir Goldstein 				pr_err("lower data-only dirs require metacopy support.\n");
1752*37ebf056SAmir Goldstein 				goto out_err;
1753*37ebf056SAmir Goldstein 			}
1754*37ebf056SAmir Goldstein 			if (i == numlower - 1) {
1755*37ebf056SAmir Goldstein 				pr_err("lowerdir argument must not end with double colon.\n");
1756*37ebf056SAmir Goldstein 				goto out_err;
1757*37ebf056SAmir Goldstein 			}
1758*37ebf056SAmir Goldstein 			lower++;
1759*37ebf056SAmir Goldstein 			numlower--;
1760*37ebf056SAmir Goldstein 			numlowerdata++;
1761*37ebf056SAmir Goldstein 		}
1762*37ebf056SAmir Goldstein 	}
1763*37ebf056SAmir Goldstein 
1764*37ebf056SAmir Goldstein 	if (numlowerdata) {
1765*37ebf056SAmir Goldstein 		ofs->numdatalayer = numlowerdata;
1766*37ebf056SAmir Goldstein 		pr_info("using the lowest %d of %d lowerdirs as data layers\n",
1767*37ebf056SAmir Goldstein 			numlowerdata, numlower);
176853dbb0b4SMiklos Szeredi 	}
176953dbb0b4SMiklos Szeredi 
177053dbb0b4SMiklos Szeredi 	err = -EINVAL;
177153dbb0b4SMiklos Szeredi 	sb->s_stack_depth++;
177253dbb0b4SMiklos Szeredi 	if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
17731bd0a3aeSlijiazi 		pr_err("maximum fs stacking depth exceeded\n");
17744155c10aSMiklos Szeredi 		goto out_err;
177553dbb0b4SMiklos Szeredi 	}
177653dbb0b4SMiklos Szeredi 
1777b8e42a65SMiklos Szeredi 	err = ovl_get_layers(sb, ofs, stack, numlower, layers);
17784155c10aSMiklos Szeredi 	if (err)
17794155c10aSMiklos Szeredi 		goto out_err;
17804155c10aSMiklos Szeredi 
17814155c10aSMiklos Szeredi 	err = -ENOMEM;
1782*37ebf056SAmir Goldstein 	/* Data-only layers are not merged in root directory */
1783*37ebf056SAmir Goldstein 	oe = ovl_alloc_entry(numlower - numlowerdata);
17844155c10aSMiklos Szeredi 	if (!oe)
17854155c10aSMiklos Szeredi 		goto out_err;
17864155c10aSMiklos Szeredi 
17875522c9c7SAmir Goldstein 	lowerstack = ovl_lowerstack(oe);
1788*37ebf056SAmir Goldstein 	for (i = 0; i < numlower - numlowerdata; i++) {
17895522c9c7SAmir Goldstein 		lowerstack[i].dentry = dget(stack[i].dentry);
17905522c9c7SAmir Goldstein 		lowerstack[i].layer = &ofs->layers[i+1];
17914155c10aSMiklos Szeredi 	}
179253dbb0b4SMiklos Szeredi 
179353dbb0b4SMiklos Szeredi out:
179453dbb0b4SMiklos Szeredi 	for (i = 0; i < numlower; i++)
179553dbb0b4SMiklos Szeredi 		path_put(&stack[i]);
179653dbb0b4SMiklos Szeredi 	kfree(stack);
17974155c10aSMiklos Szeredi 
17984155c10aSMiklos Szeredi 	return oe;
17994155c10aSMiklos Szeredi 
18004155c10aSMiklos Szeredi out_err:
18014155c10aSMiklos Szeredi 	oe = ERR_PTR(err);
180253dbb0b4SMiklos Szeredi 	goto out;
180353dbb0b4SMiklos Szeredi }
180453dbb0b4SMiklos Szeredi 
1805146d62e5SAmir Goldstein /*
1806146d62e5SAmir Goldstein  * Check if this layer root is a descendant of:
1807146d62e5SAmir Goldstein  * - another layer of this overlayfs instance
1808146d62e5SAmir Goldstein  * - upper/work dir of any overlayfs instance
1809146d62e5SAmir Goldstein  */
18100be0bfd2SAmir Goldstein static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs,
1811708fa015SMiklos Szeredi 			   struct dentry *dentry, const char *name,
1812708fa015SMiklos Szeredi 			   bool is_lower)
1813146d62e5SAmir Goldstein {
18149179c21dSMiklos Szeredi 	struct dentry *next = dentry, *parent;
1815146d62e5SAmir Goldstein 	int err = 0;
1816146d62e5SAmir Goldstein 
18179179c21dSMiklos Szeredi 	if (!dentry)
1818146d62e5SAmir Goldstein 		return 0;
1819146d62e5SAmir Goldstein 
1820146d62e5SAmir Goldstein 	parent = dget_parent(next);
18219179c21dSMiklos Szeredi 
18229179c21dSMiklos Szeredi 	/* Walk back ancestors to root (inclusive) looking for traps */
18239179c21dSMiklos Szeredi 	while (!err && parent != next) {
1824708fa015SMiklos Szeredi 		if (is_lower && ovl_lookup_trap_inode(sb, parent)) {
1825146d62e5SAmir Goldstein 			err = -ELOOP;
18261bd0a3aeSlijiazi 			pr_err("overlapping %s path\n", name);
18270be0bfd2SAmir Goldstein 		} else if (ovl_is_inuse(parent)) {
18280be0bfd2SAmir Goldstein 			err = ovl_report_in_use(ofs, name);
1829146d62e5SAmir Goldstein 		}
1830146d62e5SAmir Goldstein 		next = parent;
18319179c21dSMiklos Szeredi 		parent = dget_parent(next);
18329179c21dSMiklos Szeredi 		dput(next);
1833146d62e5SAmir Goldstein 	}
1834146d62e5SAmir Goldstein 
18359179c21dSMiklos Szeredi 	dput(parent);
1836146d62e5SAmir Goldstein 
1837146d62e5SAmir Goldstein 	return err;
1838146d62e5SAmir Goldstein }
1839146d62e5SAmir Goldstein 
1840146d62e5SAmir Goldstein /*
1841146d62e5SAmir Goldstein  * Check if any of the layers or work dirs overlap.
1842146d62e5SAmir Goldstein  */
1843146d62e5SAmir Goldstein static int ovl_check_overlapping_layers(struct super_block *sb,
1844146d62e5SAmir Goldstein 					struct ovl_fs *ofs)
1845146d62e5SAmir Goldstein {
1846146d62e5SAmir Goldstein 	int i, err;
1847146d62e5SAmir Goldstein 
184808f4c7c8SMiklos Szeredi 	if (ovl_upper_mnt(ofs)) {
184908f4c7c8SMiklos Szeredi 		err = ovl_check_layer(sb, ofs, ovl_upper_mnt(ofs)->mnt_root,
1850708fa015SMiklos Szeredi 				      "upperdir", false);
1851146d62e5SAmir Goldstein 		if (err)
1852146d62e5SAmir Goldstein 			return err;
1853146d62e5SAmir Goldstein 
1854146d62e5SAmir Goldstein 		/*
1855146d62e5SAmir Goldstein 		 * Checking workbasedir avoids hitting ovl_is_inuse(parent) of
1856146d62e5SAmir Goldstein 		 * this instance and covers overlapping work and index dirs,
1857146d62e5SAmir Goldstein 		 * unless work or index dir have been moved since created inside
1858146d62e5SAmir Goldstein 		 * workbasedir.  In that case, we already have their traps in
1859146d62e5SAmir Goldstein 		 * inode cache and we will catch that case on lookup.
1860146d62e5SAmir Goldstein 		 */
1861708fa015SMiklos Szeredi 		err = ovl_check_layer(sb, ofs, ofs->workbasedir, "workdir",
1862708fa015SMiklos Szeredi 				      false);
1863146d62e5SAmir Goldstein 		if (err)
1864146d62e5SAmir Goldstein 			return err;
1865146d62e5SAmir Goldstein 	}
1866146d62e5SAmir Goldstein 
186794375f9dSAmir Goldstein 	for (i = 1; i < ofs->numlayer; i++) {
18680be0bfd2SAmir Goldstein 		err = ovl_check_layer(sb, ofs,
186994375f9dSAmir Goldstein 				      ofs->layers[i].mnt->mnt_root,
1870708fa015SMiklos Szeredi 				      "lowerdir", true);
1871146d62e5SAmir Goldstein 		if (err)
1872146d62e5SAmir Goldstein 			return err;
1873146d62e5SAmir Goldstein 	}
1874146d62e5SAmir Goldstein 
1875146d62e5SAmir Goldstein 	return 0;
1876146d62e5SAmir Goldstein }
1877146d62e5SAmir Goldstein 
18782effc5c2SAmir Goldstein static struct dentry *ovl_get_root(struct super_block *sb,
18792effc5c2SAmir Goldstein 				   struct dentry *upperdentry,
18802effc5c2SAmir Goldstein 				   struct ovl_entry *oe)
18812effc5c2SAmir Goldstein {
18822effc5c2SAmir Goldstein 	struct dentry *root;
18835522c9c7SAmir Goldstein 	struct ovl_path *lowerpath = ovl_lowerstack(oe);
188462c832edSAmir Goldstein 	unsigned long ino = d_inode(lowerpath->dentry)->i_ino;
188562c832edSAmir Goldstein 	int fsid = lowerpath->layer->fsid;
188662c832edSAmir Goldstein 	struct ovl_inode_params oip = {
188762c832edSAmir Goldstein 		.upperdentry = upperdentry,
18880af950f5SAmir Goldstein 		.oe = oe,
188962c832edSAmir Goldstein 	};
18902effc5c2SAmir Goldstein 
18912effc5c2SAmir Goldstein 	root = d_make_root(ovl_new_inode(sb, S_IFDIR, 0));
18922effc5c2SAmir Goldstein 	if (!root)
18932effc5c2SAmir Goldstein 		return NULL;
18942effc5c2SAmir Goldstein 
18952effc5c2SAmir Goldstein 	if (upperdentry) {
189662c832edSAmir Goldstein 		/* Root inode uses upper st_ino/i_ino */
189762c832edSAmir Goldstein 		ino = d_inode(upperdentry)->i_ino;
189862c832edSAmir Goldstein 		fsid = 0;
18992effc5c2SAmir Goldstein 		ovl_dentry_set_upper_alias(root);
1900610afc0bSMiklos Szeredi 		if (ovl_is_impuredir(sb, upperdentry))
19012effc5c2SAmir Goldstein 			ovl_set_flag(OVL_IMPURE, d_inode(root));
19022effc5c2SAmir Goldstein 	}
19032effc5c2SAmir Goldstein 
19042effc5c2SAmir Goldstein 	/* Root is always merge -> can have whiteouts */
19052effc5c2SAmir Goldstein 	ovl_set_flag(OVL_WHITEOUTS, d_inode(root));
19062effc5c2SAmir Goldstein 	ovl_dentry_set_flag(OVL_E_CONNECTED, root);
19072effc5c2SAmir Goldstein 	ovl_set_upperdata(d_inode(root));
190862c832edSAmir Goldstein 	ovl_inode_init(d_inode(root), &oip, ino, fsid);
19090af950f5SAmir Goldstein 	ovl_dentry_init_flags(root, upperdentry, oe, DCACHE_OP_WEAK_REVALIDATE);
19102effc5c2SAmir Goldstein 
19112effc5c2SAmir Goldstein 	return root;
19122effc5c2SAmir Goldstein }
19132effc5c2SAmir Goldstein 
1914e9be9d5eSMiklos Szeredi static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1915e9be9d5eSMiklos Szeredi {
191633006cdfSKees Cook 	struct path upperpath = { };
1917e9be9d5eSMiklos Szeredi 	struct dentry *root_dentry;
19184155c10aSMiklos Szeredi 	struct ovl_entry *oe;
1919ad204488SMiklos Szeredi 	struct ovl_fs *ofs;
1920b8e42a65SMiklos Szeredi 	struct ovl_layer *layers;
192151f8f3c4SKonstantin Khlebnikov 	struct cred *cred;
1922b8e42a65SMiklos Szeredi 	char *splitlower = NULL;
1923b8e42a65SMiklos Szeredi 	unsigned int numlower;
1924e9be9d5eSMiklos Szeredi 	int err;
1925e9be9d5eSMiklos Szeredi 
19269efb069dSMiklos Szeredi 	err = -EIO;
19279efb069dSMiklos Szeredi 	if (WARN_ON(sb->s_user_ns != current_user_ns()))
19289efb069dSMiklos Szeredi 		goto out;
19299efb069dSMiklos Szeredi 
1930f4288844SMiklos Szeredi 	sb->s_d_op = &ovl_dentry_operations;
1931f4288844SMiklos Szeredi 
1932f45827e8SErez Zadok 	err = -ENOMEM;
1933ad204488SMiklos Szeredi 	ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL);
1934ad204488SMiklos Szeredi 	if (!ofs)
1935e9be9d5eSMiklos Szeredi 		goto out;
1936e9be9d5eSMiklos Szeredi 
1937d7b49b10SChengguang Xu 	err = -ENOMEM;
1938ad204488SMiklos Szeredi 	ofs->creator_cred = cred = prepare_creds();
1939c6fe6254SMiklos Szeredi 	if (!cred)
1940c6fe6254SMiklos Szeredi 		goto out_err;
1941c6fe6254SMiklos Szeredi 
1942c21c839bSChengguang Xu 	/* Is there a reason anyone would want not to share whiteouts? */
1943c21c839bSChengguang Xu 	ofs->share_whiteout = true;
1944c21c839bSChengguang Xu 
1945ad204488SMiklos Szeredi 	ofs->config.index = ovl_index_def;
19465830fb6bSPavel Tikhomirov 	ofs->config.uuid = true;
1947f168f109SAmir Goldstein 	ofs->config.nfs_export = ovl_nfs_export_def;
1948795939a9SAmir Goldstein 	ofs->config.xino = ovl_xino_def();
1949d5791044SVivek Goyal 	ofs->config.metacopy = ovl_metacopy_def;
1950ad204488SMiklos Szeredi 	err = ovl_parse_opt((char *) data, &ofs->config);
1951f45827e8SErez Zadok 	if (err)
1952a9075cdbSMiklos Szeredi 		goto out_err;
1953f45827e8SErez Zadok 
1954e9be9d5eSMiklos Szeredi 	err = -EINVAL;
1955ad204488SMiklos Szeredi 	if (!ofs->config.lowerdir) {
195607f2af7bSKonstantin Khlebnikov 		if (!silent)
19571bd0a3aeSlijiazi 			pr_err("missing 'lowerdir'\n");
1958a9075cdbSMiklos Szeredi 		goto out_err;
195953a08cb9SMiklos Szeredi 	}
196053a08cb9SMiklos Szeredi 
1961b8e42a65SMiklos Szeredi 	err = -ENOMEM;
1962b8e42a65SMiklos Szeredi 	splitlower = kstrdup(ofs->config.lowerdir, GFP_KERNEL);
1963b8e42a65SMiklos Szeredi 	if (!splitlower)
1964b8e42a65SMiklos Szeredi 		goto out_err;
1965b8e42a65SMiklos Szeredi 
1966d7b49b10SChengguang Xu 	err = -EINVAL;
1967b8e42a65SMiklos Szeredi 	numlower = ovl_split_lowerdirs(splitlower);
1968b8e42a65SMiklos Szeredi 	if (numlower > OVL_MAX_STACK) {
1969b8e42a65SMiklos Szeredi 		pr_err("too many lower directories, limit is %d\n",
1970b8e42a65SMiklos Szeredi 		       OVL_MAX_STACK);
1971b8e42a65SMiklos Szeredi 		goto out_err;
1972b8e42a65SMiklos Szeredi 	}
1973b8e42a65SMiklos Szeredi 
1974d7b49b10SChengguang Xu 	err = -ENOMEM;
1975b8e42a65SMiklos Szeredi 	layers = kcalloc(numlower + 1, sizeof(struct ovl_layer), GFP_KERNEL);
1976b8e42a65SMiklos Szeredi 	if (!layers)
1977b8e42a65SMiklos Szeredi 		goto out_err;
1978b8e42a65SMiklos Szeredi 
1979b8e42a65SMiklos Szeredi 	ofs->layers = layers;
1980b8e42a65SMiklos Szeredi 	/* Layer 0 is reserved for upper even if there's no upper */
1981b8e42a65SMiklos Szeredi 	ofs->numlayer = 1;
1982b8e42a65SMiklos Szeredi 
198353a08cb9SMiklos Szeredi 	sb->s_stack_depth = 0;
1984cf9a6784SMiklos Szeredi 	sb->s_maxbytes = MAX_LFS_FILESIZE;
19854d314f78SAmir Goldstein 	atomic_long_set(&ofs->last_ino, 1);
19864f119628SWilliam Dean 	/* Assume underlying fs uses 32bit inodes unless proven otherwise */
198753afcd31SAmir Goldstein 	if (ofs->config.xino != OVL_XINO_OFF) {
19880f831ec8SAmir Goldstein 		ofs->xino_mode = BITS_PER_LONG - 32;
198953afcd31SAmir Goldstein 		if (!ofs->xino_mode) {
199053afcd31SAmir Goldstein 			pr_warn("xino not supported on 32bit kernel, falling back to xino=off.\n");
199153afcd31SAmir Goldstein 			ofs->config.xino = OVL_XINO_OFF;
199253afcd31SAmir Goldstein 		}
199353afcd31SAmir Goldstein 	}
1994795939a9SAmir Goldstein 
1995146d62e5SAmir Goldstein 	/* alloc/destroy_inode needed for setting up traps in inode cache */
1996146d62e5SAmir Goldstein 	sb->s_op = &ovl_super_operations;
1997146d62e5SAmir Goldstein 
1998ad204488SMiklos Szeredi 	if (ofs->config.upperdir) {
1999335d3fc5SSargun Dhillon 		struct super_block *upper_sb;
2000335d3fc5SSargun Dhillon 
2001d7b49b10SChengguang Xu 		err = -EINVAL;
2002ad204488SMiklos Szeredi 		if (!ofs->config.workdir) {
20031bd0a3aeSlijiazi 			pr_err("missing 'workdir'\n");
2004a9075cdbSMiklos Szeredi 			goto out_err;
2005e9be9d5eSMiklos Szeredi 		}
2006e9be9d5eSMiklos Szeredi 
2007b8e42a65SMiklos Szeredi 		err = ovl_get_upper(sb, ofs, &layers[0], &upperpath);
200821a3b317SMiklos Szeredi 		if (err)
2009a9075cdbSMiklos Szeredi 			goto out_err;
2010d719e8f2SMiklos Szeredi 
2011335d3fc5SSargun Dhillon 		upper_sb = ovl_upper_mnt(ofs)->mnt_sb;
2012335d3fc5SSargun Dhillon 		if (!ovl_should_sync(ofs)) {
2013335d3fc5SSargun Dhillon 			ofs->errseq = errseq_sample(&upper_sb->s_wb_err);
2014335d3fc5SSargun Dhillon 			if (errseq_check(&upper_sb->s_wb_err, ofs->errseq)) {
2015335d3fc5SSargun Dhillon 				err = -EIO;
2016335d3fc5SSargun Dhillon 				pr_err("Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n");
2017335d3fc5SSargun Dhillon 				goto out_err;
2018335d3fc5SSargun Dhillon 			}
2019335d3fc5SSargun Dhillon 		}
2020335d3fc5SSargun Dhillon 
2021146d62e5SAmir Goldstein 		err = ovl_get_workdir(sb, ofs, &upperpath);
20228ed61dc3SMiklos Szeredi 		if (err)
2023a9075cdbSMiklos Szeredi 			goto out_err;
2024c6fe6254SMiklos Szeredi 
2025ad204488SMiklos Szeredi 		if (!ofs->workdir)
20261751e8a6SLinus Torvalds 			sb->s_flags |= SB_RDONLY;
20276e88256eSMiklos Szeredi 
2028335d3fc5SSargun Dhillon 		sb->s_stack_depth = upper_sb->s_stack_depth;
2029335d3fc5SSargun Dhillon 		sb->s_time_gran = upper_sb->s_time_gran;
203021765194SVivek Goyal 	}
2031b8e42a65SMiklos Szeredi 	oe = ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers);
20324155c10aSMiklos Szeredi 	err = PTR_ERR(oe);
20334155c10aSMiklos Szeredi 	if (IS_ERR(oe))
2034a9075cdbSMiklos Szeredi 		goto out_err;
2035e9be9d5eSMiklos Szeredi 
203671cbad7eShujianyang 	/* If the upper fs is nonexistent, we mark overlayfs r/o too */
203708f4c7c8SMiklos Szeredi 	if (!ovl_upper_mnt(ofs))
20381751e8a6SLinus Torvalds 		sb->s_flags |= SB_RDONLY;
2039e9be9d5eSMiklos Szeredi 
20405830fb6bSPavel Tikhomirov 	if (!ofs->config.uuid && ofs->numfs > 1) {
20415830fb6bSPavel Tikhomirov 		pr_warn("The uuid=off requires a single fs for lower and upper, falling back to uuid=on.\n");
20425830fb6bSPavel Tikhomirov 		ofs->config.uuid = true;
20435830fb6bSPavel Tikhomirov 	}
20445830fb6bSPavel Tikhomirov 
2045470c1563SAmir Goldstein 	if (!ovl_force_readonly(ofs) && ofs->config.index) {
2046146d62e5SAmir Goldstein 		err = ovl_get_indexdir(sb, ofs, oe, &upperpath);
204754fb347eSAmir Goldstein 		if (err)
20484155c10aSMiklos Szeredi 			goto out_free_oe;
20496e88256eSMiklos Szeredi 
2050972d0093SAmir Goldstein 		/* Force r/o mount with no index dir */
205120396365SAmir Goldstein 		if (!ofs->indexdir)
20521751e8a6SLinus Torvalds 			sb->s_flags |= SB_RDONLY;
205302bcd157SAmir Goldstein 	}
205402bcd157SAmir Goldstein 
2055146d62e5SAmir Goldstein 	err = ovl_check_overlapping_layers(sb, ofs);
2056146d62e5SAmir Goldstein 	if (err)
2057146d62e5SAmir Goldstein 		goto out_free_oe;
2058146d62e5SAmir Goldstein 
2059972d0093SAmir Goldstein 	/* Show index=off in /proc/mounts for forced r/o mount */
2060f168f109SAmir Goldstein 	if (!ofs->indexdir) {
2061ad204488SMiklos Szeredi 		ofs->config.index = false;
206208f4c7c8SMiklos Szeredi 		if (ovl_upper_mnt(ofs) && ofs->config.nfs_export) {
20631bd0a3aeSlijiazi 			pr_warn("NFS export requires an index dir, falling back to nfs_export=off.\n");
2064f168f109SAmir Goldstein 			ofs->config.nfs_export = false;
2065f168f109SAmir Goldstein 		}
2066f168f109SAmir Goldstein 	}
206702bcd157SAmir Goldstein 
2068d5791044SVivek Goyal 	if (ofs->config.metacopy && ofs->config.nfs_export) {
20691bd0a3aeSlijiazi 		pr_warn("NFS export is not supported with metadata only copy up, falling back to nfs_export=off.\n");
2070d5791044SVivek Goyal 		ofs->config.nfs_export = false;
2071d5791044SVivek Goyal 	}
2072d5791044SVivek Goyal 
20738383f174SAmir Goldstein 	if (ofs->config.nfs_export)
20748383f174SAmir Goldstein 		sb->s_export_op = &ovl_export_operations;
20758383f174SAmir Goldstein 
207651f8f3c4SKonstantin Khlebnikov 	/* Never override disk quota limits or use reserved space */
207751f8f3c4SKonstantin Khlebnikov 	cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
207851f8f3c4SKonstantin Khlebnikov 
2079655042ccSVivek Goyal 	sb->s_magic = OVERLAYFS_SUPER_MAGIC;
20802d2f2d73SMiklos Szeredi 	sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers :
20812d2f2d73SMiklos Szeredi 		ovl_trusted_xattr_handlers;
2082ad204488SMiklos Szeredi 	sb->s_fs_info = ofs;
2083de2a4a50SMiklos Szeredi 	sb->s_flags |= SB_POSIXACL;
208432b1924bSKonstantin Khlebnikov 	sb->s_iflags |= SB_I_SKIP_SYNC;
2085655042ccSVivek Goyal 
2086c6fe6254SMiklos Szeredi 	err = -ENOMEM;
20872effc5c2SAmir Goldstein 	root_dentry = ovl_get_root(sb, upperpath.dentry, oe);
2088e9be9d5eSMiklos Szeredi 	if (!root_dentry)
20894155c10aSMiklos Szeredi 		goto out_free_oe;
2090e9be9d5eSMiklos Szeredi 
2091e9be9d5eSMiklos Szeredi 	mntput(upperpath.mnt);
2092b8e42a65SMiklos Szeredi 	kfree(splitlower);
2093ed06e069SMiklos Szeredi 
2094e9be9d5eSMiklos Szeredi 	sb->s_root = root_dentry;
2095e9be9d5eSMiklos Szeredi 
2096e9be9d5eSMiklos Szeredi 	return 0;
2097e9be9d5eSMiklos Szeredi 
20984155c10aSMiklos Szeredi out_free_oe:
2099163db0daSAmir Goldstein 	ovl_free_entry(oe);
21004155c10aSMiklos Szeredi out_err:
2101b8e42a65SMiklos Szeredi 	kfree(splitlower);
2102e9be9d5eSMiklos Szeredi 	path_put(&upperpath);
2103ad204488SMiklos Szeredi 	ovl_free_fs(ofs);
2104e9be9d5eSMiklos Szeredi out:
2105e9be9d5eSMiklos Szeredi 	return err;
2106e9be9d5eSMiklos Szeredi }
2107e9be9d5eSMiklos Szeredi 
2108e9be9d5eSMiklos Szeredi static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags,
2109e9be9d5eSMiklos Szeredi 				const char *dev_name, void *raw_data)
2110e9be9d5eSMiklos Szeredi {
2111e9be9d5eSMiklos Szeredi 	return mount_nodev(fs_type, flags, raw_data, ovl_fill_super);
2112e9be9d5eSMiklos Szeredi }
2113e9be9d5eSMiklos Szeredi 
2114e9be9d5eSMiklos Szeredi static struct file_system_type ovl_fs_type = {
2115e9be9d5eSMiklos Szeredi 	.owner		= THIS_MODULE,
2116ef94b186SMiklos Szeredi 	.name		= "overlay",
2117459c7c56SMiklos Szeredi 	.fs_flags	= FS_USERNS_MOUNT,
2118e9be9d5eSMiklos Szeredi 	.mount		= ovl_mount,
2119e9be9d5eSMiklos Szeredi 	.kill_sb	= kill_anon_super,
2120e9be9d5eSMiklos Szeredi };
2121ef94b186SMiklos Szeredi MODULE_ALIAS_FS("overlay");
2122e9be9d5eSMiklos Szeredi 
212313cf199dSAmir Goldstein static void ovl_inode_init_once(void *foo)
212413cf199dSAmir Goldstein {
212513cf199dSAmir Goldstein 	struct ovl_inode *oi = foo;
212613cf199dSAmir Goldstein 
212713cf199dSAmir Goldstein 	inode_init_once(&oi->vfs_inode);
212813cf199dSAmir Goldstein }
212913cf199dSAmir Goldstein 
2130e9be9d5eSMiklos Szeredi static int __init ovl_init(void)
2131e9be9d5eSMiklos Szeredi {
213213cf199dSAmir Goldstein 	int err;
213313cf199dSAmir Goldstein 
213413cf199dSAmir Goldstein 	ovl_inode_cachep = kmem_cache_create("ovl_inode",
213513cf199dSAmir Goldstein 					     sizeof(struct ovl_inode), 0,
213613cf199dSAmir Goldstein 					     (SLAB_RECLAIM_ACCOUNT|
213713cf199dSAmir Goldstein 					      SLAB_MEM_SPREAD|SLAB_ACCOUNT),
213813cf199dSAmir Goldstein 					     ovl_inode_init_once);
213913cf199dSAmir Goldstein 	if (ovl_inode_cachep == NULL)
214013cf199dSAmir Goldstein 		return -ENOMEM;
214113cf199dSAmir Goldstein 
21422406a307SJiufei Xue 	err = ovl_aio_request_cache_init();
21432406a307SJiufei Xue 	if (!err) {
214413cf199dSAmir Goldstein 		err = register_filesystem(&ovl_fs_type);
21452406a307SJiufei Xue 		if (!err)
21462406a307SJiufei Xue 			return 0;
21472406a307SJiufei Xue 
21482406a307SJiufei Xue 		ovl_aio_request_cache_destroy();
21492406a307SJiufei Xue 	}
215013cf199dSAmir Goldstein 	kmem_cache_destroy(ovl_inode_cachep);
215113cf199dSAmir Goldstein 
215213cf199dSAmir Goldstein 	return err;
2153e9be9d5eSMiklos Szeredi }
2154e9be9d5eSMiklos Szeredi 
2155e9be9d5eSMiklos Szeredi static void __exit ovl_exit(void)
2156e9be9d5eSMiklos Szeredi {
2157e9be9d5eSMiklos Szeredi 	unregister_filesystem(&ovl_fs_type);
215813cf199dSAmir Goldstein 
215913cf199dSAmir Goldstein 	/*
216013cf199dSAmir Goldstein 	 * Make sure all delayed rcu free inodes are flushed before we
216113cf199dSAmir Goldstein 	 * destroy cache.
216213cf199dSAmir Goldstein 	 */
216313cf199dSAmir Goldstein 	rcu_barrier();
216413cf199dSAmir Goldstein 	kmem_cache_destroy(ovl_inode_cachep);
21652406a307SJiufei Xue 	ovl_aio_request_cache_destroy();
2166e9be9d5eSMiklos Szeredi }
2167e9be9d5eSMiklos Szeredi 
2168e9be9d5eSMiklos Szeredi module_init(ovl_init);
2169e9be9d5eSMiklos Szeredi module_exit(ovl_exit);
2170