aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/v9fs_vfs.h1
-rw-r--r--fs/9p/vfs_inode.c177
-rw-r--r--fs/9p/vfs_super.c43
3 files changed, 187 insertions, 34 deletions
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 32ef4009d030..f47c6bbb01b3 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -55,6 +55,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode);
55void v9fs_clear_inode(struct inode *inode); 55void v9fs_clear_inode(struct inode *inode);
56ino_t v9fs_qid2ino(struct p9_qid *qid); 56ino_t v9fs_qid2ino(struct p9_qid *qid);
57void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); 57void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
58void v9fs_stat2inode_dotl(struct p9_stat_dotl *, struct inode *);
58int v9fs_dir_release(struct inode *inode, struct file *filp); 59int v9fs_dir_release(struct inode *inode, struct file *filp);
59int v9fs_file_open(struct inode *inode, struct file *file); 60int v9fs_file_open(struct inode *inode, struct file *file);
60void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat); 61void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
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};
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index be74d020436e..3623f692b448 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -107,7 +107,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
107 struct inode *inode = NULL; 107 struct inode *inode = NULL;
108 struct dentry *root = NULL; 108 struct dentry *root = NULL;
109 struct v9fs_session_info *v9ses = NULL; 109 struct v9fs_session_info *v9ses = NULL;
110 struct p9_wstat *st = NULL;
111 int mode = S_IRWXUGO | S_ISVTX; 110 int mode = S_IRWXUGO | S_ISVTX;
112 struct p9_fid *fid; 111 struct p9_fid *fid;
113 int retval = 0; 112 int retval = 0;
@@ -124,16 +123,10 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
124 goto close_session; 123 goto close_session;
125 } 124 }
126 125
127 st = p9_client_stat(fid);
128 if (IS_ERR(st)) {
129 retval = PTR_ERR(st);
130 goto clunk_fid;
131 }
132
133 sb = sget(fs_type, NULL, v9fs_set_super, v9ses); 126 sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
134 if (IS_ERR(sb)) { 127 if (IS_ERR(sb)) {
135 retval = PTR_ERR(sb); 128 retval = PTR_ERR(sb);
136 goto free_stat; 129 goto clunk_fid;
137 } 130 }
138 v9fs_fill_super(sb, v9ses, flags, data); 131 v9fs_fill_super(sb, v9ses, flags, data);
139 132
@@ -151,22 +144,38 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
151 } 144 }
152 145
153 sb->s_root = root; 146 sb->s_root = root;
154 root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
155 147
156 v9fs_stat2inode(st, root->d_inode, sb); 148 if (v9fs_proto_dotl(v9ses)) {
149 struct p9_stat_dotl *st = NULL;
150 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
151 if (IS_ERR(st)) {
152 retval = PTR_ERR(st);
153 goto clunk_fid;
154 }
155
156 v9fs_stat2inode_dotl(st, root->d_inode);
157 kfree(st);
158 } else {
159 struct p9_wstat *st = NULL;
160 st = p9_client_stat(fid);
161 if (IS_ERR(st)) {
162 retval = PTR_ERR(st);
163 goto clunk_fid;
164 }
165
166 root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
167 v9fs_stat2inode(st, root->d_inode, sb);
168
169 p9stat_free(st);
170 kfree(st);
171 }
157 172
158 v9fs_fid_add(root, fid); 173 v9fs_fid_add(root, fid);
159 p9stat_free(st);
160 kfree(st);
161 174
162P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); 175P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
163 simple_set_mnt(mnt, sb); 176 simple_set_mnt(mnt, sb);
164 return 0; 177 return 0;
165 178
166free_stat:
167 p9stat_free(st);
168 kfree(st);
169
170clunk_fid: 179clunk_fid:
171 p9_client_clunk(fid); 180 p9_client_clunk(fid);
172 181
@@ -176,8 +185,6 @@ close_session:
176 return retval; 185 return retval;
177 186
178release_sb: 187release_sb:
179 p9stat_free(st);
180 kfree(st);
181 deactivate_locked_super(sb); 188 deactivate_locked_super(sb);
182 return retval; 189 return retval;
183} 190}