brintos

brintos / linux-shallow public Read only

0
0
Text · 1.6 KiB · 094aec8 Raw
76 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *  linux/fs/affs/symlink.c4 *5 *  1995  Hans-Joachim Widmaier - Modified for affs.6 *7 *  Copyright (C) 1991, 1992  Linus Torvalds8 *9 *  affs symlink handling code10 */11 12#include "affs.h"13 14static int affs_symlink_read_folio(struct file *file, struct folio *folio)15{16	struct buffer_head *bh;17	struct inode *inode = folio->mapping->host;18	char *link = folio_address(folio);19	struct slink_front *lf;20	int			 i, j;21	char			 c;22	char			 lc;23 24	pr_debug("get_link(ino=%lu)\n", inode->i_ino);25 26	bh = affs_bread(inode->i_sb, inode->i_ino);27	if (!bh)28		goto fail;29	i  = 0;30	j  = 0;31	lf = (struct slink_front *)bh->b_data;32	lc = 0;33 34	if (strchr(lf->symname,':')) {	/* Handle assign or volume name */35		struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);36		char *pf;37		spin_lock(&sbi->symlink_lock);38		pf = sbi->s_prefix ? sbi->s_prefix : "/";39		while (i < 1023 && (c = pf[i]))40			link[i++] = c;41		spin_unlock(&sbi->symlink_lock);42		while (i < 1023 && lf->symname[j] != ':')43			link[i++] = lf->symname[j++];44		if (i < 1023)45			link[i++] = '/';46		j++;47		lc = '/';48	}49	while (i < 1023 && (c = lf->symname[j])) {50		if (c == '/' && lc == '/' && i < 1020) {	/* parent dir */51			link[i++] = '.';52			link[i++] = '.';53		}54		link[i++] = c;55		lc = c;56		j++;57	}58	link[i] = '\0';59	affs_brelse(bh);60	folio_mark_uptodate(folio);61	folio_unlock(folio);62	return 0;63fail:64	folio_unlock(folio);65	return -EIO;66}67 68const struct address_space_operations affs_symlink_aops = {69	.read_folio	= affs_symlink_read_folio,70};71 72const struct inode_operations affs_symlink_inode_operations = {73	.get_link	= page_get_link,74	.setattr	= affs_notify_change,75};76