mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Right now ovl_inode stores inode pointer for lower inode. This helps with quickly getting lower inode given overlay inode (ovl_inode_lower()). Now with metadata only copy-up, we can have metacopy inode in middle layer as well and inode containing data can be different from ->lower. I need to be able to open the real file in ovl_open_realfile() and for that I need to quickly find the lower data inode. Hence store lower data inode also in ovl_inode. Also provide an helper ovl_inode_lowerdata() to access this field. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
		
			
				
	
	
		
			115 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *
 | 
						|
 * Copyright (C) 2011 Novell Inc.
 | 
						|
 * Copyright (C) 2016 Red Hat, Inc.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify it
 | 
						|
 * under the terms of the GNU General Public License version 2 as published by
 | 
						|
 * the Free Software Foundation.
 | 
						|
 */
 | 
						|
 | 
						|
struct ovl_config {
 | 
						|
	char *lowerdir;
 | 
						|
	char *upperdir;
 | 
						|
	char *workdir;
 | 
						|
	bool default_permissions;
 | 
						|
	bool redirect_dir;
 | 
						|
	bool redirect_follow;
 | 
						|
	const char *redirect_mode;
 | 
						|
	bool index;
 | 
						|
	bool nfs_export;
 | 
						|
	int xino;
 | 
						|
	bool metacopy;
 | 
						|
};
 | 
						|
 | 
						|
struct ovl_sb {
 | 
						|
	struct super_block *sb;
 | 
						|
	dev_t pseudo_dev;
 | 
						|
};
 | 
						|
 | 
						|
struct ovl_layer {
 | 
						|
	struct vfsmount *mnt;
 | 
						|
	struct ovl_sb *fs;
 | 
						|
	/* Index of this layer in fs root (upper idx == 0) */
 | 
						|
	int idx;
 | 
						|
	/* One fsid per unique underlying sb (upper fsid == 0) */
 | 
						|
	int fsid;
 | 
						|
};
 | 
						|
 | 
						|
struct ovl_path {
 | 
						|
	struct ovl_layer *layer;
 | 
						|
	struct dentry *dentry;
 | 
						|
};
 | 
						|
 | 
						|
/* private information held for overlayfs's superblock */
 | 
						|
struct ovl_fs {
 | 
						|
	struct vfsmount *upper_mnt;
 | 
						|
	unsigned int numlower;
 | 
						|
	/* Number of unique lower sb that differ from upper sb */
 | 
						|
	unsigned int numlowerfs;
 | 
						|
	struct ovl_layer *lower_layers;
 | 
						|
	struct ovl_sb *lower_fs;
 | 
						|
	/* workbasedir is the path at workdir= mount option */
 | 
						|
	struct dentry *workbasedir;
 | 
						|
	/* workdir is the 'work' directory under workbasedir */
 | 
						|
	struct dentry *workdir;
 | 
						|
	/* index directory listing overlay inodes by origin file handle */
 | 
						|
	struct dentry *indexdir;
 | 
						|
	long namelen;
 | 
						|
	/* pathnames of lower and upper dirs, for show_options */
 | 
						|
	struct ovl_config config;
 | 
						|
	/* creds of process who forced instantiation of super block */
 | 
						|
	const struct cred *creator_cred;
 | 
						|
	bool tmpfile;
 | 
						|
	bool noxattr;
 | 
						|
	/* Did we take the inuse lock? */
 | 
						|
	bool upperdir_locked;
 | 
						|
	bool workdir_locked;
 | 
						|
	/* Inode numbers in all layers do not use the high xino_bits */
 | 
						|
	unsigned int xino_bits;
 | 
						|
};
 | 
						|
 | 
						|
/* private information held for every overlayfs dentry */
 | 
						|
struct ovl_entry {
 | 
						|
	union {
 | 
						|
		struct {
 | 
						|
			unsigned long flags;
 | 
						|
		};
 | 
						|
		struct rcu_head rcu;
 | 
						|
	};
 | 
						|
	unsigned numlower;
 | 
						|
	struct ovl_path lowerstack[];
 | 
						|
};
 | 
						|
 | 
						|
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
 | 
						|
 | 
						|
static inline struct ovl_entry *OVL_E(struct dentry *dentry)
 | 
						|
{
 | 
						|
	return (struct ovl_entry *) dentry->d_fsdata;
 | 
						|
}
 | 
						|
 | 
						|
struct ovl_inode {
 | 
						|
	union {
 | 
						|
		struct ovl_dir_cache *cache;	/* directory */
 | 
						|
		struct inode *lowerdata;	/* regular file */
 | 
						|
	};
 | 
						|
	const char *redirect;
 | 
						|
	u64 version;
 | 
						|
	unsigned long flags;
 | 
						|
	struct inode vfs_inode;
 | 
						|
	struct dentry *__upperdentry;
 | 
						|
	struct inode *lower;
 | 
						|
 | 
						|
	/* synchronize copy up and more */
 | 
						|
	struct mutex lock;
 | 
						|
};
 | 
						|
 | 
						|
static inline struct ovl_inode *OVL_I(struct inode *inode)
 | 
						|
{
 | 
						|
	return container_of(inode, struct ovl_inode, vfs_inode);
 | 
						|
}
 | 
						|
 | 
						|
static inline struct dentry *ovl_upperdentry_dereference(struct ovl_inode *oi)
 | 
						|
{
 | 
						|
	return READ_ONCE(oi->__upperdentry);
 | 
						|
}
 |