From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoph Hellwig Subject: Re: [PATCH]: nfsd: more vfs_getxattr Date: Mon, 7 Nov 2005 13:03:10 +0100 Message-ID: <20051107120310.GA24101@lst.de> References: <20051107053657.GA18278@lst.de> <20051106222143.765bdb18.akpm@osdl.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Christoph Hellwig , neilb@cse.unsw.edu.au, linux-fsdevel@vger.kernel.org Return-path: Received: from verein.lst.de ([213.95.11.210]:53992 "EHLO mail.lst.de") by vger.kernel.org with ESMTP id S1751351AbVKGMDX (ORCPT ); Mon, 7 Nov 2005 07:03:23 -0500 To: Andrew Morton Content-Disposition: inline In-Reply-To: <20051106222143.765bdb18.akpm@osdl.org> Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org On Sun, Nov 06, 2005 at 10:21:43PM -0800, Andrew Morton wrote: > Christoph Hellwig wrote: > > > > looks like I missed NFSv4 previously. > > When sending fixes for earlier patches, it greatly helps if you can > identify which patch it is that needs fixing. Usually it's obvious, but in > this case it's not. vfs_getxattr was introduced in [PATCH 1/8] add vfs_* helpers for xattr operations but at that point it was just a cleanup. it only became mandatory in later patches to remove xattr checks in the filesystems. > > > + *buf = kmalloc(buflen, GFP_KERNEL); > > + if (!buf) > > + return -ENOMEM; > > That's obviously broken. Fixed one below: Index: linux-2.6/fs/nfsd/vfs.c =================================================================== --- linux-2.6.orig/fs/nfsd/vfs.c 2005-11-06 22:25:55.000000000 +0100 +++ linux-2.6/fs/nfsd/vfs.c 2005-11-07 04:22:05.000000000 +0100 @@ -358,8 +358,30 @@ goto out; } -#if defined(CONFIG_NFSD_V4) +#if defined(CONFIG_NFSD_V2_ACL) || \ + defined(CONFIG_NFSD_V3_ACL) || \ + defined(CONFIG_NFSD_V4) +static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) +{ + ssize_t buflen; + int error; + + buflen = vfs_getxattr(dentry, key, NULL, 0); + if (buflen <= 0) + return buflen; + + *buf = kmalloc(buflen, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + + error = vfs_getxattr(dentry, key, *buf, buflen); + if (error < 0) + return error; + return buflen; +} +#endif +#if defined(CONFIG_NFSD_V4) static int set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) { @@ -439,30 +461,17 @@ static struct posix_acl * _get_posix_acl(struct dentry *dentry, char *key) { - char *buf = NULL; - int buflen, error = 0; + void *buf = NULL; struct posix_acl *pacl = NULL; + int buflen; - buflen = vfs_getxattr(dentry, key, NULL, 0); - if (buflen <= 0) { - pacl = ERR_PTR(buflen < 0 ? buflen : -ENODATA); - goto out; - } - - buf = kmalloc(buflen, GFP_KERNEL); - if (buf == NULL) { - pacl = ERR_PTR(-ENOMEM); - goto out; - } - - error = vfs_getxattr(dentry, key, buf, buflen); - if (error < 0) { - pacl = ERR_PTR(error); - goto out; - } + buflen = nfsd_getxattr(dentry, key, &buf); + if (!buflen) + buflen = -ENODATA; + if (buflen <= 0) + return ERR_PTR(buflen); pacl = posix_acl_from_xattr(buf, buflen); - out: kfree(buf); return pacl; } @@ -1846,39 +1855,25 @@ ssize_t size; struct posix_acl *acl; - if (!IS_POSIXACL(inode) || !inode->i_op || !inode->i_op->getxattr) + if (!IS_POSIXACL(inode)) + return ERR_PTR(-EOPNOTSUPP); + + switch (type) { + case ACL_TYPE_ACCESS: + name = POSIX_ACL_XATTR_ACCESS; + break; + case ACL_TYPE_DEFAULT: + name = POSIX_ACL_XATTR_DEFAULT; + break; + default: return ERR_PTR(-EOPNOTSUPP); - switch(type) { - case ACL_TYPE_ACCESS: - name = POSIX_ACL_XATTR_ACCESS; - break; - case ACL_TYPE_DEFAULT: - name = POSIX_ACL_XATTR_DEFAULT; - break; - default: - return ERR_PTR(-EOPNOTSUPP); } - size = inode->i_op->getxattr(fhp->fh_dentry, name, NULL, 0); + size = nfsd_getxattr(fhp->fh_dentry, name, &value); + if (size < 0) + return ERR_PTR(size); - if (size < 0) { - acl = ERR_PTR(size); - goto getout; - } else if (size > 0) { - value = kmalloc(size, GFP_KERNEL); - if (!value) { - acl = ERR_PTR(-ENOMEM); - goto getout; - } - size = inode->i_op->getxattr(fhp->fh_dentry, name, value, size); - if (size < 0) { - acl = ERR_PTR(size); - goto getout; - } - } acl = posix_acl_from_xattr(value, size); - -getout: kfree(value); return acl; }