Re: [PATCH 2/5 v3] locks: Copy all infomation for conflock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 8/18/2014 19:54, Jeff Layton wrote:
> On Sun, 17 Aug 2014 21:42:21 +0800
> Kinglong Mee <kinglongmee@xxxxxxxxx> wrote:
> 
>> On 8/16/2014 21:35, Kinglong Mee wrote:
>>> On 8/15/2014 22:33, Kinglong Mee wrote:
>>>> On 8/15/2014 19:14, Jeff Layton wrote:
>>>>> On Fri, 15 Aug 2014 08:07:12 +0800
>>>>> Kinglong Mee <kinglongmee@xxxxxxxxx> wrote:
>>>>>
>>>>>> Commit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using
>>>>>> fl_lmops field in file_lock for checking nfsd4 lockowner.
>>>>>>
>>>>>> But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return
>>>>>> of conflicting locks) causes the fl_lmops of conflock always be NULL.
>>>>>>
>>>>>> Also, commit 0996905f93 (lockd: posix_test_lock() should not call
>>>>>> locks_copy_lock()) caused the fl_lmops of conflock always be NULL too.
>>>>>>
>>>>>> Make sure copy the private information by fl_copy_lock() in struct
>>>>>> file_lock_operations, merge __locks_copy_lock() to fl_copy_lock().
>>>>>>
>>>>>> v3: Update based on Joe and Jeff's patch.
>>>>>>
>>>>>> Signed-off-by: Kinglong Mee <kinglongmee@xxxxxxxxx>
>>>>>> ---
>>>>>>  fs/locks.c         | 24 +++++++-----------------
>>>>>>  include/linux/fs.h |  6 ------
>>>>>>  2 files changed, 7 insertions(+), 23 deletions(-)
>>>>>>
>>>>>> diff --git a/fs/locks.c b/fs/locks.c
>>>>>> index cb66fb0..fe52abb 100644
>>>>>> --- a/fs/locks.c
>>>>>> +++ b/fs/locks.c
>>>>>> @@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
>>>>>>  /*
>>>>>>   * Initialize a new lock from an existing file_lock structure.
>>>>>>   */
>>>>>> -void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
>>>>>> +void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
>>>>>>  {
>>>>>> +	/* "new" must be a freshly-initialized lock */
>>>>>> +	WARN_ON_ONCE(new->fl_ops);
>>>>>> +
>>>>>>  	new->fl_owner = fl->fl_owner;
>>>>>>  	new->fl_pid = fl->fl_pid;
>>>>>> -	new->fl_file = NULL;
>>>>>> +	new->fl_file = fl->fl_file;
>>>>>>  	new->fl_flags = fl->fl_flags;
>>>>>>  	new->fl_type = fl->fl_type;
>>>>>>  	new->fl_start = fl->fl_start;
>>>>>>  	new->fl_end = fl->fl_end;
>>>>>>  	new->fl_ops = NULL;
>>>>>>  	new->fl_lmops = NULL;
>>>>>> -}
>>>>>> -EXPORT_SYMBOL(__locks_copy_lock);
>>>>>> -
>>>>>> -void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
>>>>>> -{
>>>>>> -	/* "new" must be a freshly-initialized lock */
>>>>>> -	WARN_ON_ONCE(new->fl_ops);
>>>>>> -
>>>>>> -	__locks_copy_lock(new, fl);
>>>>>> -	new->fl_file = fl->fl_file;
>>>>>> -	new->fl_ops = fl->fl_ops;
>>>>>> -	new->fl_lmops = fl->fl_lmops;
>>>>>>  
>>>>>>  	locks_copy_private(new, fl);
>>>>>>  }
>>>>>> -
>>>>>>  EXPORT_SYMBOL(locks_copy_lock);
>>>>>>  
>>>>>>  static inline int flock_translate_cmd(int cmd) {
>>>>>> @@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
>>>>>>  			break;
>>>>>>  	}
>>>>>>  	if (cfl) {
>>>>>> -		__locks_copy_lock(fl, cfl);
>>>>>> +		locks_copy_lock(fl, cfl);
>>>>>>  		if (cfl->fl_nspid)
>>>>>>  			fl->fl_pid = pid_vnr(cfl->fl_nspid);
>>>>>>  	} else
>>>>>> @@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
>>>>>>  			if (!posix_locks_conflict(request, fl))
>>>>>>  				continue;
>>>>>>  			if (conflock)
>>>>>> -				__locks_copy_lock(conflock, fl);
>>>>>> +				locks_copy_lock(conflock, fl);
>>>>>>  			error = -EAGAIN;
>>>>>>  			if (!(request->fl_flags & FL_SLEEP))
>>>>>>  				goto out;
>>>>>> diff --git a/include/linux/fs.h b/include/linux/fs.h
>>>>>> index 908af4f..a383a30 100644
>>>>>> --- a/include/linux/fs.h
>>>>>> +++ b/include/linux/fs.h
>>>>>> @@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);
>>>>>>  extern void locks_init_lock(struct file_lock *);
>>>>>>  extern struct file_lock * locks_alloc_lock(void);
>>>>>>  extern void locks_copy_lock(struct file_lock *, struct file_lock *);
>>>>>> -extern void __locks_copy_lock(struct file_lock *, const struct file_lock *);
>>>>>>  extern void locks_remove_posix(struct file *, fl_owner_t);
>>>>>>  extern void locks_remove_file(struct file *);
>>>>>>  extern void locks_release_private(struct file_lock *);
>>>>>> @@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)
>>>>>>  	return;
>>>>>>  }
>>>>>>  
>>>>>> -static inline void __locks_copy_lock(struct file_lock *new, struct file_lock *fl)
>>>>>> -{
>>>>>> -	return;
>>>>>> -}
>>>>>> -
>>>>>>  static inline void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
>>>>>>  {
>>>>>>  	return;
>>>>>
>>>>> I'm not sure this is really what you want to do. Calling fl_copy_lock
>>>>> for a conflock looks relatively harmless for nfs and nlm. AFS though
>>>>> seems to add the lock to a list associated with the inode. That seems a
>>>>> little suspicious for a conflock and could be problematic. It may be
>>>>> best to avoid dealing with fl_ops for a conflock.
>>>>>
>>>>> Also in the case of fcntl_getlk, the struct file_lock lives on the
>>>>> stack, and locks_release_private is never called on it. You'll need to
>>>>> audit all of the current callers of __locks_copy_lock to ensure that
>>>>> any resources you end up taking references on when copying the conflock
>>>>> are eventually released.
>>>>
>>>> Sorry for my no further think about it.
>>>> I will check that again next day.
>>>
>>> I think we should not change the logical of coping lock,
>>> leave fl_ops and fl_lmops as private data as right now.
> 
> Why not? I think we'd benefit from making conflock creation a more
> distinct operation.
> 
>>>
>>> I have plan to,
>>> 1. move fl_owner assign from __locks_copy_lock() to locks_copy_private(),
>>>    I think it should be a private data, am I right?
>>> 2. call locks_copy_private() coping private data specifically.
>>>    a. add an argument for posix_test_lock() and __posix_lock_file() and etc,
>>>       to point whether coping private data.
>>>    b. hack the conflock's fl_flags to do the same thing as a,
>>>       adds FL_NEED_PRIV fl_flags only valid for conflock.
>>>
>>> I don't think 2.a is a nice resolve, because it changes the interface
>>> and many caller don't care the private data (I think contains fl_owner)
>>> for conflock except nfsd.
>>>
>>> So, I'd like *2.b*. A draft is appended as following,
>>
>> I'm so sorry for the first draft, there is a bug of it.
>> Please using the new draft.
>>
>> thanks,
>> Kinglong Mee
>>
> 
> Personally, I'm not a fan of the approach below. I don't think we need
> a new flag for this and it doesn't do anything to solve the problem
> where the lockowner could go away while you're operating on it in a
> conflock.

I just want fix the bug with minimal code change.
But, I known my fault now.

> 
> I think we need several smaller changes:
> 
> 1. Right now __locks_copy_lock is only used to copy conflocks. It would
> be good to rename that to something more distinct (i.e.
> locks_copy_conflock), to make it clear that we're generating a conflock
> there.
> 
> 2. Set fl_lmops on conflocks, but don't set fl_ops. fl_ops are
> superfluous, since they are callbacks into the filesystem. There should
> be no need to bother the filesystem at all with info in a conflock.
> But, lock _ownership_ matters for conflocks and that's indicated by the
> fl_lmops. So you really do want to copy the fl_lmops for conflocks I
> think.
> 
> 3. Add the operations you added before to fl_lmops to copy and release
> the owner (maybe even rename them lm_get_owner/lm_put_owner?), and
> ensure that the places that copy conflocks call those operations
> appropriately.
> 
> That should be all that's required here.

I think I know what you are advice.
I will send an update patch as v4.

thanks,
Kinglong Mee
--
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




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux