diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/v9fs_vfs.h | 1 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 177 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 43 |
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); | |||
55 | void v9fs_clear_inode(struct inode *inode); | 55 | void v9fs_clear_inode(struct inode *inode); |
56 | ino_t v9fs_qid2ino(struct p9_qid *qid); | 56 | ino_t v9fs_qid2ino(struct p9_qid *qid); |
57 | void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); | 57 | void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); |
58 | void v9fs_stat2inode_dotl(struct p9_stat_dotl *, struct inode *); | ||
58 | int v9fs_dir_release(struct inode *inode, struct file *filp); | 59 | int v9fs_dir_release(struct inode *inode, struct file *filp); |
59 | int v9fs_file_open(struct inode *inode, struct file *file); | 60 | int v9fs_file_open(struct inode *inode, struct file *file); |
60 | void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat); | 61 | void 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 | |||
407 | static struct inode * | 399 | static struct inode * |
408 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | 400 | v9fs_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 | |||
439 | error: | 428 | error: |
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 | ||
434 | static struct inode * | ||
435 | v9fs_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; | ||
460 | error: | ||
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 | */ | ||
473 | static inline struct inode * | ||
474 | v9fs_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 | ||
894 | static int | ||
895 | v9fs_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 | |||
1064 | void | ||
1065 | v9fs_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 | ||
1278 | static const struct inode_operations v9fs_file_inode_operations_dotl = { | 1423 | static 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 | ||
162 | P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); | 175 | P9_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 | ||
166 | free_stat: | ||
167 | p9stat_free(st); | ||
168 | kfree(st); | ||
169 | |||
170 | clunk_fid: | 179 | clunk_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 | ||
178 | release_sb: | 187 | release_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 | } |