aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/eventpoll.c12
-rw-r--r--fs/fcntl.c33
-rw-r--r--fs/file_table.c1
-rw-r--r--fs/ioctl.c18
-rw-r--r--fs/nfsd/vfs.c5
-rw-r--r--fs/pipe.c16
6 files changed, 39 insertions, 46 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 011b9b8c90c6..c5c424f23fd5 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -417,10 +417,10 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
417 ep_unregister_pollwait(ep, epi); 417 ep_unregister_pollwait(ep, epi);
418 418
419 /* Remove the current item from the list of epoll hooks */ 419 /* Remove the current item from the list of epoll hooks */
420 spin_lock(&file->f_ep_lock); 420 spin_lock(&file->f_lock);
421 if (ep_is_linked(&epi->fllink)) 421 if (ep_is_linked(&epi->fllink))
422 list_del_init(&epi->fllink); 422 list_del_init(&epi->fllink);
423 spin_unlock(&file->f_ep_lock); 423 spin_unlock(&file->f_lock);
424 424
425 rb_erase(&epi->rbn, &ep->rbr); 425 rb_erase(&epi->rbn, &ep->rbr);
426 426
@@ -538,7 +538,7 @@ void eventpoll_release_file(struct file *file)
538 struct epitem *epi; 538 struct epitem *epi;
539 539
540 /* 540 /*
541 * We don't want to get "file->f_ep_lock" because it is not 541 * We don't want to get "file->f_lock" because it is not
542 * necessary. It is not necessary because we're in the "struct file" 542 * necessary. It is not necessary because we're in the "struct file"
543 * cleanup path, and this means that noone is using this file anymore. 543 * cleanup path, and this means that noone is using this file anymore.
544 * So, for example, epoll_ctl() cannot hit here sicne if we reach this 544 * So, for example, epoll_ctl() cannot hit here sicne if we reach this
@@ -547,6 +547,8 @@ void eventpoll_release_file(struct file *file)
547 * will correctly serialize the operation. We do need to acquire 547 * will correctly serialize the operation. We do need to acquire
548 * "ep->mtx" after "epmutex" because ep_remove() requires it when called 548 * "ep->mtx" after "epmutex" because ep_remove() requires it when called
549 * from anywhere but ep_free(). 549 * from anywhere but ep_free().
550 *
551 * Besides, ep_remove() acquires the lock, so we can't hold it here.
550 */ 552 */
551 mutex_lock(&epmutex); 553 mutex_lock(&epmutex);
552 554
@@ -785,9 +787,9 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
785 goto error_unregister; 787 goto error_unregister;
786 788
787 /* Add the current item to the list of active epoll hook for this file */ 789 /* Add the current item to the list of active epoll hook for this file */
788 spin_lock(&tfile->f_ep_lock); 790 spin_lock(&tfile->f_lock);
789 list_add_tail(&epi->fllink, &tfile->f_ep_links); 791 list_add_tail(&epi->fllink, &tfile->f_ep_links);
790 spin_unlock(&tfile->f_ep_lock); 792 spin_unlock(&tfile->f_lock);
791 793
792 /* 794 /*
793 * Add the current item to the RB tree. All RB tree operations are 795 * Add the current item to the RB tree. All RB tree operations are
diff --git a/fs/fcntl.c b/fs/fcntl.c
index bd215cc791da..d865ca66ccba 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -141,7 +141,7 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes)
141 return ret; 141 return ret;
142} 142}
143 143
144#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME) 144#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
145 145
146static int setfl(int fd, struct file * filp, unsigned long arg) 146static int setfl(int fd, struct file * filp, unsigned long arg)
147{ 147{
@@ -177,21 +177,21 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
177 return error; 177 return error;
178 178
179 /* 179 /*
180 * We still need a lock here for now to keep multiple FASYNC calls 180 * ->fasync() is responsible for setting the FASYNC bit.
181 * from racing with each other.
182 */ 181 */
183 lock_kernel(); 182 if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op &&
184 if ((arg ^ filp->f_flags) & FASYNC) { 183 filp->f_op->fasync) {
185 if (filp->f_op && filp->f_op->fasync) { 184 error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
186 error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); 185 if (error < 0)
187 if (error < 0) 186 goto out;
188 goto out; 187 if (error > 0)
189 } 188 error = 0;
190 } 189 }
191 190 spin_lock(&filp->f_lock);
192 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); 191 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
192 spin_unlock(&filp->f_lock);
193
193 out: 194 out:
194 unlock_kernel();
195 return error; 195 return error;
196} 196}
197 197
@@ -516,7 +516,7 @@ static DEFINE_RWLOCK(fasync_lock);
516static struct kmem_cache *fasync_cache __read_mostly; 516static struct kmem_cache *fasync_cache __read_mostly;
517 517
518/* 518/*
519 * fasync_helper() is used by some character device drivers (mainly mice) 519 * fasync_helper() is used by almost all character device drivers
520 * to set up the fasync queue. It returns negative on error, 0 if it did 520 * to set up the fasync queue. It returns negative on error, 0 if it did
521 * no changes and positive if it added/deleted the entry. 521 * no changes and positive if it added/deleted the entry.
522 */ 522 */
@@ -555,6 +555,13 @@ int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fap
555 result = 1; 555 result = 1;
556 } 556 }
557out: 557out:
558 /* Fix up FASYNC bit while still holding fasync_lock */
559 spin_lock(&filp->f_lock);
560 if (on)
561 filp->f_flags |= FASYNC;
562 else
563 filp->f_flags &= ~FASYNC;
564 spin_unlock(&filp->f_lock);
558 write_unlock_irq(&fasync_lock); 565 write_unlock_irq(&fasync_lock);
559 return result; 566 return result;
560} 567}
diff --git a/fs/file_table.c b/fs/file_table.c
index da806aceae3f..b74a8e1da913 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -128,6 +128,7 @@ struct file *get_empty_filp(void)
128 atomic_long_set(&f->f_count, 1); 128 atomic_long_set(&f->f_count, 1);
129 rwlock_init(&f->f_owner.lock); 129 rwlock_init(&f->f_owner.lock);
130 f->f_cred = get_cred(cred); 130 f->f_cred = get_cred(cred);
131 spin_lock_init(&f->f_lock);
131 eventpoll_init_file(f); 132 eventpoll_init_file(f);
132 /* f->f_version: 0 */ 133 /* f->f_version: 0 */
133 return f; 134 return f;
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 240ec63984cb..ac2d47e43926 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -404,10 +404,12 @@ static int ioctl_fionbio(struct file *filp, int __user *argp)
404 if (O_NONBLOCK != O_NDELAY) 404 if (O_NONBLOCK != O_NDELAY)
405 flag |= O_NDELAY; 405 flag |= O_NDELAY;
406#endif 406#endif
407 spin_lock(&filp->f_lock);
407 if (on) 408 if (on)
408 filp->f_flags |= flag; 409 filp->f_flags |= flag;
409 else 410 else
410 filp->f_flags &= ~flag; 411 filp->f_flags &= ~flag;
412 spin_unlock(&filp->f_lock);
411 return error; 413 return error;
412} 414}
413 415
@@ -425,18 +427,12 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp,
425 /* Did FASYNC state change ? */ 427 /* Did FASYNC state change ? */
426 if ((flag ^ filp->f_flags) & FASYNC) { 428 if ((flag ^ filp->f_flags) & FASYNC) {
427 if (filp->f_op && filp->f_op->fasync) 429 if (filp->f_op && filp->f_op->fasync)
430 /* fasync() adjusts filp->f_flags */
428 error = filp->f_op->fasync(fd, filp, on); 431 error = filp->f_op->fasync(fd, filp, on);
429 else 432 else
430 error = -ENOTTY; 433 error = -ENOTTY;
431 } 434 }
432 if (error) 435 return error < 0 ? error : 0;
433 return error;
434
435 if (on)
436 filp->f_flags |= FASYNC;
437 else
438 filp->f_flags &= ~FASYNC;
439 return error;
440} 436}
441 437
442static int ioctl_fsfreeze(struct file *filp) 438static int ioctl_fsfreeze(struct file *filp)
@@ -499,17 +495,11 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
499 break; 495 break;
500 496
501 case FIONBIO: 497 case FIONBIO:
502 /* BKL needed to avoid races tweaking f_flags */
503 lock_kernel();
504 error = ioctl_fionbio(filp, argp); 498 error = ioctl_fionbio(filp, argp);
505 unlock_kernel();
506 break; 499 break;
507 500
508 case FIOASYNC: 501 case FIOASYNC:
509 /* BKL needed to avoid races tweaking f_flags */
510 lock_kernel();
511 error = ioctl_fioasync(fd, filp, argp); 502 error = ioctl_fioasync(fd, filp, argp);
512 unlock_kernel();
513 break; 503 break;
514 504
515 case FIOQSIZE: 505 case FIOQSIZE:
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 6e50aaa56ca2..c165a6403df0 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -998,8 +998,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
998 998
999 if (!EX_ISSYNC(exp)) 999 if (!EX_ISSYNC(exp))
1000 stable = 0; 1000 stable = 0;
1001 if (stable && !EX_WGATHER(exp)) 1001 if (stable && !EX_WGATHER(exp)) {
1002 spin_lock(&file->f_lock);
1002 file->f_flags |= O_SYNC; 1003 file->f_flags |= O_SYNC;
1004 spin_unlock(&file->f_lock);
1005 }
1003 1006
1004 /* Write the data. */ 1007 /* Write the data. */
1005 oldfs = get_fs(); set_fs(KERNEL_DS); 1008 oldfs = get_fs(); set_fs(KERNEL_DS);
diff --git a/fs/pipe.c b/fs/pipe.c
index 14f502b89cf5..94ad15967cf9 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -667,10 +667,7 @@ pipe_read_fasync(int fd, struct file *filp, int on)
667 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); 667 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers);
668 mutex_unlock(&inode->i_mutex); 668 mutex_unlock(&inode->i_mutex);
669 669
670 if (retval < 0) 670 return retval;
671 return retval;
672
673 return 0;
674} 671}
675 672
676 673
@@ -684,10 +681,7 @@ pipe_write_fasync(int fd, struct file *filp, int on)
684 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); 681 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers);
685 mutex_unlock(&inode->i_mutex); 682 mutex_unlock(&inode->i_mutex);
686 683
687 if (retval < 0) 684 return retval;
688 return retval;
689
690 return 0;
691} 685}
692 686
693 687
@@ -706,11 +700,7 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on)
706 fasync_helper(-1, filp, 0, &pipe->fasync_readers); 700 fasync_helper(-1, filp, 0, &pipe->fasync_readers);
707 } 701 }
708 mutex_unlock(&inode->i_mutex); 702 mutex_unlock(&inode->i_mutex);
709 703 return retval;
710 if (retval < 0)
711 return retval;
712
713 return 0;
714} 704}
715 705
716 706