X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=fs%2F9p%2Fvfs_inode.c;fp=fs%2F9p%2Fvfs_inode.c;h=651a9e14d9a9e5f53f6ba4b5a7861751cf2838dc;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=7a7ec2d1d2f4a8f60bb79c2f82bc0f110f9509b9;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7a7ec2d1d..651a9e14d 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -7,8 +7,9 @@ * Copyright (C) 2002 by Ron Minnich * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -204,6 +205,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) inode->i_mode = mode; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; + inode->i_blksize = sb->s_blocksize; inode->i_blocks = 0; inode->i_rdev = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; @@ -253,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, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) +v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, + u32 perm, u8 mode, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) { u32 fid; int err; @@ -269,17 +271,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); if (err < 0) { PRINT_FCALL_ERROR("clone error", fcall); - if (fcall && fcall->id == RWALK) - goto clunk_fid; - else - goto put_fid; + goto error; } kfree(fcall); - err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall); + err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); if (err < 0) { PRINT_FCALL_ERROR("create fails", fcall); - goto clunk_fid; + goto error; } if (iounit) @@ -294,12 +293,8 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, kfree(fcall); return 0; -clunk_fid: - v9fs_t_clunk(v9ses, fid); - fid = V9FS_NOFID; - -put_fid: - if (fid != V9FS_NOFID) +error: + if (fid >= 0) v9fs_put_idpool(fid, &v9ses->fidpool); kfree(fcall); @@ -324,9 +319,6 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) &fcall); if (err < 0) { - if (fcall && fcall->id == RWALK) - goto clunk_fid; - PRINT_FCALL_ERROR("walk error", fcall); v9fs_put_idpool(nfid, &v9ses->fidpool); goto error; @@ -356,7 +348,7 @@ error: return ERR_PTR(err); } -static struct inode * +struct inode * v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, struct super_block *sb) { @@ -433,11 +425,11 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) result = v9fs_t_remove(v9ses, fid, &fcall); if (result < 0) { PRINT_FCALL_ERROR("remove fails", fcall); + } else { + v9fs_put_idpool(fid, &v9ses->fidpool); + v9fs_fid_destroy(v9fid); } - v9fs_put_idpool(fid, &v9ses->fidpool); - v9fs_fid_destroy(v9fid); - kfree(fcall); return result; } @@ -482,7 +474,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), NULL, &fid, &qid, &iounit); + perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); if (err) goto error; @@ -529,6 +521,9 @@ error: if (vfid) v9fs_fid_destroy(vfid); + if (inode) + iput(inode); + return err; } @@ -555,7 +550,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, NULL, &fid, NULL, NULL); + perm, V9FS_OREAD, &fid, NULL, NULL); if (err) { dprintk(DEBUG_ERROR, "create error %d\n", err); @@ -642,26 +637,19 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, } result = v9fs_t_walk(v9ses, dirfidnum, newfid, - (char *)dentry->d_name.name, &fcall); - + (char *)dentry->d_name.name, NULL); if (result < 0) { - if (fcall && fcall->id == RWALK) - v9fs_t_clunk(v9ses, newfid); - else - v9fs_put_idpool(newfid, &v9ses->fidpool); - + v9fs_put_idpool(newfid, &v9ses->fidpool); if (result == -ENOENT) { d_add(dentry, NULL); dprintk(DEBUG_VFS, "Return negative dentry %p count %d\n", dentry, atomic_read(&dentry->d_count)); - kfree(fcall); return NULL; } dprintk(DEBUG_ERROR, "walk error:%d\n", result); goto FreeFcall; } - kfree(fcall); result = v9fs_t_stat(v9ses, newfid, &fcall); if (result < 0) { @@ -949,8 +937,9 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, inode->i_size = stat->length; + inode->i_blksize = sb->s_blocksize; inode->i_blocks = - (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; + (inode->i_size + inode->i_blksize - 1) >> sb->s_blocksize_bits; } /** @@ -1019,13 +1008,11 @@ 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 + 1; + buflen = fcall->params.rstat.stat.extension.len; - memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); + memcpy(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: @@ -1049,9 +1036,6 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer, int ret; char *link = __getname(); - if (unlikely(!link)) - return -ENOMEM; - if (buflen > PATH_MAX) buflen = PATH_MAX; @@ -1088,7 +1072,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, PATH_MAX); + len = v9fs_readlink(dentry, link, strlen(link)); if (len < 0) { __putname(link); @@ -1125,7 +1109,10 @@ 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); @@ -1138,7 +1125,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, (char *) extension, &fid, NULL, NULL); + perm, V9FS_OREAD, &fid, NULL, NULL); if (err) goto error; @@ -1161,14 +1148,29 @@ 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); + if (inode) + iput(inode); + return err; } @@ -1222,10 +1224,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, } name = __getname(); - if (unlikely(!name)) - return -ENOMEM; - - sprintf(name, "%d\n", oldfid->fid); + sprintf(name, "hardlink(%d)\n", oldfid->fid); retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); __putname(name); @@ -1254,8 +1253,6 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) return -EINVAL; name = __getname(); - if (!name) - return -ENOMEM; /* build extension */ if (S_ISBLK(mode)) sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));