LCOV - code coverage report
Current view: top level - fs/nfs - nfs3acl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 97 0.0 %
Date: 2014-04-16 Functions: 0 4 0.0 %
Branches: 0 75 0.0 %

           Branch data     Line data    Source code
       1                 :            : #include <linux/fs.h>
       2                 :            : #include <linux/gfp.h>
       3                 :            : #include <linux/nfs.h>
       4                 :            : #include <linux/nfs3.h>
       5                 :            : #include <linux/nfs_fs.h>
       6                 :            : #include <linux/posix_acl_xattr.h>
       7                 :            : #include <linux/nfsacl.h>
       8                 :            : 
       9                 :            : #include "internal.h"
      10                 :            : 
      11                 :            : #define NFSDBG_FACILITY NFSDBG_PROC
      12                 :            : 
      13                 :          0 : struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
      14                 :            : {
      15                 :            :         struct nfs_server *server = NFS_SERVER(inode);
      16                 :          0 :         struct page *pages[NFSACL_MAXPAGES] = { };
      17                 :          0 :         struct nfs3_getaclargs args = {
      18                 :          0 :                 .fh = NFS_FH(inode),
      19                 :            :                 /* The xdr layer may allocate pages here. */
      20                 :            :                 .pages = pages,
      21                 :            :         };
      22                 :          0 :         struct nfs3_getaclres res = {
      23                 :            :                 NULL,
      24                 :            :         };
      25                 :          0 :         struct rpc_message msg = {
      26                 :            :                 .rpc_argp       = &args,
      27                 :            :                 .rpc_resp       = &res,
      28                 :            :         };
      29                 :            :         int status, count;
      30                 :            : 
      31         [ #  # ]:          0 :         if (!nfs_server_capable(inode, NFS_CAP_ACLS))
      32                 :            :                 return ERR_PTR(-EOPNOTSUPP);
      33                 :            : 
      34                 :          0 :         status = nfs_revalidate_inode(server, inode);
      35         [ #  # ]:          0 :         if (status < 0)
      36                 :          0 :                 return ERR_PTR(status);
      37                 :            : 
      38                 :            :         /*
      39                 :            :          * Only get the access acl when explicitly requested: We don't
      40                 :            :          * need it for access decisions, and only some applications use
      41                 :            :          * it. Applications which request the access acl first are not
      42                 :            :          * penalized from this optimization.
      43                 :            :          */
      44         [ #  # ]:          0 :         if (type == ACL_TYPE_ACCESS)
      45                 :          0 :                 args.mask |= NFS_ACLCNT|NFS_ACL;
      46         [ #  # ]:          0 :         if (S_ISDIR(inode->i_mode))
      47                 :          0 :                 args.mask |= NFS_DFACLCNT|NFS_DFACL;
      48         [ #  # ]:          0 :         if (args.mask == 0)
      49                 :            :                 return NULL;
      50                 :            : 
      51                 :            :         dprintk("NFS call getacl\n");
      52                 :          0 :         msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL];
      53                 :          0 :         res.fattr = nfs_alloc_fattr();
      54         [ #  # ]:          0 :         if (res.fattr == NULL)
      55                 :            :                 return ERR_PTR(-ENOMEM);
      56                 :            : 
      57                 :          0 :         status = rpc_call_sync(server->client_acl, &msg, 0);
      58                 :            :         dprintk("NFS reply getacl: %d\n", status);
      59                 :            : 
      60                 :            :         /* pages may have been allocated at the xdr layer. */
      61 [ #  # ][ #  # ]:          0 :         for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
      62                 :          0 :                 __free_page(args.pages[count]);
      63                 :            : 
      64   [ #  #  #  # ]:          0 :         switch (status) {
      65                 :            :                 case 0:
      66                 :          0 :                         status = nfs_refresh_inode(inode, res.fattr);
      67                 :            :                         break;
      68                 :            :                 case -EPFNOSUPPORT:
      69                 :            :                 case -EPROTONOSUPPORT:
      70                 :            :                         dprintk("NFS_V3_ACL extension not supported; disabling\n");
      71                 :          0 :                         server->caps &= ~NFS_CAP_ACLS;
      72                 :            :                 case -ENOTSUPP:
      73                 :            :                         status = -EOPNOTSUPP;
      74                 :            :                 default:
      75                 :            :                         goto getout;
      76                 :            :         }
      77         [ #  # ]:          0 :         if ((args.mask & res.mask) != args.mask) {
      78                 :            :                 status = -EIO;
      79                 :            :                 goto getout;
      80                 :            :         }
      81                 :            : 
      82         [ #  # ]:          0 :         if (res.acl_access != NULL) {
      83 [ #  # ][ #  # ]:          0 :                 if ((posix_acl_equiv_mode(res.acl_access, NULL) == 0) ||
      84                 :          0 :                     res.acl_access->a_count == 0) {
      85                 :          0 :                         posix_acl_release(res.acl_access);
      86                 :          0 :                         res.acl_access = NULL;
      87                 :            :                 }
      88                 :            :         }
      89                 :            : 
      90         [ #  # ]:          0 :         if (res.mask & NFS_ACL)
      91                 :          0 :                 set_cached_acl(inode, ACL_TYPE_ACCESS, res.acl_access);
      92                 :            :         else
      93                 :          0 :                 forget_cached_acl(inode, ACL_TYPE_ACCESS);
      94                 :            : 
      95         [ #  # ]:          0 :         if (res.mask & NFS_DFACL)
      96                 :          0 :                 set_cached_acl(inode, ACL_TYPE_DEFAULT, res.acl_default);
      97                 :            :         else
      98                 :          0 :                 forget_cached_acl(inode, ACL_TYPE_DEFAULT);
      99                 :            : 
     100                 :          0 :         nfs_free_fattr(res.fattr);
     101         [ #  # ]:          0 :         if (type == ACL_TYPE_ACCESS) {
     102                 :          0 :                 posix_acl_release(res.acl_default);
     103                 :          0 :                 return res.acl_access;
     104                 :            :         } else {
     105                 :          0 :                 posix_acl_release(res.acl_access);
     106                 :          0 :                 return res.acl_default;
     107                 :            :         }
     108                 :            : 
     109                 :            : getout:
     110                 :          0 :         posix_acl_release(res.acl_access);
     111                 :          0 :         posix_acl_release(res.acl_default);
     112                 :          0 :         nfs_free_fattr(res.fattr);
     113                 :          0 :         return ERR_PTR(status);
     114                 :            : }
     115                 :            : 
     116                 :          0 : static int __nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
     117                 :            :                 struct posix_acl *dfacl)
     118                 :            : {
     119                 :            :         struct nfs_server *server = NFS_SERVER(inode);
     120                 :            :         struct nfs_fattr *fattr;
     121                 :            :         struct page *pages[NFSACL_MAXPAGES];
     122                 :          0 :         struct nfs3_setaclargs args = {
     123                 :            :                 .inode = inode,
     124                 :            :                 .mask = NFS_ACL,
     125                 :            :                 .acl_access = acl,
     126                 :            :                 .pages = pages,
     127                 :            :         };
     128                 :          0 :         struct rpc_message msg = {
     129                 :            :                 .rpc_argp       = &args,
     130                 :            :                 .rpc_resp       = &fattr,
     131                 :            :         };
     132                 :            :         int status;
     133                 :            : 
     134                 :            :         status = -EOPNOTSUPP;
     135         [ #  # ]:          0 :         if (!nfs_server_capable(inode, NFS_CAP_ACLS))
     136                 :            :                 goto out;
     137                 :            : 
     138                 :            :         /* We are doing this here because XDR marshalling does not
     139                 :            :          * return any results, it BUGs. */
     140                 :            :         status = -ENOSPC;
     141 [ #  # ][ #  # ]:          0 :         if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES)
     142                 :            :                 goto out;
     143 [ #  # ][ #  # ]:          0 :         if (dfacl != NULL && dfacl->a_count > NFS_ACL_MAX_ENTRIES)
     144                 :            :                 goto out;
     145         [ #  # ]:          0 :         if (S_ISDIR(inode->i_mode)) {
     146                 :          0 :                 args.mask |= NFS_DFACL;
     147                 :          0 :                 args.acl_default = dfacl;
     148                 :          0 :                 args.len = nfsacl_size(acl, dfacl);
     149                 :            :         } else
     150                 :          0 :                 args.len = nfsacl_size(acl, NULL);
     151                 :            : 
     152         [ #  # ]:          0 :         if (args.len > NFS_ACL_INLINE_BUFSIZE) {
     153                 :          0 :                 unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT);
     154                 :            : 
     155                 :            :                 status = -ENOMEM;
     156                 :            :                 do {
     157                 :          0 :                         args.pages[args.npages] = alloc_page(GFP_KERNEL);
     158         [ #  # ]:          0 :                         if (args.pages[args.npages] == NULL)
     159                 :            :                                 goto out_freepages;
     160                 :          0 :                         args.npages++;
     161         [ #  # ]:          0 :                 } while (args.npages < npages);
     162                 :            :         }
     163                 :            : 
     164                 :            :         dprintk("NFS call setacl\n");
     165                 :            :         status = -ENOMEM;
     166                 :          0 :         fattr = nfs_alloc_fattr();
     167         [ #  # ]:          0 :         if (fattr == NULL)
     168                 :            :                 goto out_freepages;
     169                 :            : 
     170                 :          0 :         msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL];
     171                 :          0 :         msg.rpc_resp = fattr;
     172                 :          0 :         status = rpc_call_sync(server->client_acl, &msg, 0);
     173                 :          0 :         nfs_access_zap_cache(inode);
     174                 :          0 :         nfs_zap_acl_cache(inode);
     175                 :            :         dprintk("NFS reply setacl: %d\n", status);
     176                 :            : 
     177   [ #  #  #  # ]:          0 :         switch (status) {
     178                 :            :                 case 0:
     179                 :          0 :                         status = nfs_refresh_inode(inode, fattr);
     180                 :          0 :                         set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
     181                 :          0 :                         set_cached_acl(inode, ACL_TYPE_DEFAULT, dfacl);
     182                 :          0 :                         break;
     183                 :            :                 case -EPFNOSUPPORT:
     184                 :            :                 case -EPROTONOSUPPORT:
     185                 :            :                         dprintk("NFS_V3_ACL SETACL RPC not supported"
     186                 :            :                                         "(will not retry)\n");
     187                 :          0 :                         server->caps &= ~NFS_CAP_ACLS;
     188                 :            :                 case -ENOTSUPP:
     189                 :            :                         status = -EOPNOTSUPP;
     190                 :            :         }
     191                 :          0 :         nfs_free_fattr(fattr);
     192                 :            : out_freepages:
     193         [ #  # ]:          0 :         while (args.npages != 0) {
     194                 :          0 :                 args.npages--;
     195                 :          0 :                 __free_page(args.pages[args.npages]);
     196                 :            :         }
     197                 :            : out:
     198                 :          0 :         return status;
     199                 :            : }
     200                 :            : 
     201                 :          0 : int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
     202                 :            :                 struct posix_acl *dfacl)
     203                 :            : {
     204                 :            :         int ret;
     205                 :          0 :         ret = __nfs3_proc_setacls(inode, acl, dfacl);
     206         [ #  # ]:          0 :         return (ret == -EOPNOTSUPP) ? 0 : ret;
     207                 :            : 
     208                 :            : }
     209                 :            : 
     210                 :          0 : int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type)
     211                 :            : {
     212                 :            :         struct posix_acl *alloc = NULL, *dfacl = NULL;
     213                 :            :         int status;
     214                 :            : 
     215         [ #  # ]:          0 :         if (S_ISDIR(inode->i_mode)) {
     216      [ #  #  # ]:          0 :                 switch(type) {
     217                 :            :                 case ACL_TYPE_ACCESS:
     218                 :          0 :                         alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT);
     219         [ #  # ]:          0 :                         if (IS_ERR(alloc))
     220                 :            :                                 goto fail;
     221                 :            :                         break;
     222                 :            : 
     223                 :            :                 case ACL_TYPE_DEFAULT:
     224                 :            :                         dfacl = acl;
     225                 :          0 :                         alloc = acl = get_acl(inode, ACL_TYPE_ACCESS);
     226         [ #  # ]:          0 :                         if (IS_ERR(alloc))
     227                 :            :                                 goto fail;
     228                 :            :                         break;
     229                 :            :                 }
     230                 :            :         }
     231                 :            : 
     232         [ #  # ]:          0 :         if (acl == NULL) {
     233                 :          0 :                 alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
     234         [ #  # ]:          0 :                 if (IS_ERR(alloc))
     235                 :            :                         goto fail;
     236                 :            :         }
     237                 :          0 :         status = __nfs3_proc_setacls(inode, acl, dfacl);
     238                 :            :         posix_acl_release(alloc);
     239                 :          0 :         return status;
     240                 :            : 
     241                 :            : fail:
     242                 :          0 :         return PTR_ERR(alloc);
     243                 :            : }
     244                 :            : 
     245                 :            : const struct xattr_handler *nfs3_xattr_handlers[] = {
     246                 :            :         &posix_acl_access_xattr_handler,
     247                 :            :         &posix_acl_default_xattr_handler,
     248                 :            :         NULL,
     249                 :            : };

Generated by: LCOV version 1.9