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.c59
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
257static int 256static int
258v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, 257v9fs_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
296error: 295clunk_fid:
296 v9fs_t_clunk(v9ses, fid);
297 fid = V9FS_NOFID;
298
299put_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
351struct inode * 354static struct inode *
352v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, 355v9fs_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
1167error: 1157error:
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));