aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r--fs/9p/vfs_inode.c177
1 files changed, 161 insertions, 16 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 4331b3b5ee1c..afcb8d889382 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -396,23 +396,14 @@ void v9fs_clear_inode(struct inode *inode)
396#endif 396#endif
397} 397}
398 398
399/**
400 * v9fs_inode_from_fid - populate an inode by issuing a attribute request
401 * @v9ses: session information
402 * @fid: fid to issue attribute request for
403 * @sb: superblock on which to create inode
404 *
405 */
406
407static struct inode * 399static struct inode *
408v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 400v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
409 struct super_block *sb) 401 struct super_block *sb)
410{ 402{
411 int err, umode; 403 int err, umode;
412 struct inode *ret; 404 struct inode *ret = NULL;
413 struct p9_wstat *st; 405 struct p9_wstat *st;
414 406
415 ret = NULL;
416 st = p9_client_stat(fid); 407 st = p9_client_stat(fid);
417 if (IS_ERR(st)) 408 if (IS_ERR(st))
418 return ERR_CAST(st); 409 return ERR_CAST(st);
@@ -433,15 +424,62 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
433#endif 424#endif
434 p9stat_free(st); 425 p9stat_free(st);
435 kfree(st); 426 kfree(st);
436
437 return ret; 427 return ret;
438
439error: 428error:
440 p9stat_free(st); 429 p9stat_free(st);
441 kfree(st); 430 kfree(st);
442 return ERR_PTR(err); 431 return ERR_PTR(err);
443} 432}
444 433
434static struct inode *
435v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
436 struct super_block *sb)
437{
438 struct inode *ret = NULL;
439 int err;
440 struct p9_stat_dotl *st;
441
442 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
443 if (IS_ERR(st))
444 return ERR_CAST(st);
445
446 ret = v9fs_get_inode(sb, st->st_mode);
447 if (IS_ERR(ret)) {
448 err = PTR_ERR(ret);
449 goto error;
450 }
451
452 v9fs_stat2inode_dotl(st, ret);
453 ret->i_ino = v9fs_qid2ino(&st->qid);
454#ifdef CONFIG_9P_FSCACHE
455 v9fs_vcookie_set_qid(ret, &st->qid);
456 v9fs_cache_inode_get_cookie(ret);
457#endif
458 kfree(st);
459 return ret;
460error:
461 kfree(st);
462 return ERR_PTR(err);
463}
464
465/**
466 * v9fs_inode_from_fid - Helper routine to populate an inode by
467 * issuing a attribute request
468 * @v9ses: session information
469 * @fid: fid to issue attribute request for
470 * @sb: superblock on which to create inode
471 *
472 */
473static inline struct inode *
474v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
475 struct super_block *sb)
476{
477 if (v9fs_proto_dotl(v9ses))
478 return v9fs_inode_dotl(v9ses, fid, sb);
479 else
480 return v9fs_inode(v9ses, fid, sb);
481}
482
445/** 483/**
446 * v9fs_remove - helper function to remove files and directories 484 * v9fs_remove - helper function to remove files and directories
447 * @dir: directory inode that is being deleted 485 * @dir: directory inode that is being deleted
@@ -853,6 +891,42 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
853 return 0; 891 return 0;
854} 892}
855 893
894static int
895v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
896 struct kstat *stat)
897{
898 int err;
899 struct v9fs_session_info *v9ses;
900 struct p9_fid *fid;
901 struct p9_stat_dotl *st;
902
903 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
904 err = -EPERM;
905 v9ses = v9fs_inode2v9ses(dentry->d_inode);
906 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
907 return simple_getattr(mnt, dentry, stat);
908
909 fid = v9fs_fid_lookup(dentry);
910 if (IS_ERR(fid))
911 return PTR_ERR(fid);
912
913 /* Ask for all the fields in stat structure. Server will return
914 * whatever it supports
915 */
916
917 st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
918 if (IS_ERR(st))
919 return PTR_ERR(st);
920
921 v9fs_stat2inode_dotl(st, dentry->d_inode);
922 generic_fillattr(dentry->d_inode, stat);
923 /* Change block size to what the server returned */
924 stat->blksize = st->st_blksize;
925
926 kfree(st);
927 return 0;
928}
929
856/** 930/**
857 * v9fs_vfs_setattr - set file metadata 931 * v9fs_vfs_setattr - set file metadata
858 * @dentry: file whose metadata to set 932 * @dentry: file whose metadata to set
@@ -980,6 +1054,77 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
980} 1054}
981 1055
982/** 1056/**
1057 * v9fs_stat2inode_dotl - populate an inode structure with stat info
1058 * @stat: stat structure
1059 * @inode: inode to populate
1060 * @sb: superblock of filesystem
1061 *
1062 */
1063
1064void
1065v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
1066{
1067
1068 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
1069 inode->i_atime.tv_sec = stat->st_atime_sec;
1070 inode->i_atime.tv_nsec = stat->st_atime_nsec;
1071 inode->i_mtime.tv_sec = stat->st_mtime_sec;
1072 inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
1073 inode->i_ctime.tv_sec = stat->st_ctime_sec;
1074 inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
1075 inode->i_uid = stat->st_uid;
1076 inode->i_gid = stat->st_gid;
1077 inode->i_nlink = stat->st_nlink;
1078 inode->i_mode = stat->st_mode;
1079 inode->i_rdev = new_decode_dev(stat->st_rdev);
1080
1081 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
1082 init_special_inode(inode, inode->i_mode, inode->i_rdev);
1083
1084 i_size_write(inode, stat->st_size);
1085 inode->i_blocks = stat->st_blocks;
1086 } else {
1087 if (stat->st_result_mask & P9_STATS_ATIME) {
1088 inode->i_atime.tv_sec = stat->st_atime_sec;
1089 inode->i_atime.tv_nsec = stat->st_atime_nsec;
1090 }
1091 if (stat->st_result_mask & P9_STATS_MTIME) {
1092 inode->i_mtime.tv_sec = stat->st_mtime_sec;
1093 inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
1094 }
1095 if (stat->st_result_mask & P9_STATS_CTIME) {
1096 inode->i_ctime.tv_sec = stat->st_ctime_sec;
1097 inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
1098 }
1099 if (stat->st_result_mask & P9_STATS_UID)
1100 inode->i_uid = stat->st_uid;
1101 if (stat->st_result_mask & P9_STATS_GID)
1102 inode->i_gid = stat->st_gid;
1103 if (stat->st_result_mask & P9_STATS_NLINK)
1104 inode->i_nlink = stat->st_nlink;
1105 if (stat->st_result_mask & P9_STATS_MODE) {
1106 inode->i_mode = stat->st_mode;
1107 if ((S_ISBLK(inode->i_mode)) ||
1108 (S_ISCHR(inode->i_mode)))
1109 init_special_inode(inode, inode->i_mode,
1110 inode->i_rdev);
1111 }
1112 if (stat->st_result_mask & P9_STATS_RDEV)
1113 inode->i_rdev = new_decode_dev(stat->st_rdev);
1114 if (stat->st_result_mask & P9_STATS_SIZE)
1115 i_size_write(inode, stat->st_size);
1116 if (stat->st_result_mask & P9_STATS_BLOCKS)
1117 inode->i_blocks = stat->st_blocks;
1118 }
1119 if (stat->st_result_mask & P9_STATS_GEN)
1120 inode->i_generation = stat->st_gen;
1121
1122 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
1123 * because the inode structure does not have fields for them.
1124 */
1125}
1126
1127/**
983 * v9fs_qid2ino - convert qid into inode number 1128 * v9fs_qid2ino - convert qid into inode number
984 * @qid: qid to hash 1129 * @qid: qid to hash
985 * 1130 *
@@ -1254,7 +1399,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = {
1254 .rmdir = v9fs_vfs_rmdir, 1399 .rmdir = v9fs_vfs_rmdir,
1255 .mknod = v9fs_vfs_mknod, 1400 .mknod = v9fs_vfs_mknod,
1256 .rename = v9fs_vfs_rename, 1401 .rename = v9fs_vfs_rename,
1257 .getattr = v9fs_vfs_getattr, 1402 .getattr = v9fs_vfs_getattr_dotl,
1258 .setattr = v9fs_vfs_setattr, 1403 .setattr = v9fs_vfs_setattr,
1259}; 1404};
1260 1405
@@ -1276,7 +1421,7 @@ static const struct inode_operations v9fs_file_inode_operations = {
1276}; 1421};
1277 1422
1278static const struct inode_operations v9fs_file_inode_operations_dotl = { 1423static const struct inode_operations v9fs_file_inode_operations_dotl = {
1279 .getattr = v9fs_vfs_getattr, 1424 .getattr = v9fs_vfs_getattr_dotl,
1280 .setattr = v9fs_vfs_setattr, 1425 .setattr = v9fs_vfs_setattr,
1281}; 1426};
1282 1427
@@ -1292,6 +1437,6 @@ static const struct inode_operations v9fs_symlink_inode_operations_dotl = {
1292 .readlink = generic_readlink, 1437 .readlink = generic_readlink,
1293 .follow_link = v9fs_vfs_follow_link, 1438 .follow_link = v9fs_vfs_follow_link,
1294 .put_link = v9fs_vfs_put_link, 1439 .put_link = v9fs_vfs_put_link,
1295 .getattr = v9fs_vfs_getattr, 1440 .getattr = v9fs_vfs_getattr_dotl,
1296 .setattr = v9fs_vfs_setattr, 1441 .setattr = v9fs_vfs_setattr,
1297}; 1442};