History

Fix nasty ncpfs symlink handling bug.

This bug could cause oopses and page state corruption, because ncpfs used the generic page-cache symlink handlign functions. But those functions only work if the page cache is guaranteed to be "stable", ie a page that was installed when the symlink walk was started has to still be installed in the page cache at the end of the walk. We could have fixed ncpfs to not use the generic helper routines, but it is in many ways much cleaner to instead improve on the symlink walking helper routines so that they don't require that absolute stability. We do this by allowing "follow_link()" to return a error-pointer as a cookie, which is fed back to the cleanup "put_link()" routine. This also simplifies NFS symlink handling.

Linus Torvalds committed 21 years ago

Commit cc314ee1 parent 2fb1e3010 files · +54 −77Browse files

Showing the changes to include/linux (1 of 10 files). Show all

Unified · Split

include/linux/fs.h+4−4
@@ -993,8 +993,8 @@ struct inode_operations { · 992 unmodified lines
993993 int (*rename) (struct inode *, struct dentry *,
994994 struct inode *, struct dentry *);
995995 int (*readlink) (struct dentry *, char __user *,int);
996− int (*follow_link) (struct dentry *, struct nameidata *);
997− void (*put_link) (struct dentry *, struct nameidata *);
996+ void * (*follow_link) (struct dentry *, struct nameidata *);
997+ void (*put_link) (struct dentry *, struct nameidata *, void *);
998998 void (*truncate) (struct inode *);
999999 int (*permission) (struct inode *, int, struct nameidata *);
10001000 int (*setattr) (struct dentry *, struct iattr *);
@@ -1602,8 +1602,8 @@ extern struct file_operations generic_ro_fops; · 601 unmodified lines
16021602 extern int vfs_readlink(struct dentry *, char __user *, int, const char *);
16031603 extern int vfs_follow_link(struct nameidata *, const char *);
16041604 extern int page_readlink(struct dentry *, char __user *, int);
1605−extern int page_follow_link_light(struct dentry *, struct nameidata *);
1606−extern void page_put_link(struct dentry *, struct nameidata *);
1605+extern void *page_follow_link_light(struct dentry *, struct nameidata *);
1606+extern void page_put_link(struct dentry *, struct nameidata *, void *);
16071607 extern int page_symlink(struct inode *inode, const char *symname, int len);
16081608 extern struct inode_operations page_symlink_inode_operations;
16091609 extern int generic_readlink(struct dentry *, char __user *, int);