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 #define NFS_NEED_XDR_TYPES 14 #include <linux/time.h> 15 #include <linux/errno.h> 16 #include <linux/sunrpc/clnt.h> 17 #include <linux/nfs.h> 18 #include <linux/nfs2.h> 19 #include <linux/nfs_fs.h> 20 #include <linux/pagemap.h> 21 #include <linux/stat.h> 22 #include <linux/mm.h> 23 #include <linux/slab.h> 24 #include <linux/string.h> 25 #include <linux/smp_lock.h> 26 #include <linux/namei.h> 27 28 /* Symlink caching in the page cache is even more simplistic 29 * and straight-forward than readdir caching. 30 * 31 * At the beginning of the page we store pointer to struct page in question, 32 * simplifying nfs_put_link() (if inode got invalidated we can't find the page 33 * to be freed via pagecache lookup). 34 * The NUL-terminated string follows immediately thereafter. 35 */ 36 37 struct nfs_symlink { 38 struct page *page; 39 char body[0]; 40 }; 41 42 static int nfs_symlink_filler(struct inode *inode, struct page *page) 43 { 44 const unsigned int pgbase = offsetof(struct nfs_symlink, body); 45 const unsigned int pglen = PAGE_SIZE - pgbase; 46 int error; 47 48 lock_kernel(); 49 error = NFS_PROTO(inode)->readlink(inode, page, pgbase, pglen); 50 unlock_kernel(); 51 if (error < 0) 52 goto error; 53 SetPageUptodate(page); 54 unlock_page(page); 55 return 0; 56 57 error: 58 SetPageError(page); 59 unlock_page(page); 60 return -EIO; 61 } 62 63 static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd) 64 { 65 struct inode *inode = dentry->d_inode; 66 struct page *page; 67 struct nfs_symlink *p; 68 void *err = ERR_PTR(nfs_revalidate_inode(NFS_SERVER(inode), inode)); 69 if (err) 70 goto read_failed; 71 page = read_cache_page(&inode->i_data, 0, 72 (filler_t *)nfs_symlink_filler, inode); 73 if (IS_ERR(page)) { 74 err = page; 75 goto read_failed; 76 } 77 if (!PageUptodate(page)) { 78 err = ERR_PTR(-EIO); 79 goto getlink_read_error; 80 } 81 p = kmap(page); 82 p->page = page; 83 nd_set_link(nd, p->body); 84 return 0; 85 86 getlink_read_error: 87 page_cache_release(page); 88 read_failed: 89 nd_set_link(nd, err); 90 return 0; 91 } 92 93 static void nfs_put_link(struct dentry *dentry, struct nameidata *nd) 94 { 95 char *s = nd_get_link(nd); 96 if (!IS_ERR(s)) { 97 struct nfs_symlink *p; 98 struct page *page; 99 100 p = container_of(s, struct nfs_symlink, body[0]); 101 page = p->page; 102 103 kunmap(page); 104 page_cache_release(page); 105 } 106 } 107 108 /* 109 * symlinks can't do much... 110 */ 111 struct inode_operations nfs_symlink_inode_operations = { 112 .readlink = generic_readlink, 113 .follow_link = nfs_follow_link, 114 .put_link = nfs_put_link, 115 .getattr = nfs_getattr, 116 .setattr = nfs_setattr, 117 }; 118