patch-2.3.32 linux/fs/namei.c
Next file: linux/fs/ncpfs/symlink.c
Previous file: linux/fs/minix/symlink.c
Back to the patch index
Back to the overall index
- Lines: 111
- Date:
Mon Dec 13 07:59:51 1999
- Orig file:
v2.3.31/linux/fs/namei.c
- Orig date:
Fri Oct 15 15:25:14 1999
diff -u --recursive --new-file v2.3.31/linux/fs/namei.c linux/fs/namei.c
@@ -16,6 +16,7 @@
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/quotaops.h>
+#include <linux/pagemap.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
@@ -283,7 +284,7 @@
if ((follow & LOOKUP_FOLLOW)
&& inode && inode->i_op && inode->i_op->follow_link) {
- if (current->link_count < 5) {
+ if (current->link_count < 32) {
struct dentry * result;
current->link_count++;
@@ -1418,4 +1419,93 @@
}
unlock_kernel();
return error;
+}
+
+int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, char *link)
+{
+ u32 len;
+
+ len = PTR_ERR(link);
+ if (IS_ERR(link))
+ goto out;
+
+ len = strlen(link);
+ if (len > buflen)
+ len = buflen;
+ copy_to_user(buffer, link, len);
+out:
+ return len;
+}
+
+static inline struct dentry *
+__vfs_follow_link(struct dentry *dentry, struct dentry *base,
+ unsigned follow, char *link)
+{
+ struct dentry *result;
+ UPDATE_ATIME(dentry->d_inode);
+
+ if (IS_ERR(link))
+ goto fail;
+
+ result = lookup_dentry(link, base, follow);
+ return result;
+
+fail:
+ dput(base);
+ return (struct dentry *)link;
+}
+
+struct dentry *
+vfs_follow_link(struct dentry *dentry, struct dentry *base,
+unsigned int follow, char *link)
+{
+ return __vfs_follow_link(dentry,base,follow,link);
+}
+
+/* get the link contents into pagecache */
+static char *page_getlink(struct dentry * dentry, struct page **ppage)
+{
+ struct page * page;
+ page = read_cache_page(&dentry->d_inode->i_data, 0,
+ (filler_t *)dentry->d_inode->i_op->readpage,
+ dentry);
+ if (IS_ERR(page))
+ goto sync_fail;
+ wait_on_page(page);
+ if (!Page_Uptodate(page))
+ goto async_fail;
+ *ppage = page;
+ return (char*) kmap(page);
+
+async_fail:
+ page_cache_release(page);
+ return ERR_PTR(-EIO);
+
+sync_fail:
+ return (char*)page;
+}
+
+int page_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+ struct page *page = NULL;
+ char *s = page_getlink(dentry, &page);
+ int res = vfs_readlink(dentry,buffer,buflen,s);
+ if (page) {
+ kunmap(page);
+ page_cache_release(page);
+ }
+ return res;
+}
+
+struct dentry *
+page_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow)
+{
+ struct page *page = NULL;
+ char *s = page_getlink(dentry, &page);
+ struct dentry *res = __vfs_follow_link(dentry,base,follow,s);
+ if (page) {
+ kunmap(page);
+ page_cache_release(page);
+ }
+ return res;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)