@@ -282,6 +282,8 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
if (fl->fl_lmops) {
if (fl->fl_lmops->lm_copy_owner)
fl->fl_lmops->lm_copy_owner(new, fl);
+ else
+ new->fl_owner = fl->fl_owner;
new->fl_lmops = fl->fl_lmops;
}
}
@@ -291,7 +293,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
*/
void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
{
- new->fl_owner = fl->fl_owner;
+ new->fl_owner = NULL;
new->fl_pid = fl->fl_pid;
new->fl_file = NULL;
new->fl_flags = fl->fl_flags;
@@ -734,6 +736,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
{
struct file_lock *cfl;
struct inode *inode = file_inode(filp);
+ bool need_priv = !!(fl->fl_flags & FL_NEED_PRIV);
spin_lock(&inode->i_lock);
for (cfl = file_inode(filp)->i_flock; cfl; cfl = cfl->fl_next) {
@@ -746,6 +749,8 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
__locks_copy_lock(fl, cfl);
if (cfl->fl_nspid)
fl->fl_pid = pid_vnr(cfl->fl_nspid);
+ if (need_priv)
+ locks_copy_private(fl, cfl);
} else
fl->fl_type = F_UNLCK;
spin_unlock(&inode->i_lock);
@@ -919,7 +924,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
struct file_lock *right = NULL;
struct file_lock **before;
int error;
- bool added = false;
+ bool added = false, need_priv = false;
LIST_HEAD(dispose);
/*
@@ -948,8 +953,12 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
continue;
if (!posix_locks_conflict(request, fl))
continue;
- if (conflock)
+ if (conflock) {
+ need_priv = !!(conflock->fl_flags & FL_NEED_PRIV);
__locks_copy_lock(conflock, fl);
+ if (need_priv)
+ locks_copy_private(conflock, fl);
+ }
error = -EAGAIN;
if (!(request->fl_flags & FL_SLEEP))
goto out;
@@ -5275,6 +5275,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
}
+ conflock->fl_flags = FL_NEED_PRIV;
err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
switch (-err) {
case 0: /* success! */
@@ -5396,7 +5397,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (lo)
file_lock->fl_owner = (fl_owner_t)lo;
file_lock->fl_pid = current->tgid;
- file_lock->fl_flags = FL_POSIX;
+ file_lock->fl_flags = FL_POSIX | FL_NEED_PRIV;
file_lock->fl_start = lockt->lt_offset;
file_lock->fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length);
@@ -844,6 +844,7 @@ static inline struct file *get_file(struct file *f)
#define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */
#define FL_UNLOCK_PENDING 512 /* Lease is being broken */
#define FL_OFDLCK 1024 /* lock is "owned" by struct file */
+#define FL_NEED_PRIV 2048 /* Need copy private data from conflock */
/*
* Special return value from posix_lock_file() and vfs_lock_file() for