Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
fs
udf
symlink.c
Go to the documentation of this file.
1
/*
2
* symlink.c
3
*
4
* PURPOSE
5
* Symlink handling routines for the OSTA-UDF(tm) filesystem.
6
*
7
* COPYRIGHT
8
* This file is distributed under the terms of the GNU General Public
9
* License (GPL). Copies of the GPL can be obtained from:
10
* ftp://prep.ai.mit.edu/pub/gnu/GPL
11
* Each contributing author retains all rights to their own work.
12
*
13
* (C) 1998-2001 Ben Fennema
14
* (C) 1999 Stelias Computing Inc
15
*
16
* HISTORY
17
*
18
* 04/16/99 blf Created.
19
*
20
*/
21
22
#include "
udfdecl.h
"
23
#include <asm/uaccess.h>
24
#include <linux/errno.h>
25
#include <linux/fs.h>
26
#include <linux/time.h>
27
#include <
linux/mm.h
>
28
#include <linux/stat.h>
29
#include <
linux/pagemap.h
>
30
#include <
linux/buffer_head.h
>
31
#include "
udf_i.h
"
32
33
static
void
udf_pc_to_char(
struct
super_block
*
sb
,
unsigned
char
*
from
,
34
int
fromlen,
unsigned
char
*to)
35
{
36
struct
pathComponent
*
pc
;
37
int
elen = 0;
38
unsigned
char
*
p
= to;
39
40
while
(elen < fromlen) {
41
pc = (
struct
pathComponent
*)(from + elen);
42
switch
(pc->
componentType
) {
43
case
1:
44
/*
45
* Symlink points to some place which should be agreed
46
* upon between originator and receiver of the media. Ignore.
47
*/
48
if
(pc->
lengthComponentIdent
> 0)
49
break
;
50
/* Fall through */
51
case
2:
52
p = to;
53
*p++ =
'/'
;
54
break
;
55
case
3:
56
memcpy
(p,
"../"
, 3);
57
p += 3;
58
break
;
59
case
4:
60
memcpy
(p,
"./"
, 2);
61
p += 2;
62
/* that would be . - just ignore */
63
break
;
64
case
5:
65
p +=
udf_get_filename
(sb, pc->
componentIdent
, p,
66
pc->
lengthComponentIdent
);
67
*p++ =
'/'
;
68
break
;
69
}
70
elen +=
sizeof
(
struct
pathComponent
) + pc->
lengthComponentIdent
;
71
}
72
if
(p > to + 1)
73
p[-1] =
'\0'
;
74
else
75
p[0] =
'\0'
;
76
}
77
78
static
int
udf_symlink_filler(
struct
file
*
file
,
struct
page
*
page
)
79
{
80
struct
inode
*
inode
= page->
mapping
->host;
81
struct
buffer_head *bh =
NULL
;
82
unsigned
char
*symlink;
83
int
err
= -
EIO
;
84
unsigned
char
*p =
kmap
(page);
85
struct
udf_inode_info
*iinfo;
86
uint32_t
pos
;
87
88
iinfo = UDF_I(inode);
89
pos =
udf_block_map
(inode, 0);
90
91
down_read
(&iinfo->
i_data_sem
);
92
if
(iinfo->
i_alloc_type
==
ICBTAG_FLAG_AD_IN_ICB
) {
93
symlink = iinfo->
i_ext
.
i_data
+ iinfo->
i_lenEAttr
;
94
}
else
{
95
bh = sb_bread(inode->
i_sb
, pos);
96
97
if
(!bh)
98
goto
out
;
99
100
symlink = bh->b_data;
101
}
102
103
udf_pc_to_char(inode->
i_sb
, symlink, inode->
i_size
, p);
104
brelse(bh);
105
106
up_read
(&iinfo->
i_data_sem
);
107
SetPageUptodate(page);
108
kunmap
(page);
109
unlock_page
(page);
110
return
0;
111
112
out
:
113
up_read
(&iinfo->
i_data_sem
);
114
SetPageError(page);
115
kunmap
(page);
116
unlock_page
(page);
117
return
err
;
118
}
119
120
/*
121
* symlinks can't do much...
122
*/
123
const
struct
address_space_operations
udf_symlink_aops
= {
124
.readpage = udf_symlink_filler,
125
};
Generated on Thu Jan 10 2013 14:44:49 for Linux Kernel by
1.8.2