xref: /openbmc/linux/fs/affs/symlink.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *  linux/fs/affs/symlink.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *  1995  Hans-Joachim Widmaier - Modified for affs.
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  *  Copyright (C) 1991, 1992  Linus Torvalds
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  *  affs symlink handling code
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include "affs.h"
131da177e4SLinus Torvalds 
affs_symlink_read_folio(struct file * file,struct folio * folio)141b6f3c87SMatthew Wilcox (Oracle) static int affs_symlink_read_folio(struct file *file, struct folio *folio)
151da177e4SLinus Torvalds {
161da177e4SLinus Torvalds 	struct buffer_head *bh;
17*41a638a1SMatthew Wilcox (Oracle) 	struct inode *inode = folio->mapping->host;
18*41a638a1SMatthew Wilcox (Oracle) 	char *link = folio_address(folio);
191da177e4SLinus Torvalds 	struct slink_front *lf;
201da177e4SLinus Torvalds 	int			 i, j;
211da177e4SLinus Torvalds 	char			 c;
221da177e4SLinus Torvalds 	char			 lc;
231da177e4SLinus Torvalds 
246b255391SAl Viro 	pr_debug("get_link(ino=%lu)\n", inode->i_ino);
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds 	bh = affs_bread(inode->i_sb, inode->i_ino);
271da177e4SLinus Torvalds 	if (!bh)
281da177e4SLinus Torvalds 		goto fail;
291da177e4SLinus Torvalds 	i  = 0;
301da177e4SLinus Torvalds 	j  = 0;
311da177e4SLinus Torvalds 	lf = (struct slink_front *)bh->b_data;
321da177e4SLinus Torvalds 	lc = 0;
331da177e4SLinus Torvalds 
341da177e4SLinus Torvalds 	if (strchr(lf->symname,':')) {	/* Handle assign or volume name */
3529333920SAl Viro 		struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);
3629333920SAl Viro 		char *pf;
3729333920SAl Viro 		spin_lock(&sbi->symlink_lock);
3829333920SAl Viro 		pf = sbi->s_prefix ? sbi->s_prefix : "/";
391da177e4SLinus Torvalds 		while (i < 1023 && (c = pf[i]))
401da177e4SLinus Torvalds 			link[i++] = c;
4129333920SAl Viro 		spin_unlock(&sbi->symlink_lock);
421da177e4SLinus Torvalds 		while (i < 1023 && lf->symname[j] != ':')
431da177e4SLinus Torvalds 			link[i++] = lf->symname[j++];
441da177e4SLinus Torvalds 		if (i < 1023)
451da177e4SLinus Torvalds 			link[i++] = '/';
461da177e4SLinus Torvalds 		j++;
471da177e4SLinus Torvalds 		lc = '/';
481da177e4SLinus Torvalds 	}
491da177e4SLinus Torvalds 	while (i < 1023 && (c = lf->symname[j])) {
501da177e4SLinus Torvalds 		if (c == '/' && lc == '/' && i < 1020) {	/* parent dir */
511da177e4SLinus Torvalds 			link[i++] = '.';
521da177e4SLinus Torvalds 			link[i++] = '.';
531da177e4SLinus Torvalds 		}
541da177e4SLinus Torvalds 		link[i++] = c;
551da177e4SLinus Torvalds 		lc = c;
561da177e4SLinus Torvalds 		j++;
571da177e4SLinus Torvalds 	}
581da177e4SLinus Torvalds 	link[i] = '\0';
591da177e4SLinus Torvalds 	affs_brelse(bh);
60*41a638a1SMatthew Wilcox (Oracle) 	folio_mark_uptodate(folio);
61*41a638a1SMatthew Wilcox (Oracle) 	folio_unlock(folio);
621da177e4SLinus Torvalds 	return 0;
631da177e4SLinus Torvalds fail:
64*41a638a1SMatthew Wilcox (Oracle) 	folio_unlock(folio);
65196a4f82SFabian Frederick 	return -EIO;
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds 
68f5e54d6eSChristoph Hellwig const struct address_space_operations affs_symlink_aops = {
691b6f3c87SMatthew Wilcox (Oracle) 	.read_folio	= affs_symlink_read_folio,
701da177e4SLinus Torvalds };
711da177e4SLinus Torvalds 
72754661f1SArjan van de Ven const struct inode_operations affs_symlink_inode_operations = {
736b255391SAl Viro 	.get_link	= page_get_link,
741da177e4SLinus Torvalds 	.setattr	= affs_notify_change,
751da177e4SLinus Torvalds };
76