[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: Latchesar Ionkov <lucho@ionkov.net> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
5174fdab9f
commit
16cce6d27e
6 changed files with 50 additions and 51 deletions
|
@ -334,8 +334,8 @@ v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
|
|||
*/
|
||||
|
||||
int
|
||||
v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
|
||||
u32 perm, u8 mode, struct v9fs_fcall **rcp)
|
||||
v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, u32 perm,
|
||||
u8 mode, char *extension, struct v9fs_fcall **rcp)
|
||||
{
|
||||
int ret;
|
||||
struct v9fs_fcall *tc;
|
||||
|
@ -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",
|
||||
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)) {
|
||||
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
|
||||
kfree(tc);
|
||||
|
|
|
@ -235,6 +235,7 @@ struct Tcreate {
|
|||
struct v9fs_str name;
|
||||
u32 perm;
|
||||
u8 mode;
|
||||
struct v9fs_str extension;
|
||||
};
|
||||
|
||||
struct Rcreate {
|
||||
|
@ -364,7 +365,7 @@ int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
|
|||
struct v9fs_fcall **rcall);
|
||||
|
||||
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,
|
||||
u64 offset, u32 count, struct v9fs_fcall **rcall);
|
||||
|
|
|
@ -666,7 +666,8 @@ struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode)
|
|||
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;
|
||||
struct v9fs_fcall *fc;
|
||||
|
@ -674,6 +675,9 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode)
|
|||
struct cbuf *bufp = &buffer;
|
||||
|
||||
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);
|
||||
if (IS_ERR(fc))
|
||||
goto error;
|
||||
|
@ -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_int32(bufp, perm, &fc->params.tcreate.perm);
|
||||
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)) {
|
||||
kfree(fc);
|
||||
|
|
|
@ -39,7 +39,8 @@ struct v9fs_fcall *v9fs_create_tflush(u16 oldtag);
|
|||
struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
|
||||
char **wnames);
|
||||
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_twrite(u32 fid, u64 offset, u32 count,
|
||||
const char __user *data);
|
||||
|
|
|
@ -69,29 +69,30 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
|||
|
||||
fid = v9fs_get_idpool(&v9ses->fidpool);
|
||||
if (fid < 0) {
|
||||
eprintk(KERN_WARNING, "newfid fails!\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
eprintk(KERN_WARNING, "newfid fails!\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL);
|
||||
if (err < 0) {
|
||||
dprintk(DEBUG_ERROR, "rewalk didn't work\n");
|
||||
dprintk(DEBUG_ERROR, "rewalk didn't work\n");
|
||||
goto put_fid;
|
||||
}
|
||||
|
||||
/* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
|
||||
/* translate open mode appropriately */
|
||||
omode = v9fs_uflags2omode(file->f_flags);
|
||||
err = v9fs_t_open(v9ses, fid, omode, &fcall);
|
||||
if (err < 0) {
|
||||
PRINT_FCALL_ERROR("open failed", fcall);
|
||||
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;
|
||||
}
|
||||
|
||||
/* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
|
||||
/* translate open mode appropriately */
|
||||
omode = v9fs_uflags2omode(file->f_flags);
|
||||
err = v9fs_t_open(v9ses, fid, omode, &fcall);
|
||||
if (err < 0) {
|
||||
PRINT_FCALL_ERROR("open failed", fcall);
|
||||
goto destroy_vfid;
|
||||
}
|
||||
|
||||
file->private_data = vfid;
|
||||
|
@ -106,15 +107,12 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
|||
|
||||
return 0;
|
||||
|
||||
destroy_vfid:
|
||||
v9fs_fid_destroy(vfid);
|
||||
|
||||
clunk_fid:
|
||||
v9fs_t_clunk(v9ses, fid);
|
||||
|
||||
put_fid:
|
||||
v9fs_put_idpool(fid, &v9ses->fidpool);
|
||||
kfree(fcall);
|
||||
kfree(fcall);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -255,8 +255,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
|
|||
}
|
||||
|
||||
static int
|
||||
v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name,
|
||||
u32 perm, u8 mode, u32 *fidp, struct v9fs_qid *qid, u32 *iounit)
|
||||
v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm,
|
||||
u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit)
|
||||
{
|
||||
u32 fid;
|
||||
int err;
|
||||
|
@ -271,14 +271,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name,
|
|||
err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall);
|
||||
if (err < 0) {
|
||||
PRINT_FCALL_ERROR("clone error", fcall);
|
||||
goto error;
|
||||
goto put_fid;
|
||||
}
|
||||
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) {
|
||||
PRINT_FCALL_ERROR("create fails", fcall);
|
||||
goto error;
|
||||
goto clunk_fid;
|
||||
}
|
||||
|
||||
if (iounit)
|
||||
|
@ -293,7 +293,11 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name,
|
|||
kfree(fcall);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
clunk_fid:
|
||||
v9fs_t_clunk(v9ses, fid);
|
||||
fid = V9FS_NOFID;
|
||||
|
||||
put_fid:
|
||||
if (fid >= 0)
|
||||
v9fs_put_idpool(fid, &v9ses->fidpool);
|
||||
|
||||
|
@ -474,7 +478,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
|
|||
flags = O_RDWR;
|
||||
|
||||
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)
|
||||
goto error;
|
||||
|
@ -550,7 +554,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
|||
perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
|
||||
|
||||
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) {
|
||||
dprintk(DEBUG_ERROR, "create error %d\n", err);
|
||||
|
@ -1008,11 +1012,13 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
|
|||
|
||||
/* copy extension buffer into buffer */
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
FreeFcall:
|
||||
|
@ -1072,7 +1078,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
|
|||
if (!link)
|
||||
link = ERR_PTR(-ENOMEM);
|
||||
else {
|
||||
len = v9fs_readlink(dentry, link, strlen(link));
|
||||
len = v9fs_readlink(dentry, link, PATH_MAX);
|
||||
|
||||
if (len < 0) {
|
||||
__putname(link);
|
||||
|
@ -1109,10 +1115,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
|
|||
struct v9fs_session_info *v9ses;
|
||||
struct v9fs_fid *dfid, *vfid;
|
||||
struct inode *inode;
|
||||
struct v9fs_fcall *fcall;
|
||||
struct v9fs_wstat wstat;
|
||||
|
||||
fcall = NULL;
|
||||
inode = NULL;
|
||||
vfid = NULL;
|
||||
v9ses = v9fs_inode2v9ses(dir);
|
||||
|
@ -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,
|
||||
perm, V9FS_OREAD, &fid, NULL, NULL);
|
||||
perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL);
|
||||
|
||||
if (err)
|
||||
goto error;
|
||||
|
@ -1148,23 +1151,11 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
|
|||
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;
|
||||
d_instantiate(dentry, inode);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
kfree(fcall);
|
||||
if (vfid)
|
||||
v9fs_fid_destroy(vfid);
|
||||
|
||||
|
@ -1224,7 +1215,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
|
|||
}
|
||||
|
||||
name = __getname();
|
||||
sprintf(name, "hardlink(%d)\n", oldfid->fid);
|
||||
sprintf(name, "%d\n", oldfid->fid);
|
||||
retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name);
|
||||
__putname(name);
|
||||
|
||||
|
|
Loading…
Reference in a new issue