^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) }