Commit cc41b90f authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] kill ->i_op->revalidate()

kill ->i_op->revalidate()
parent e3b08ca8
...@@ -42,9 +42,8 @@ prototypes: ...@@ -42,9 +42,8 @@ prototypes:
int (*follow_link) (struct dentry *, struct nameidata *); int (*follow_link) (struct dentry *, struct nameidata *);
void (*truncate) (struct inode *); void (*truncate) (struct inode *);
int (*permission) (struct inode *, int); int (*permission) (struct inode *, int);
int (*revalidate) (struct dentry *);
int (*setattr) (struct dentry *, struct iattr *); int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *, void *, size_t, int); int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t);
...@@ -67,8 +66,7 @@ follow_link: no no ...@@ -67,8 +66,7 @@ follow_link: no no
truncate: no yes (see below) truncate: no yes (see below)
setattr: no yes setattr: no yes
permission: yes no permission: yes no
getattr: (see below) getattr: no no
revalidate: no (see below)
setxattr: no yes setxattr: no yes
getxattr: no yes getxattr: no yes
listxattr: no yes listxattr: no yes
...@@ -76,14 +74,11 @@ removexattr: no yes ...@@ -76,14 +74,11 @@ removexattr: no yes
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_sem on Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_sem on
victim. victim.
cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
->revalidate(), it may be called both with and without the i_sem
on dentry->d_inode.
->truncate() is never called directly - it's a callback, not a ->truncate() is never called directly - it's a callback, not a
method. It's called by vmtruncate() - library function normally used by method. It's called by vmtruncate() - library function normally used by
->setattr(). Locking information above applies to that call (i.e. is ->setattr(). Locking information above applies to that call (i.e. is
inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been
passed). passed).
->getattr() is currently unused.
See Documentation/filesystems/directory-locking for more detailed discussion See Documentation/filesystems/directory-locking for more detailed discussion
of the locking scheme for directory operations. of the locking scheme for directory operations.
......
...@@ -187,3 +187,14 @@ e.g. ...@@ -187,3 +187,14 @@ e.g.
unlock_new_inode(inode); unlock_new_inode(inode);
} }
---
[recommended]
->getattr() finally getting used. See instances in nfs, minix, etc.
---
[mandatory]
->revalidate() is gone. If your filesystem had it - provide ->getattr()
and let it call whatever you had as ->revlidate() + (for symlinks that
had ->revalidate()) add calls in ->follow_link()/->readlink().
...@@ -60,7 +60,6 @@ struct inode_operations bad_inode_ops = ...@@ -60,7 +60,6 @@ struct inode_operations bad_inode_ops =
follow_link: bad_follow_link, follow_link: bad_follow_link,
truncate: EIO_ERROR, truncate: EIO_ERROR,
permission: EIO_ERROR, permission: EIO_ERROR,
revalidate: EIO_ERROR,
getattr: EIO_ERROR, getattr: EIO_ERROR,
}; };
......
...@@ -28,7 +28,7 @@ inline int coda_isnullfid(ViceFid *fid) ...@@ -28,7 +28,7 @@ inline int coda_isnullfid(ViceFid *fid)
static struct inode_operations coda_symlink_inode_operations = { static struct inode_operations coda_symlink_inode_operations = {
readlink: page_readlink, readlink: page_readlink,
follow_link: page_follow_link, follow_link: page_follow_link,
setattr: coda_notify_change, setattr: coda_setattr,
}; };
/* cnode.c */ /* cnode.c */
......
...@@ -72,8 +72,8 @@ struct inode_operations coda_dir_inode_operations = ...@@ -72,8 +72,8 @@ struct inode_operations coda_dir_inode_operations =
mknod: coda_mknod, mknod: coda_mknod,
rename: coda_rename, rename: coda_rename,
permission: coda_permission, permission: coda_permission,
revalidate: coda_revalidate_inode, getattr: coda_getattr,
setattr: coda_notify_change, setattr: coda_setattr,
}; };
struct file_operations coda_dir_operations = { struct file_operations coda_dir_operations = {
...@@ -147,7 +147,6 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry) ...@@ -147,7 +147,6 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
int coda_permission(struct inode *inode, int mask) int coda_permission(struct inode *inode, int mask)
{ {
umode_t mode = inode->i_mode;
int error; int error;
if (!mask) if (!mask)
......
...@@ -237,7 +237,15 @@ static void coda_clear_inode(struct inode *inode) ...@@ -237,7 +237,15 @@ static void coda_clear_inode(struct inode *inode)
coda_cache_clear_inode(inode); coda_cache_clear_inode(inode);
} }
int coda_notify_change(struct dentry *de, struct iattr *iattr) int coda_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
int err = coda_revalidate_inode(dentry);
if (!err)
generic_fillattr(dentry->d_inode, stat);
return err;
}
int coda_setattr(struct dentry *de, struct iattr *iattr)
{ {
struct inode *inode = de->d_inode; struct inode *inode = de->d_inode;
struct coda_vattr vattr; struct coda_vattr vattr;
...@@ -266,8 +274,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr) ...@@ -266,8 +274,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr)
struct inode_operations coda_file_inode_operations = { struct inode_operations coda_file_inode_operations = {
permission: coda_permission, permission: coda_permission,
revalidate: coda_revalidate_inode, getattr: coda_getattr,
setattr: coda_notify_change, setattr: coda_setattr,
}; };
static int coda_statfs(struct super_block *sb, struct statfs *buf) static int coda_statfs(struct super_block *sb, struct statfs *buf)
......
...@@ -32,7 +32,7 @@ static int coda_pioctl(struct inode * inode, struct file * filp, ...@@ -32,7 +32,7 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
struct inode_operations coda_ioctl_inode_operations = struct inode_operations coda_ioctl_inode_operations =
{ {
permission: coda_ioctl_permission, permission: coda_ioctl_permission,
setattr: coda_notify_change, setattr: coda_setattr,
}; };
struct file_operations coda_ioctl_operations = { struct file_operations coda_ioctl_operations = {
......
...@@ -64,8 +64,8 @@ struct inode_operations nfs_dir_inode_operations = { ...@@ -64,8 +64,8 @@ struct inode_operations nfs_dir_inode_operations = {
mknod: nfs_mknod, mknod: nfs_mknod,
rename: nfs_rename, rename: nfs_rename,
permission: nfs_permission, permission: nfs_permission,
revalidate: nfs_revalidate, getattr: nfs_getattr,
setattr: nfs_notify_change, setattr: nfs_setattr,
}; };
typedef u32 * (*decode_dirent_t)(u32 *, struct nfs_entry *, int); typedef u32 * (*decode_dirent_t)(u32 *, struct nfs_entry *, int);
...@@ -357,7 +357,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -357,7 +357,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
lock_kernel(); lock_kernel();
res = nfs_revalidate(dentry); res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
if (res < 0) { if (res < 0) {
unlock_kernel(); unlock_kernel();
return res; return res;
......
...@@ -54,8 +54,8 @@ struct file_operations nfs_file_operations = { ...@@ -54,8 +54,8 @@ struct file_operations nfs_file_operations = {
struct inode_operations nfs_file_inode_operations = { struct inode_operations nfs_file_inode_operations = {
permission: nfs_permission, permission: nfs_permission,
revalidate: nfs_revalidate, getattr: nfs_getattr,
setattr: nfs_notify_change, setattr: nfs_setattr,
}; };
/* Hack for future NFS swap support */ /* Hack for future NFS swap support */
......
...@@ -730,7 +730,7 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) ...@@ -730,7 +730,7 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
} }
int int
nfs_notify_change(struct dentry *dentry, struct iattr *attr) nfs_setattr(struct dentry *dentry, struct iattr *attr)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct nfs_fattr fattr; struct nfs_fattr fattr;
...@@ -744,7 +744,7 @@ nfs_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -744,7 +744,7 @@ nfs_notify_change(struct dentry *dentry, struct iattr *attr)
error = nfs_revalidate_inode(NFS_SERVER(inode),inode); error = nfs_revalidate_inode(NFS_SERVER(inode),inode);
if (error) { if (error) {
#ifdef NFS_PARANOIA #ifdef NFS_PARANOIA
printk("nfs_notify_change: revalidate failed, error=%d\n", error); printk("nfs_setattr: revalidate failed, error=%d\n", error);
#endif #endif
goto out; goto out;
} }
...@@ -768,7 +768,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error); ...@@ -768,7 +768,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
*/ */
if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_valid & ATTR_SIZE) {
if (attr->ia_size != fattr.size) if (attr->ia_size != fattr.size)
printk("nfs_notify_change: attr=%Ld, fattr=%Ld??\n", printk("nfs_setattr: attr=%Ld, fattr=%Ld??\n",
(long long) attr->ia_size, (long long)fattr.size); (long long) attr->ia_size, (long long)fattr.size);
vmtruncate(inode, attr->ia_size); vmtruncate(inode, attr->ia_size);
} }
...@@ -808,14 +808,13 @@ nfs_wait_on_inode(struct inode *inode, int flag) ...@@ -808,14 +808,13 @@ nfs_wait_on_inode(struct inode *inode, int flag)
return error; return error;
} }
/* int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
* Externally visible revalidation function
*/
int
nfs_revalidate(struct dentry *dentry)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
return nfs_revalidate_inode(NFS_SERVER(inode), inode); int err = nfs_revalidate_inode(NFS_SERVER(inode), inode);
if (!err)
generic_fillattr(inode, stat);
return err;
} }
/* /*
......
...@@ -59,7 +59,9 @@ static char *nfs_getlink(struct inode *inode, struct page **ppage) ...@@ -59,7 +59,9 @@ static char *nfs_getlink(struct inode *inode, struct page **ppage)
struct page *page; struct page *page;
u32 *p; u32 *p;
/* Caller revalidated the directory inode already. */ page = ERR_PTR(nfs_revalidate_inode(NFS_SERVER(inode), inode));
if (page)
goto read_failed;
page = read_cache_page(&inode->i_data, 0, page = read_cache_page(&inode->i_data, 0,
(filler_t *)nfs_symlink_filler, inode); (filler_t *)nfs_symlink_filler, inode);
if (IS_ERR(page)) if (IS_ERR(page))
...@@ -72,7 +74,7 @@ static char *nfs_getlink(struct inode *inode, struct page **ppage) ...@@ -72,7 +74,7 @@ static char *nfs_getlink(struct inode *inode, struct page **ppage)
getlink_read_error: getlink_read_error:
page_cache_release(page); page_cache_release(page);
return ERR_PTR(-EIO); page = ERR_PTR(-EIO);
read_failed: read_failed:
return (char*)page; return (char*)page;
} }
...@@ -107,6 +109,6 @@ static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -107,6 +109,6 @@ static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
struct inode_operations nfs_symlink_inode_operations = { struct inode_operations nfs_symlink_inode_operations = {
readlink: nfs_readlink, readlink: nfs_readlink,
follow_link: nfs_follow_link, follow_link: nfs_follow_link,
revalidate: nfs_revalidate, getattr: nfs_getattr,
setattr: nfs_notify_change, setattr: nfs_setattr,
}; };
...@@ -47,7 +47,7 @@ struct inode_operations smb_dir_inode_operations = ...@@ -47,7 +47,7 @@ struct inode_operations smb_dir_inode_operations =
mkdir: smb_mkdir, mkdir: smb_mkdir,
rmdir: smb_rmdir, rmdir: smb_rmdir,
rename: smb_rename, rename: smb_rename,
revalidate: smb_revalidate_inode, getattr: smb_getattr,
setattr: smb_notify_change, setattr: smb_notify_change,
}; };
......
...@@ -398,6 +398,6 @@ struct file_operations smb_file_operations = ...@@ -398,6 +398,6 @@ struct file_operations smb_file_operations =
struct inode_operations smb_file_inode_operations = struct inode_operations smb_file_inode_operations =
{ {
permission: smb_file_permission, permission: smb_file_permission,
revalidate: smb_revalidate_inode, getattr: smb_getattr,
setattr: smb_notify_change, setattr: smb_notify_change,
}; };
...@@ -611,6 +611,14 @@ smb_statfs(struct super_block *sb, struct statfs *buf) ...@@ -611,6 +611,14 @@ smb_statfs(struct super_block *sb, struct statfs *buf)
return result; return result;
} }
int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
int err = smb_revalidate_inode(dentry);
if (!err)
generic_fillattr(dentry->d_inode, stat);
return err;
}
int int
smb_notify_change(struct dentry *dentry, struct iattr *attr) smb_notify_change(struct dentry *dentry, struct iattr *attr)
{ {
......
...@@ -49,6 +49,7 @@ extern void smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr); ...@@ -49,6 +49,7 @@ extern void smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr);
extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr); extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr);
extern void smb_invalidate_inodes(struct smb_sb_info *server); extern void smb_invalidate_inodes(struct smb_sb_info *server);
extern int smb_revalidate_inode(struct dentry *dentry); extern int smb_revalidate_inode(struct dentry *dentry);
extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
extern int smb_notify_change(struct dentry *dentry, struct iattr *attr); extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
/* file.c */ /* file.c */
extern struct address_space_operations smb_file_aops; extern struct address_space_operations smb_file_aops;
......
...@@ -14,18 +14,6 @@ ...@@ -14,18 +14,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
/*
* Revalidate the inode. This is required for proper NFS attribute caching.
*/
static __inline__ int
do_revalidate(struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
if (inode->i_op->revalidate)
return inode->i_op->revalidate(dentry);
return 0;
}
void generic_fillattr(struct inode *inode, struct kstat *stat) void generic_fillattr(struct inode *inode, struct kstat *stat)
{ {
stat->dev = kdev_t_to_nr(inode->i_dev); stat->dev = kdev_t_to_nr(inode->i_dev);
...@@ -46,16 +34,11 @@ void generic_fillattr(struct inode *inode, struct kstat *stat) ...@@ -46,16 +34,11 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{ {
int res = 0;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
if (inode->i_op->getattr) if (inode->i_op->getattr)
return inode->i_op->getattr(mnt, dentry, stat); return inode->i_op->getattr(mnt, dentry, stat);
res = do_revalidate(dentry);
if (res)
return res;
generic_fillattr(inode, stat); generic_fillattr(inode, stat);
if (!stat->blksize) { if (!stat->blksize) {
struct super_block *s = inode->i_sb; struct super_block *s = inode->i_sb;
...@@ -247,8 +230,7 @@ asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz) ...@@ -247,8 +230,7 @@ asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz)
struct inode * inode = nd.dentry->d_inode; struct inode * inode = nd.dentry->d_inode;
error = -EINVAL; error = -EINVAL;
if (inode->i_op && inode->i_op->readlink && if (inode->i_op && inode->i_op->readlink) {
!(error = do_revalidate(nd.dentry))) {
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
error = inode->i_op->readlink(nd.dentry, buf, bufsiz); error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
} }
......
...@@ -40,7 +40,8 @@ int coda_flush(struct file *f); ...@@ -40,7 +40,8 @@ int coda_flush(struct file *f);
int coda_release(struct inode *i, struct file *f); int coda_release(struct inode *i, struct file *f);
int coda_permission(struct inode *inode, int mask); int coda_permission(struct inode *inode, int mask);
int coda_revalidate_inode(struct dentry *); int coda_revalidate_inode(struct dentry *);
int coda_notify_change(struct dentry *, struct iattr *); int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
int coda_setattr(struct dentry *, struct iattr *);
int coda_isnullfid(ViceFid *fid); int coda_isnullfid(ViceFid *fid);
/* global variables */ /* global variables */
......
...@@ -781,7 +781,6 @@ struct inode_operations { ...@@ -781,7 +781,6 @@ struct inode_operations {
int (*follow_link) (struct dentry *, struct nameidata *); int (*follow_link) (struct dentry *, struct nameidata *);
void (*truncate) (struct inode *); void (*truncate) (struct inode *);
int (*permission) (struct inode *, int); int (*permission) (struct inode *, int);
int (*revalidate) (struct dentry *);
int (*setattr) (struct dentry *, struct iattr *); int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *, void *, size_t, int); int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
......
...@@ -234,12 +234,12 @@ extern int nfs_inode_is_stale(struct inode *, struct nfs_fh *, ...@@ -234,12 +234,12 @@ extern int nfs_inode_is_stale(struct inode *, struct nfs_fh *,
extern struct inode *nfs_fhget(struct dentry *, struct nfs_fh *, extern struct inode *nfs_fhget(struct dentry *, struct nfs_fh *,
struct nfs_fattr *); struct nfs_fattr *);
extern int __nfs_refresh_inode(struct inode *, struct nfs_fattr *); extern int __nfs_refresh_inode(struct inode *, struct nfs_fattr *);
extern int nfs_revalidate(struct dentry *); extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int nfs_permission(struct inode *, int); extern int nfs_permission(struct inode *, int);
extern int nfs_open(struct inode *, struct file *); extern int nfs_open(struct inode *, struct file *);
extern int nfs_release(struct inode *, struct file *); extern int nfs_release(struct inode *, struct file *);
extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
extern int nfs_notify_change(struct dentry *, struct iattr *); extern int nfs_setattr(struct dentry *, struct iattr *);
/* /*
* linux/fs/nfs/file.c * linux/fs/nfs/file.c
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment