From aa69947399a119d7f1b35bbcd62c849839b35449 Mon Sep 17 00:00:00 2001 From: Stanislav Kinsbursky Date: Wed, 8 Dec 2010 12:40:13 +0300 Subject: NFS: suppressing showing of default mount port value in /proc fixed Update: added check for zero value as it was before (note: can't simply check mountd_port for positive value because it's typeof unsigned short) Default value for mount server port is set to NFS_UNSPEC_PORT (-1) and will not be changed during parsing mount options for mound data version 6. This default value will be showed for mountport in /proc/mounts always since current default check is for zero value. This small mistake leads to big problem, because during umount.nfs execution from old user-space utils (at least nfs-utils 1.0.9) this value will be used as the server port to connect to. This request will be rejected (since port is 65535) and thus nfs mount point can't be unmounted. Note from Chuck Lever (chuck.lever@oracle.com): this is only possible if /etc/mtab is a link to /proc/mounts. Not all systems have this configuration. Signed-off-by: Stanislav Kinsbursky Signed-off-by: Trond Myklebust --- fs/nfs/super.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/nfs/super.c') diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 4100630c9a5..dd56eec16ea 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -598,7 +598,9 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, if (nfss->mountd_version || showdefaults) seq_printf(m, ",mountvers=%u", nfss->mountd_version); - if (nfss->mountd_port || showdefaults) + if ((nfss->mountd_port && + nfss->mountd_port != (unsigned short)NFS_UNSPEC_PORT) || + showdefaults) seq_printf(m, ",mountport=%u", nfss->mountd_port); nfs_show_mountd_netid(m, nfss, showdefaults); -- cgit v1.2.3-70-g09d2 From a8a5da996df7d2d91b5aef2752da9adcefea4bc6 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Thu, 9 Dec 2010 11:35:14 +0000 Subject: nfs: Set MS_POSIXACL always We want to skip VFS applying mode for NFS. So set MS_POSIXACL always and selectively use umask. Ideally we would want to use umask only when we don't have inheritable ACEs set. But NFS currently don't allow to send umask to the server. So this is best what we can do and this is consistent with NFSv3 Signed-off-by: Aneesh Kumar K.V Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 3 +-- fs/nfs/nfs4proc.c | 5 +++++ fs/nfs/super.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'fs/nfs/super.c') diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 831d61c4449..6ceedc7b98d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1352,8 +1352,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry if (nd->flags & LOOKUP_CREATE) { attr.ia_mode = nd->intent.open.create_mode; attr.ia_valid = ATTR_MODE; - if (!IS_POSIXACL(dir)) - attr.ia_mode &= ~current_umask(); + attr.ia_mode &= ~current_umask(); } else { open_flags &= ~(O_EXCL | O_CREAT); attr.ia_valid = 0; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 78b08993a38..ca88f294f0a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2486,6 +2486,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, path = &ctx->path; fmode = ctx->mode; } + sattr->ia_mode &= ~current_umask(); state = nfs4_do_open(dir, path, fmode, flags, sattr, cred); d_drop(dentry); if (IS_ERR(state)) { @@ -2816,6 +2817,8 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, { struct nfs4_exception exception = { }; int err; + + sattr->ia_mode &= ~current_umask(); do { err = nfs4_handle_exception(NFS_SERVER(dir), _nfs4_proc_mkdir(dir, dentry, sattr), @@ -2916,6 +2919,8 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, { struct nfs4_exception exception = { }; int err; + + sattr->ia_mode &= ~current_umask(); do { err = nfs4_handle_exception(NFS_SERVER(dir), _nfs4_proc_mknod(dir, dentry, sattr, rdev), diff --git a/fs/nfs/super.c b/fs/nfs/super.c index dd56eec16ea..001f9cb2804 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2496,6 +2496,11 @@ static void nfs4_clone_super(struct super_block *sb, sb->s_maxbytes = old_sb->s_maxbytes; sb->s_time_gran = 1; sb->s_op = old_sb->s_op; + /* + * The VFS shouldn't apply the umask to mode bits. We will do + * so ourselves when necessary. + */ + sb->s_flags |= MS_POSIXACL; nfs_initialise_sb(sb); } @@ -2506,6 +2511,11 @@ static void nfs4_fill_super(struct super_block *sb) { sb->s_time_gran = 1; sb->s_op = &nfs4_sops; + /* + * The VFS shouldn't apply the umask to mode bits. We will do + * so ourselves when necessary. + */ + sb->s_flags |= MS_POSIXACL; nfs_initialise_sb(sb); } -- cgit v1.2.3-70-g09d2 From 64c2ce8b72eceec4030b04bca32d098b3d1431bb Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Thu, 9 Dec 2010 11:35:25 +0000 Subject: nfsv4: Switch to generic xattr handling code This patch make nfsv4 use the generic xattr handling code to get the nfsv4 acl. This will help us to add richacl support to nfsv4 in later patches Signed-off-by: Aneesh Kumar K.V Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 8 ++++--- fs/nfs/nfs4_fs.h | 7 +------ fs/nfs/nfs4proc.c | 62 +++++++++++++++++++++++++++++++------------------------ fs/nfs/super.c | 4 +++- 4 files changed, 44 insertions(+), 37 deletions(-) (limited to 'fs/nfs/super.c') diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 6ceedc7b98d..65d5cb4f70b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "delegation.h" #include "iostat.h" @@ -125,9 +126,10 @@ const struct inode_operations nfs4_dir_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, - .getxattr = nfs4_getxattr, - .setxattr = nfs4_setxattr, - .listxattr = nfs4_listxattr, + .getxattr = generic_getxattr, + .setxattr = generic_setxattr, + .listxattr = generic_listxattr, + .removexattr = generic_removexattr, }; #endif /* CONFIG_NFS_V4 */ diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 7a6eecffcae..3b3829c3098 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -227,12 +227,6 @@ struct nfs4_state_maintenance_ops { extern const struct dentry_operations nfs4_dentry_operations; extern const struct inode_operations nfs4_dir_inode_operations; -/* inode.c */ -extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t); -extern int nfs4_setxattr(struct dentry *, const char *, const void *, size_t, int); -extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t); - - /* nfs4proc.c */ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); 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 extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, struct nfs4_fs_locations *fs_locations, struct page *page); extern void nfs4_release_lockowner(const struct nfs4_lock_state *); +extern const struct xattr_handler *nfs4_xattr_handlers[]; #if defined(CONFIG_NFS_V4_1) 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 ca88f294f0a..82f3a82b711 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "nfs4_fs.h" #include "delegation.h" @@ -4403,42 +4404,36 @@ void nfs4_release_lockowner(const struct nfs4_lock_state *lsp) #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" -int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf, - size_t buflen, int flags) +static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, + const void *buf, size_t buflen, + int flags, int type) { - struct inode *inode = dentry->d_inode; - - if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0) - return -EOPNOTSUPP; + if (strcmp(key, "") != 0) + return -EINVAL; - return nfs4_proc_set_acl(inode, buf, buflen); + return nfs4_proc_set_acl(dentry->d_inode, buf, buflen); } -/* The getxattr man page suggests returning -ENODATA for unknown attributes, - * and that's what we'll do for e.g. user attributes that haven't been set. - * But we'll follow ext2/ext3's lead by returning -EOPNOTSUPP for unsupported - * attributes in kernel-managed attribute namespaces. */ -ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf, - size_t buflen) +static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, + void *buf, size_t buflen, int type) { - struct inode *inode = dentry->d_inode; - - if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0) - return -EOPNOTSUPP; + if (strcmp(key, "") != 0) + return -EINVAL; - return nfs4_proc_get_acl(inode, buf, buflen); + return nfs4_proc_get_acl(dentry->d_inode, buf, buflen); } -ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen) +static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, + size_t list_len, const char *name, + size_t name_len, int type) { - size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1; + size_t len = sizeof(XATTR_NAME_NFSV4_ACL); if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode))) return 0; - if (buf && buflen < len) - return -ERANGE; - if (buf) - memcpy(buf, XATTR_NAME_NFSV4_ACL, len); + + if (list && len <= list_len) + memcpy(list, XATTR_NAME_NFSV4_ACL, len); return len; } @@ -5509,9 +5504,10 @@ static const struct inode_operations nfs4_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, - .getxattr = nfs4_getxattr, - .setxattr = nfs4_setxattr, - .listxattr = nfs4_listxattr, + .getxattr = generic_getxattr, + .setxattr = generic_setxattr, + .listxattr = generic_listxattr, + .removexattr = generic_removexattr, }; const struct nfs_rpc_ops nfs_v4_clientops = { @@ -5556,6 +5552,18 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .open_context = nfs4_atomic_open, }; +static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { + .prefix = XATTR_NAME_NFSV4_ACL, + .list = nfs4_xattr_list_nfs4_acl, + .get = nfs4_xattr_get_nfs4_acl, + .set = nfs4_xattr_set_nfs4_acl, +}; + +const struct xattr_handler *nfs4_xattr_handlers[] = { + &nfs4_xattr_nfs4_acl_handler, + NULL +}; + /* * Local variables: * c-basic-offset: 8 diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 001f9cb2804..0f9ea73e778 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2501,7 +2501,8 @@ static void nfs4_clone_super(struct super_block *sb, * so ourselves when necessary. */ sb->s_flags |= MS_POSIXACL; - nfs_initialise_sb(sb); + sb->s_xattr = old_sb->s_xattr; + nfs_initialise_sb(sb); } /* @@ -2516,6 +2517,7 @@ static void nfs4_fill_super(struct super_block *sb) * so ourselves when necessary. */ sb->s_flags |= MS_POSIXACL; + sb->s_xattr = nfs4_xattr_handlers; nfs_initialise_sb(sb); } -- cgit v1.2.3-70-g09d2