summary refs log tree commit diff
path: root/fs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-11-02 15:27:52 +0000
committerDavid Howells <dhowells@redhat.com>2017-11-13 15:38:20 +0000
commit215804a99283c57fdd869aab350fdf6acc3460b6 (patch)
treea06a57ba4b15decbd079c0f9d17ca964280d570c /fs
parent83732ec5146916bd49b3036b0ea7dedb7831b90e (diff)
downloadlinux-215804a99283c57fdd869aab350fdf6acc3460b6.tar.gz
afs: Introduce a file-private data record
Introduce a file-private data record for kAFS and put the key into it
rather than storing the key in file->private_data.

Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/dir.c2
-rw-r--r--fs/afs/file.c39
-rw-r--r--fs/afs/flock.c10
-rw-r--r--fs/afs/inode.c2
-rw-r--r--fs/afs/internal.h14
-rw-r--r--fs/afs/write.c4
6 files changed, 51 insertions, 20 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index ecda0e6a9f7e..ab618d32554c 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -396,7 +396,7 @@ out:
  */
 static int afs_readdir(struct file *file, struct dir_context *ctx)
 {
-	return afs_dir_iterate(file_inode(file), ctx, file->private_data);
+	return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file));
 }
 
 /*
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 5786f68f87f1..e33b34f01795 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -68,6 +68,7 @@ const struct address_space_operations afs_fs_aops = {
 int afs_open(struct inode *inode, struct file *file)
 {
 	struct afs_vnode *vnode = AFS_FS_I(inode);
+	struct afs_file *af;
 	struct key *key;
 	int ret;
 
@@ -75,19 +76,32 @@ int afs_open(struct inode *inode, struct file *file)
 
 	key = afs_request_key(vnode->volume->cell);
 	if (IS_ERR(key)) {
-		_leave(" = %ld [key]", PTR_ERR(key));
-		return PTR_ERR(key);
+		ret = PTR_ERR(key);
+		goto error;
 	}
 
-	ret = afs_validate(vnode, key);
-	if (ret < 0) {
-		_leave(" = %d [val]", ret);
-		return ret;
+	af = kzalloc(sizeof(*af), GFP_KERNEL);
+	if (!af) {
+		ret = -ENOMEM;
+		goto error_key;
 	}
 
-	file->private_data = key;
+	ret = afs_validate(vnode, key);
+	if (ret < 0)
+		goto error_af;
+
+	af->key = key;
+	file->private_data = af;
 	_leave(" = 0");
 	return 0;
+
+error_af:
+	kfree(af);
+error_key:
+	key_put(key);
+error:
+	_leave(" = %d", ret);
+	return ret;
 }
 
 /*
@@ -96,10 +110,13 @@ int afs_open(struct inode *inode, struct file *file)
 int afs_release(struct inode *inode, struct file *file)
 {
 	struct afs_vnode *vnode = AFS_FS_I(inode);
+	struct afs_file *af = file->private_data;
 
 	_enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
 
-	key_put(file->private_data);
+	file->private_data = NULL;
+	key_put(af->key);
+	kfree(af);
 	_leave(" = 0");
 	return 0;
 }
@@ -295,7 +312,7 @@ static int afs_readpage(struct file *file, struct page *page)
 	int ret;
 
 	if (file) {
-		key = file->private_data;
+		key = afs_file_key(file);
 		ASSERT(key != NULL);
 		ret = afs_page_filler(key, page);
 	} else {
@@ -346,7 +363,7 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping,
 	struct afs_read *req;
 	struct list_head *p;
 	struct page *first, *page;
-	struct key *key = file->private_data;
+	struct key *key = afs_file_key(file);
 	pgoff_t index;
 	int ret, n, i;
 
@@ -442,7 +459,7 @@ error:
 static int afs_readpages(struct file *file, struct address_space *mapping,
 			 struct list_head *pages, unsigned nr_pages)
 {
-	struct key *key = file->private_data;
+	struct key *key = afs_file_key(file);
 	struct afs_vnode *vnode;
 	int ret = 0;
 
diff --git a/fs/afs/flock.c b/fs/afs/flock.c
index 77b0a4606efd..7571a5dfd5a3 100644
--- a/fs/afs/flock.c
+++ b/fs/afs/flock.c
@@ -206,7 +206,7 @@ void afs_lock_work(struct work_struct *work)
 			BUG();
 		fl = list_entry(vnode->granted_locks.next,
 				struct file_lock, fl_u.afs.link);
-		key = key_get(fl->fl_file->private_data);
+		key = key_get(afs_file_key(fl->fl_file));
 		spin_unlock(&vnode->lock);
 
 		ret = afs_extend_lock(vnode, key);
@@ -240,7 +240,7 @@ void afs_lock_work(struct work_struct *work)
 			BUG();
 		fl = list_entry(vnode->pending_locks.next,
 				struct file_lock, fl_u.afs.link);
-		key = key_get(fl->fl_file->private_data);
+		key = key_get(afs_file_key(fl->fl_file));
 		type = (fl->fl_type == F_RDLCK) ?
 			AFS_LOCK_READ : AFS_LOCK_WRITE;
 		spin_unlock(&vnode->lock);
@@ -318,7 +318,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)
 	struct inode *inode = file_inode(file);
 	struct afs_vnode *vnode = AFS_FS_I(inode);
 	afs_lock_type_t type;
-	struct key *key = file->private_data;
+	struct key *key = afs_file_key(file);
 	int ret;
 
 	_enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);
@@ -500,7 +500,7 @@ vfs_rejected_lock:
 static int afs_do_unlk(struct file *file, struct file_lock *fl)
 {
 	struct afs_vnode *vnode = AFS_FS_I(file->f_mapping->host);
-	struct key *key = file->private_data;
+	struct key *key = afs_file_key(file);
 	int ret;
 
 	_enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);
@@ -535,7 +535,7 @@ static int afs_do_unlk(struct file *file, struct file_lock *fl)
 static int afs_do_getlk(struct file *file, struct file_lock *fl)
 {
 	struct afs_vnode *vnode = AFS_FS_I(file->f_mapping->host);
-	struct key *key = file->private_data;
+	struct key *key = afs_file_key(file);
 	int ret, lock_count;
 
 	_enter("");
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 5a2f5854f349..da2ba7a68cac 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -520,7 +520,7 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr)
 	}
 
 	if (attr->ia_valid & ATTR_FILE) {
-		key = attr->ia_file->private_data;
+		key = afs_file_key(attr->ia_file);
 	} else {
 		key = afs_request_key(vnode->volume->cell);
 		if (IS_ERR(key)) {
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 6aa6e9957c44..facf5b9844d2 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -139,6 +139,20 @@ struct afs_call_type {
 };
 
 /*
+ * AFS open file information record.  Pointed to by file->private_data.
+ */
+struct afs_file {
+	struct key		*key;		/* The key this file was opened with */
+};
+
+static inline struct key *afs_file_key(struct file *file)
+{
+	struct afs_file *af = file->private_data;
+
+	return af->key;
+}
+
+/*
  * Record of an outstanding read operation on a vnode.
  */
 struct afs_read {
diff --git a/fs/afs/write.c b/fs/afs/write.c
index 1377a40ecdbb..1cdd0e3cd531 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -128,7 +128,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
 	struct afs_writeback *candidate, *wb;
 	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
 	struct page *page;
-	struct key *key = file->private_data;
+	struct key *key = afs_file_key(file);
 	unsigned from = pos & (PAGE_SIZE - 1);
 	unsigned to = from + len;
 	pgoff_t index = pos >> PAGE_SHIFT;
@@ -255,7 +255,7 @@ int afs_write_end(struct file *file, struct address_space *mapping,
 		  struct page *page, void *fsdata)
 {
 	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
-	struct key *key = file->private_data;
+	struct key *key = afs_file_key(file);
 	loff_t i_size, maybe_i_size;
 	int ret;