Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro: "Assorted stuff all over the place" * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: useful constants: struct qstr for ".." hostfs_open(): don't open-code file_dentry() whack-a-mole: kill strlen_user() (again) autofs: should_expire() argument is guaranteed to be positive apparmor:match_mn() - constify devpath argument buffer: a small optimization in grow_buffers get rid of autofs_getpath() constify dentry argument of dentry_path()/dentry_path_raw()
This commit is contained in:
		
						commit
						27787ba3fa
					
				| @ -397,8 +397,6 @@ long __strncpy_from_user(char *dst, const char *src, long count); | ||||
|  */ | ||||
| long strnlen_user(const char *src, long n); | ||||
| 
 | ||||
| #define strlen_user(str) strnlen_user(str, 32767) | ||||
| 
 | ||||
| struct exception_table_entry { | ||||
| 	unsigned long insn; | ||||
| 	unsigned long nextinsn; | ||||
|  | ||||
| @ -116,7 +116,7 @@ long strncpy_from_user(char *dst, const char *src, long count) | ||||
| EXPORT_SYMBOL(strncpy_from_user); | ||||
| 
 | ||||
| /*
 | ||||
|  * strlen_user: - Get the size of a string in user space. | ||||
|  * strnlen_user: - Get the size of a string in user space. | ||||
|  * @str: The string to measure. | ||||
|  * @n:   The maximum valid length | ||||
|  * | ||||
|  | ||||
| @ -260,7 +260,6 @@ do {									\ | ||||
| 
 | ||||
| extern unsigned long __arch_clear_user(void __user * addr, unsigned long n); | ||||
| extern long strncpy_from_user(char *dest, const char __user * src, long count); | ||||
| extern __must_check long strlen_user(const char __user * str); | ||||
| extern __must_check long strnlen_user(const char __user * str, long n); | ||||
| extern unsigned long __arch_copy_from_user(void *to, const void __user * from, | ||||
|                                            unsigned long n); | ||||
|  | ||||
| @ -83,7 +83,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n); | ||||
| 
 | ||||
| extern long strncpy_from_user(char *__to, const char __user *__from, | ||||
| 			      long __len); | ||||
| extern __must_check long strlen_user(const char __user *str); | ||||
| extern __must_check long strnlen_user(const char __user *s, long n); | ||||
| 
 | ||||
| /* Optimized macros */ | ||||
|  | ||||
| @ -375,7 +375,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n) | ||||
| 
 | ||||
| extern long strncpy_from_user(char *dest, const char __user *src, long count); | ||||
| 
 | ||||
| extern long __must_check strlen_user(const char __user *str); | ||||
| extern long __must_check strnlen_user(const char __user *str, long n); | ||||
| 
 | ||||
| extern | ||||
|  | ||||
| @ -87,6 +87,7 @@ struct autofs_wait_queue { | ||||
| 	autofs_wqt_t wait_queue_token; | ||||
| 	/* We use the following to see what we are waiting for */ | ||||
| 	struct qstr name; | ||||
| 	u32 offset; | ||||
| 	u32 dev; | ||||
| 	u64 ino; | ||||
| 	kuid_t uid; | ||||
|  | ||||
| @ -355,7 +355,7 @@ static struct dentry *should_expire(struct dentry *dentry, | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (d_really_is_positive(dentry) && d_is_symlink(dentry)) { | ||||
| 	if (d_is_symlink(dentry)) { | ||||
| 		pr_debug("checking symlink %p %pd\n", dentry, dentry); | ||||
| 
 | ||||
| 		/* Forced expire, user space handles busy mounts */ | ||||
|  | ||||
| @ -30,7 +30,7 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi) | ||||
| 	while (wq) { | ||||
| 		nwq = wq->next; | ||||
| 		wq->status = -ENOENT; /* Magic is gone - report failure */ | ||||
| 		kfree(wq->name.name); | ||||
| 		kfree(wq->name.name - wq->offset); | ||||
| 		wq->name.name = NULL; | ||||
| 		wq->wait_ctr--; | ||||
| 		wake_up_interruptible(&wq->queue); | ||||
| @ -175,51 +175,6 @@ static void autofs_notify_daemon(struct autofs_sb_info *sbi, | ||||
| 	fput(pipe); | ||||
| } | ||||
| 
 | ||||
| static int autofs_getpath(struct autofs_sb_info *sbi, | ||||
| 			  struct dentry *dentry, char *name) | ||||
| { | ||||
| 	struct dentry *root = sbi->sb->s_root; | ||||
| 	struct dentry *tmp; | ||||
| 	char *buf; | ||||
| 	char *p; | ||||
| 	int len; | ||||
| 	unsigned seq; | ||||
| 
 | ||||
| rename_retry: | ||||
| 	buf = name; | ||||
| 	len = 0; | ||||
| 
 | ||||
| 	seq = read_seqbegin(&rename_lock); | ||||
| 	rcu_read_lock(); | ||||
| 	spin_lock(&sbi->fs_lock); | ||||
| 	for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent) | ||||
| 		len += tmp->d_name.len + 1; | ||||
| 
 | ||||
| 	if (!len || --len > NAME_MAX) { | ||||
| 		spin_unlock(&sbi->fs_lock); | ||||
| 		rcu_read_unlock(); | ||||
| 		if (read_seqretry(&rename_lock, seq)) | ||||
| 			goto rename_retry; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	*(buf + len) = '\0'; | ||||
| 	p = buf + len - dentry->d_name.len; | ||||
| 	strncpy(p, dentry->d_name.name, dentry->d_name.len); | ||||
| 
 | ||||
| 	for (tmp = dentry->d_parent; tmp != root ; tmp = tmp->d_parent) { | ||||
| 		*(--p) = '/'; | ||||
| 		p -= tmp->d_name.len; | ||||
| 		strncpy(p, tmp->d_name.name, tmp->d_name.len); | ||||
| 	} | ||||
| 	spin_unlock(&sbi->fs_lock); | ||||
| 	rcu_read_unlock(); | ||||
| 	if (read_seqretry(&rename_lock, seq)) | ||||
| 		goto rename_retry; | ||||
| 
 | ||||
| 	return len; | ||||
| } | ||||
| 
 | ||||
| static struct autofs_wait_queue * | ||||
| autofs_find_wait(struct autofs_sb_info *sbi, const struct qstr *qstr) | ||||
| { | ||||
| @ -352,6 +307,7 @@ int autofs_wait(struct autofs_sb_info *sbi, | ||||
| 	struct qstr qstr; | ||||
| 	char *name; | ||||
| 	int status, ret, type; | ||||
| 	unsigned int offset = 0; | ||||
| 	pid_t pid; | ||||
| 	pid_t tgid; | ||||
| 
 | ||||
| @ -389,20 +345,23 @@ int autofs_wait(struct autofs_sb_info *sbi, | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	/* If this is a direct mount request create a dummy name */ | ||||
| 	if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type)) | ||||
| 	if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type)) { | ||||
| 		qstr.name = name; | ||||
| 		qstr.len = sprintf(name, "%p", dentry); | ||||
| 	else { | ||||
| 		qstr.len = autofs_getpath(sbi, dentry, name); | ||||
| 		if (!qstr.len) { | ||||
| 	} else { | ||||
| 		char *p = dentry_path_raw(dentry, name, NAME_MAX); | ||||
| 		if (IS_ERR(p)) { | ||||
| 			kfree(name); | ||||
| 			return -ENOENT; | ||||
| 		} | ||||
| 		qstr.name = ++p; // skip the leading slash
 | ||||
| 		qstr.len = strlen(p); | ||||
| 		offset = p - name; | ||||
| 	} | ||||
| 	qstr.name = name; | ||||
| 	qstr.hash = full_name_hash(dentry, name, qstr.len); | ||||
| 
 | ||||
| 	if (mutex_lock_interruptible(&sbi->wq_mutex)) { | ||||
| 		kfree(qstr.name); | ||||
| 		kfree(name); | ||||
| 		return -EINTR; | ||||
| 	} | ||||
| 
 | ||||
| @ -410,7 +369,7 @@ int autofs_wait(struct autofs_sb_info *sbi, | ||||
| 	if (ret <= 0) { | ||||
| 		if (ret != -EINTR) | ||||
| 			mutex_unlock(&sbi->wq_mutex); | ||||
| 		kfree(qstr.name); | ||||
| 		kfree(name); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| @ -418,7 +377,7 @@ int autofs_wait(struct autofs_sb_info *sbi, | ||||
| 		/* Create a new wait queue */ | ||||
| 		wq = kmalloc(sizeof(struct autofs_wait_queue), GFP_KERNEL); | ||||
| 		if (!wq) { | ||||
| 			kfree(qstr.name); | ||||
| 			kfree(name); | ||||
| 			mutex_unlock(&sbi->wq_mutex); | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| @ -430,6 +389,7 @@ int autofs_wait(struct autofs_sb_info *sbi, | ||||
| 		sbi->queues = wq; | ||||
| 		init_waitqueue_head(&wq->queue); | ||||
| 		memcpy(&wq->name, &qstr, sizeof(struct qstr)); | ||||
| 		wq->offset = offset; | ||||
| 		wq->dev = autofs_get_dev(sbi); | ||||
| 		wq->ino = autofs_get_ino(sbi); | ||||
| 		wq->uid = current_uid(); | ||||
| @ -469,7 +429,7 @@ int autofs_wait(struct autofs_sb_info *sbi, | ||||
| 			 (unsigned long) wq->wait_queue_token, wq->name.len, | ||||
| 			 wq->name.name, notify); | ||||
| 		mutex_unlock(&sbi->wq_mutex); | ||||
| 		kfree(qstr.name); | ||||
| 		kfree(name); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| @ -540,7 +500,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi, | ||||
| 	} | ||||
| 
 | ||||
| 	*wql = wq->next;	/* Unlink from chain */ | ||||
| 	kfree(wq->name.name); | ||||
| 	kfree(wq->name.name - wq->offset); | ||||
| 	wq->name.name = NULL;	/* Do not wait on this queue */ | ||||
| 	wq->status = status; | ||||
| 	wake_up(&wq->queue); | ||||
|  | ||||
| @ -1020,11 +1020,7 @@ grow_buffers(struct block_device *bdev, sector_t block, int size, gfp_t gfp) | ||||
| 	pgoff_t index; | ||||
| 	int sizebits; | ||||
| 
 | ||||
| 	sizebits = -1; | ||||
| 	do { | ||||
| 		sizebits++; | ||||
| 	} while ((size << sizebits) < PAGE_SIZE); | ||||
| 
 | ||||
| 	sizebits = PAGE_SHIFT - __ffs(size); | ||||
| 	index = block >> sizebits; | ||||
| 
 | ||||
| 	/*
 | ||||
|  | ||||
							
								
								
									
										10
									
								
								fs/d_path.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								fs/d_path.c
									
									
									
									
									
								
							| @ -326,9 +326,9 @@ char *simple_dname(struct dentry *dentry, char *buffer, int buflen) | ||||
| /*
 | ||||
|  * Write full pathname from the root of the filesystem into the buffer. | ||||
|  */ | ||||
| static char *__dentry_path(struct dentry *d, char *buf, int buflen) | ||||
| static char *__dentry_path(const struct dentry *d, char *buf, int buflen) | ||||
| { | ||||
| 	struct dentry *dentry; | ||||
| 	const struct dentry *dentry; | ||||
| 	char *end, *retval; | ||||
| 	int len, seq = 0; | ||||
| 	int error = 0; | ||||
| @ -347,7 +347,7 @@ restart: | ||||
| 	*retval = '/'; | ||||
| 	read_seqbegin_or_lock(&rename_lock, &seq); | ||||
| 	while (!IS_ROOT(dentry)) { | ||||
| 		struct dentry *parent = dentry->d_parent; | ||||
| 		const struct dentry *parent = dentry->d_parent; | ||||
| 
 | ||||
| 		prefetch(parent); | ||||
| 		error = prepend_name(&end, &len, &dentry->d_name); | ||||
| @ -371,13 +371,13 @@ Elong: | ||||
| 	return ERR_PTR(-ENAMETOOLONG); | ||||
| } | ||||
| 
 | ||||
| char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen) | ||||
| char *dentry_path_raw(const struct dentry *dentry, char *buf, int buflen) | ||||
| { | ||||
| 	return __dentry_path(dentry, buf, buflen); | ||||
| } | ||||
| EXPORT_SYMBOL(dentry_path_raw); | ||||
| 
 | ||||
| char *dentry_path(struct dentry *dentry, char *buf, int buflen) | ||||
| char *dentry_path(const struct dentry *dentry, char *buf, int buflen) | ||||
| { | ||||
| 	char *p = NULL; | ||||
| 	char *retval; | ||||
|  | ||||
| @ -84,6 +84,8 @@ const struct qstr empty_name = QSTR_INIT("", 0); | ||||
| EXPORT_SYMBOL(empty_name); | ||||
| const struct qstr slash_name = QSTR_INIT("/", 1); | ||||
| EXPORT_SYMBOL(slash_name); | ||||
| const struct qstr dotdot_name = QSTR_INIT("..", 2); | ||||
| EXPORT_SYMBOL(dotdot_name); | ||||
| 
 | ||||
| /*
 | ||||
|  * This is the single most critical data structure when it comes | ||||
|  | ||||
| @ -81,11 +81,10 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, uns | ||||
| 
 | ||||
| struct dentry *ext2_get_parent(struct dentry *child) | ||||
| { | ||||
| 	struct qstr dotdot = QSTR_INIT("..", 2); | ||||
| 	ino_t ino; | ||||
| 	int res; | ||||
| 
 | ||||
| 	res = ext2_inode_by_name(d_inode(child), &dotdot, &ino); | ||||
| 	res = ext2_inode_by_name(d_inode(child), &dotdot_name, &ino); | ||||
| 	if (res) | ||||
| 		return ERR_PTR(res); | ||||
| 
 | ||||
|  | ||||
| @ -1814,11 +1814,10 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi | ||||
| struct dentry *ext4_get_parent(struct dentry *child) | ||||
| { | ||||
| 	__u32 ino; | ||||
| 	static const struct qstr dotdot = QSTR_INIT("..", 2); | ||||
| 	struct ext4_dir_entry_2 * de; | ||||
| 	struct buffer_head *bh; | ||||
| 
 | ||||
| 	bh = ext4_find_entry(d_inode(child), &dotdot, &de, NULL); | ||||
| 	bh = ext4_find_entry(d_inode(child), &dotdot_name, &de, NULL); | ||||
| 	if (IS_ERR(bh)) | ||||
| 		return ERR_CAST(bh); | ||||
| 	if (!bh) | ||||
|  | ||||
| @ -449,9 +449,7 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, | ||||
| 
 | ||||
| struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) | ||||
| { | ||||
| 	struct qstr dotdot = QSTR_INIT("..", 2); | ||||
| 
 | ||||
| 	return f2fs_find_entry(dir, &dotdot, p); | ||||
| 	return f2fs_find_entry(dir, &dotdot_name, p); | ||||
| } | ||||
| 
 | ||||
| ino_t f2fs_inode_by_name(struct inode *dir, const struct qstr *qstr, | ||||
|  | ||||
| @ -416,9 +416,8 @@ out: | ||||
| 
 | ||||
| struct dentry *f2fs_get_parent(struct dentry *child) | ||||
| { | ||||
| 	struct qstr dotdot = QSTR_INIT("..", 2); | ||||
| 	struct page *page; | ||||
| 	unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot, &page); | ||||
| 	unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot_name, &page); | ||||
| 	if (!ino) { | ||||
| 		if (IS_ERR(page)) | ||||
| 			return ERR_CAST(page); | ||||
|  | ||||
| @ -873,14 +873,13 @@ static struct dentry *fuse_get_parent(struct dentry *child) | ||||
| 	struct inode *inode; | ||||
| 	struct dentry *parent; | ||||
| 	struct fuse_entry_out outarg; | ||||
| 	const struct qstr name = QSTR_INIT("..", 2); | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (!fc->export_support) | ||||
| 		return ERR_PTR(-ESTALE); | ||||
| 
 | ||||
| 	err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode), | ||||
| 			       &name, &outarg, &inode); | ||||
| 			       &dotdot_name, &outarg, &inode); | ||||
| 	if (err) { | ||||
| 		if (err == -ENOENT) | ||||
| 			return ERR_PTR(-ESTALE); | ||||
|  | ||||
| @ -316,7 +316,7 @@ retry: | ||||
| 	if (mode & FMODE_WRITE) | ||||
| 		r = w = 1; | ||||
| 
 | ||||
| 	name = dentry_name(d_real(file->f_path.dentry, file->f_inode)); | ||||
| 	name = dentry_name(file_dentry(file)); | ||||
| 	if (name == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
|  | ||||
| @ -440,10 +440,9 @@ static struct dentry *nilfs_get_parent(struct dentry *child) | ||||
| { | ||||
| 	unsigned long ino; | ||||
| 	struct inode *inode; | ||||
| 	struct qstr dotdot = QSTR_INIT("..", 2); | ||||
| 	struct nilfs_root *root; | ||||
| 
 | ||||
| 	ino = nilfs_inode_by_name(d_inode(child), &dotdot); | ||||
| 	ino = nilfs_inode_by_name(d_inode(child), &dotdot_name); | ||||
| 	if (!ino) | ||||
| 		return ERR_PTR(-ENOENT); | ||||
| 
 | ||||
|  | ||||
| @ -1215,11 +1215,10 @@ static struct dentry *udf_get_parent(struct dentry *child) | ||||
| { | ||||
| 	struct kernel_lb_addr tloc; | ||||
| 	struct inode *inode = NULL; | ||||
| 	struct qstr dotdot = QSTR_INIT("..", 2); | ||||
| 	struct fileIdentDesc cfi; | ||||
| 	struct udf_fileident_bh fibh; | ||||
| 
 | ||||
| 	if (!udf_find_entry(d_inode(child), &dotdot, &fibh, &cfi)) | ||||
| 	if (!udf_find_entry(d_inode(child), &dotdot_name, &fibh, &cfi)) | ||||
| 		return ERR_PTR(-EACCES); | ||||
| 
 | ||||
| 	if (fibh.sbh != fibh.ebh) | ||||
|  | ||||
| @ -128,10 +128,9 @@ static struct dentry *ufs_fh_to_parent(struct super_block *sb, struct fid *fid, | ||||
| 
 | ||||
| static struct dentry *ufs_get_parent(struct dentry *child) | ||||
| { | ||||
| 	struct qstr dot_dot = QSTR_INIT("..", 2); | ||||
| 	ino_t ino; | ||||
| 
 | ||||
| 	ino = ufs_inode_by_name(d_inode(child), &dot_dot); | ||||
| 	ino = ufs_inode_by_name(d_inode(child), &dotdot_name); | ||||
| 	if (!ino) | ||||
| 		return ERR_PTR(-ENOENT); | ||||
| 	return d_obtain_alias(ufs_iget(child->d_sb, ino)); | ||||
|  | ||||
| @ -59,6 +59,7 @@ struct qstr { | ||||
| 
 | ||||
| extern const struct qstr empty_name; | ||||
| extern const struct qstr slash_name; | ||||
| extern const struct qstr dotdot_name; | ||||
| 
 | ||||
| struct dentry_stat_t { | ||||
| 	long nr_dentry; | ||||
| @ -300,8 +301,8 @@ char *dynamic_dname(struct dentry *, char *, int, const char *, ...); | ||||
| extern char *__d_path(const struct path *, const struct path *, char *, int); | ||||
| extern char *d_absolute_path(const struct path *, char *, int); | ||||
| extern char *d_path(const struct path *, char *, int); | ||||
| extern char *dentry_path_raw(struct dentry *, char *, int); | ||||
| extern char *dentry_path(struct dentry *, char *, int); | ||||
| extern char *dentry_path_raw(const struct dentry *, char *, int); | ||||
| extern char *dentry_path(const struct dentry *, char *, int); | ||||
| 
 | ||||
| /* Allocation counts.. */ | ||||
| 
 | ||||
|  | ||||
| @ -370,7 +370,7 @@ audit: | ||||
|  * Returns: 0 on success else error | ||||
|  */ | ||||
| static int match_mnt(struct aa_profile *profile, const struct path *path, | ||||
| 		     char *buffer, struct path *devpath, char *devbuffer, | ||||
| 		     char *buffer, const struct path *devpath, char *devbuffer, | ||||
| 		     const char *type, unsigned long flags, void *data, | ||||
| 		     bool binary) | ||||
| { | ||||
| @ -579,7 +579,7 @@ out: | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| static int profile_umount(struct aa_profile *profile, struct path *path, | ||||
| static int profile_umount(struct aa_profile *profile, const struct path *path, | ||||
| 			  char *buffer) | ||||
| { | ||||
| 	struct aa_perms perms = { }; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user