Merge branches 'work.path' and 'work.mount' into work.f_path

This commit is contained in:
Al Viro
2025-09-27 20:18:21 -04:00
36 changed files with 663 additions and 712 deletions

View File

@@ -79,7 +79,7 @@ __bpf_kfunc void bpf_put_file(struct file *file)
* pathname in *buf*, including the NUL termination character. On error, a
* negative integer is returned.
*/
__bpf_kfunc int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz)
__bpf_kfunc int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz)
{
int len;
char *ret;

View File

@@ -114,26 +114,21 @@ static int create_link(struct config_item *parent_item,
}
static int get_target(const char *symname, struct path *path,
struct config_item **target, struct super_block *sb)
static int get_target(const char *symname, struct config_item **target,
struct super_block *sb)
{
struct path path __free(path_put) = {};
int ret;
ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
if (!ret) {
if (path->dentry->d_sb == sb) {
*target = configfs_get_config_item(path->dentry);
if (!*target) {
ret = -ENOENT;
path_put(path);
}
} else {
ret = -EPERM;
path_put(path);
}
}
return ret;
ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
if (ret)
return ret;
if (path.dentry->d_sb != sb)
return -EPERM;
*target = configfs_get_config_item(path.dentry);
if (!*target)
return -ENOENT;
return 0;
}
@@ -141,7 +136,6 @@ int configfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int ret;
struct path path;
struct configfs_dirent *sd;
struct config_item *parent_item;
struct config_item *target_item = NULL;
@@ -188,7 +182,7 @@ int configfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
* AV, a thoroughly annoyed bastard.
*/
inode_unlock(dir);
ret = get_target(symname, &path, &target_item, dentry->d_sb);
ret = get_target(symname, &target_item, dentry->d_sb);
inode_lock(dir);
if (ret)
goto out_put;
@@ -210,7 +204,6 @@ int configfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
}
config_item_put(target_item);
path_put(&path);
out_put:
config_item_put(parent_item);

View File

@@ -1390,6 +1390,7 @@ struct check_mount {
unsigned int mounted;
};
/* locks: mount_locked_reader && dentry->d_lock */
static enum d_walk_ret path_check_mount(void *data, struct dentry *dentry)
{
struct check_mount *info = data;
@@ -1416,9 +1417,8 @@ int path_has_submounts(const struct path *parent)
{
struct check_mount data = { .mnt = parent->mnt, .mounted = 0 };
read_seqlock_excl(&mount_lock);
guard(mount_locked_reader)();
d_walk(parent->dentry, &data, path_check_mount);
read_sequnlock_excl(&mount_lock);
return data.mounted;
}

View File

@@ -59,14 +59,6 @@ static int ecryptfs_d_revalidate(struct inode *dir, const struct qstr *name,
return rc;
}
struct kmem_cache *ecryptfs_dentry_info_cache;
static void ecryptfs_dentry_free_rcu(struct rcu_head *head)
{
kmem_cache_free(ecryptfs_dentry_info_cache,
container_of(head, struct ecryptfs_dentry_info, rcu));
}
/**
* ecryptfs_d_release
* @dentry: The ecryptfs dentry
@@ -75,11 +67,7 @@ static void ecryptfs_dentry_free_rcu(struct rcu_head *head)
*/
static void ecryptfs_d_release(struct dentry *dentry)
{
struct ecryptfs_dentry_info *p = dentry->d_fsdata;
if (p) {
path_put(&p->lower_path);
call_rcu(&p->rcu, ecryptfs_dentry_free_rcu);
}
dput(dentry->d_fsdata);
}
const struct dentry_operations ecryptfs_dops = {

View File

@@ -258,13 +258,6 @@ struct ecryptfs_inode_info {
struct ecryptfs_crypt_stat crypt_stat;
};
/* dentry private data. Each dentry must keep track of a lower
* vfsmount too. */
struct ecryptfs_dentry_info {
struct path lower_path;
struct rcu_head rcu;
};
/**
* ecryptfs_global_auth_tok - A key used to encrypt all new files under the mountpoint
* @flags: Status flags
@@ -348,6 +341,7 @@ struct ecryptfs_mount_crypt_stat {
/* superblock private data. */
struct ecryptfs_sb_info {
struct super_block *wsi_sb;
struct vfsmount *lower_mnt;
struct ecryptfs_mount_crypt_stat mount_crypt_stat;
};
@@ -494,22 +488,25 @@ ecryptfs_set_superblock_lower(struct super_block *sb,
}
static inline void
ecryptfs_set_dentry_private(struct dentry *dentry,
struct ecryptfs_dentry_info *dentry_info)
ecryptfs_set_dentry_lower(struct dentry *dentry,
struct dentry *lower_dentry)
{
dentry->d_fsdata = dentry_info;
dentry->d_fsdata = lower_dentry;
}
static inline struct dentry *
ecryptfs_dentry_to_lower(struct dentry *dentry)
{
return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry;
return dentry->d_fsdata;
}
static inline const struct path *
ecryptfs_dentry_to_lower_path(struct dentry *dentry)
static inline struct path
ecryptfs_lower_path(struct dentry *dentry)
{
return &((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path;
return (struct path){
.mnt = ecryptfs_superblock_to_private(dentry->d_sb)->lower_mnt,
.dentry = ecryptfs_dentry_to_lower(dentry)
};
}
#define ecryptfs_printk(type, fmt, arg...) \
@@ -532,7 +529,6 @@ extern unsigned int ecryptfs_number_of_users;
extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
extern struct kmem_cache *ecryptfs_file_info_cache;
extern struct kmem_cache *ecryptfs_dentry_info_cache;
extern struct kmem_cache *ecryptfs_inode_info_cache;
extern struct kmem_cache *ecryptfs_sb_info_cache;
extern struct kmem_cache *ecryptfs_header_cache;
@@ -557,7 +553,6 @@ int ecryptfs_encrypt_and_encode_filename(
size_t *encoded_name_size,
struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
const char *name, size_t name_size);
struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry);
void ecryptfs_dump_hex(char *data, int bytes);
int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
int sg_size);

View File

@@ -33,13 +33,12 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
struct iov_iter *to)
{
ssize_t rc;
const struct path *path;
struct file *file = iocb->ki_filp;
rc = generic_file_read_iter(iocb, to);
if (rc >= 0) {
path = ecryptfs_dentry_to_lower_path(file->f_path.dentry);
touch_atime(path);
struct path path = ecryptfs_lower_path(file->f_path.dentry);
touch_atime(&path);
}
return rc;
}
@@ -59,12 +58,11 @@ static ssize_t ecryptfs_splice_read_update_atime(struct file *in, loff_t *ppos,
size_t len, unsigned int flags)
{
ssize_t rc;
const struct path *path;
rc = filemap_splice_read(in, ppos, pipe, len, flags);
if (rc >= 0) {
path = ecryptfs_dentry_to_lower_path(in->f_path.dentry);
touch_atime(path);
struct path path = ecryptfs_lower_path(in->f_path.dentry);
touch_atime(&path);
}
return rc;
}
@@ -283,6 +281,7 @@ static int ecryptfs_dir_open(struct inode *inode, struct file *file)
* ecryptfs_lookup() */
struct ecryptfs_file_info *file_info;
struct file *lower_file;
struct path path;
/* Released in ecryptfs_release or end of function if failure */
file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL);
@@ -292,8 +291,8 @@ static int ecryptfs_dir_open(struct inode *inode, struct file *file)
"Error attempting to allocate memory\n");
return -ENOMEM;
}
lower_file = dentry_open(ecryptfs_dentry_to_lower_path(ecryptfs_dentry),
file->f_flags, current_cred());
path = ecryptfs_lower_path(ecryptfs_dentry);
lower_file = dentry_open(&path, file->f_flags, current_cred());
if (IS_ERR(lower_file)) {
printk(KERN_ERR "%s: Error attempting to initialize "
"the lower file for the dentry with name "

View File

@@ -327,24 +327,15 @@ static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode)
static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
struct dentry *lower_dentry)
{
const struct path *path = ecryptfs_dentry_to_lower_path(dentry->d_parent);
struct dentry *lower_parent = ecryptfs_dentry_to_lower(dentry->d_parent);
struct inode *inode, *lower_inode;
struct ecryptfs_dentry_info *dentry_info;
int rc = 0;
dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
if (!dentry_info) {
dput(lower_dentry);
return ERR_PTR(-ENOMEM);
}
fsstack_copy_attr_atime(d_inode(dentry->d_parent),
d_inode(path->dentry));
d_inode(lower_parent));
BUG_ON(!d_count(lower_dentry));
ecryptfs_set_dentry_private(dentry, dentry_info);
dentry_info->lower_path.mnt = mntget(path->mnt);
dentry_info->lower_path.dentry = lower_dentry;
ecryptfs_set_dentry_lower(dentry, lower_dentry);
/*
* negative dentry can go positive under us here - its parent is not
@@ -1022,10 +1013,10 @@ static int ecryptfs_getattr(struct mnt_idmap *idmap,
{
struct dentry *dentry = path->dentry;
struct kstat lower_stat;
struct path lower_path = ecryptfs_lower_path(dentry);
int rc;
rc = vfs_getattr_nosec(ecryptfs_dentry_to_lower_path(dentry),
&lower_stat, request_mask, flags);
rc = vfs_getattr_nosec(&lower_path, &lower_stat, request_mask, flags);
if (!rc) {
fsstack_copy_attr_all(d_inode(dentry),
ecryptfs_inode_to_lower(d_inode(dentry)));

View File

@@ -106,15 +106,14 @@ static int ecryptfs_init_lower_file(struct dentry *dentry,
struct file **lower_file)
{
const struct cred *cred = current_cred();
const struct path *path = ecryptfs_dentry_to_lower_path(dentry);
struct path path = ecryptfs_lower_path(dentry);
int rc;
rc = ecryptfs_privileged_open(lower_file, path->dentry, path->mnt,
cred);
rc = ecryptfs_privileged_open(lower_file, path.dentry, path.mnt, cred);
if (rc) {
printk(KERN_ERR "Error opening lower file "
"for lower_dentry [0x%p] and lower_mnt [0x%p]; "
"rc = [%d]\n", path->dentry, path->mnt, rc);
"rc = [%d]\n", path.dentry, path.mnt, rc);
(*lower_file) = NULL;
}
return rc;
@@ -437,7 +436,6 @@ static int ecryptfs_get_tree(struct fs_context *fc)
struct ecryptfs_fs_context *ctx = fc->fs_private;
struct ecryptfs_sb_info *sbi = fc->s_fs_info;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
struct ecryptfs_dentry_info *root_info;
const char *err = "Getting sb failed";
struct inode *inode;
struct path path;
@@ -543,14 +541,8 @@ static int ecryptfs_get_tree(struct fs_context *fc)
goto out_free;
}
rc = -ENOMEM;
root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
if (!root_info)
goto out_free;
/* ->kill_sb() will take care of root_info */
ecryptfs_set_dentry_private(s->s_root, root_info);
root_info->lower_path = path;
ecryptfs_set_dentry_lower(s->s_root, path.dentry);
ecryptfs_superblock_to_private(s)->lower_mnt = path.mnt;
s->s_flags |= SB_ACTIVE;
fc->root = dget(s->s_root);
@@ -580,6 +572,7 @@ static void ecryptfs_kill_block_super(struct super_block *sb)
kill_anon_super(sb);
if (!sb_info)
return;
mntput(sb_info->lower_mnt);
ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
}
@@ -667,11 +660,6 @@ static struct ecryptfs_cache_info {
.name = "ecryptfs_file_cache",
.size = sizeof(struct ecryptfs_file_info),
},
{
.cache = &ecryptfs_dentry_info_cache,
.name = "ecryptfs_dentry_info_cache",
.size = sizeof(struct ecryptfs_dentry_info),
},
{
.cache = &ecryptfs_inode_info_cache,
.name = "ecryptfs_inode_cache",

View File

@@ -54,7 +54,7 @@ struct backing_file {
#define backing_file(f) container_of(f, struct backing_file, file)
struct path *backing_file_user_path(const struct file *f)
const struct path *backing_file_user_path(const struct file *f)
{
return &backing_file(f)->user_path;
}

View File

@@ -53,7 +53,7 @@ extern int finish_clean_context(struct fs_context *fc);
* namei.c
*/
extern int filename_lookup(int dfd, struct filename *name, unsigned flags,
struct path *path, struct path *root);
struct path *path, const struct path *root);
int do_rmdir(int dfd, struct filename *name);
int do_unlinkat(int dfd, struct filename *name);
int may_linkat(struct mnt_idmap *idmap, const struct path *link);
@@ -84,9 +84,9 @@ void mnt_put_write_access_file(struct file *file);
extern void dissolve_on_fput(struct vfsmount *);
extern bool may_mount(void);
int path_mount(const char *dev_name, struct path *path,
int path_mount(const char *dev_name, const struct path *path,
const char *type_page, unsigned long flags, void *data_page);
int path_umount(struct path *path, int flags);
int path_umount(const struct path *path, int flags);
int show_path(struct seq_file *m, struct dentry *root);

View File

@@ -64,7 +64,10 @@ struct mount {
#endif
struct list_head mnt_mounts; /* list of children, anchored here */
struct list_head mnt_child; /* and going through their mnt_child */
struct list_head mnt_instance; /* mount instance on sb->s_mounts */
struct mount *mnt_next_for_sb; /* the next two fields are hlist_node, */
struct mount * __aligned(1) *mnt_pprev_for_sb;
/* except that LSB of pprev is stolen */
#define WRITE_HOLD 1 /* ... for use by mnt_hold_writers() */
const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
struct list_head mnt_expire; /* link in fs-specific expiry list */
@@ -154,6 +157,11 @@ static inline void get_mnt_ns(struct mnt_namespace *ns)
extern seqlock_t mount_lock;
DEFINE_LOCK_GUARD_0(mount_writer, write_seqlock(&mount_lock),
write_sequnlock(&mount_lock))
DEFINE_LOCK_GUARD_0(mount_locked_reader, read_seqlock_excl(&mount_lock),
read_sequnlock_excl(&mount_lock))
struct proc_mounts {
struct mnt_namespace *ns;
struct path root;
@@ -230,4 +238,33 @@ static inline void mnt_notify_add(struct mount *m)
}
#endif
static inline struct mount *topmost_overmount(struct mount *m)
{
while (m->overmount)
m = m->overmount;
return m;
}
static inline bool __test_write_hold(struct mount * __aligned(1) *val)
{
return (unsigned long)val & WRITE_HOLD;
}
static inline bool test_write_hold(const struct mount *m)
{
return __test_write_hold(m->mnt_pprev_for_sb);
}
static inline void set_write_hold(struct mount *m)
{
m->mnt_pprev_for_sb = (void *)((unsigned long)m->mnt_pprev_for_sb
| WRITE_HOLD);
}
static inline void clear_write_hold(struct mount *m)
{
m->mnt_pprev_for_sb = (void *)((unsigned long)m->mnt_pprev_for_sb
& ~WRITE_HOLD);
}
struct mnt_namespace *mnt_ns_from_dentry(struct dentry *dentry);

View File

@@ -2673,7 +2673,7 @@ static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path
}
int filename_lookup(int dfd, struct filename *name, unsigned flags,
struct path *path, struct path *root)
struct path *path, const struct path *root)
{
int retval;
struct nameidata nd;
@@ -4170,7 +4170,7 @@ struct dentry *kern_path_create(int dfd, const char *pathname,
}
EXPORT_SYMBOL(kern_path_create);
void done_path_create(struct path *path, struct dentry *dentry)
void done_path_create(const struct path *path, struct dentry *dentry)
{
if (!IS_ERR(dentry))
dput(dentry);

File diff suppressed because it is too large Load Diff

View File

@@ -529,7 +529,7 @@ nfs_set_local_verifier(struct inode *inode,
}
/* Factored out from fs/nfsd/vfs.h:fh_getattr() */
static int __vfs_getattr(struct path *p, struct kstat *stat, int version)
static int __vfs_getattr(const struct path *p, struct kstat *stat, int version)
{
u32 request_mask = STATX_BASIC_STATS;

View File

@@ -402,7 +402,7 @@ static struct svc_export *svc_export_update(struct svc_export *new,
struct svc_export *old);
static struct svc_export *svc_export_lookup(struct svc_export *);
static int check_export(struct path *path, int *flags, unsigned char *uuid)
static int check_export(const struct path *path, int *flags, unsigned char *uuid)
{
struct inode *inode = d_inode(path->dentry);
@@ -1181,7 +1181,7 @@ denied:
* use exp_get_by_name() or exp_find().
*/
struct svc_export *
rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
rqst_exp_get_by_name(struct svc_rqst *rqstp, const struct path *path)
{
struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);

View File

@@ -111,7 +111,7 @@ int nfsd_export_init(struct net *);
void nfsd_export_shutdown(struct net *);
void nfsd_export_flush(struct net *);
struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
struct path *);
const struct path *);
struct svc_export * rqst_exp_parent(struct svc_rqst *,
struct path *);
struct svc_export * rqst_find_fsidzero_export(struct svc_rqst *);

View File

@@ -242,7 +242,7 @@ static int ovl_verify_area(loff_t pos, loff_t pos2, loff_t len, loff_t totlen)
return 0;
}
static int ovl_sync_file(struct path *path)
static int ovl_sync_file(const struct path *path)
{
struct file *new_file;
int err;

View File

@@ -120,7 +120,7 @@ static bool ovl_is_real_file(const struct file *realfile,
}
static struct file *ovl_real_file_path(const struct file *file,
struct path *realpath)
const struct path *realpath)
{
struct ovl_file *of = file->private_data;
struct file *realfile = of->realfile;

View File

@@ -563,11 +563,11 @@ int ovl_set_metacopy_xattr(struct ovl_fs *ofs, struct dentry *d,
struct ovl_metacopy *metacopy);
bool ovl_is_metacopy_dentry(struct dentry *dentry);
char *ovl_get_redirect_xattr(struct ovl_fs *ofs, const struct path *path, int padding);
int ovl_ensure_verity_loaded(struct path *path);
int ovl_ensure_verity_loaded(const struct path *path);
int ovl_validate_verity(struct ovl_fs *ofs,
struct path *metapath,
struct path *datapath);
int ovl_get_verity_digest(struct ovl_fs *ofs, struct path *src,
const struct path *metapath,
const struct path *datapath);
int ovl_get_verity_digest(struct ovl_fs *ofs, const struct path *src,
struct ovl_metacopy *metacopy);
int ovl_sync_status(struct ovl_fs *ofs);

View File

@@ -394,7 +394,7 @@ static int ovl_check_namelen(const struct path *path, struct ovl_fs *ofs,
return err;
}
static int ovl_lower_dir(const char *name, struct path *path,
static int ovl_lower_dir(const char *name, const struct path *path,
struct ovl_fs *ofs, int *stack_depth)
{
int fh_type;

View File

@@ -1381,7 +1381,7 @@ err_free:
}
/* Call with mounter creds as it may open the file */
int ovl_ensure_verity_loaded(struct path *datapath)
int ovl_ensure_verity_loaded(const struct path *datapath)
{
struct inode *inode = d_inode(datapath->dentry);
struct file *filp;
@@ -1401,8 +1401,8 @@ int ovl_ensure_verity_loaded(struct path *datapath)
}
int ovl_validate_verity(struct ovl_fs *ofs,
struct path *metapath,
struct path *datapath)
const struct path *metapath,
const struct path *datapath)
{
struct ovl_metacopy metacopy_data;
u8 actual_digest[FS_VERITY_MAX_DIGEST_SIZE];
@@ -1455,7 +1455,7 @@ int ovl_validate_verity(struct ovl_fs *ofs,
return 0;
}
int ovl_get_verity_digest(struct ovl_fs *ofs, struct path *src,
int ovl_get_verity_digest(struct ovl_fs *ofs, const struct path *src,
struct ovl_metacopy *metacopy)
{
int err, digest_size;

View File

@@ -847,7 +847,7 @@ static int pidfs_export_permission(struct handle_to_path_ctx *ctx,
return 0;
}
static struct file *pidfs_export_open(struct path *path, unsigned int oflags)
static struct file *pidfs_export_open(const struct path *path, unsigned int oflags)
{
/*
* Clear O_LARGEFILE as open_by_handle_at() forces it and raise

View File

@@ -29,6 +29,7 @@ static inline struct mount *next_slave(struct mount *p)
return hlist_entry(p->mnt_slave.next, struct mount, mnt_slave);
}
/* locks: namespace_shared && is_mounted(mnt) */
static struct mount *get_peer_under_root(struct mount *mnt,
struct mnt_namespace *ns,
const struct path *root)
@@ -50,7 +51,7 @@ static struct mount *get_peer_under_root(struct mount *mnt,
* Get ID of closest dominating peer group having a representative
* under the given root.
*
* Caller must hold namespace_sem
* locks: namespace_shared
*/
int get_dominating_id(struct mount *mnt, const struct path *root)
{
@@ -70,19 +71,6 @@ static inline bool will_be_unmounted(struct mount *m)
return m->mnt.mnt_flags & MNT_UMOUNT;
}
static struct mount *propagation_source(struct mount *mnt)
{
do {
struct mount *m;
for (m = next_peer(mnt); m != mnt; m = next_peer(m)) {
if (!will_be_unmounted(m))
return m;
}
mnt = mnt->mnt_master;
} while (mnt && will_be_unmounted(mnt));
return mnt;
}
static void transfer_propagation(struct mount *mnt, struct mount *to)
{
struct hlist_node *p = NULL, *n;
@@ -111,11 +99,10 @@ void change_mnt_propagation(struct mount *mnt, int type)
return;
}
if (IS_MNT_SHARED(mnt)) {
if (type == MS_SLAVE || !hlist_empty(&mnt->mnt_slave_list))
m = propagation_source(mnt);
if (list_empty(&mnt->mnt_share)) {
mnt_release_group_id(mnt);
} else {
m = next_peer(mnt);
list_del_init(&mnt->mnt_share);
mnt->mnt_group_id = 0;
}
@@ -136,6 +123,57 @@ void change_mnt_propagation(struct mount *mnt, int type)
}
}
static struct mount *trace_transfers(struct mount *m)
{
while (1) {
struct mount *next = next_peer(m);
if (next != m) {
list_del_init(&m->mnt_share);
m->mnt_group_id = 0;
m->mnt_master = next;
} else {
if (IS_MNT_SHARED(m))
mnt_release_group_id(m);
next = m->mnt_master;
}
hlist_del_init(&m->mnt_slave);
CLEAR_MNT_SHARED(m);
SET_MNT_MARK(m);
if (!next || !will_be_unmounted(next))
return next;
if (IS_MNT_MARKED(next))
return next->mnt_master;
m = next;
}
}
static void set_destinations(struct mount *m, struct mount *master)
{
struct mount *next;
while ((next = m->mnt_master) != master) {
m->mnt_master = master;
m = next;
}
}
void bulk_make_private(struct list_head *set)
{
struct mount *m;
list_for_each_entry(m, set, mnt_list)
if (!IS_MNT_MARKED(m))
set_destinations(m, trace_transfers(m));
list_for_each_entry(m, set, mnt_list) {
transfer_propagation(m, m->mnt_master);
m->mnt_master = NULL;
CLEAR_MNT_MARK(m);
}
}
static struct mount *__propagation_next(struct mount *m,
struct mount *origin)
{
@@ -304,9 +342,8 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
err = PTR_ERR(this);
break;
}
read_seqlock_excl(&mount_lock);
mnt_set_mountpoint(n, dest_mp, this);
read_sequnlock_excl(&mount_lock);
scoped_guard(mount_locked_reader)
mnt_set_mountpoint(n, dest_mp, this);
if (n->mnt_master)
SET_MNT_MARK(n->mnt_master);
copy = this;

View File

@@ -42,6 +42,7 @@ static inline bool peers(const struct mount *m1, const struct mount *m2)
}
void change_mnt_propagation(struct mount *, int);
void bulk_make_private(struct list_head *);
int propagate_mnt(struct mount *, struct mountpoint *, struct mount *,
struct hlist_head *);
void propagate_umount(struct list_head *);

View File

@@ -72,7 +72,7 @@ static int ksmbd_vfs_path_lookup(struct ksmbd_share_config *share_conf,
{
struct qstr last;
struct filename *filename __free(putname) = NULL;
struct path *root_share_path = &share_conf->vfs_path;
const struct path *root_share_path = &share_conf->vfs_path;
int err, type;
struct dentry *d;
@@ -1306,7 +1306,7 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *filepath,
caseless, true);
}
void ksmbd_vfs_kern_path_unlock(struct path *path)
void ksmbd_vfs_kern_path_unlock(const struct path *path)
{
/* While lock is still held, ->d_parent is safe */
inode_unlock(d_inode(path->dentry->d_parent));
@@ -1856,7 +1856,7 @@ void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock)
}
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
struct path *path)
const struct path *path)
{
struct posix_acl_state acl_state;
struct posix_acl *acls;
@@ -1909,7 +1909,7 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
}
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
struct path *path, struct inode *parent_inode)
const struct path *path, struct inode *parent_inode)
{
struct posix_acl *acls;
struct posix_acl_entry *pace;

View File

@@ -123,7 +123,7 @@ int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name,
int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
unsigned int flags,
struct path *path, bool caseless);
void ksmbd_vfs_kern_path_unlock(struct path *path);
void ksmbd_vfs_kern_path_unlock(const struct path *path);
struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
const char *name,
unsigned int flags,
@@ -164,8 +164,8 @@ int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
struct dentry *dentry,
struct xattr_dos_attrib *da);
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
struct path *path);
const struct path *path);
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
struct path *path,
const struct path *path,
struct inode *parent_inode);
#endif /* __KSMBD_VFS_H__ */

View File

@@ -293,7 +293,7 @@ static int statx_lookup_flags(int flags)
return lookup_flags;
}
static int vfs_statx_path(struct path *path, int flags, struct kstat *stat,
static int vfs_statx_path(const struct path *path, int flags, struct kstat *stat,
u32 request_mask)
{
int error = vfs_getattr(path, stat, request_mask, flags);

View File

@@ -323,7 +323,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
if (!s)
return NULL;
INIT_LIST_HEAD(&s->s_mounts);
s->s_user_ns = get_user_ns(user_ns);
init_rwsem(&s->s_umount);
lockdep_set_class(&s->s_umount, &type->s_umount_key);
@@ -408,7 +407,7 @@ static void __put_super(struct super_block *s)
list_del_init(&s->s_list);
WARN_ON(s->s_dentry_lru.node);
WARN_ON(s->s_inode_lru.node);
WARN_ON(!list_empty(&s->s_mounts));
WARN_ON(s->s_mounts);
call_rcu(&s->rcu, destroy_super_rcu);
}
}

View File

@@ -270,7 +270,7 @@ struct export_operations {
int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
int nr_iomaps, struct iattr *iattr);
int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags);
struct file * (*open)(struct path *path, unsigned int oflags);
struct file * (*open)(const struct path *path, unsigned int oflags);
#define EXPORT_OP_NOWCC (0x1) /* don't collect v3 wcc data */
#define EXPORT_OP_NOSUBTREECHK (0x2) /* no subtree checking */
#define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4) /* close files before unlink */

View File

@@ -1324,6 +1324,8 @@ struct sb_writers {
struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS];
};
struct mount;
struct super_block {
struct list_head s_list; /* Keep this first */
dev_t s_dev; /* search index; _not_ kdev_t */
@@ -1358,7 +1360,7 @@ struct super_block {
__u16 s_encoding_flags;
#endif
struct hlist_bl_head s_roots; /* alternate root dentries for NFS */
struct list_head s_mounts; /* list of mounts; _not_ for fs use */
struct mount *s_mounts; /* list of mounts; _not_ for fs use */
struct block_device *s_bdev; /* can go away once we use an accessor for @s_bdev_file */
struct file *s_bdev_file;
struct backing_dev_info *s_bdi;
@@ -2879,7 +2881,7 @@ struct file *dentry_open_nonotify(const struct path *path, int flags,
const struct cred *cred);
struct file *dentry_create(const struct path *path, int flags, umode_t mode,
const struct cred *cred);
struct path *backing_file_user_path(const struct file *f);
const struct path *backing_file_user_path(const struct file *f);
/*
* When mmapping a file on a stackable filesystem (e.g., overlayfs), the file

View File

@@ -33,7 +33,6 @@ enum mount_flags {
MNT_NOSYMFOLLOW = 0x80,
MNT_SHRINKABLE = 0x100,
MNT_WRITE_HOLD = 0x200,
MNT_INTERNAL = 0x4000,
@@ -52,7 +51,7 @@ enum mount_flags {
| MNT_READONLY | MNT_NOSYMFOLLOW,
MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,
MNT_INTERNAL_FLAGS = MNT_WRITE_HOLD | MNT_INTERNAL | MNT_DOOMED |
MNT_INTERNAL_FLAGS = MNT_INTERNAL | MNT_DOOMED |
MNT_SYNC_UMOUNT | MNT_LOCKED
};
@@ -77,7 +76,7 @@ extern void mntput(struct vfsmount *mnt);
extern struct vfsmount *mntget(struct vfsmount *mnt);
extern void mnt_make_shortterm(struct vfsmount *mnt);
extern struct vfsmount *mnt_clone_internal(const struct path *path);
extern bool __mnt_is_readonly(struct vfsmount *mnt);
extern bool __mnt_is_readonly(const struct vfsmount *mnt);
extern bool mnt_may_suid(struct vfsmount *mnt);
extern struct vfsmount *clone_private_mount(const struct path *path);
@@ -104,8 +103,8 @@ extern int may_umount_tree(struct vfsmount *);
extern int may_umount(struct vfsmount *);
int do_mount(const char *, const char __user *,
const char *, unsigned long, void *);
extern struct path *collect_paths(const struct path *, struct path *, unsigned);
extern void drop_collected_paths(struct path *, struct path *);
extern const struct path *collect_paths(const struct path *, struct path *, unsigned);
extern void drop_collected_paths(const struct path *, const struct path *);
extern void kern_unmount_array(struct vfsmount *mnt[], unsigned int num);
extern int cifs_root_data(char **dev, char **opts);

View File

@@ -60,7 +60,7 @@ extern int kern_path(const char *, unsigned, struct path *);
extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int);
extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int);
extern void done_path_create(struct path *, struct dentry *);
extern void done_path_create(const struct path *, struct dentry *);
extern struct dentry *kern_path_locked(const char *, struct path *);
extern struct dentry *kern_path_locked_negative(const char *, struct path *);
extern struct dentry *user_path_locked_at(int , const char __user *, struct path *);

View File

@@ -678,7 +678,7 @@ void audit_trim_trees(void)
struct audit_tree *tree;
struct path path;
struct audit_node *node;
struct path *paths;
const struct path *paths;
struct path array[16];
int err;
@@ -701,7 +701,7 @@ void audit_trim_trees(void)
struct audit_chunk *chunk = find_chunk(node);
/* this could be NULL if the watch is dying else where... */
node->index |= 1U<<31;
for (struct path *p = paths; p->dentry; p++) {
for (const struct path *p = paths; p->dentry; p++) {
struct inode *inode = p->dentry->d_inode;
if (inode_to_key(inode) == chunk->key) {
node->index &= ~(1U<<31);
@@ -740,9 +740,9 @@ void audit_put_tree(struct audit_tree *tree)
put_tree(tree);
}
static int tag_mounts(struct path *paths, struct audit_tree *tree)
static int tag_mounts(const struct path *paths, struct audit_tree *tree)
{
for (struct path *p = paths; p->dentry; p++) {
for (const struct path *p = paths; p->dentry; p++) {
int err = tag_chunk(p->dentry->d_inode, tree);
if (err)
return err;
@@ -805,7 +805,7 @@ int audit_add_tree_rule(struct audit_krule *rule)
struct audit_tree *seed = rule->tree, *tree;
struct path path;
struct path array[16];
struct path *paths;
const struct path *paths;
int err;
rule->tree = NULL;
@@ -877,7 +877,7 @@ int audit_tag_tree(char *old, char *new)
int failed = 0;
struct path path1, path2;
struct path array[16];
struct path *paths;
const struct path *paths;
int err;
err = kern_path(new, 0, &path2);

View File

@@ -900,7 +900,7 @@ const struct bpf_func_proto bpf_send_signal_thread_proto = {
.arg1_type = ARG_ANYTHING,
};
BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz)
BPF_CALL_3(bpf_d_path, const struct path *, path, char *, buf, u32, sz)
{
struct path copy;
long len;

View File

@@ -31,7 +31,7 @@ static inline struct sock *aa_unix_sk(struct unix_sock *u)
}
static int unix_fs_perm(const char *op, u32 mask, const struct cred *subj_cred,
struct aa_label *label, struct path *path)
struct aa_label *label, const struct path *path)
{
AA_BUG(!label);
AA_BUG(!path);
@@ -224,7 +224,7 @@ static int profile_create_perm(struct aa_profile *profile, int family,
static int profile_sk_perm(struct aa_profile *profile,
struct apparmor_audit_data *ad,
u32 request, struct sock *sk, struct path *path)
u32 request, struct sock *sk, const struct path *path)
{
struct aa_ruleset *rules = profile->label.rules[0];
struct aa_perms *p = NULL;
@@ -386,9 +386,9 @@ static int profile_opt_perm(struct aa_profile *profile, u32 request,
/* null peer_label is allowed, in which case the peer_sk label is used */
static int profile_peer_perm(struct aa_profile *profile, u32 request,
struct sock *sk, struct path *path,
struct sock *sk, const struct path *path,
struct sockaddr_un *peer_addr,
int peer_addrlen, struct path *peer_path,
int peer_addrlen, const struct path *peer_path,
struct aa_label *peer_label,
struct apparmor_audit_data *ad)
{
@@ -445,7 +445,7 @@ int aa_unix_create_perm(struct aa_label *label, int family, int type,
static int aa_unix_label_sk_perm(const struct cred *subj_cred,
struct aa_label *label,
const char *op, u32 request, struct sock *sk,
struct path *path)
const struct path *path)
{
if (!unconfined(label)) {
struct aa_profile *profile;
@@ -599,9 +599,9 @@ int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock,
static int unix_peer_perm(const struct cred *subj_cred,
struct aa_label *label, const char *op, u32 request,
struct sock *sk, struct path *path,
struct sock *sk, const struct path *path,
struct sockaddr_un *peer_addr, int peer_addrlen,
struct path *peer_path, struct aa_label *peer_label)
const struct path *peer_path, struct aa_label *peer_label)
{
struct aa_profile *profile;
DEFINE_AUDIT_SK(ad, op, subj_cred, sk);

View File

@@ -219,7 +219,7 @@ extern void bpf_put_file(struct file *file) __ksym;
* including the NULL termination character, stored in the supplied
* buffer. On error, a negative integer is returned.
*/
extern int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz) __ksym;
extern int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz) __ksym;
/* This macro must be used to mark the exception callback corresponding to the
* main program. For example: