Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/fs_struct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/prefetch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) static int prepend(char **buffer, int *buflen, const char *str, int namelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 	*buflen -= namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	if (*buflen < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 		return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	*buffer -= namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	memcpy(*buffer, str, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * prepend_name - prepend a pathname in front of current buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * @buffer: buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * @buflen: allocated length of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * @name:   name string and length qstr structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * With RCU path tracing, it may race with d_move(). Use READ_ONCE() to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * make sure that either the old or the new name pointer and length are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * fetched. However, there may be mismatch between length and pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * The length cannot be trusted, we need to copy it byte-by-byte until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * the length is reached or a null byte is found. It also prepends "/" at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * the beginning of the name. The sequence number check at the caller will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * retry it again when a d_move() does happen. So any garbage in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * due to mismatched pointer and length will be discarded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * Load acquire is needed to make sure that we see that terminating NUL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static int prepend_name(char **buffer, int *buflen, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	const char *dname = smp_load_acquire(&name->name); /* ^^^ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	u32 dlen = READ_ONCE(name->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	*buflen -= dlen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (*buflen < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	p = *buffer -= dlen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	*p++ = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	while (dlen--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		char c = *dname++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		if (!c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		*p++ = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * prepend_path - Prepend path string to a buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * @path: the dentry/vfsmount to report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * @root: root vfsmnt/dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * @buffer: pointer to the end of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * @buflen: pointer to buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * The function will first try to write out the pathname without taking any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * lock other than the RCU read lock to make sure that dentries won't go away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * It only checks the sequence number of the global rename_lock as any change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * in the dentry's d_seq will be preceded by changes in the rename_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * sequence number. If the sequence number had been changed, it will restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * the whole pathname back-tracing sequence again by taking the rename_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * In this case, there is no need to take the RCU read lock as the recursive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * parent pointer references will keep the dentry chain alive as long as no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * rename operation is performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static int prepend_path(const struct path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			const struct path *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			char **buffer, int *buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct vfsmount *vfsmnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct mount *mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	unsigned seq, m_seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	char *bptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) restart_mnt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	read_seqbegin_or_lock(&mount_lock, &m_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	bptr = *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	blen = *buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	dentry = path->dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	vfsmnt = path->mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	mnt = real_mount(vfsmnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	read_seqbegin_or_lock(&rename_lock, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	while (dentry != root->dentry || vfsmnt != root->mnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		struct dentry * parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			struct mount *parent = READ_ONCE(mnt->mnt_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			struct mnt_namespace *mnt_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			/* Escaped? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			if (dentry != vfsmnt->mnt_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 				bptr = *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 				blen = *buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 				error = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			/* Global root? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			if (mnt != parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				dentry = READ_ONCE(mnt->mnt_mountpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 				mnt = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				vfsmnt = &mnt->mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			mnt_ns = READ_ONCE(mnt->mnt_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			/* open-coded is_mounted() to use local mnt_ns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			if (!IS_ERR_OR_NULL(mnt_ns) && !is_anon_ns(mnt_ns))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				error = 1;	// absolute root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				error = 2;	// detached or not attached yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		parent = dentry->d_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		prefetch(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		error = prepend_name(&bptr, &blen, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		dentry = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (!(seq & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (need_seqretry(&rename_lock, seq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		seq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	done_seqretry(&rename_lock, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (!(m_seq & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (need_seqretry(&mount_lock, m_seq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		m_seq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		goto restart_mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	done_seqretry(&mount_lock, m_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (error >= 0 && bptr == *buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		if (--blen < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			error = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			*--bptr = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	*buffer = bptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	*buflen = blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * __d_path - return the path of a dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * @path: the dentry/vfsmount to report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * @root: root vfsmnt/dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * @buf: buffer to return value in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * @buflen: buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * Convert a dentry into an ASCII path name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * Returns a pointer into the buffer or an error code if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * path was too long.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * "buflen" should be positive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * If the path is not reachable from the supplied root, return %NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) char *__d_path(const struct path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	       const struct path *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	       char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	char *res = buf + buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	prepend(&res, &buflen, "\0", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	error = prepend_path(path, root, &res, &buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	if (error > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) char *d_absolute_path(const struct path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	       char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	struct path root = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	char *res = buf + buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	prepend(&res, &buflen, "\0", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	error = prepend_path(path, &root, &res, &buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (error > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * same as __d_path but appends "(deleted)" for unlinked files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int path_with_deleted(const struct path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			     const struct path *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			     char **buf, int *buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	prepend(buf, buflen, "\0", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (d_unlinked(path->dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		int error = prepend(buf, buflen, " (deleted)", 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	return prepend_path(path, root, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int prepend_unreachable(char **buffer, int *buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	return prepend(buffer, buflen, "(unreachable)", 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void get_fs_root_rcu(struct fs_struct *fs, struct path *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	unsigned seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		seq = read_seqcount_begin(&fs->seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		*root = fs->root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	} while (read_seqcount_retry(&fs->seq, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * d_path - return the path of a dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * @path: path to report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  * @buf: buffer to return value in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  * @buflen: buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * Convert a dentry into an ASCII path name. If the entry has been deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * the string " (deleted)" is appended. Note that this is ambiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * Returns a pointer into the buffer or an error code if the path was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * too long. Note: Callers should use the returned pointer, not the passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  * in buffer, to use the name! The implementation often starts at an offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  * into the buffer, and may leave 0 bytes at the start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  * "buflen" should be positive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) char *d_path(const struct path *path, char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	char *res = buf + buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	struct path root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	 * We have various synthetic filesystems that never get mounted.  On
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	 * these filesystems dentries are never used for lookup purposes, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	 * thus don't need to be hashed.  They also don't need a name until a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	 * user wants to identify the object in /proc/pid/fd/.  The little hack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	 * below allows us to generate a name for these objects on demand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	 * Some pseudo inodes are mountable.  When they are mounted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	 * path->dentry == path->mnt->mnt_root.  In that case don't call d_dname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	 * and instead have d_path return the mounted path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (path->dentry->d_op && path->dentry->d_op->d_dname &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	    (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	get_fs_root_rcu(current->fs, &root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	error = path_with_deleted(path, &root, &res, &buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		res = ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) EXPORT_SYMBOL(d_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * Helper function for dentry_operations.d_dname() members
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	char temp[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	int sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (sz > sizeof(temp) || sz > buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	buffer += buflen - sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	return memcpy(buffer, temp, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	char *end = buffer + buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	/* these dentries are never renamed, so d_lock is not needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (prepend(&end, &buflen, " (deleted)", 11) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	    prepend(&end, &buflen, dentry->d_name.name, dentry->d_name.len) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	    prepend(&end, &buflen, "/", 1))  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		end = ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	return end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * Write full pathname from the root of the filesystem into the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static char *__dentry_path(struct dentry *d, char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	char *end, *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	int len, seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (buflen < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		goto Elong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	dentry = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	end = buf + buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	len = buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	prepend(&end, &len, "\0", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	/* Get '/' right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	retval = end-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	*retval = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	read_seqbegin_or_lock(&rename_lock, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	while (!IS_ROOT(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		struct dentry *parent = dentry->d_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		prefetch(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		error = prepend_name(&end, &len, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		retval = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		dentry = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (!(seq & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (need_seqretry(&rename_lock, seq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		seq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	done_seqretry(&rename_lock, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		goto Elong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) Elong:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return __dentry_path(dentry, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) EXPORT_SYMBOL(dentry_path_raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) char *dentry_path(struct dentry *dentry, char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	char *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	char *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	if (d_unlinked(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		p = buf + buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		if (prepend(&p, &buflen, "//deleted", 10) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			goto Elong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		buflen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	retval = __dentry_path(dentry, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	if (!IS_ERR(retval) && p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		*p = '/';	/* restore '/' overriden with '\0' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) Elong:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void get_fs_root_and_pwd_rcu(struct fs_struct *fs, struct path *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 				    struct path *pwd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	unsigned seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		seq = read_seqcount_begin(&fs->seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		*root = fs->root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		*pwd = fs->pwd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	} while (read_seqcount_retry(&fs->seq, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)  * NOTE! The user-level library version returns a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  * character pointer. The kernel system call just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  * returns the length of the buffer filled (which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  * includes the ending '\0' character), or a negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  * error value. So libc would do something like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  *	char *getcwd(char * buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  *	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)  *		int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  *		retval = sys_getcwd(buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  *		if (retval >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  *			return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  *		errno = -retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  *		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  *	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct path pwd, root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	char *page = __getname();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	get_fs_root_and_pwd_rcu(current->fs, &root, &pwd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	error = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (!d_unlinked(pwd.dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		unsigned long len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		char *cwd = page + PATH_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		int buflen = PATH_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		prepend(&cwd, &buflen, "\0", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		error = prepend_path(&pwd, &root, &cwd, &buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		/* Unreachable from current root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		if (error > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			error = prepend_unreachable(&cwd, &buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		error = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		len = PATH_MAX + page - cwd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		if (len <= size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			error = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			if (copy_to_user(buf, cwd, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 				error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	__putname(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }