aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/vfs_inode.c49
-rw-r--r--include/net/9p/9p.h28
-rw-r--r--include/net/9p/client.h1
-rw-r--r--net/9p/client.c30
-rw-r--r--net/9p/protocol.c17
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
986static 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
1406static const struct inode_operations v9fs_dir_inode_operations = { 1449static const struct inode_operations v9fs_dir_inode_operations = {
@@ -1422,7 +1465,7 @@ static const struct inode_operations v9fs_file_inode_operations = {
1422 1465
1423static const struct inode_operations v9fs_file_inode_operations_dotl = { 1466static 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
1428static const struct inode_operations v9fs_symlink_inode_operations = { 1471static 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
425struct 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 */
410struct p9_tstatfs { 438struct 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);
238struct p9_wstat *p9_client_stat(struct p9_fid *fid); 238struct p9_wstat *p9_client_stat(struct p9_fid *fid);
239int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); 239int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
240int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *attr);
240 241
241struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, 242struct 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}
1427EXPORT_SYMBOL(p9_client_wstat); 1427EXPORT_SYMBOL(p9_client_wstat);
1428 1428
1429int 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);
1454error:
1455 return err;
1456}
1457EXPORT_SYMBOL(p9_client_setattr);
1458
1429int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb) 1459int 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))