aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xattr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 20:11:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 20:11:47 -0500
commit33caf82acf4dc420bf0f0136b886f7b27ecf90c5 (patch)
treeb24b0b5c8f257ae7db3b8df939821a0856869895 /fs/xattr.c
parentca9706a282943899981e83604f2ed13e88ce4239 (diff)
parentbbddca8e8fac07ece3938e03526b5d00fa791a4c (diff)
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro: "All kinds of stuff. That probably should've been 5 or 6 separate branches, but by the time I'd realized how large and mixed that bag had become it had been too close to -final to play with rebasing. Some fs/namei.c cleanups there, memdup_user_nul() introduction and switching open-coded instances, burying long-dead code, whack-a-mole of various kinds, several new helpers for ->llseek(), assorted cleanups and fixes from various people, etc. One piece probably deserves special mention - Neil's lookup_one_len_unlocked(). Similar to lookup_one_len(), but gets called without ->i_mutex and tries to avoid ever taking it. That, of course, means that it's not useful for any directory modifications, but things like getting inode attributes in nfds readdirplus are fine with that. I really should've asked for moratorium on lookup-related changes this cycle, but since I hadn't done that early enough... I *am* asking for that for the coming cycle, though - I'm going to try and get conversion of i_mutex to rwsem with ->lookup() done under lock taken shared. There will be a patch closer to the end of the window, along the lines of the one Linus had posted last May - mechanical conversion of ->i_mutex accesses to inode_lock()/inode_unlock()/inode_trylock()/ inode_is_locked()/inode_lock_nested(). To quote Linus back then: ----- | This is an automated patch using | | sed 's/mutex_lock(&\(.*\)->i_mutex)/inode_lock(\1)/' | sed 's/mutex_unlock(&\(.*\)->i_mutex)/inode_unlock(\1)/' | sed 's/mutex_lock_nested(&\(.*\)->i_mutex,[ ]*I_MUTEX_\([A-Z0-9_]*\))/inode_lock_nested(\1, I_MUTEX_\2)/' | sed 's/mutex_is_locked(&\(.*\)->i_mutex)/inode_is_locked(\1)/' | sed 's/mutex_trylock(&\(.*\)->i_mutex)/inode_trylock(\1)/' | | with a very few manual fixups ----- I'm going to send that once the ->i_mutex-affecting stuff in -next gets mostly merged (or when Linus says he's about to stop taking merges)" * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits) nfsd: don't hold i_mutex over userspace upcalls fs:affs:Replace time_t with time64_t fs/9p: use fscache mutex rather than spinlock proc: add a reschedule point in proc_readfd_common() logfs: constify logfs_block_ops structures fcntl: allow to set O_DIRECT flag on pipe fs: __generic_file_splice_read retry lookup on AOP_TRUNCATED_PAGE fs: xattr: Use kvfree() [s390] page_to_phys() always returns a multiple of PAGE_SIZE nbd: use ->compat_ioctl() fs: use block_device name vsprintf helper lib/vsprintf: add %*pg format specifier fs: use gendisk->disk_name where possible poll: plug an unused argument to do_poll amdkfd: don't open-code memdup_user() cdrom: don't open-code memdup_user() rsxx: don't open-code memdup_user() mtip32xx: don't open-code memdup_user() [um] mconsole: don't open-code memdup_user_nul() [um] hostaudio: don't open-code memdup_user() ...
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c38
1 files changed, 14 insertions, 24 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index d7f5037a17b5..d5dd6c8b82a7 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -305,7 +305,6 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
305{ 305{
306 int error; 306 int error;
307 void *kvalue = NULL; 307 void *kvalue = NULL;
308 void *vvalue = NULL; /* If non-NULL, we used vmalloc() */
309 char kname[XATTR_NAME_MAX + 1]; 308 char kname[XATTR_NAME_MAX + 1];
310 309
311 if (flags & ~(XATTR_CREATE|XATTR_REPLACE)) 310 if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
@@ -322,10 +321,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
322 return -E2BIG; 321 return -E2BIG;
323 kvalue = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); 322 kvalue = kmalloc(size, GFP_KERNEL | __GFP_NOWARN);
324 if (!kvalue) { 323 if (!kvalue) {
325 vvalue = vmalloc(size); 324 kvalue = vmalloc(size);
326 if (!vvalue) 325 if (!kvalue)
327 return -ENOMEM; 326 return -ENOMEM;
328 kvalue = vvalue;
329 } 327 }
330 if (copy_from_user(kvalue, value, size)) { 328 if (copy_from_user(kvalue, value, size)) {
331 error = -EFAULT; 329 error = -EFAULT;
@@ -338,10 +336,8 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
338 336
339 error = vfs_setxattr(d, kname, kvalue, size, flags); 337 error = vfs_setxattr(d, kname, kvalue, size, flags);
340out: 338out:
341 if (vvalue) 339 kvfree(kvalue);
342 vfree(vvalue); 340
343 else
344 kfree(kvalue);
345 return error; 341 return error;
346} 342}
347 343
@@ -409,7 +405,6 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
409{ 405{
410 ssize_t error; 406 ssize_t error;
411 void *kvalue = NULL; 407 void *kvalue = NULL;
412 void *vvalue = NULL;
413 char kname[XATTR_NAME_MAX + 1]; 408 char kname[XATTR_NAME_MAX + 1];
414 409
415 error = strncpy_from_user(kname, name, sizeof(kname)); 410 error = strncpy_from_user(kname, name, sizeof(kname));
@@ -423,10 +418,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
423 size = XATTR_SIZE_MAX; 418 size = XATTR_SIZE_MAX;
424 kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); 419 kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
425 if (!kvalue) { 420 if (!kvalue) {
426 vvalue = vmalloc(size); 421 kvalue = vmalloc(size);
427 if (!vvalue) 422 if (!kvalue)
428 return -ENOMEM; 423 return -ENOMEM;
429 kvalue = vvalue;
430 } 424 }
431 } 425 }
432 426
@@ -442,10 +436,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
442 than XATTR_SIZE_MAX bytes. Not possible. */ 436 than XATTR_SIZE_MAX bytes. Not possible. */
443 error = -E2BIG; 437 error = -E2BIG;
444 } 438 }
445 if (vvalue) 439
446 vfree(vvalue); 440 kvfree(kvalue);
447 else 441
448 kfree(kvalue);
449 return error; 442 return error;
450} 443}
451 444
@@ -502,17 +495,15 @@ listxattr(struct dentry *d, char __user *list, size_t size)
502{ 495{
503 ssize_t error; 496 ssize_t error;
504 char *klist = NULL; 497 char *klist = NULL;
505 char *vlist = NULL; /* If non-NULL, we used vmalloc() */
506 498
507 if (size) { 499 if (size) {
508 if (size > XATTR_LIST_MAX) 500 if (size > XATTR_LIST_MAX)
509 size = XATTR_LIST_MAX; 501 size = XATTR_LIST_MAX;
510 klist = kmalloc(size, __GFP_NOWARN | GFP_KERNEL); 502 klist = kmalloc(size, __GFP_NOWARN | GFP_KERNEL);
511 if (!klist) { 503 if (!klist) {
512 vlist = vmalloc(size); 504 klist = vmalloc(size);
513 if (!vlist) 505 if (!klist)
514 return -ENOMEM; 506 return -ENOMEM;
515 klist = vlist;
516 } 507 }
517 } 508 }
518 509
@@ -525,10 +516,9 @@ listxattr(struct dentry *d, char __user *list, size_t size)
525 than XATTR_LIST_MAX bytes. Not possible. */ 516 than XATTR_LIST_MAX bytes. Not possible. */
526 error = -E2BIG; 517 error = -E2BIG;
527 } 518 }
528 if (vlist) 519
529 vfree(vlist); 520 kvfree(klist);
530 else 521
531 kfree(klist);
532 return error; 522 return error;
533} 523}
534 524