Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2785
b: refs/heads/master
c: 5c6a9f7
h: refs/heads/master
i:
  2783: 4891d46
v: v3
  • Loading branch information
Andreas Gruenbacher authored and Trond Myklebust committed Jun 22, 2005
1 parent 6c3ec6c commit 6c3434f
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 055ffbea0596942579b0dae71d5dab78de8135f6
refs/heads/master: 5c6a9f7d92291c832d47e792ed1fafa44acb066e
100 changes: 85 additions & 15 deletions trunk/fs/nfs/nfs3acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,69 @@ int nfs3_removexattr(struct dentry *dentry, const char *name)
return nfs3_proc_setacl(inode, type, NULL);
}

static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi)
{
if (nfsi->acl_access != ERR_PTR(-EAGAIN)) {
posix_acl_release(nfsi->acl_access);
nfsi->acl_access = ERR_PTR(-EAGAIN);
}
if (nfsi->acl_default != ERR_PTR(-EAGAIN)) {
posix_acl_release(nfsi->acl_default);
nfsi->acl_default = ERR_PTR(-EAGAIN);
}
}

void nfs3_forget_cached_acls(struct inode *inode)
{
dprintk("NFS: nfs3_forget_cached_acls(%s/%ld)\n", inode->i_sb->s_id,
inode->i_ino);
spin_lock(&inode->i_lock);
__nfs3_forget_cached_acls(NFS_I(inode));
spin_unlock(&inode->i_lock);
}

static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type)
{
struct nfs_inode *nfsi = NFS_I(inode);
struct posix_acl *acl = ERR_PTR(-EAGAIN);

spin_lock(&inode->i_lock);
switch(type) {
case ACL_TYPE_ACCESS:
acl = nfsi->acl_access;
break;

case ACL_TYPE_DEFAULT:
acl = nfsi->acl_default;
break;

default:
return ERR_PTR(-EINVAL);
}
if (acl == ERR_PTR(-EAGAIN))
acl = ERR_PTR(-EAGAIN);
else
acl = posix_acl_dup(acl);
spin_unlock(&inode->i_lock);
dprintk("NFS: nfs3_get_cached_acl(%s/%ld, %d) = %p\n", inode->i_sb->s_id,
inode->i_ino, type, acl);
return acl;
}

static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
struct posix_acl *dfacl)
{
struct nfs_inode *nfsi = NFS_I(inode);

dprintk("nfs3_cache_acls(%s/%ld, %p, %p)\n", inode->i_sb->s_id,
inode->i_ino, acl, dfacl);
spin_lock(&inode->i_lock);
__nfs3_forget_cached_acls(NFS_I(inode));
nfsi->acl_access = posix_acl_dup(acl);
nfsi->acl_default = posix_acl_dup(dfacl);
spin_unlock(&inode->i_lock);
}

struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
{
struct nfs_server *server = NFS_SERVER(inode);
Expand All @@ -126,26 +189,32 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
struct nfs3_getaclres res = {
.fattr = &fattr,
};
struct posix_acl *acl = NULL;
struct posix_acl *acl;
int status, count;

if (!nfs_server_capable(inode, NFS_CAP_ACLS))
return ERR_PTR(-EOPNOTSUPP);

switch (type) {
case ACL_TYPE_ACCESS:
args.mask = NFS_ACLCNT|NFS_ACL;
break;

case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode))
return NULL;
args.mask = NFS_DFACLCNT|NFS_DFACL;
break;

default:
return ERR_PTR(-EINVAL);
}
status = nfs_revalidate_inode(server, inode);
if (status < 0)
return ERR_PTR(status);
acl = nfs3_get_cached_acl(inode, type);
if (acl != ERR_PTR(-EAGAIN))
return acl;
acl = NULL;

/*
* Only get the access acl when explicitly requested: We don't
* need it for access decisions, and only some applications use
* it. Applications which request the access acl first are not
* penalized from this optimization.
*/
if (type == ACL_TYPE_ACCESS)
args.mask |= NFS_ACLCNT|NFS_ACL;
if (S_ISDIR(inode->i_mode))
args.mask |= NFS_DFACLCNT|NFS_DFACL;
if (args.mask == 0)
return NULL;

dprintk("NFS call getacl\n");
status = rpc_call(server->client_acl, ACLPROC3_GETACL,
Expand Down Expand Up @@ -180,6 +249,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
res.acl_access = NULL;
}
}
nfs3_cache_acls(inode, res.acl_access, res.acl_default);

switch(type) {
case ACL_TYPE_ACCESS:
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/nfs/nfs3proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,4 +882,5 @@ struct nfs_rpc_ops nfs_v3_clientops = {
.file_open = nfs_open,
.file_release = nfs_release,
.lock = nfs3_proc_lock,
.clear_acl_cache = nfs3_forget_cached_acls,
};
11 changes: 11 additions & 0 deletions trunk/include/linux/nfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ struct nfs_open_context {
*/
struct nfs_delegation;

struct posix_acl;

/*
* nfs fs inode data in memory
*/
Expand Down Expand Up @@ -144,6 +146,10 @@ struct nfs_inode {
atomic_t data_updates;

struct nfs_access_entry cache_access;
#ifdef CONFIG_NFS_V3_ACL
struct posix_acl *acl_access;
struct posix_acl *acl_default;
#endif

/*
* This is the cookie verifier used for NFSv3 readdir
Expand Down Expand Up @@ -480,13 +486,18 @@ extern int nfs3_proc_setacl(struct inode *inode, int type,
struct posix_acl *acl);
extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
mode_t mode);
extern void nfs3_forget_cached_acls(struct inode *inode);
#else
static inline int nfs3_proc_set_default_acl(struct inode *dir,
struct inode *inode,
mode_t mode)
{
return 0;
}

static inline void nfs3_forget_cached_acls(struct inode *inode)
{
}
#endif /* CONFIG_NFS_V3_ACL */

/*
Expand Down

0 comments on commit 6c3434f

Please sign in to comment.