2 * linux/fs/nfs/symlink.c
4 * Copyright (C) 1992 Rick Sladkey
6 * Optimization changes Copyright (C) 1994 Florian La Roche
8 * Jun 7 1999, cache symlink lookups in the page cache. -DaveM
10 * nfs symlink handling code
13 #define NFS_NEED_XDR_TYPES
14 #include <linux/sched.h>
15 #include <linux/errno.h>
16 #include <linux/sunrpc/clnt.h>
17 #include <linux/nfs_fs.h>
18 #include <linux/nfs.h>
19 #include <linux/pagemap.h>
20 #include <linux/stat.h>
22 #include <linux/malloc.h>
23 #include <linux/string.h>
25 #include <asm/uaccess.h>
27 static int nfs_readlink(struct dentry
*, char *, int);
28 static struct dentry
*nfs_follow_link(struct dentry
*, struct dentry
*, unsigned int);
31 * symlinks can't do much...
33 struct inode_operations nfs_symlink_inode_operations
= {
34 NULL
, /* no file-operations */
44 nfs_readlink
, /* readlink */
45 nfs_follow_link
, /* follow_link */
51 NULL
, /* permission */
56 /* Symlink caching in the page cache is even more simplistic
57 * and straight-forward than readdir caching.
59 static struct page
*try_to_get_symlink_page(struct dentry
*dentry
, struct inode
*inode
)
61 struct nfs_readlinkargs rl_args
;
62 struct page
*page
, **hash
;
63 unsigned long page_cache
;
66 page_cache
= page_cache_alloc();
70 hash
= page_hash(inode
, 0);
72 page
= __find_lock_page(inode
, 0, hash
);
74 page_cache_free(page_cache
);
78 page
= page_cache_entry(page_cache
);
79 if (add_to_page_cache_unique(page
, inode
, 0, hash
)) {
80 page_cache_release(page
);
84 /* We place the length at the beginning of the page,
85 * in host byte order, followed by the string. The
86 * XDR response verification will NULL terminate it.
88 rl_args
.fh
= NFS_FH(dentry
);
89 rl_args
.buffer
= (const void *)page_cache
;
90 if (rpc_call(NFS_CLIENT(inode
), NFSPROC_READLINK
,
91 &rl_args
, NULL
, 0) < 0)
93 SetPageUptodate(page
);
104 static int nfs_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
106 struct inode
*inode
= dentry
->d_inode
;
110 /* Caller revalidated the directory inode already. */
111 page
= find_get_page(inode
, 0);
113 goto no_readlink_page
;
114 if (!Page_Uptodate(page
))
115 goto readlink_read_error
;
117 p
= (u32
*) page_address(page
);
121 copy_to_user(buffer
, p
, len
);
122 page_cache_release(page
);
126 page
= try_to_get_symlink_page(dentry
, inode
);
129 if (Page_Uptodate(page
))
132 page_cache_release(page
);
137 static struct dentry
*
138 nfs_follow_link(struct dentry
*dentry
, struct dentry
*base
, unsigned int follow
)
140 struct dentry
*result
;
141 struct inode
*inode
= dentry
->d_inode
;
145 /* Caller revalidated the directory inode already. */
146 page
= find_get_page(inode
, 0);
148 goto no_followlink_page
;
149 if (!Page_Uptodate(page
))
150 goto followlink_read_error
;
152 p
= (u32
*) page_address(page
);
153 result
= lookup_dentry((char *) (p
+ 1), base
, follow
);
154 page_cache_release(page
);
158 page
= try_to_get_symlink_page(dentry
, inode
);
161 if (Page_Uptodate(page
))
163 followlink_read_error
:
164 page_cache_release(page
);
166 return ERR_PTR(-EIO
);