cache the value of file_inode() in struct file
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 2 Mar 2013 00:48:30 +0000 (19:48 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 2 Mar 2013 00:48:30 +0000 (19:48 -0500)
Note that this thing does *not* contribute to inode refcount;
it's pinned down by dentry.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/file_table.c
fs/open.c
include/linux/fs.h

index aa07d36..cd4d87a 100644 (file)
@@ -176,6 +176,7 @@ struct file *alloc_file(struct path *path, fmode_t mode,
                return file;
 
        file->f_path = *path;
+       file->f_inode = path->dentry->d_inode;
        file->f_mapping = path->dentry->d_inode->i_mapping;
        file->f_mode = mode;
        file->f_op = fop;
@@ -258,6 +259,7 @@ static void __fput(struct file *file)
                drop_file_write_access(file);
        file->f_path.dentry = NULL;
        file->f_path.mnt = NULL;
+       file->f_inode = NULL;
        file_free(file);
        dput(dentry);
        mntput(mnt);
index 62f907e..806d458 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -689,7 +689,7 @@ static int do_dentry_open(struct file *f,
                f->f_mode = FMODE_PATH;
 
        path_get(&f->f_path);
-       inode = file_inode(f);
+       inode = f->f_inode = f->f_path.dentry->d_inode;
        if (f->f_mode & FMODE_WRITE) {
                error = __get_file_write_access(inode, f->f_path.mnt);
                if (error)
@@ -752,6 +752,7 @@ cleanup_file:
        path_put(&f->f_path);
        f->f_path.mnt = NULL;
        f->f_path.dentry = NULL;
+       f->f_inode = NULL;
        return error;
 }
 
index 4e686a0..74a907b 100644 (file)
@@ -769,6 +769,7 @@ struct file {
        } f_u;
        struct path             f_path;
 #define f_dentry       f_path.dentry
+       struct inode            *f_inode;       /* cached value */
        const struct file_operations    *f_op;
 
        /*
@@ -2217,7 +2218,7 @@ static inline bool execute_ok(struct inode *inode)
 
 static inline struct inode *file_inode(struct file *f)
 {
-       return f->f_path.dentry->d_inode;
+       return f->f_inode;
 }
 
 /*