Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/fs/affs/symlink.c
26285 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* linux/fs/affs/symlink.c
4
*
5
* 1995 Hans-Joachim Widmaier - Modified for affs.
6
*
7
* Copyright (C) 1991, 1992 Linus Torvalds
8
*
9
* affs symlink handling code
10
*/
11
12
#include "affs.h"
13
14
static 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;
63
fail:
64
folio_unlock(folio);
65
return -EIO;
66
}
67
68
const struct address_space_operations affs_symlink_aops = {
69
.read_folio = affs_symlink_read_folio,
70
};
71
72
const struct inode_operations affs_symlink_inode_operations = {
73
.get_link = page_get_link,
74
.setattr = affs_notify_change,
75
};
76
77