diff options
| -rw-r--r-- | fs/9p/vfs_super.c | 39 | ||||
| -rw-r--r-- | include/net/9p/9p.h | 20 | ||||
| -rw-r--r-- | include/net/9p/client.h | 1 | ||||
| -rw-r--r-- | net/9p/client.c | 39 |
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 | ||
| 218 | static 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); | ||
| 250 | done: | ||
| 251 | return res; | ||
| 252 | } | ||
| 253 | |||
| 217 | static const struct super_operations v9fs_super_ops = { | 254 | static 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 | ||
| 127 | enum p9_msg_t { | 129 | enum 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 */ |
| 357 | struct p9_tstatfs { | ||
| 358 | u32 fid; | ||
| 359 | }; | ||
| 360 | |||
| 361 | struct 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 | |||
| 353 | struct p9_tversion { | 373 | struct 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 | ||
| 198 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); | ||
| 198 | int p9_client_version(struct p9_client *); | 199 | int p9_client_version(struct p9_client *); |
| 199 | struct p9_client *p9_client_create(const char *dev_name, char *options); | 200 | struct p9_client *p9_client_create(const char *dev_name, char *options); |
| 200 | void p9_client_destroy(struct p9_client *clnt); | 201 | void 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 | } |
| 1367 | EXPORT_SYMBOL(p9_client_wstat); | 1367 | EXPORT_SYMBOL(p9_client_wstat); |
| 1368 | |||
| 1369 | int 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); | ||
| 1403 | error: | ||
| 1404 | return err; | ||
| 1405 | } | ||
| 1406 | EXPORT_SYMBOL(p9_client_statfs); | ||
