On Mon, Jan 14, 2008 at 09:29:39PM -0700, Matthew Wilcox wrote: > > Reduce the spaghetti-like nature of flock_lock_file by making the chunk > of code labelled find_conflict into its own function. Also allocate > memory before taking the kernel lock in preparation for switching to a > normal spinlock. If we did those two steps separately, would the result be two simpler patches? > > Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxxxx> > > diff --git a/fs/locks.c b/fs/locks.c > index b681459..bc691e5 100644 > --- a/fs/locks.c > +++ b/fs/locks.c > @@ -699,6 +699,33 @@ next_task: > return 0; > } > > +/* > + * A helper function for flock_lock_file(). It searches the list of locks > + * for @inode looking for one which would conflict with @request. > + * If it does not find one, it returns the address where the requested lock > + * should be inserted. If it does find a conflicting lock, it returns NULL. > + */ The return value is the reverse of what I'd naively expect--I don't expect something named flock_find_conflict to return something exactly when conflict is *not* found, but I don't see a better way to do it. Perhaps there's a better name? --b. > +static struct file_lock ** > +flock_find_conflict(struct inode *inode, struct file_lock *request) > +{ > + struct file_lock **before; > + > + for_each_lock(inode, before) { > + struct file_lock *fl = *before; > + if (IS_POSIX(fl)) > + break; > + if (IS_LEASE(fl)) > + continue; > + if (!flock_locks_conflict(request, fl)) > + continue; > + > + if (request->fl_flags & FL_SLEEP) > + locks_insert_block(fl, request); > + return NULL; > + } > + return before; > +} > + > /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks > * after any leases, but before any posix locks. > * > @@ -714,18 +741,21 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) > int error = 0; > int found = 0; > > - lock_kernel(); > - if (request->fl_flags & FL_ACCESS) > - goto find_conflict; > + if (request->fl_flags & FL_ACCESS) { > + lock_kernel(); > + before = flock_find_conflict(inode, request); > + unlock_kernel(); > + return before ? 0 : -EAGAIN; > + } > > if (request->fl_type != F_UNLCK) { > - error = -ENOMEM; > new_fl = locks_alloc_lock(); > - if (new_fl == NULL) > - goto out; > - error = 0; > + if (!new_fl) > + return -ENOMEM; > } > > + lock_kernel(); > + > for_each_lock(inode, before) { > struct file_lock *fl = *before; > if (IS_POSIX(fl)) > @@ -754,22 +784,12 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) > if (found) > cond_resched(); > > -find_conflict: > - for_each_lock(inode, before) { > - struct file_lock *fl = *before; > - if (IS_POSIX(fl)) > - break; > - if (IS_LEASE(fl)) > - continue; > - if (!flock_locks_conflict(request, fl)) > - continue; > + before = flock_find_conflict(inode, request); > + if (!before) { > error = -EAGAIN; > - if (request->fl_flags & FL_SLEEP) > - locks_insert_block(fl, request); > goto out; > } > - if (request->fl_flags & FL_ACCESS) > - goto out; > + > locks_copy_lock(new_fl, request); > locks_insert_lock(before, new_fl); > new_fl = NULL; > -- > Intel are signing my paycheques ... these opinions are still mine > "Bill, look, we understand that you're interested in selling us this > operating system, but compare it to ours. We can't possibly take such > a retrograde step." - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html