Skip to content

Commit b7fa055

Browse files
Andreas GruenbacherTrond Myklebust
Andreas Gruenbacher
authored and
Trond Myklebust
committed
[PATCH] NFS: Add support for NFSv3 ACLs
This adds acl support fo nfs clients via the NFSACL protocol extension, by implementing the getxattr, listxattr, setxattr, and removexattr iops for the system.posix_acl_access and system.posix_acl_default attributes. This patch implements a dumb version that uses no caching (and thus adds some overhead). (Another patch in this patchset adds caching as well.) Signed-off-by: Andreas Gruenbacher <[email protected]> Acked-by: Olaf Kirch <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent a257cdd commit b7fa055

13 files changed

+601
-6
lines changed

fs/Kconfig

+11
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,7 @@ config NFS_FS
12681268
depends on INET
12691269
select LOCKD
12701270
select SUNRPC
1271+
select NFS_ACL_SUPPORT if NFS_V3_ACL
12711272
help
12721273
If you are connected to some other (usually local) Unix computer
12731274
(using SLIP, PLIP, PPP or Ethernet) and want to mount files residing
@@ -1310,6 +1311,16 @@ config NFS_V3
13101311

13111312
If unsure, say Y.
13121313

1314+
config NFS_V3_ACL
1315+
bool "Provide client support for the NFSv3 ACL protocol extension"
1316+
depends on NFS_V3
1317+
help
1318+
Implement the NFSv3 ACL protocol extension for manipulating POSIX
1319+
Access Control Lists. The server should also be compiled with
1320+
the NFSv3 ACL protocol extension; see the CONFIG_NFSD_V3_ACL option.
1321+
1322+
If unsure, say N.
1323+
13131324
config NFS_V4
13141325
bool "Provide NFSv4 client support (EXPERIMENTAL)"
13151326
depends on NFS_FS && EXPERIMENTAL

fs/nfs/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ nfs-y := dir.o file.o inode.o nfs2xdr.o pagelist.o \
88
proc.o read.o symlink.o unlink.o write.o
99
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o
1010
nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
11+
nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
1112
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
1213
delegation.o idmap.o \
1314
callback.o callback_xdr.o callback_proc.o

fs/nfs/dir.c

+21
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ struct inode_operations nfs_dir_inode_operations = {
7575
.setattr = nfs_setattr,
7676
};
7777

78+
#ifdef CONFIG_NFS_V3
79+
struct inode_operations nfs3_dir_inode_operations = {
80+
.create = nfs_create,
81+
.lookup = nfs_lookup,
82+
.link = nfs_link,
83+
.unlink = nfs_unlink,
84+
.symlink = nfs_symlink,
85+
.mkdir = nfs_mkdir,
86+
.rmdir = nfs_rmdir,
87+
.mknod = nfs_mknod,
88+
.rename = nfs_rename,
89+
.permission = nfs_permission,
90+
.getattr = nfs_getattr,
91+
.setattr = nfs_setattr,
92+
.listxattr = nfs3_listxattr,
93+
.getxattr = nfs3_getxattr,
94+
.setxattr = nfs3_setxattr,
95+
.removexattr = nfs3_removexattr,
96+
};
97+
#endif /* CONFIG_NFS_V3 */
98+
7899
#ifdef CONFIG_NFS_V4
79100

80101
static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);

fs/nfs/file.c

+12
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ struct inode_operations nfs_file_inode_operations = {
7171
.setattr = nfs_setattr,
7272
};
7373

74+
#ifdef CONFIG_NFS_V3
75+
struct inode_operations nfs3_file_inode_operations = {
76+
.permission = nfs_permission,
77+
.getattr = nfs_getattr,
78+
.setattr = nfs_setattr,
79+
.listxattr = nfs3_listxattr,
80+
.getxattr = nfs3_getxattr,
81+
.setxattr = nfs3_setxattr,
82+
.removexattr = nfs3_removexattr,
83+
};
84+
#endif /* CONFIG_NFS_v3 */
85+
7486
/* Hack for future NFS swap support */
7587
#ifndef IS_SWAPFILE
7688
# define IS_SWAPFILE(inode) (0)

fs/nfs/inode.c

+33-3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,21 @@ static struct rpc_program nfs_program = {
108108
.pipe_dir_name = "/nfs",
109109
};
110110

111+
#ifdef CONFIG_NFS_V3_ACL
112+
static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
113+
static struct rpc_version * nfsacl_version[] = {
114+
[3] = &nfsacl_version3,
115+
};
116+
117+
struct rpc_program nfsacl_program = {
118+
.name = "nfsacl",
119+
.number = NFS_ACL_PROGRAM,
120+
.nrvers = sizeof(nfsacl_version) / sizeof(nfsacl_version[0]),
121+
.version = nfsacl_version,
122+
.stats = &nfsacl_rpcstat,
123+
};
124+
#endif /* CONFIG_NFS_V3_ACL */
125+
111126
static inline unsigned long
112127
nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
113128
{
@@ -165,6 +180,9 @@ nfs_umount_begin(struct super_block *sb)
165180
/* -EIO all pending I/O */
166181
if (!IS_ERR(rpc))
167182
rpc_killall_tasks(rpc);
183+
rpc = NFS_SB(sb)->client_acl;
184+
if (!IS_ERR(rpc))
185+
rpc_killall_tasks(rpc);
168186
}
169187

170188

@@ -461,8 +479,17 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
461479
atomic_inc(&server->client->cl_count);
462480
server->client_sys = server->client;
463481
}
464-
465482
if (server->flags & NFS_MOUNT_VER3) {
483+
#ifdef CONFIG_NFS_V3_ACL
484+
if (!(server->flags & NFS_MOUNT_NOACL)) {
485+
server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
486+
/* No errors! Assume that Sun nfsacls are supported */
487+
if (!IS_ERR(server->client_acl))
488+
server->caps |= NFS_CAP_ACLS;
489+
}
490+
#else
491+
server->flags &= ~NFS_MOUNT_NOACL;
492+
#endif /* CONFIG_NFS_V3_ACL */
466493
if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
467494
server->namelen = NFS3_MAXNAMLEN;
468495
sb->s_time_gran = 1;
@@ -546,6 +573,7 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
546573
{ NFS_MOUNT_NOCTO, ",nocto", "" },
547574
{ NFS_MOUNT_NOAC, ",noac", "" },
548575
{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
576+
{ NFS_MOUNT_NOACL, ",noacl", "" },
549577
{ 0, NULL, NULL }
550578
};
551579
struct proc_nfs_info *nfs_infop;
@@ -1452,7 +1480,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
14521480
memset(server, 0, sizeof(struct nfs_server));
14531481
/* Zero out the NFS state stuff */
14541482
init_nfsv4_state(server);
1455-
server->client = server->client_sys = ERR_PTR(-EINVAL);
1483+
server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
14561484

14571485
root = &server->fh;
14581486
if (data->flags & NFS_MOUNT_VER3)
@@ -1513,6 +1541,8 @@ static void nfs_kill_super(struct super_block *s)
15131541
rpc_shutdown_client(server->client);
15141542
if (!IS_ERR(server->client_sys))
15151543
rpc_shutdown_client(server->client_sys);
1544+
if (!IS_ERR(server->client_acl))
1545+
rpc_shutdown_client(server->client_acl);
15161546

15171547
if (!(server->flags & NFS_MOUNT_NONLM))
15181548
lockd_down(); /* release rpc.lockd */
@@ -1794,7 +1824,7 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
17941824
memset(server, 0, sizeof(struct nfs_server));
17951825
/* Zero out the NFS state stuff */
17961826
init_nfsv4_state(server);
1797-
server->client = server->client_sys = ERR_PTR(-EINVAL);
1827+
server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
17981828

17991829
p = nfs_copy_user_string(NULL, &data->hostname, 256);
18001830
if (IS_ERR(p))

0 commit comments

Comments
 (0)