Branch data Line data Source code
1 : : /*
2 : : * linux/fs/nfs/symlink.c
3 : : *
4 : : * Copyright (C) 1992 Rick Sladkey
5 : : *
6 : : * Optimization changes Copyright (C) 1994 Florian La Roche
7 : : *
8 : : * Jun 7 1999, cache symlink lookups in the page cache. -DaveM
9 : : *
10 : : * nfs symlink handling code
11 : : */
12 : :
13 : : #include <linux/time.h>
14 : : #include <linux/errno.h>
15 : : #include <linux/sunrpc/clnt.h>
16 : : #include <linux/nfs.h>
17 : : #include <linux/nfs2.h>
18 : : #include <linux/nfs_fs.h>
19 : : #include <linux/pagemap.h>
20 : : #include <linux/stat.h>
21 : : #include <linux/mm.h>
22 : : #include <linux/string.h>
23 : : #include <linux/namei.h>
24 : :
25 : : /* Symlink caching in the page cache is even more simplistic
26 : : * and straight-forward than readdir caching.
27 : : */
28 : :
29 : 0 : static int nfs_symlink_filler(struct inode *inode, struct page *page)
30 : : {
31 : : int error;
32 : :
33 : 0 : error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE);
34 [ # # ]: 0 : if (error < 0)
35 : : goto error;
36 : : SetPageUptodate(page);
37 : 0 : unlock_page(page);
38 : 0 : return 0;
39 : :
40 : : error:
41 : : SetPageError(page);
42 : 0 : unlock_page(page);
43 : 0 : return -EIO;
44 : : }
45 : :
46 : 0 : static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
47 : : {
48 : 0 : struct inode *inode = dentry->d_inode;
49 : : struct page *page;
50 : : void *err;
51 : :
52 : 0 : err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
53 [ # # ]: 0 : if (err)
54 : : goto read_failed;
55 : 0 : page = read_cache_page(&inode->i_data, 0,
56 : : (filler_t *)nfs_symlink_filler, inode);
57 [ # # ]: 0 : if (IS_ERR(page)) {
58 : : err = page;
59 : : goto read_failed;
60 : : }
61 : 0 : nd_set_link(nd, kmap(page));
62 : 0 : return page;
63 : :
64 : : read_failed:
65 : : nd_set_link(nd, err);
66 : 0 : return NULL;
67 : : }
68 : :
69 : : /*
70 : : * symlinks can't do much...
71 : : */
72 : : const struct inode_operations nfs_symlink_inode_operations = {
73 : : .readlink = generic_readlink,
74 : : .follow_link = nfs_follow_link,
75 : : .put_link = page_put_link,
76 : : .getattr = nfs_getattr,
77 : : .setattr = nfs_setattr,
78 : : };
|