[PATCH] nfs: Get lock context by fl_owner/fl_pid when unlocking file

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

 



Whan a file unlocking is cuased by 'Ctrl + C', the current->files is NULL,
so that, nfs_get_lock_context always create a new lock context in do_unlk().

A new helper nfs_get_lock_context_by_owner requests the owner and pid
for searching and creating lock context.

Ps: I'm not sure it's needed in ->flush logical.

Signed-off-by: Kinglong Mee <kinglongmee@xxxxxxxxx>
---
 fs/nfs/file.c          |  3 ++-
 fs/nfs/inode.c         | 37 ++++++++++++++++++++++++++-----------
 include/linux/nfs_fs.h |  2 ++
 3 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index cc4fa1e..85e01c7 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -774,7 +774,8 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
 	 */
 	vfs_fsync(filp, 0);
 
-	l_ctx = nfs_get_lock_context(nfs_file_open_context(filp));
+	l_ctx = nfs_get_lock_context_by_owner(nfs_file_open_context(filp),
+					      fl->fl_owner, fl->fl_pid);
 	if (!IS_ERR(l_ctx)) {
 		status = nfs_iocounter_wait(&l_ctx->io_count);
 		nfs_put_lock_context(l_ctx);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 0adc7d2..cbc1256 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -688,24 +688,26 @@ out:
 }
 EXPORT_SYMBOL_GPL(nfs_getattr);
 
-static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
+static void nfs_init_lock_context(struct nfs_lock_context *l_ctx,
+				  fl_owner_t owner, pid_t pid)
 {
 	atomic_set(&l_ctx->count, 1);
-	l_ctx->lockowner.l_owner = current->files;
-	l_ctx->lockowner.l_pid = current->tgid;
+	l_ctx->lockowner.l_owner = owner;
+	l_ctx->lockowner.l_pid = pid;
 	INIT_LIST_HEAD(&l_ctx->list);
 	nfs_iocounter_init(&l_ctx->io_count);
 }
 
-static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx)
+static struct nfs_lock_context *
+__nfs_find_lock_context(struct nfs_open_context *ctx, fl_owner_t owner, pid_t pid)
 {
 	struct nfs_lock_context *head = &ctx->lock_context;
 	struct nfs_lock_context *pos = head;
 
 	do {
-		if (pos->lockowner.l_owner != current->files)
+		if (pos->lockowner.l_owner != owner)
 			continue;
-		if (pos->lockowner.l_pid != current->tgid)
+		if (pos->lockowner.l_pid != pid)
 			continue;
 		atomic_inc(&pos->count);
 		return pos;
@@ -713,21 +715,22 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context
 	return NULL;
 }
 
-struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
+static struct nfs_lock_context *
+__nfs_get_lock_context(struct nfs_open_context *ctx, fl_owner_t owner, pid_t pid)
 {
 	struct nfs_lock_context *res, *new = NULL;
 	struct inode *inode = d_inode(ctx->dentry);
 
 	spin_lock(&inode->i_lock);
-	res = __nfs_find_lock_context(ctx);
+	res = __nfs_find_lock_context(ctx, owner, pid);
 	if (res == NULL) {
 		spin_unlock(&inode->i_lock);
 		new = kmalloc(sizeof(*new), GFP_KERNEL);
 		if (new == NULL)
 			return ERR_PTR(-ENOMEM);
-		nfs_init_lock_context(new);
+		nfs_init_lock_context(new, owner, pid);
 		spin_lock(&inode->i_lock);
-		res = __nfs_find_lock_context(ctx);
+		res = __nfs_find_lock_context(ctx, owner, pid);
 		if (res == NULL) {
 			list_add_tail(&new->list, &ctx->lock_context.list);
 			new->open_context = ctx;
@@ -739,8 +742,20 @@ struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
 	kfree(new);
 	return res;
 }
+
+struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
+{
+	return __nfs_get_lock_context(ctx, current->files, current->tgid);
+}
 EXPORT_SYMBOL_GPL(nfs_get_lock_context);
 
+struct nfs_lock_context *
+nfs_get_lock_context_by_owner(struct nfs_open_context *ctx, fl_owner_t owner, pid_t pid)
+{
+	return __nfs_get_lock_context(ctx, owner, pid);
+}
+EXPORT_SYMBOL_GPL(nfs_get_lock_context_by_owner);
+
 void nfs_put_lock_context(struct nfs_lock_context *l_ctx)
 {
 	struct nfs_open_context *ctx = l_ctx->open_context;
@@ -800,7 +815,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f
 	ctx->mode = f_mode;
 	ctx->flags = 0;
 	ctx->error = 0;
-	nfs_init_lock_context(&ctx->lock_context);
+	nfs_init_lock_context(&ctx->lock_context, current->files, current->tgid);
 	ctx->lock_context.open_context = ctx;
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->mdsthreshold = NULL;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 874b772..a13c16e5 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -372,6 +372,8 @@ extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fm
 extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx);
 extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
 extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx);
+extern struct nfs_lock_context *nfs_get_lock_context_by_owner(
+		struct nfs_open_context *ctx, fl_owner_t owner, pid_t pid);
 extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx);
 extern u64 nfs_compat_user_ino64(u64 fileid);
 extern void nfs_fattr_init(struct nfs_fattr *fattr);
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux