Unionfs: fix readonly nfs2/3 permission handling
authorErez Zadok <ezk@cs.sunysb.edu>
Tue, 22 Sep 2009 21:27:23 +0000 (17:27 -0400)
committerErez Zadok <ezk@cs.sunysb.edu>
Fri, 24 Jun 2011 18:08:11 +0000 (14:08 -0400)
In unionfs_permission: NFSv2/3 return EACCES on readonly-exported, locally
readonly-mounted file systems, instead of EROFS like other file systems do.
So we have no choice here but to intercept this and ignore it for NFS
branches marked readonly.  Specifically, we avoid using NFS's own "broken"
->permission method, and rely on generic_permission() to do basic checking
for us.

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

index 7c17093e0d2e5aadb240e4451a1b4e8eb418eea8..7e86273583d8f799ee6ada99508b74758ddece4c 100644 (file)
@@ -842,6 +842,20 @@ static int unionfs_permission(struct inode *inode, int mask)
                                err = 0;
                }
 
+               /*
+                * NFS HACK: NFSv2/3 return EACCES on readonly-exported,
+                * locally readonly-mounted file systems, instead of EROFS
+                * like other file systems do.  So we have no choice here
+                * but to intercept this and ignore it for NFS branches
+                * marked readonly.  Specifically, we avoid using NFS's own
+                * "broken" ->permission method, and rely on
+                * generic_permission() to do basic checking for us.
+                */
+               if (err && err == -EACCES &&
+                   is_robranch_super(inode->i_sb, bindex) &&
+                   lower_inode->i_sb->s_magic == NFS_SUPER_MAGIC)
+                       err = generic_permission(lower_inode, mask, NULL);
+
                /*
                 * The permissions are an intersection of the overall directory
                 * permissions, so we fail if one fails.