aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/vfs_super.c39
-rw-r--r--include/net/9p/9p.h20
-rw-r--r--include/net/9p/client.h1
-rw-r--r--net/9p/client.c39
4 files changed, 98 insertions, 1 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index cc3fa8c3aab6..be74d020436e 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -38,6 +38,7 @@
38#include <linux/idr.h> 38#include <linux/idr.h>
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/statfs.h>
41#include <net/9p/9p.h> 42#include <net/9p/9p.h>
42#include <net/9p/client.h> 43#include <net/9p/client.h>
43 44
@@ -214,6 +215,42 @@ v9fs_umount_begin(struct super_block *sb)
214 v9fs_session_begin_cancel(v9ses); 215 v9fs_session_begin_cancel(v9ses);
215} 216}
216 217
218static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
219{
220 struct v9fs_session_info *v9ses;
221 struct p9_fid *fid;
222 struct p9_rstatfs rs;
223 int res;
224
225 fid = v9fs_fid_lookup(dentry);
226 if (IS_ERR(fid)) {
227 res = PTR_ERR(fid);
228 goto done;
229 }
230
231 v9ses = v9fs_inode2v9ses(dentry->d_inode);
232 if (v9fs_proto_dotl(v9ses)) {
233 res = p9_client_statfs(fid, &rs);
234 if (res == 0) {
235 buf->f_type = rs.type;
236 buf->f_bsize = rs.bsize;
237 buf->f_blocks = rs.blocks;
238 buf->f_bfree = rs.bfree;
239 buf->f_bavail = rs.bavail;
240 buf->f_files = rs.files;
241 buf->f_ffree = rs.ffree;
242 buf->f_fsid.val[0] = rs.fsid & 0xFFFFFFFFUL;
243 buf->f_fsid.val[1] = (rs.fsid >> 32) & 0xFFFFFFFFUL;
244 buf->f_namelen = rs.namelen;
245 }
246 if (res != -ENOSYS)
247 goto done;
248 }
249 res = simple_statfs(dentry, buf);
250done:
251 return res;
252}
253
217static const struct super_operations v9fs_super_ops = { 254static const struct super_operations v9fs_super_ops = {
218#ifdef CONFIG_9P_FSCACHE 255#ifdef CONFIG_9P_FSCACHE
219 .alloc_inode = v9fs_alloc_inode, 256 .alloc_inode = v9fs_alloc_inode,
@@ -230,7 +267,7 @@ static const struct super_operations v9fs_super_ops_dotl = {
230 .alloc_inode = v9fs_alloc_inode, 267 .alloc_inode = v9fs_alloc_inode,
231 .destroy_inode = v9fs_destroy_inode, 268 .destroy_inode = v9fs_destroy_inode,
232#endif 269#endif
233 .statfs = simple_statfs, 270 .statfs = v9fs_statfs,
234 .clear_inode = v9fs_clear_inode, 271 .clear_inode = v9fs_clear_inode,
235 .show_options = generic_show_options, 272 .show_options = generic_show_options,
236 .umount_begin = v9fs_umount_begin, 273 .umount_begin = v9fs_umount_begin,
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index a7fb54808a23..59300dc22dd0 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -86,6 +86,8 @@ do { \
86 86
87/** 87/**
88 * enum p9_msg_t - 9P message types 88 * enum p9_msg_t - 9P message types
89 * @P9_TSTATFS: file system status request
90 * @P9_RSTATFS: file system status response
89 * @P9_TVERSION: version handshake request 91 * @P9_TVERSION: version handshake request
90 * @P9_RVERSION: version handshake response 92 * @P9_RVERSION: version handshake response
91 * @P9_TAUTH: request to establish authentication channel 93 * @P9_TAUTH: request to establish authentication channel
@@ -125,6 +127,8 @@ do { \
125 */ 127 */
126 128
127enum p9_msg_t { 129enum p9_msg_t {
130 P9_TSTATFS = 8,
131 P9_RSTATFS,
128 P9_TVERSION = 100, 132 P9_TVERSION = 100,
129 P9_RVERSION, 133 P9_RVERSION,
130 P9_TAUTH = 102, 134 P9_TAUTH = 102,
@@ -350,6 +354,22 @@ struct p9_wstat {
350}; 354};
351 355
352/* Structures for Protocol Operations */ 356/* Structures for Protocol Operations */
357struct p9_tstatfs {
358 u32 fid;
359};
360
361struct p9_rstatfs {
362 u32 type;
363 u32 bsize;
364 u64 blocks;
365 u64 bfree;
366 u64 bavail;
367 u64 files;
368 u64 ffree;
369 u64 fsid;
370 u32 namelen;
371};
372
353struct p9_tversion { 373struct p9_tversion {
354 u32 msize; 374 u32 msize;
355 struct p9_str version; 375 struct p9_str version;
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 4f3760afc20f..f83c0d99e592 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -195,6 +195,7 @@ struct p9_fid {
195 struct list_head dlist; /* list of all fids attached to a dentry */ 195 struct list_head dlist; /* list of all fids attached to a dentry */
196}; 196};
197 197
198int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
198int p9_client_version(struct p9_client *); 199int p9_client_version(struct p9_client *);
199struct p9_client *p9_client_create(const char *dev_name, char *options); 200struct p9_client *p9_client_create(const char *dev_name, char *options);
200void p9_client_destroy(struct p9_client *clnt); 201void p9_client_destroy(struct p9_client *clnt);
diff --git a/net/9p/client.c b/net/9p/client.c
index e2d314674965..430a1c4a7c6f 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1365,3 +1365,42 @@ error:
1365 return err; 1365 return err;
1366} 1366}
1367EXPORT_SYMBOL(p9_client_wstat); 1367EXPORT_SYMBOL(p9_client_wstat);
1368
1369int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
1370{
1371 int err;
1372 struct p9_req_t *req;
1373 struct p9_client *clnt;
1374
1375 err = 0;
1376 clnt = fid->clnt;
1377
1378 P9_DPRINTK(P9_DEBUG_9P, ">>> TSTATFS fid %d\n", fid->fid);
1379
1380 req = p9_client_rpc(clnt, P9_TSTATFS, "d", fid->fid);
1381 if (IS_ERR(req)) {
1382 err = PTR_ERR(req);
1383 goto error;
1384 }
1385
1386 err = p9pdu_readf(req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
1387 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
1388 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
1389 if (err) {
1390 p9pdu_dump(1, req->rc);
1391 p9_free_req(clnt, req);
1392 goto error;
1393 }
1394
1395 P9_DPRINTK(P9_DEBUG_9P, "<<< RSTATFS fid %d type 0x%lx bsize %ld "
1396 "blocks %llu bfree %llu bavail %llu files %llu ffree %llu "
1397 "fsid %llu namelen %ld\n",
1398 fid->fid, (long unsigned int)sb->type, (long int)sb->bsize,
1399 sb->blocks, sb->bfree, sb->bavail, sb->files, sb->ffree,
1400 sb->fsid, (long int)sb->namelen);
1401
1402 p9_free_req(clnt, req);
1403error:
1404 return err;
1405}
1406EXPORT_SYMBOL(p9_client_statfs);