Blame view
fs/9p/vfs_file.c
4.68 KB
e69e7fe5b
|
1 2 3 4 5 6 7 8 9 |
/* * linux/fs/9p/vfs_file.c * * This file contians vfs file ops for 9P2000. * * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify |
42e8c509c
|
10 11 |
* it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. |
e69e7fe5b
|
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to: * Free Software Foundation * 51 Franklin Street, Fifth Floor * Boston, MA 02111-1301 USA * */ #include <linux/module.h> #include <linux/errno.h> #include <linux/fs.h> |
914e26379
|
29 |
#include <linux/sched.h> |
e69e7fe5b
|
30 31 32 |
#include <linux/file.h> #include <linux/stat.h> #include <linux/string.h> |
e69e7fe5b
|
33 |
#include <linux/inet.h> |
e69e7fe5b
|
34 35 36 |
#include <linux/list.h> #include <asm/uaccess.h> #include <linux/idr.h> |
bd238fb43
|
37 38 |
#include <net/9p/9p.h> #include <net/9p/client.h> |
e69e7fe5b
|
39 |
|
e69e7fe5b
|
40 |
#include "v9fs.h" |
e69e7fe5b
|
41 42 |
#include "v9fs_vfs.h" #include "fid.h" |
d32b687e2
|
43 |
static const struct file_operations v9fs_cached_file_operations; |
e69e7fe5b
|
44 45 46 47 48 49 50 51 52 |
/** * v9fs_file_open - open a file (or directory) * @inode: inode to be opened * @file: file being opened * */ int v9fs_file_open(struct inode *inode, struct file *file) { |
6a3124a39
|
53 |
int err; |
bd238fb43
|
54 55 56 |
struct v9fs_session_info *v9ses; struct p9_fid *fid; int omode; |
e69e7fe5b
|
57 |
|
bd238fb43
|
58 59 60 |
P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p ", inode, file); v9ses = v9fs_inode2v9ses(inode); |
6a3124a39
|
61 |
omode = v9fs_uflags2omode(file->f_flags); |
bd238fb43
|
62 63 64 65 66 67 68 |
fid = file->private_data; if (!fid) { fid = v9fs_fid_clone(file->f_path.dentry); if (IS_ERR(fid)) return PTR_ERR(fid); err = p9_client_open(fid, omode); |
9523a841b
|
69 |
if (err < 0) { |
bd238fb43
|
70 71 72 |
p9_client_clunk(fid); return err; } |
9523a841b
|
73 74 75 76 |
if (omode & P9_OTRUNC) { inode->i_size = 0; inode->i_blocks = 0; } |
6a3124a39
|
77 |
} |
e69e7fe5b
|
78 |
|
bd238fb43
|
79 80 81 |
file->private_data = fid; if ((fid->qid.version) && (v9ses->cache)) { P9_DPRINTK(P9_DEBUG_VFS, "cached"); |
e03abc0c9
|
82 83 84 85 |
/* enable cached file options */ if(file->f_op == &v9fs_file_operations) file->f_op = &v9fs_cached_file_operations; } |
6a3124a39
|
86 |
return 0; |
e69e7fe5b
|
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
} /** * v9fs_file_lock - lock a file (or directory) * @inode: inode to be opened * @file: file being opened * * XXX - this looks like a local only lock, we should extend into 9P * by using open exclusive */ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) { int res = 0; |
d6f787bce
|
101 |
struct inode *inode = filp->f_path.dentry->d_inode; |
e69e7fe5b
|
102 |
|
bd238fb43
|
103 104 |
P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p ", filp, fl); |
e69e7fe5b
|
105 106 107 108 109 110 |
/* No mandatory locks */ if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) return -ENOLCK; if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { |
28fd12982
|
111 |
filemap_write_and_wait(inode->i_mapping); |
fc0ecff69
|
112 |
invalidate_mapping_pages(&inode->i_data, 0, -1); |
e69e7fe5b
|
113 114 115 116 117 118 |
} return res; } /** |
19cba8abd
|
119 |
* v9fs_file_read - read from a file |
e69e7fe5b
|
120 121 122 123 124 125 |
* @filep: file pointer to read * @data: data buffer to read data into * @count: size of buffer * @offset: offset at which to read data * */ |
e69e7fe5b
|
126 |
static ssize_t |
19cba8abd
|
127 128 |
v9fs_file_read(struct file *filp, char __user * data, size_t count, loff_t * offset) |
e69e7fe5b
|
129 |
{ |
bd238fb43
|
130 131 |
int ret; struct p9_fid *fid; |
e69e7fe5b
|
132 |
|
bd238fb43
|
133 134 135 136 137 138 |
P9_DPRINTK(P9_DEBUG_VFS, " "); fid = filp->private_data; ret = p9_client_uread(fid, data, *offset, count); if (ret > 0) *offset += ret; |
e69e7fe5b
|
139 |
|
bd238fb43
|
140 |
return ret; |
e69e7fe5b
|
141 142 143 |
} /** |
19cba8abd
|
144 |
* v9fs_file_write - write to a file |
e69e7fe5b
|
145 146 147 148 149 150 151 152 |
* @filep: file pointer to write * @data: data buffer to write data from * @count: size of buffer * @offset: offset at which to write data * */ static ssize_t |
19cba8abd
|
153 154 |
v9fs_file_write(struct file *filp, const char __user * data, size_t count, loff_t * offset) |
e69e7fe5b
|
155 |
{ |
bd238fb43
|
156 157 |
int ret; struct p9_fid *fid; |
9523a841b
|
158 |
struct inode *inode = filp->f_path.dentry->d_inode; |
e69e7fe5b
|
159 |
|
bd238fb43
|
160 161 162 |
P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x ", data, (int)count, (int)*offset); |
e69e7fe5b
|
163 |
|
bd238fb43
|
164 165 166 167 |
fid = filp->private_data; ret = p9_client_uwrite(fid, data, *offset, count); if (ret > 0) *offset += ret; |
e69e7fe5b
|
168 |
|
9523a841b
|
169 170 171 172 173 174 |
if (*offset > inode->i_size) { inode->i_size = *offset; inode->i_blocks = (inode->i_size + 512 - 1) >> 9; } invalidate_inode_pages2(inode->i_mapping); |
bd238fb43
|
175 |
return ret; |
e69e7fe5b
|
176 |
} |
d32b687e2
|
177 |
static const struct file_operations v9fs_cached_file_operations = { |
e03abc0c9
|
178 179 180 181 182 183 184 185 186 |
.llseek = generic_file_llseek, .read = do_sync_read, .aio_read = generic_file_aio_read, .write = v9fs_file_write, .open = v9fs_file_open, .release = v9fs_dir_release, .lock = v9fs_file_lock, .mmap = generic_file_mmap, }; |
4b6f5d20b
|
187 |
const struct file_operations v9fs_file_operations = { |
e69e7fe5b
|
188 189 190 191 192 193 |
.llseek = generic_file_llseek, .read = v9fs_file_read, .write = v9fs_file_write, .open = v9fs_file_open, .release = v9fs_dir_release, .lock = v9fs_file_lock, |
147b31cf0
|
194 |
.mmap = generic_file_mmap, |
e69e7fe5b
|
195 |
}; |