[XFS] use generic_permission
authorChristoph Hellwig <hch@infradead.org>
Tue, 5 Feb 2008 01:13:24 +0000 (12:13 +1100)
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>
Thu, 7 Feb 2008 07:22:38 +0000 (18:22 +1100)
Now that all direct caller of xfs_iaccess are gone we can kill xfs_iaccess
and xfs_access and just use generic_permission with a check_acl callback.
This is required for the per-mount read-only patchset in -mm to work
properly with XFS.

SGI-PV: 971186
SGI-Modid: xfs-linux-melb:xfs-kern:30370a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_acl.h
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_vnodeops.c
fs/xfs/xfs_vnodeops.h

index 1ecd86a8c6e684515506a9dda6e62bc5dd8ab07c..c3231a5193618e53b4bacad4392780b67d28e62c 100644 (file)
@@ -558,13 +558,32 @@ xfs_vn_put_link(
 }
 
 #ifdef CONFIG_XFS_POSIX_ACL
+STATIC int
+xfs_check_acl(
+       struct inode            *inode,
+       int                     mask)
+{
+       struct xfs_inode        *ip = XFS_I(inode);
+       int                     error;
+
+       xfs_itrace_entry(ip);
+
+       if (XFS_IFORK_Q(ip)) {
+               error = xfs_acl_iaccess(ip, mask, NULL);
+               if (error != -1)
+                       return -error;
+       }
+
+       return -EAGAIN;
+}
+
 STATIC int
 xfs_vn_permission(
-       struct inode    *inode,
-       int             mode,
-       struct nameidata *nd)
+       struct inode            *inode,
+       int                     mask,
+       struct nameidata        *nd)
 {
-       return -xfs_access(XFS_I(inode), mode << 6, NULL);
+       return generic_permission(inode, mask, xfs_check_acl);
 }
 #else
 #define xfs_vn_permission NULL
index 5bfb66f33cafce0b4e81b8ec22c3985a10f53e2b..7272fe39a92de3c1007999e14ffb310a933654f0 100644 (file)
@@ -391,32 +391,6 @@ xfs_acl_allow_set(
        return error;
 }
 
-/*
- * The access control process to determine the access permission:
- *     if uid == file owner id, use the file owner bits.
- *     if gid == file owner group id, use the file group bits.
- *     scan ACL for a matching user or group, and use matched entry
- *     permission. Use total permissions of all matching group entries,
- *     until all acl entries are exhausted. The final permission produced
- *     by matching acl entry or entries needs to be & with group permission.
- *     if not owner, owning group, or matching entry in ACL, use file
- *     other bits.  
- */
-STATIC int
-xfs_acl_capability_check(
-       mode_t          mode,
-       cred_t          *cr)
-{
-       if ((mode & ACL_READ) && !capable_cred(cr, CAP_DAC_READ_SEARCH))
-               return EACCES;
-       if ((mode & ACL_WRITE) && !capable_cred(cr, CAP_DAC_OVERRIDE))
-               return EACCES;
-       if ((mode & ACL_EXECUTE) && !capable_cred(cr, CAP_DAC_OVERRIDE))
-               return EACCES;
-
-       return 0;
-}
-
 /*
  * Note: cr is only used here for the capability check if the ACL test fails.
  *       It is not used to find out the credentials uid or groups etc, as was
@@ -438,7 +412,6 @@ xfs_acl_access(
 
        matched.ae_tag = 0;     /* Invalid type */
        matched.ae_perm = 0;
-       md >>= 6;       /* Normalize the bits for comparison */
 
        for (i = 0; i < fap->acl_cnt; i++) {
                /*
@@ -520,7 +493,8 @@ xfs_acl_access(
                break;
        }
 
-       return xfs_acl_capability_check(md, cr);
+       /* EACCES tells generic_permission to check for capability overrides */
+       return EACCES;
 }
 
 /*
index 34b7d3391299a02b3e76d8203b876a28b067cf54..332a772461c47ad6a25fc42a812bd055d6579d3c 100644 (file)
@@ -75,7 +75,6 @@ extern int xfs_acl_vremove(bhv_vnode_t *, int);
 #define _ACL_GET_DEFAULT(pv,pd)        (xfs_acl_vtoacl(pv,NULL,pd) == 0)
 #define _ACL_ACCESS_EXISTS     xfs_acl_vhasacl_access
 #define _ACL_DEFAULT_EXISTS    xfs_acl_vhasacl_default
-#define _ACL_XFS_IACCESS(i,m,c) (XFS_IFORK_Q(i) ? xfs_acl_iaccess(i,m,c) : -1)
 
 #define _ACL_ALLOC(a)          ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP))
 #define _ACL_FREE(a)           ((a)? kmem_zone_free(xfs_acl_zone, (a)):(void)0)
@@ -95,7 +94,6 @@ extern int xfs_acl_vremove(bhv_vnode_t *, int);
 #define _ACL_GET_DEFAULT(pv,pd)        (0)
 #define _ACL_ACCESS_EXISTS     (NULL)
 #define _ACL_DEFAULT_EXISTS    (NULL)
-#define _ACL_XFS_IACCESS(i,m,c) (-1)
 #endif
 
 #endif /* __XFS_ACL_H__ */
index 75b636c14876c0c600c00a21fa676dd4709be506..a550546a70832dc727dd117ef1c4bbc3f0ef5e90 100644 (file)
@@ -3583,69 +3583,6 @@ xfs_iflush_all(
        XFS_MOUNT_IUNLOCK(mp);
 }
 
-/*
- * xfs_iaccess: check accessibility of inode for mode.
- */
-int
-xfs_iaccess(
-       xfs_inode_t     *ip,
-       mode_t          mode,
-       cred_t          *cr)
-{
-       int             error;
-       mode_t          orgmode = mode;
-       struct inode    *inode = vn_to_inode(XFS_ITOV(ip));
-
-       if (mode & S_IWUSR) {
-               umode_t         imode = inode->i_mode;
-
-               if (IS_RDONLY(inode) &&
-                   (S_ISREG(imode) || S_ISDIR(imode) || S_ISLNK(imode)))
-                       return XFS_ERROR(EROFS);
-
-               if (IS_IMMUTABLE(inode))
-                       return XFS_ERROR(EACCES);
-       }
-
-       /*
-        * If there's an Access Control List it's used instead of
-        * the mode bits.
-        */
-       if ((error = _ACL_XFS_IACCESS(ip, mode, cr)) != -1)
-               return error ? XFS_ERROR(error) : 0;
-
-       if (current_fsuid(cr) != ip->i_d.di_uid) {
-               mode >>= 3;
-               if (!in_group_p((gid_t)ip->i_d.di_gid))
-                       mode >>= 3;
-       }
-
-       /*
-        * If the DACs are ok we don't need any capability check.
-        */
-       if ((ip->i_d.di_mode & mode) == mode)
-               return 0;
-       /*
-        * Read/write DACs are always overridable.
-        * Executable DACs are overridable if at least one exec bit is set.
-        */
-       if (!(orgmode & S_IXUSR) ||
-           (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
-               if (capable_cred(cr, CAP_DAC_OVERRIDE))
-                       return 0;
-
-       if ((orgmode == S_IRUSR) ||
-           (S_ISDIR(inode->i_mode) && (!(orgmode & S_IWUSR)))) {
-               if (capable_cred(cr, CAP_DAC_READ_SEARCH))
-                       return 0;
-#ifdef NOISE
-               cmn_err(CE_NOTE, "Ick: mode=%o, orgmode=%o", mode, orgmode);
-#endif /* NOISE */
-               return XFS_ERROR(EACCES);
-       }
-       return XFS_ERROR(EACCES);
-}
-
 #ifdef XFS_ILOCK_TRACE
 ktrace_t       *xfs_ilock_trace_buf;
 
index a8d6f5e251aa28247cecc86fda663ca9ae82130f..bfcd72cbaeea9f4e95b1892979d93768f8476d8a 100644 (file)
@@ -550,7 +550,6 @@ void                xfs_iunpin(xfs_inode_t *);
 int            xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
 int            xfs_iflush(xfs_inode_t *, uint);
 void           xfs_iflush_all(struct xfs_mount *);
-int            xfs_iaccess(xfs_inode_t *, mode_t, cred_t *);
 void           xfs_ichgtime(xfs_inode_t *, int);
 xfs_fsize_t    xfs_file_last_byte(xfs_inode_t *);
 void           xfs_lock_inodes(xfs_inode_t **, int, int, uint);
index 076555e8763f52188b3262d8667cf72bb5c5fde1..27e1bea8169f216b187fc3ab85da5e96efb69b77 100644 (file)
@@ -898,27 +898,6 @@ xfs_setattr(
        return code;
 }
 
-
-/*
- * xfs_access
- * Null conversion from vnode mode bits to inode mode bits, as in efs.
- */
-int
-xfs_access(
-       xfs_inode_t     *ip,
-       int             mode,
-       cred_t          *credp)
-{
-       int             error;
-
-       xfs_itrace_entry(ip);
-       xfs_ilock(ip, XFS_ILOCK_SHARED);
-       error = xfs_iaccess(ip, mode, credp);
-       xfs_iunlock(ip, XFS_ILOCK_SHARED);
-       return error;
-}
-
-
 /*
  * The maximum pathlen is 1024 bytes. Since the minimum file system
  * blocksize is 512 bytes, we can get a max of 2 extents back from
index a501aeffb808a999c0131a7bada7bbff653980ee..4e3970f0e5e37f96138189aef88a305f27ee06bd 100644 (file)
@@ -18,7 +18,6 @@ int xfs_open(struct xfs_inode *ip);
 int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags);
 int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags,
                struct cred *credp);
-int xfs_access(struct xfs_inode *ip, int mode, struct cred *credp);
 int xfs_readlink(struct xfs_inode *ip, char *link);
 int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start,
                xfs_off_t stop);