diff options
-rw-r--r-- | Documentation/filesystems/porting | 4 | ||||
-rw-r--r-- | Documentation/filesystems/vfs.txt | 9 | ||||
-rw-r--r-- | fs/namei.c | 15 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
4 files changed, 23 insertions, 6 deletions
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index bdd025ceb763..95280079c0b3 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -596,3 +596,7 @@ in your dentry operations instead. | |||
596 | [mandatory] | 596 | [mandatory] |
597 | ->rename() has an added flags argument. Any flags not handled by the | 597 | ->rename() has an added flags argument. Any flags not handled by the |
598 | filesystem should result in EINVAL being returned. | 598 | filesystem should result in EINVAL being returned. |
599 | -- | ||
600 | [recommended] | ||
601 | ->readlink is optional for symlinks. Don't set, unless filesystem needs | ||
602 | to fake something for readlink(2). | ||
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index b5039a00caaf..038241123ca5 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -451,9 +451,6 @@ otherwise noted. | |||
451 | exist; this is checked by the VFS. Unlike plain rename, | 451 | exist; this is checked by the VFS. Unlike plain rename, |
452 | source and target may be of different type. | 452 | source and target may be of different type. |
453 | 453 | ||
454 | readlink: called by the readlink(2) system call. Only required if | ||
455 | you want to support reading symbolic links | ||
456 | |||
457 | get_link: called by the VFS to follow a symbolic link to the | 454 | get_link: called by the VFS to follow a symbolic link to the |
458 | inode it points to. Only required if you want to support | 455 | inode it points to. Only required if you want to support |
459 | symbolic links. This method returns the symlink body | 456 | symbolic links. This method returns the symlink body |
@@ -468,6 +465,12 @@ otherwise noted. | |||
468 | argument. If request can't be handled without leaving RCU mode, | 465 | argument. If request can't be handled without leaving RCU mode, |
469 | have it return ERR_PTR(-ECHILD). | 466 | have it return ERR_PTR(-ECHILD). |
470 | 467 | ||
468 | readlink: this is now just an override for use by readlink(2) for the | ||
469 | cases when ->get_link uses nd_jump_link() or object is not in | ||
470 | fact a symlink. Normally filesystems should only implement | ||
471 | ->get_link for symlinks and readlink(2) will automatically use | ||
472 | that. | ||
473 | |||
471 | permission: called by the VFS to check for access rights on a POSIX-like | 474 | permission: called by the VFS to check for access rights on a POSIX-like |
472 | filesystem. | 475 | filesystem. |
473 | 476 | ||
diff --git a/fs/namei.c b/fs/namei.c index 12a4159de72a..b87465d67c60 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -4682,10 +4682,19 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen) | |||
4682 | { | 4682 | { |
4683 | struct inode *inode = d_inode(dentry); | 4683 | struct inode *inode = d_inode(dentry); |
4684 | 4684 | ||
4685 | if (!inode->i_op->readlink) | 4685 | if (unlikely(!(inode->i_opflags & IOP_DEFAULT_READLINK))) { |
4686 | return -EINVAL; | 4686 | if (unlikely(inode->i_op->readlink)) |
4687 | return inode->i_op->readlink(dentry, buffer, buflen); | ||
4688 | |||
4689 | if (!d_is_symlink(dentry)) | ||
4690 | return -EINVAL; | ||
4691 | |||
4692 | spin_lock(&inode->i_lock); | ||
4693 | inode->i_opflags |= IOP_DEFAULT_READLINK; | ||
4694 | spin_unlock(&inode->i_lock); | ||
4695 | } | ||
4687 | 4696 | ||
4688 | return inode->i_op->readlink(dentry, buffer, buflen); | 4697 | return generic_readlink(dentry, buffer, buflen); |
4689 | } | 4698 | } |
4690 | EXPORT_SYMBOL(vfs_readlink); | 4699 | EXPORT_SYMBOL(vfs_readlink); |
4691 | 4700 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index eba20d1c068d..f6c206eae6ac 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -595,6 +595,7 @@ is_uncached_acl(struct posix_acl *acl) | |||
595 | #define IOP_LOOKUP 0x0002 | 595 | #define IOP_LOOKUP 0x0002 |
596 | #define IOP_NOFOLLOW 0x0004 | 596 | #define IOP_NOFOLLOW 0x0004 |
597 | #define IOP_XATTR 0x0008 | 597 | #define IOP_XATTR 0x0008 |
598 | #define IOP_DEFAULT_READLINK 0x0010 | ||
598 | 599 | ||
599 | /* | 600 | /* |
600 | * Keep mostly read-only and often accessed (especially for | 601 | * Keep mostly read-only and often accessed (especially for |