mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-12 05:06:39 +07:00
5fa3ea047a
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
355 lines
9.5 KiB
C
355 lines
9.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2005-2019 Junjiro R. Okajima
|
|
*
|
|
* This program, aufs is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* sub-routines for VFS
|
|
*/
|
|
|
|
#ifndef __AUFS_VFSUB_H__
|
|
#define __AUFS_VFSUB_H__
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
#include <linux/fs.h>
|
|
#include <linux/mount.h>
|
|
#include <linux/posix_acl.h>
|
|
#include <linux/xattr.h>
|
|
#include "debug.h"
|
|
|
|
/* copied from linux/fs/internal.h */
|
|
/* todo: BAD approach!! */
|
|
extern void __mnt_drop_write(struct vfsmount *);
|
|
extern struct file *alloc_empty_file(int, const struct cred *);
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
/* lock subclass for lower inode */
|
|
/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
|
|
/* reduce? gave up. */
|
|
enum {
|
|
AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
|
|
AuLsc_I_PARENT, /* lower inode, parent first */
|
|
AuLsc_I_PARENT2, /* copyup dirs */
|
|
AuLsc_I_PARENT3, /* copyup wh */
|
|
AuLsc_I_CHILD,
|
|
AuLsc_I_CHILD2,
|
|
AuLsc_I_End
|
|
};
|
|
|
|
/* to debug easier, do not make them inlined functions */
|
|
#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
|
|
#define IMustLock(i) AuDebugOn(!inode_is_locked(i))
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static inline void vfsub_drop_nlink(struct inode *inode)
|
|
{
|
|
AuDebugOn(!inode->i_nlink);
|
|
drop_nlink(inode);
|
|
}
|
|
|
|
static inline void vfsub_dead_dir(struct inode *inode)
|
|
{
|
|
AuDebugOn(!S_ISDIR(inode->i_mode));
|
|
inode->i_flags |= S_DEAD;
|
|
clear_nlink(inode);
|
|
}
|
|
|
|
static inline int vfsub_native_ro(struct inode *inode)
|
|
{
|
|
return sb_rdonly(inode->i_sb)
|
|
|| IS_RDONLY(inode)
|
|
/* || IS_APPEND(inode) */
|
|
|| IS_IMMUTABLE(inode);
|
|
}
|
|
|
|
#ifdef CONFIG_AUFS_BR_FUSE
|
|
int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
|
|
#else
|
|
AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
|
|
#endif
|
|
|
|
int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
int vfsub_update_h_iattr(struct path *h_path, int *did);
|
|
struct file *vfsub_dentry_open(struct path *path, int flags);
|
|
struct file *vfsub_filp_open(const char *path, int oflags, int mode);
|
|
struct au_branch;
|
|
struct vfsub_aopen_args {
|
|
struct file *file;
|
|
unsigned int open_flag;
|
|
umode_t create_mode;
|
|
struct au_branch *br;
|
|
};
|
|
int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
|
|
struct vfsub_aopen_args *args);
|
|
int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
|
|
|
|
struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
|
|
struct dentry *parent, int len);
|
|
struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
|
|
int len);
|
|
|
|
struct vfsub_lkup_one_args {
|
|
struct dentry **errp;
|
|
struct qstr *name;
|
|
struct dentry *parent;
|
|
};
|
|
|
|
static inline struct dentry *vfsub_lkup_one(struct qstr *name,
|
|
struct dentry *parent)
|
|
{
|
|
return vfsub_lookup_one_len(name->name, parent, name->len);
|
|
}
|
|
|
|
void vfsub_call_lkup_one(void *args);
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
|
|
{
|
|
int err;
|
|
|
|
lockdep_off();
|
|
err = mnt_want_write(mnt);
|
|
lockdep_on();
|
|
return err;
|
|
}
|
|
|
|
static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
|
|
{
|
|
lockdep_off();
|
|
mnt_drop_write(mnt);
|
|
lockdep_on();
|
|
}
|
|
|
|
#if 0 /* reserved */
|
|
static inline void vfsub_mnt_drop_write_file(struct file *file)
|
|
{
|
|
lockdep_off();
|
|
mnt_drop_write_file(file);
|
|
lockdep_on();
|
|
}
|
|
#endif
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
struct au_hinode;
|
|
struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
|
|
struct dentry *d2, struct au_hinode *hdir2);
|
|
void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
|
|
struct dentry *d2, struct au_hinode *hdir2);
|
|
|
|
int vfsub_create(struct inode *dir, struct path *path, int mode,
|
|
bool want_excl);
|
|
int vfsub_symlink(struct inode *dir, struct path *path,
|
|
const char *symname);
|
|
int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
|
|
int vfsub_link(struct dentry *src_dentry, struct inode *dir,
|
|
struct path *path, struct inode **delegated_inode);
|
|
int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
|
|
struct inode *hdir, struct path *path,
|
|
struct inode **delegated_inode, unsigned int flags);
|
|
int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
|
|
int vfsub_rmdir(struct inode *dir, struct path *path);
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
|
|
loff_t *ppos);
|
|
ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
|
|
loff_t *ppos);
|
|
ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
|
|
loff_t *ppos);
|
|
ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
|
|
loff_t *ppos);
|
|
int vfsub_flush(struct file *file, fl_owner_t id);
|
|
int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
|
|
|
|
static inline loff_t vfsub_f_size_read(struct file *file)
|
|
{
|
|
return i_size_read(file_inode(file));
|
|
}
|
|
|
|
static inline unsigned int vfsub_file_flags(struct file *file)
|
|
{
|
|
unsigned int flags;
|
|
|
|
spin_lock(&file->f_lock);
|
|
flags = file->f_flags;
|
|
spin_unlock(&file->f_lock);
|
|
|
|
return flags;
|
|
}
|
|
|
|
static inline int vfsub_file_execed(struct file *file)
|
|
{
|
|
/* todo: direct access f_flags */
|
|
return !!(vfsub_file_flags(file) & __FMODE_EXEC);
|
|
}
|
|
|
|
#if 0 /* reserved */
|
|
static inline void vfsub_file_accessed(struct file *h_file)
|
|
{
|
|
file_accessed(h_file);
|
|
vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
|
|
}
|
|
#endif
|
|
|
|
#if 0 /* reserved */
|
|
static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
|
|
struct dentry *h_dentry)
|
|
{
|
|
struct path h_path = {
|
|
.dentry = h_dentry,
|
|
.mnt = h_mnt
|
|
};
|
|
touch_atime(&h_path);
|
|
vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
|
|
}
|
|
#endif
|
|
|
|
static inline int vfsub_update_time(struct inode *h_inode,
|
|
struct timespec64 *ts, int flags)
|
|
{
|
|
return update_time(h_inode, ts, flags);
|
|
/* no vfsub_update_h_iattr() since we don't have struct path */
|
|
}
|
|
|
|
#ifdef CONFIG_FS_POSIX_ACL
|
|
static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
|
|
{
|
|
int err;
|
|
|
|
err = posix_acl_chmod(h_inode, h_mode);
|
|
if (err == -EOPNOTSUPP)
|
|
err = 0;
|
|
return err;
|
|
}
|
|
#else
|
|
AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
|
|
#endif
|
|
|
|
long vfsub_splice_to(struct file *in, loff_t *ppos,
|
|
struct pipe_inode_info *pipe, size_t len,
|
|
unsigned int flags);
|
|
long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
|
loff_t *ppos, size_t len, unsigned int flags);
|
|
|
|
static inline long vfsub_truncate(struct path *path, loff_t length)
|
|
{
|
|
long err;
|
|
|
|
lockdep_off();
|
|
err = vfs_truncate(path, length);
|
|
lockdep_on();
|
|
return err;
|
|
}
|
|
|
|
int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
|
|
struct file *h_file);
|
|
int vfsub_fsync(struct file *file, struct path *path, int datasync);
|
|
|
|
/*
|
|
* re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
|
|
* ioctl.
|
|
*/
|
|
static inline loff_t vfsub_clone_file_range(struct file *src, struct file *dst,
|
|
loff_t len)
|
|
{
|
|
loff_t err;
|
|
|
|
lockdep_off();
|
|
err = vfs_clone_file_range(src, 0, dst, 0, len, /*remap_flags*/0);
|
|
lockdep_on();
|
|
|
|
return err;
|
|
}
|
|
|
|
/* copy_file_range(2) is a systemcall */
|
|
static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos,
|
|
struct file *dst, loff_t dst_pos,
|
|
size_t len, unsigned int flags)
|
|
{
|
|
ssize_t ssz;
|
|
|
|
lockdep_off();
|
|
ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags);
|
|
lockdep_on();
|
|
|
|
return ssz;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
|
|
{
|
|
loff_t err;
|
|
|
|
lockdep_off();
|
|
err = vfs_llseek(file, offset, origin);
|
|
lockdep_on();
|
|
return err;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
|
|
int vfsub_sio_rmdir(struct inode *dir, struct path *path);
|
|
int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
|
|
struct inode **delegated_inode);
|
|
int vfsub_notify_change(struct path *path, struct iattr *ia,
|
|
struct inode **delegated_inode);
|
|
int vfsub_unlink(struct inode *dir, struct path *path,
|
|
struct inode **delegated_inode, int force);
|
|
|
|
static inline int vfsub_getattr(const struct path *path, struct kstat *st)
|
|
{
|
|
return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
|
|
const void *value, size_t size, int flags)
|
|
{
|
|
int err;
|
|
|
|
lockdep_off();
|
|
err = vfs_setxattr(dentry, name, value, size, flags);
|
|
lockdep_on();
|
|
|
|
return err;
|
|
}
|
|
|
|
static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
|
|
{
|
|
int err;
|
|
|
|
lockdep_off();
|
|
err = vfs_removexattr(dentry, name);
|
|
lockdep_on();
|
|
|
|
return err;
|
|
}
|
|
|
|
#endif /* __KERNEL__ */
|
|
#endif /* __AUFS_VFSUB_H__ */
|