diff options
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r-- | fs/9p/vfs_inode.c | 59 |
1 files changed, 25 insertions, 34 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 3ad8455f8577..133db366d306 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -7,9 +7,8 @@ | |||
7 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | 7 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License version 2 |
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * as published by the Free Software Foundation. |
12 | * (at your option) any later version. | ||
13 | * | 12 | * |
14 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
@@ -255,8 +254,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
255 | } | 254 | } |
256 | 255 | ||
257 | static int | 256 | static int |
258 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | 257 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, |
259 | u32 perm, u8 mode, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) | 258 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) |
260 | { | 259 | { |
261 | u32 fid; | 260 | u32 fid; |
262 | int err; | 261 | int err; |
@@ -271,14 +270,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | |||
271 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); | 270 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); |
272 | if (err < 0) { | 271 | if (err < 0) { |
273 | PRINT_FCALL_ERROR("clone error", fcall); | 272 | PRINT_FCALL_ERROR("clone error", fcall); |
274 | goto error; | 273 | goto put_fid; |
275 | } | 274 | } |
276 | kfree(fcall); | 275 | kfree(fcall); |
277 | 276 | ||
278 | err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); | 277 | err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall); |
279 | if (err < 0) { | 278 | if (err < 0) { |
280 | PRINT_FCALL_ERROR("create fails", fcall); | 279 | PRINT_FCALL_ERROR("create fails", fcall); |
281 | goto error; | 280 | goto clunk_fid; |
282 | } | 281 | } |
283 | 282 | ||
284 | if (iounit) | 283 | if (iounit) |
@@ -293,7 +292,11 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | |||
293 | kfree(fcall); | 292 | kfree(fcall); |
294 | return 0; | 293 | return 0; |
295 | 294 | ||
296 | error: | 295 | clunk_fid: |
296 | v9fs_t_clunk(v9ses, fid); | ||
297 | fid = V9FS_NOFID; | ||
298 | |||
299 | put_fid: | ||
297 | if (fid >= 0) | 300 | if (fid >= 0) |
298 | v9fs_put_idpool(fid, &v9ses->fidpool); | 301 | v9fs_put_idpool(fid, &v9ses->fidpool); |
299 | 302 | ||
@@ -348,7 +351,7 @@ error: | |||
348 | return ERR_PTR(err); | 351 | return ERR_PTR(err); |
349 | } | 352 | } |
350 | 353 | ||
351 | struct inode * | 354 | static struct inode * |
352 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, | 355 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, |
353 | struct super_block *sb) | 356 | struct super_block *sb) |
354 | { | 357 | { |
@@ -474,7 +477,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
474 | flags = O_RDWR; | 477 | flags = O_RDWR; |
475 | 478 | ||
476 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 479 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
477 | perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); | 480 | perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); |
478 | 481 | ||
479 | if (err) | 482 | if (err) |
480 | goto error; | 483 | goto error; |
@@ -550,7 +553,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
550 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); | 553 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); |
551 | 554 | ||
552 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 555 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
553 | perm, V9FS_OREAD, &fid, NULL, NULL); | 556 | perm, V9FS_OREAD, NULL, &fid, NULL, NULL); |
554 | 557 | ||
555 | if (err) { | 558 | if (err) { |
556 | dprintk(DEBUG_ERROR, "create error %d\n", err); | 559 | dprintk(DEBUG_ERROR, "create error %d\n", err); |
@@ -614,6 +617,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
614 | 617 | ||
615 | sb = dir->i_sb; | 618 | sb = dir->i_sb; |
616 | v9ses = v9fs_inode2v9ses(dir); | 619 | v9ses = v9fs_inode2v9ses(dir); |
620 | dentry->d_op = &v9fs_dentry_operations; | ||
617 | dirfid = v9fs_fid_lookup(dentry->d_parent); | 621 | dirfid = v9fs_fid_lookup(dentry->d_parent); |
618 | 622 | ||
619 | if (!dirfid) { | 623 | if (!dirfid) { |
@@ -681,8 +685,6 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
681 | goto FreeFcall; | 685 | goto FreeFcall; |
682 | 686 | ||
683 | fid->qid = fcall->params.rstat.stat.qid; | 687 | fid->qid = fcall->params.rstat.stat.qid; |
684 | |||
685 | dentry->d_op = &v9fs_dentry_operations; | ||
686 | v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); | 688 | v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); |
687 | 689 | ||
688 | d_add(dentry, inode); | 690 | d_add(dentry, inode); |
@@ -1009,11 +1011,13 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1009 | 1011 | ||
1010 | /* copy extension buffer into buffer */ | 1012 | /* copy extension buffer into buffer */ |
1011 | if (fcall->params.rstat.stat.extension.len < buflen) | 1013 | if (fcall->params.rstat.stat.extension.len < buflen) |
1012 | buflen = fcall->params.rstat.stat.extension.len; | 1014 | buflen = fcall->params.rstat.stat.extension.len + 1; |
1013 | 1015 | ||
1014 | memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); | 1016 | memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); |
1015 | buffer[buflen-1] = 0; | 1017 | buffer[buflen-1] = 0; |
1016 | 1018 | ||
1019 | dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len, | ||
1020 | fcall->params.rstat.stat.extension.str, buffer); | ||
1017 | retval = buflen; | 1021 | retval = buflen; |
1018 | 1022 | ||
1019 | FreeFcall: | 1023 | FreeFcall: |
@@ -1073,7 +1077,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1073 | if (!link) | 1077 | if (!link) |
1074 | link = ERR_PTR(-ENOMEM); | 1078 | link = ERR_PTR(-ENOMEM); |
1075 | else { | 1079 | else { |
1076 | len = v9fs_readlink(dentry, link, strlen(link)); | 1080 | len = v9fs_readlink(dentry, link, PATH_MAX); |
1077 | 1081 | ||
1078 | if (len < 0) { | 1082 | if (len < 0) { |
1079 | __putname(link); | 1083 | __putname(link); |
@@ -1110,10 +1114,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1110 | struct v9fs_session_info *v9ses; | 1114 | struct v9fs_session_info *v9ses; |
1111 | struct v9fs_fid *dfid, *vfid; | 1115 | struct v9fs_fid *dfid, *vfid; |
1112 | struct inode *inode; | 1116 | struct inode *inode; |
1113 | struct v9fs_fcall *fcall; | ||
1114 | struct v9fs_wstat wstat; | ||
1115 | 1117 | ||
1116 | fcall = NULL; | ||
1117 | inode = NULL; | 1118 | inode = NULL; |
1118 | vfid = NULL; | 1119 | vfid = NULL; |
1119 | v9ses = v9fs_inode2v9ses(dir); | 1120 | v9ses = v9fs_inode2v9ses(dir); |
@@ -1126,7 +1127,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1126 | } | 1127 | } |
1127 | 1128 | ||
1128 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 1129 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
1129 | perm, V9FS_OREAD, &fid, NULL, NULL); | 1130 | perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); |
1130 | 1131 | ||
1131 | if (err) | 1132 | if (err) |
1132 | goto error; | 1133 | goto error; |
@@ -1149,23 +1150,11 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1149 | goto error; | 1150 | goto error; |
1150 | } | 1151 | } |
1151 | 1152 | ||
1152 | /* issue a Twstat */ | ||
1153 | v9fs_blank_wstat(&wstat); | ||
1154 | wstat.muid = v9ses->name; | ||
1155 | wstat.extension = (char *) extension; | ||
1156 | err = v9fs_t_wstat(v9ses, vfid->fid, &wstat, &fcall); | ||
1157 | if (err < 0) { | ||
1158 | PRINT_FCALL_ERROR("wstat error", fcall); | ||
1159 | goto error; | ||
1160 | } | ||
1161 | |||
1162 | kfree(fcall); | ||
1163 | dentry->d_op = &v9fs_dentry_operations; | 1153 | dentry->d_op = &v9fs_dentry_operations; |
1164 | d_instantiate(dentry, inode); | 1154 | d_instantiate(dentry, inode); |
1165 | return 0; | 1155 | return 0; |
1166 | 1156 | ||
1167 | error: | 1157 | error: |
1168 | kfree(fcall); | ||
1169 | if (vfid) | 1158 | if (vfid) |
1170 | v9fs_fid_destroy(vfid); | 1159 | v9fs_fid_destroy(vfid); |
1171 | 1160 | ||
@@ -1225,7 +1214,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1225 | } | 1214 | } |
1226 | 1215 | ||
1227 | name = __getname(); | 1216 | name = __getname(); |
1228 | sprintf(name, "hardlink(%d)\n", oldfid->fid); | 1217 | sprintf(name, "%d\n", oldfid->fid); |
1229 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); | 1218 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); |
1230 | __putname(name); | 1219 | __putname(name); |
1231 | 1220 | ||
@@ -1254,6 +1243,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
1254 | return -EINVAL; | 1243 | return -EINVAL; |
1255 | 1244 | ||
1256 | name = __getname(); | 1245 | name = __getname(); |
1246 | if (!name) | ||
1247 | return -ENOMEM; | ||
1257 | /* build extension */ | 1248 | /* build extension */ |
1258 | if (S_ISBLK(mode)) | 1249 | if (S_ISBLK(mode)) |
1259 | sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); | 1250 | sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); |