Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfs: default to generic_readlink()

If i_op->readlink is NULL, but i_op->get_link is set then vfs_readlink()
defaults to calling generic_readlink().

The IOP_DEFAULT_READLINK flag indicates that the above conditions are met
and the default action can be taken.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

+23 -6
+4
Documentation/filesystems/porting
··· 596 596 [mandatory] 597 597 ->rename() has an added flags argument. Any flags not handled by the 598 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).
+6 -3
Documentation/filesystems/vfs.txt
··· 451 451 exist; this is checked by the VFS. Unlike plain rename, 452 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 454 get_link: called by the VFS to follow a symbolic link to the 458 455 inode it points to. Only required if you want to support 459 456 symbolic links. This method returns the symlink body ··· 464 467 May be called in RCU mode; that is indicated by NULL dentry 465 468 argument. If request can't be handled without leaving RCU mode, 466 469 have it return ERR_PTR(-ECHILD). 470 + 471 + readlink: this is now just an override for use by readlink(2) for the 472 + cases when ->get_link uses nd_jump_link() or object is not in 473 + fact a symlink. Normally filesystems should only implement 474 + ->get_link for symlinks and readlink(2) will automatically use 475 + that. 467 476 468 477 permission: called by the VFS to check for access rights on a POSIX-like 469 478 filesystem.
+12 -3
fs/namei.c
··· 4682 4682 { 4683 4683 struct inode *inode = d_inode(dentry); 4684 4684 4685 - if (!inode->i_op->readlink) 4686 - return -EINVAL; 4685 + if (unlikely(!(inode->i_opflags & IOP_DEFAULT_READLINK))) { 4686 + if (unlikely(inode->i_op->readlink)) 4687 + return inode->i_op->readlink(dentry, buffer, buflen); 4687 4688 4688 - return inode->i_op->readlink(dentry, buffer, buflen); 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 + } 4696 + 4697 + return generic_readlink(dentry, buffer, buflen); 4689 4698 } 4690 4699 EXPORT_SYMBOL(vfs_readlink); 4691 4700
+1
include/linux/fs.h
··· 595 595 #define IOP_LOOKUP 0x0002 596 596 #define IOP_NOFOLLOW 0x0004 597 597 #define IOP_XATTR 0x0008 598 + #define IOP_DEFAULT_READLINK 0x0010 598 599 599 600 /* 600 601 * Keep mostly read-only and often accessed (especially for