diff options
-rw-r--r-- | fs/9p/vfs_inode.c | 49 | ||||
-rw-r--r-- | include/net/9p/9p.h | 28 | ||||
-rw-r--r-- | include/net/9p/client.h | 1 | ||||
-rw-r--r-- | net/9p/client.c | 30 | ||||
-rw-r--r-- | net/9p/protocol.c | 17 |
5 files changed, 122 insertions, 3 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index afcb8d889382..a90324f4546a 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -977,6 +977,49 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
977 | } | 977 | } |
978 | 978 | ||
979 | /** | 979 | /** |
980 | * v9fs_vfs_setattr_dotl - set file metadata | ||
981 | * @dentry: file whose metadata to set | ||
982 | * @iattr: metadata assignment structure | ||
983 | * | ||
984 | */ | ||
985 | |||
986 | static int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) | ||
987 | { | ||
988 | int retval; | ||
989 | struct v9fs_session_info *v9ses; | ||
990 | struct p9_fid *fid; | ||
991 | struct p9_iattr_dotl p9attr; | ||
992 | |||
993 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | ||
994 | |||
995 | retval = inode_change_ok(dentry->d_inode, iattr); | ||
996 | if (retval) | ||
997 | return retval; | ||
998 | |||
999 | p9attr.valid = iattr->ia_valid; | ||
1000 | p9attr.mode = iattr->ia_mode; | ||
1001 | p9attr.uid = iattr->ia_uid; | ||
1002 | p9attr.gid = iattr->ia_gid; | ||
1003 | p9attr.size = iattr->ia_size; | ||
1004 | p9attr.atime_sec = iattr->ia_atime.tv_sec; | ||
1005 | p9attr.atime_nsec = iattr->ia_atime.tv_nsec; | ||
1006 | p9attr.mtime_sec = iattr->ia_mtime.tv_sec; | ||
1007 | p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec; | ||
1008 | |||
1009 | retval = -EPERM; | ||
1010 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
1011 | fid = v9fs_fid_lookup(dentry); | ||
1012 | if (IS_ERR(fid)) | ||
1013 | return PTR_ERR(fid); | ||
1014 | |||
1015 | retval = p9_client_setattr(fid, &p9attr); | ||
1016 | if (retval >= 0) | ||
1017 | retval = inode_setattr(dentry->d_inode, iattr); | ||
1018 | |||
1019 | return retval; | ||
1020 | } | ||
1021 | |||
1022 | /** | ||
980 | * v9fs_stat2inode - populate an inode structure with mistat info | 1023 | * v9fs_stat2inode - populate an inode structure with mistat info |
981 | * @stat: Plan 9 metadata (mistat) structure | 1024 | * @stat: Plan 9 metadata (mistat) structure |
982 | * @inode: inode to populate | 1025 | * @inode: inode to populate |
@@ -1400,7 +1443,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = { | |||
1400 | .mknod = v9fs_vfs_mknod, | 1443 | .mknod = v9fs_vfs_mknod, |
1401 | .rename = v9fs_vfs_rename, | 1444 | .rename = v9fs_vfs_rename, |
1402 | .getattr = v9fs_vfs_getattr_dotl, | 1445 | .getattr = v9fs_vfs_getattr_dotl, |
1403 | .setattr = v9fs_vfs_setattr, | 1446 | .setattr = v9fs_vfs_setattr_dotl, |
1404 | }; | 1447 | }; |
1405 | 1448 | ||
1406 | static const struct inode_operations v9fs_dir_inode_operations = { | 1449 | static const struct inode_operations v9fs_dir_inode_operations = { |
@@ -1422,7 +1465,7 @@ static const struct inode_operations v9fs_file_inode_operations = { | |||
1422 | 1465 | ||
1423 | static const struct inode_operations v9fs_file_inode_operations_dotl = { | 1466 | static const struct inode_operations v9fs_file_inode_operations_dotl = { |
1424 | .getattr = v9fs_vfs_getattr_dotl, | 1467 | .getattr = v9fs_vfs_getattr_dotl, |
1425 | .setattr = v9fs_vfs_setattr, | 1468 | .setattr = v9fs_vfs_setattr_dotl, |
1426 | }; | 1469 | }; |
1427 | 1470 | ||
1428 | static const struct inode_operations v9fs_symlink_inode_operations = { | 1471 | static const struct inode_operations v9fs_symlink_inode_operations = { |
@@ -1438,5 +1481,5 @@ static const struct inode_operations v9fs_symlink_inode_operations_dotl = { | |||
1438 | .follow_link = v9fs_vfs_follow_link, | 1481 | .follow_link = v9fs_vfs_follow_link, |
1439 | .put_link = v9fs_vfs_put_link, | 1482 | .put_link = v9fs_vfs_put_link, |
1440 | .getattr = v9fs_vfs_getattr_dotl, | 1483 | .getattr = v9fs_vfs_getattr_dotl, |
1441 | .setattr = v9fs_vfs_setattr, | 1484 | .setattr = v9fs_vfs_setattr_dotl, |
1442 | }; | 1485 | }; |
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index ab12e1c9cc7e..7f64d72f6c61 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h | |||
@@ -135,6 +135,8 @@ enum p9_msg_t { | |||
135 | P9_RRENAME, | 135 | P9_RRENAME, |
136 | P9_TGETATTR = 24, | 136 | P9_TGETATTR = 24, |
137 | P9_RGETATTR, | 137 | P9_RGETATTR, |
138 | P9_TSETATTR = 26, | ||
139 | P9_RSETATTR, | ||
138 | P9_TREADDIR = 40, | 140 | P9_TREADDIR = 40, |
139 | P9_RREADDIR, | 141 | P9_RREADDIR, |
140 | P9_TVERSION = 100, | 142 | P9_TVERSION = 100, |
@@ -406,6 +408,32 @@ struct p9_stat_dotl { | |||
406 | #define P9_STATS_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */ | 408 | #define P9_STATS_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */ |
407 | #define P9_STATS_ALL 0x00003fffULL /* Mask for All fields above */ | 409 | #define P9_STATS_ALL 0x00003fffULL /* Mask for All fields above */ |
408 | 410 | ||
411 | /** | ||
412 | * struct p9_iattr_dotl - P9 inode attribute for setattr | ||
413 | * @valid: bitfield specifying which fields are valid | ||
414 | * same as in struct iattr | ||
415 | * @mode: File permission bits | ||
416 | * @uid: user id of owner | ||
417 | * @gid: group id | ||
418 | * @size: File size | ||
419 | * @atime_sec: Last access time, seconds | ||
420 | * @atime_nsec: Last access time, nanoseconds | ||
421 | * @mtime_sec: Last modification time, seconds | ||
422 | * @mtime_nsec: Last modification time, nanoseconds | ||
423 | */ | ||
424 | |||
425 | struct p9_iattr_dotl { | ||
426 | u32 valid; | ||
427 | u32 mode; | ||
428 | u32 uid; | ||
429 | u32 gid; | ||
430 | u64 size; | ||
431 | u64 atime_sec; | ||
432 | u64 atime_nsec; | ||
433 | u64 mtime_sec; | ||
434 | u64 mtime_nsec; | ||
435 | }; | ||
436 | |||
409 | /* Structures for Protocol Operations */ | 437 | /* Structures for Protocol Operations */ |
410 | struct p9_tstatfs { | 438 | struct p9_tstatfs { |
411 | u32 fid; | 439 | u32 fid; |
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 6462eec435bc..afdc385152f6 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
@@ -237,6 +237,7 @@ int p9dirent_read(char *buf, int len, struct p9_dirent *dirent, | |||
237 | int proto_version); | 237 | int proto_version); |
238 | struct p9_wstat *p9_client_stat(struct p9_fid *fid); | 238 | struct p9_wstat *p9_client_stat(struct p9_fid *fid); |
239 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); | 239 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); |
240 | int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *attr); | ||
240 | 241 | ||
241 | struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, | 242 | struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, |
242 | u64 request_mask); | 243 | u64 request_mask); |
diff --git a/net/9p/client.c b/net/9p/client.c index 5e97118da3bf..b2f70ec889c2 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1426,6 +1426,36 @@ error: | |||
1426 | } | 1426 | } |
1427 | EXPORT_SYMBOL(p9_client_wstat); | 1427 | EXPORT_SYMBOL(p9_client_wstat); |
1428 | 1428 | ||
1429 | int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr) | ||
1430 | { | ||
1431 | int err; | ||
1432 | struct p9_req_t *req; | ||
1433 | struct p9_client *clnt; | ||
1434 | |||
1435 | err = 0; | ||
1436 | clnt = fid->clnt; | ||
1437 | P9_DPRINTK(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid); | ||
1438 | P9_DPRINTK(P9_DEBUG_9P, | ||
1439 | " valid=%x mode=%x uid=%d gid=%d size=%lld\n" | ||
1440 | " atime_sec=%lld atime_nsec=%lld\n" | ||
1441 | " mtime_sec=%lld mtime_nsec=%lld\n", | ||
1442 | p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid, | ||
1443 | p9attr->size, p9attr->atime_sec, p9attr->atime_nsec, | ||
1444 | p9attr->mtime_sec, p9attr->mtime_nsec); | ||
1445 | |||
1446 | req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr); | ||
1447 | |||
1448 | if (IS_ERR(req)) { | ||
1449 | err = PTR_ERR(req); | ||
1450 | goto error; | ||
1451 | } | ||
1452 | P9_DPRINTK(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid); | ||
1453 | p9_free_req(clnt, req); | ||
1454 | error: | ||
1455 | return err; | ||
1456 | } | ||
1457 | EXPORT_SYMBOL(p9_client_setattr); | ||
1458 | |||
1429 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb) | 1459 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb) |
1430 | { | 1460 | { |
1431 | int err; | 1461 | int err; |
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 3e4f77695891..3acd3afb20c8 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
@@ -516,6 +516,23 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
516 | } | 516 | } |
517 | } | 517 | } |
518 | break; | 518 | break; |
519 | case 'I':{ | ||
520 | struct p9_iattr_dotl *p9attr = va_arg(ap, | ||
521 | struct p9_iattr_dotl *); | ||
522 | |||
523 | errcode = p9pdu_writef(pdu, proto_version, | ||
524 | "ddddqqqqq", | ||
525 | p9attr->valid, | ||
526 | p9attr->mode, | ||
527 | p9attr->uid, | ||
528 | p9attr->gid, | ||
529 | p9attr->size, | ||
530 | p9attr->atime_sec, | ||
531 | p9attr->atime_nsec, | ||
532 | p9attr->mtime_sec, | ||
533 | p9attr->mtime_nsec); | ||
534 | } | ||
535 | break; | ||
519 | case '?': | 536 | case '?': |
520 | if ((proto_version != p9_proto_2000u) && | 537 | if ((proto_version != p9_proto_2000u) && |
521 | (proto_version != p9_proto_2000L)) | 538 | (proto_version != p9_proto_2000L)) |