diff options
-rw-r--r-- | fs/nfs/dir.c | 8 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 7 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 62 | ||||
-rw-r--r-- | fs/nfs/super.c | 4 |
4 files changed, 44 insertions, 37 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 6ceedc7b98da..65d5cb4f70b1 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/kmemleak.h> | 37 | #include <linux/kmemleak.h> |
38 | #include <linux/xattr.h> | ||
38 | 39 | ||
39 | #include "delegation.h" | 40 | #include "delegation.h" |
40 | #include "iostat.h" | 41 | #include "iostat.h" |
@@ -125,9 +126,10 @@ const struct inode_operations nfs4_dir_inode_operations = { | |||
125 | .permission = nfs_permission, | 126 | .permission = nfs_permission, |
126 | .getattr = nfs_getattr, | 127 | .getattr = nfs_getattr, |
127 | .setattr = nfs_setattr, | 128 | .setattr = nfs_setattr, |
128 | .getxattr = nfs4_getxattr, | 129 | .getxattr = generic_getxattr, |
129 | .setxattr = nfs4_setxattr, | 130 | .setxattr = generic_setxattr, |
130 | .listxattr = nfs4_listxattr, | 131 | .listxattr = generic_listxattr, |
132 | .removexattr = generic_removexattr, | ||
131 | }; | 133 | }; |
132 | 134 | ||
133 | #endif /* CONFIG_NFS_V4 */ | 135 | #endif /* CONFIG_NFS_V4 */ |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 7a6eecffcaeb..3b3829c3098f 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -227,12 +227,6 @@ struct nfs4_state_maintenance_ops { | |||
227 | extern const struct dentry_operations nfs4_dentry_operations; | 227 | extern const struct dentry_operations nfs4_dentry_operations; |
228 | extern const struct inode_operations nfs4_dir_inode_operations; | 228 | extern const struct inode_operations nfs4_dir_inode_operations; |
229 | 229 | ||
230 | /* inode.c */ | ||
231 | extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t); | ||
232 | extern int nfs4_setxattr(struct dentry *, const char *, const void *, size_t, int); | ||
233 | extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t); | ||
234 | |||
235 | |||
236 | /* nfs4proc.c */ | 230 | /* nfs4proc.c */ |
237 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); | 231 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); |
238 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); | 232 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); |
@@ -246,6 +240,7 @@ extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fh | |||
246 | extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | 240 | extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, |
247 | struct nfs4_fs_locations *fs_locations, struct page *page); | 241 | struct nfs4_fs_locations *fs_locations, struct page *page); |
248 | extern void nfs4_release_lockowner(const struct nfs4_lock_state *); | 242 | extern void nfs4_release_lockowner(const struct nfs4_lock_state *); |
243 | extern const struct xattr_handler *nfs4_xattr_handlers[]; | ||
249 | 244 | ||
250 | #if defined(CONFIG_NFS_V4_1) | 245 | #if defined(CONFIG_NFS_V4_1) |
251 | static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server) | 246 | static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ca88f294f0af..82f3a82b7115 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/mount.h> | 49 | #include <linux/mount.h> |
50 | #include <linux/module.h> | 50 | #include <linux/module.h> |
51 | #include <linux/sunrpc/bc_xprt.h> | 51 | #include <linux/sunrpc/bc_xprt.h> |
52 | #include <linux/xattr.h> | ||
52 | 53 | ||
53 | #include "nfs4_fs.h" | 54 | #include "nfs4_fs.h" |
54 | #include "delegation.h" | 55 | #include "delegation.h" |
@@ -4403,42 +4404,36 @@ void nfs4_release_lockowner(const struct nfs4_lock_state *lsp) | |||
4403 | 4404 | ||
4404 | #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" | 4405 | #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" |
4405 | 4406 | ||
4406 | int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf, | 4407 | static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, |
4407 | size_t buflen, int flags) | 4408 | const void *buf, size_t buflen, |
4409 | int flags, int type) | ||
4408 | { | 4410 | { |
4409 | struct inode *inode = dentry->d_inode; | 4411 | if (strcmp(key, "") != 0) |
4410 | 4412 | return -EINVAL; | |
4411 | if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0) | ||
4412 | return -EOPNOTSUPP; | ||
4413 | 4413 | ||
4414 | return nfs4_proc_set_acl(inode, buf, buflen); | 4414 | return nfs4_proc_set_acl(dentry->d_inode, buf, buflen); |
4415 | } | 4415 | } |
4416 | 4416 | ||
4417 | /* The getxattr man page suggests returning -ENODATA for unknown attributes, | 4417 | static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, |
4418 | * and that's what we'll do for e.g. user attributes that haven't been set. | 4418 | void *buf, size_t buflen, int type) |
4419 | * But we'll follow ext2/ext3's lead by returning -EOPNOTSUPP for unsupported | ||
4420 | * attributes in kernel-managed attribute namespaces. */ | ||
4421 | ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf, | ||
4422 | size_t buflen) | ||
4423 | { | 4419 | { |
4424 | struct inode *inode = dentry->d_inode; | 4420 | if (strcmp(key, "") != 0) |
4425 | 4421 | return -EINVAL; | |
4426 | if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0) | ||
4427 | return -EOPNOTSUPP; | ||
4428 | 4422 | ||
4429 | return nfs4_proc_get_acl(inode, buf, buflen); | 4423 | return nfs4_proc_get_acl(dentry->d_inode, buf, buflen); |
4430 | } | 4424 | } |
4431 | 4425 | ||
4432 | ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen) | 4426 | static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, |
4427 | size_t list_len, const char *name, | ||
4428 | size_t name_len, int type) | ||
4433 | { | 4429 | { |
4434 | size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1; | 4430 | size_t len = sizeof(XATTR_NAME_NFSV4_ACL); |
4435 | 4431 | ||
4436 | if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode))) | 4432 | if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode))) |
4437 | return 0; | 4433 | return 0; |
4438 | if (buf && buflen < len) | 4434 | |
4439 | return -ERANGE; | 4435 | if (list && len <= list_len) |
4440 | if (buf) | 4436 | memcpy(list, XATTR_NAME_NFSV4_ACL, len); |
4441 | memcpy(buf, XATTR_NAME_NFSV4_ACL, len); | ||
4442 | return len; | 4437 | return len; |
4443 | } | 4438 | } |
4444 | 4439 | ||
@@ -5509,9 +5504,10 @@ static const struct inode_operations nfs4_file_inode_operations = { | |||
5509 | .permission = nfs_permission, | 5504 | .permission = nfs_permission, |
5510 | .getattr = nfs_getattr, | 5505 | .getattr = nfs_getattr, |
5511 | .setattr = nfs_setattr, | 5506 | .setattr = nfs_setattr, |
5512 | .getxattr = nfs4_getxattr, | 5507 | .getxattr = generic_getxattr, |
5513 | .setxattr = nfs4_setxattr, | 5508 | .setxattr = generic_setxattr, |
5514 | .listxattr = nfs4_listxattr, | 5509 | .listxattr = generic_listxattr, |
5510 | .removexattr = generic_removexattr, | ||
5515 | }; | 5511 | }; |
5516 | 5512 | ||
5517 | const struct nfs_rpc_ops nfs_v4_clientops = { | 5513 | const struct nfs_rpc_ops nfs_v4_clientops = { |
@@ -5556,6 +5552,18 @@ const struct nfs_rpc_ops nfs_v4_clientops = { | |||
5556 | .open_context = nfs4_atomic_open, | 5552 | .open_context = nfs4_atomic_open, |
5557 | }; | 5553 | }; |
5558 | 5554 | ||
5555 | static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { | ||
5556 | .prefix = XATTR_NAME_NFSV4_ACL, | ||
5557 | .list = nfs4_xattr_list_nfs4_acl, | ||
5558 | .get = nfs4_xattr_get_nfs4_acl, | ||
5559 | .set = nfs4_xattr_set_nfs4_acl, | ||
5560 | }; | ||
5561 | |||
5562 | const struct xattr_handler *nfs4_xattr_handlers[] = { | ||
5563 | &nfs4_xattr_nfs4_acl_handler, | ||
5564 | NULL | ||
5565 | }; | ||
5566 | |||
5559 | /* | 5567 | /* |
5560 | * Local variables: | 5568 | * Local variables: |
5561 | * c-basic-offset: 8 | 5569 | * c-basic-offset: 8 |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 001f9cb2804b..0f9ea73e7789 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2501,7 +2501,8 @@ static void nfs4_clone_super(struct super_block *sb, | |||
2501 | * so ourselves when necessary. | 2501 | * so ourselves when necessary. |
2502 | */ | 2502 | */ |
2503 | sb->s_flags |= MS_POSIXACL; | 2503 | sb->s_flags |= MS_POSIXACL; |
2504 | nfs_initialise_sb(sb); | 2504 | sb->s_xattr = old_sb->s_xattr; |
2505 | nfs_initialise_sb(sb); | ||
2505 | } | 2506 | } |
2506 | 2507 | ||
2507 | /* | 2508 | /* |
@@ -2516,6 +2517,7 @@ static void nfs4_fill_super(struct super_block *sb) | |||
2516 | * so ourselves when necessary. | 2517 | * so ourselves when necessary. |
2517 | */ | 2518 | */ |
2518 | sb->s_flags |= MS_POSIXACL; | 2519 | sb->s_flags |= MS_POSIXACL; |
2520 | sb->s_xattr = nfs4_xattr_handlers; | ||
2519 | nfs_initialise_sb(sb); | 2521 | nfs_initialise_sb(sb); |
2520 | } | 2522 | } |
2521 | 2523 | ||