Wrapfs: ->iget fixes
authorErez Zadok <ezk@cs.sunysb.edu>
Sun, 19 Feb 2017 00:11:22 +0000 (19:11 -0500)
committerErez Zadok <ezk@cs.sunysb.edu>
Sun, 19 Feb 2017 00:11:22 +0000 (19:11 -0500)
Change where we igrab/iput to ensure we always hold a valid lower_inode.
Return ENOMEM (not EACCES) if iget5_locked returns NULL.

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
fs/wrapfs/lookup.c

index 4216ac4a0e7de68da4a0e629c89d656823f56a3c..20499585c7cdb90dc050ee349bef87fdfe950d27 100644 (file)
@@ -73,8 +73,9 @@ struct inode *wrapfs_iget(struct super_block *sb, struct inode *lower_inode)
 {
        struct wrapfs_inode_info *info;
        struct inode *inode; /* the new inode to return */
-       int err;
 
+       if (!igrab(lower_inode))
+               return ERR_PTR(-ESTALE);
        inode = iget5_locked(sb, /* our superblock */
                             /*
                              * hashval: we use inode number, but we can
@@ -86,22 +87,19 @@ struct inode *wrapfs_iget(struct super_block *sb, struct inode *lower_inode)
                             wrapfs_inode_set, /* inode init function */
                             lower_inode); /* data passed to test+set fxns */
        if (!inode) {
-               err = -EACCES;
                iput(lower_inode);
-               return ERR_PTR(err);
+               return ERR_PTR(-ENOMEM);
        }
-       /* if found a cached inode, then just return it */
-       if (!(inode->i_state & I_NEW))
+       /* if found a cached inode, then just return it (after iput) */
+       if (!(inode->i_state & I_NEW)) {
+               iput(lower_inode);
                return inode;
+       }
 
        /* initialize new inode */
        info = WRAPFS_I(inode);
 
        inode->i_ino = lower_inode->i_ino;
-       if (!igrab(lower_inode)) {
-               err = -ESTALE;
-               return ERR_PTR(err);
-       }
        wrapfs_set_lower_inode(inode, lower_inode);
 
        inode->i_version++;