Skip to content

Commit 22b620e

Browse files
committed
NFSD: Clean up xattr memory allocation flags
Tetsuo Handa points out: > Since GFP_KERNEL is "GFP_NOFS | __GFP_FS", usage like > "GFP_KERNEL | GFP_NOFS" does not make sense. The original intent was to hold the inode lock while estimating the buffer requirements for the requested information. Frank van der Linden, the author of NFSD's xattr code, says: > ... you need inode_lock to get an atomic view of an xattr. Since > both nfsd_getxattr and nfsd_listxattr to the standard trick of > querying the xattr length with a NULL buf argument (just getting > the length back), allocating the right buffer size, and then > querying again, they need to hold the inode lock to avoid having > the xattr changed from under them while doing that. > > From that then flows the requirement that GFP_FS could cause > problems while holding i_rwsem, so I added GFP_NOFS. However, Dave Chinner states: > You can do GFP_KERNEL allocations holding the i_rwsem just fine. > All that it requires is the caller holds a reference to the > inode ... Since these code paths acquire a dentry, they do indeed hold a reference. It is therefore safe to use GFP_KERNEL for these memory allocations. In particular, that's what this code is already doing; but now the C source code looks sane too. At a later time we can revisit in order to remove the inode lock in favor of simply retrying if the estimated buffer size is too small. Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 147abca commit 22b620e

1 file changed

Lines changed: 2 additions & 5 deletions

File tree

fs/nfsd/vfs.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,7 +2168,7 @@ nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name,
21682168
goto out;
21692169
}
21702170

2171-
buf = kvmalloc(len, GFP_KERNEL | GFP_NOFS);
2171+
buf = kvmalloc(len, GFP_KERNEL);
21722172
if (buf == NULL) {
21732173
err = nfserr_jukebox;
21742174
goto out;
@@ -2231,10 +2231,7 @@ nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char **bufp,
22312231
goto out;
22322232
}
22332233

2234-
/*
2235-
* We're holding i_rwsem - use GFP_NOFS.
2236-
*/
2237-
buf = kvmalloc(len, GFP_KERNEL | GFP_NOFS);
2234+
buf = kvmalloc(len, GFP_KERNEL);
22382235
if (buf == NULL) {
22392236
err = nfserr_jukebox;
22402237
goto out;

0 commit comments

Comments
 (0)