Commit 16cce6d2 authored by Latchesar Ionkov's avatar Latchesar Ionkov Committed by Linus Torvalds

[PATCH] v9fs: add extension field to Tcreate

Implement a new way of creating special files.  Instead of Tcreate+Twstat,
add one more field to Tcreate that contains special file description.
Signed-off-by: default avatarLatchesar Ionkov <lucho@ionkov.net>
Signed-off-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5174fdab
...@@ -334,8 +334,8 @@ v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, ...@@ -334,8 +334,8 @@ v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
*/ */
int int
v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, u32 perm,
u32 perm, u8 mode, struct v9fs_fcall **rcp) u8 mode, char *extension, struct v9fs_fcall **rcp)
{ {
int ret; int ret;
struct v9fs_fcall *tc; struct v9fs_fcall *tc;
...@@ -343,7 +343,9 @@ v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, ...@@ -343,7 +343,9 @@ v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n",
fid, name, perm, mode); fid, name, perm, mode);
tc = v9fs_create_tcreate(fid, name, perm, mode); tc = v9fs_create_tcreate(fid, name, perm, mode, extension,
v9ses->extended);
if (!IS_ERR(tc)) { if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
kfree(tc); kfree(tc);
......
...@@ -235,6 +235,7 @@ struct Tcreate { ...@@ -235,6 +235,7 @@ struct Tcreate {
struct v9fs_str name; struct v9fs_str name;
u32 perm; u32 perm;
u8 mode; u8 mode;
struct v9fs_str extension;
}; };
struct Rcreate { struct Rcreate {
...@@ -364,7 +365,7 @@ int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, ...@@ -364,7 +365,7 @@ int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
struct v9fs_fcall **rcall); struct v9fs_fcall **rcall);
int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
u32 perm, u8 mode, struct v9fs_fcall **rcall); u32 perm, u8 mode, char *extension, struct v9fs_fcall **rcall);
int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid,
u64 offset, u32 count, struct v9fs_fcall **rcall); u64 offset, u32 count, struct v9fs_fcall **rcall);
......
...@@ -666,7 +666,8 @@ struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode) ...@@ -666,7 +666,8 @@ struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode)
return fc; return fc;
} }
struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
char *extension, int extended)
{ {
int size; int size;
struct v9fs_fcall *fc; struct v9fs_fcall *fc;
...@@ -674,6 +675,9 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) ...@@ -674,6 +675,9 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode)
struct cbuf *bufp = &buffer; struct cbuf *bufp = &buffer;
size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */
if (extended && extension!=NULL)
size += 2 + strlen(extension); /* extension[s] */
fc = v9fs_create_common(bufp, size, TCREATE); fc = v9fs_create_common(bufp, size, TCREATE);
if (IS_ERR(fc)) if (IS_ERR(fc))
goto error; goto error;
...@@ -682,6 +686,8 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) ...@@ -682,6 +686,8 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode)
v9fs_put_str(bufp, name, &fc->params.tcreate.name); v9fs_put_str(bufp, name, &fc->params.tcreate.name);
v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm);
v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode);
if (extended)
v9fs_put_str(bufp, extension, &fc->params.tcreate.extension);
if (buf_check_overflow(bufp)) { if (buf_check_overflow(bufp)) {
kfree(fc); kfree(fc);
......
...@@ -39,7 +39,8 @@ struct v9fs_fcall *v9fs_create_tflush(u16 oldtag); ...@@ -39,7 +39,8 @@ struct v9fs_fcall *v9fs_create_tflush(u16 oldtag);
struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
char **wnames); char **wnames);
struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode);
struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode); struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
char *extension, int extended);
struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count);
struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
const char __user *data); const char __user *data);
......
...@@ -69,29 +69,30 @@ int v9fs_file_open(struct inode *inode, struct file *file) ...@@ -69,29 +69,30 @@ int v9fs_file_open(struct inode *inode, struct file *file)
fid = v9fs_get_idpool(&v9ses->fidpool); fid = v9fs_get_idpool(&v9ses->fidpool);
if (fid < 0) { if (fid < 0) {
eprintk(KERN_WARNING, "newfid fails!\n"); eprintk(KERN_WARNING, "newfid fails!\n");
return -ENOSPC; return -ENOSPC;
} }
err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL);
if (err < 0) { if (err < 0) {
dprintk(DEBUG_ERROR, "rewalk didn't work\n"); dprintk(DEBUG_ERROR, "rewalk didn't work\n");
goto put_fid; goto put_fid;
} }
vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
if (vfid == NULL) { /* translate open mode appropriately */
dprintk(DEBUG_ERROR, "out of memory\n");
goto clunk_fid;
}
/* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
/* translate open mode appropriately */
omode = v9fs_uflags2omode(file->f_flags); omode = v9fs_uflags2omode(file->f_flags);
err = v9fs_t_open(v9ses, fid, omode, &fcall); err = v9fs_t_open(v9ses, fid, omode, &fcall);
if (err < 0) { if (err < 0) {
PRINT_FCALL_ERROR("open failed", fcall); PRINT_FCALL_ERROR("open failed", fcall);
goto destroy_vfid; goto clunk_fid;
}
vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
if (vfid == NULL) {
dprintk(DEBUG_ERROR, "out of memory\n");
err = -ENOMEM;
goto clunk_fid;
} }
file->private_data = vfid; file->private_data = vfid;
...@@ -106,15 +107,12 @@ int v9fs_file_open(struct inode *inode, struct file *file) ...@@ -106,15 +107,12 @@ int v9fs_file_open(struct inode *inode, struct file *file)
return 0; return 0;
destroy_vfid:
v9fs_fid_destroy(vfid);
clunk_fid: clunk_fid:
v9fs_t_clunk(v9ses, fid); v9fs_t_clunk(v9ses, fid);
put_fid: put_fid:
v9fs_put_idpool(fid, &v9ses->fidpool); v9fs_put_idpool(fid, &v9ses->fidpool);
kfree(fcall); kfree(fcall);
return err; return err;
} }
......
...@@ -255,8 +255,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) ...@@ -255,8 +255,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
} }
static int static int
v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm,
u32 perm, u8 mode, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit)
{ {
u32 fid; u32 fid;
int err; int err;
...@@ -271,14 +271,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, ...@@ -271,14 +271,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name,
err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall);
if (err < 0) { if (err < 0) {
PRINT_FCALL_ERROR("clone error", fcall); PRINT_FCALL_ERROR("clone error", fcall);
goto error; goto put_fid;
} }
kfree(fcall); kfree(fcall);
err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall);
if (err < 0) { if (err < 0) {
PRINT_FCALL_ERROR("create fails", fcall); PRINT_FCALL_ERROR("create fails", fcall);
goto error; goto clunk_fid;
} }
if (iounit) if (iounit)
...@@ -293,7 +293,11 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, ...@@ -293,7 +293,11 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name,
kfree(fcall); kfree(fcall);
return 0; return 0;
error: clunk_fid:
v9fs_t_clunk(v9ses, fid);
fid = V9FS_NOFID;
put_fid:
if (fid >= 0) if (fid >= 0)
v9fs_put_idpool(fid, &v9ses->fidpool); v9fs_put_idpool(fid, &v9ses->fidpool);
...@@ -474,7 +478,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -474,7 +478,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
flags = O_RDWR; flags = O_RDWR;
err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit);
if (err) if (err)
goto error; goto error;
...@@ -550,7 +554,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -550,7 +554,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
perm = unixmode2p9mode(v9ses, mode | S_IFDIR); perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
perm, V9FS_OREAD, &fid, NULL, NULL); perm, V9FS_OREAD, NULL, &fid, NULL, NULL);
if (err) { if (err) {
dprintk(DEBUG_ERROR, "create error %d\n", err); dprintk(DEBUG_ERROR, "create error %d\n", err);
...@@ -1008,11 +1012,13 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) ...@@ -1008,11 +1012,13 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
/* copy extension buffer into buffer */ /* copy extension buffer into buffer */
if (fcall->params.rstat.stat.extension.len < buflen) if (fcall->params.rstat.stat.extension.len < buflen)
buflen = fcall->params.rstat.stat.extension.len; buflen = fcall->params.rstat.stat.extension.len + 1;
memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1);
buffer[buflen-1] = 0; buffer[buflen-1] = 0;
dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len,
fcall->params.rstat.stat.extension.str, buffer);
retval = buflen; retval = buflen;
FreeFcall: FreeFcall:
...@@ -1072,7 +1078,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -1072,7 +1078,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
if (!link) if (!link)
link = ERR_PTR(-ENOMEM); link = ERR_PTR(-ENOMEM);
else { else {
len = v9fs_readlink(dentry, link, strlen(link)); len = v9fs_readlink(dentry, link, PATH_MAX);
if (len < 0) { if (len < 0) {
__putname(link); __putname(link);
...@@ -1109,10 +1115,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ...@@ -1109,10 +1115,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
struct v9fs_session_info *v9ses; struct v9fs_session_info *v9ses;
struct v9fs_fid *dfid, *vfid; struct v9fs_fid *dfid, *vfid;
struct inode *inode; struct inode *inode;
struct v9fs_fcall *fcall;
struct v9fs_wstat wstat;
fcall = NULL;
inode = NULL; inode = NULL;
vfid = NULL; vfid = NULL;
v9ses = v9fs_inode2v9ses(dir); v9ses = v9fs_inode2v9ses(dir);
...@@ -1125,7 +1128,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ...@@ -1125,7 +1128,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
} }
err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
perm, V9FS_OREAD, &fid, NULL, NULL); perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL);
if (err) if (err)
goto error; goto error;
...@@ -1148,23 +1151,11 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ...@@ -1148,23 +1151,11 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
goto error; goto error;
} }
/* issue a Twstat */
v9fs_blank_wstat(&wstat);
wstat.muid = v9ses->name;
wstat.extension = (char *) extension;
err = v9fs_t_wstat(v9ses, vfid->fid, &wstat, &fcall);
if (err < 0) {
PRINT_FCALL_ERROR("wstat error", fcall);
goto error;
}
kfree(fcall);
dentry->d_op = &v9fs_dentry_operations; dentry->d_op = &v9fs_dentry_operations;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
error: error:
kfree(fcall);
if (vfid) if (vfid)
v9fs_fid_destroy(vfid); v9fs_fid_destroy(vfid);
...@@ -1224,7 +1215,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -1224,7 +1215,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
} }
name = __getname(); name = __getname();
sprintf(name, "hardlink(%d)\n", oldfid->fid); sprintf(name, "%d\n", oldfid->fid);
retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name);
__putname(name); __putname(name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment