^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/affs/symlink.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 1995 Hans-Joachim Widmaier - Modified for affs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * affs symlink handling code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "affs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static int affs_symlink_readpage(struct file *file, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct inode *inode = page->mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) char *link = page_address(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct slink_front *lf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) char lc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) pr_debug("get_link(ino=%lu)\n", inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) bh = affs_bread(inode->i_sb, inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) lf = (struct slink_front *)bh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) lc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (strchr(lf->symname,':')) { /* Handle assign or volume name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) char *pf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) spin_lock(&sbi->symlink_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) pf = sbi->s_prefix ? sbi->s_prefix : "/";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) while (i < 1023 && (c = pf[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) link[i++] = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) spin_unlock(&sbi->symlink_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) while (i < 1023 && lf->symname[j] != ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) link[i++] = lf->symname[j++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (i < 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) link[i++] = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) lc = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) while (i < 1023 && (c = lf->symname[j])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (c == '/' && lc == '/' && i < 1020) { /* parent dir */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) link[i++] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) link[i++] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) link[i++] = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) lc = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) link[i] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) affs_brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) SetPageError(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) const struct address_space_operations affs_symlink_aops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .readpage = affs_symlink_readpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) const struct inode_operations affs_symlink_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .get_link = page_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .setattr = affs_notify_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };