Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
Pull v9fs updates from Eric Van Hensbergen: "Just fixes and simplifications" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: fs/9p: Fix atomic_open fs/9p: Don't use O_TRUNC flag in TOPEN and TLOPEN request locking in fs/9p ->readdir()
This commit is contained in:
Коммит
2608e3d0fa
|
@ -52,10 +52,9 @@
|
|||
*/
|
||||
|
||||
struct p9_rdir {
|
||||
struct mutex mutex;
|
||||
int head;
|
||||
int tail;
|
||||
uint8_t *buf;
|
||||
uint8_t buf[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -93,33 +92,12 @@ static void p9stat_init(struct p9_wstat *stbuf)
|
|||
*
|
||||
*/
|
||||
|
||||
static int v9fs_alloc_rdir_buf(struct file *filp, int buflen)
|
||||
static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen)
|
||||
{
|
||||
struct p9_rdir *rdir;
|
||||
struct p9_fid *fid;
|
||||
int err = 0;
|
||||
|
||||
fid = filp->private_data;
|
||||
if (!fid->rdir) {
|
||||
rdir = kmalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL);
|
||||
|
||||
if (rdir == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
spin_lock(&filp->f_dentry->d_lock);
|
||||
if (!fid->rdir) {
|
||||
rdir->buf = (uint8_t *)rdir + sizeof(struct p9_rdir);
|
||||
mutex_init(&rdir->mutex);
|
||||
rdir->head = rdir->tail = 0;
|
||||
fid->rdir = (void *) rdir;
|
||||
rdir = NULL;
|
||||
}
|
||||
spin_unlock(&filp->f_dentry->d_lock);
|
||||
kfree(rdir);
|
||||
}
|
||||
exit:
|
||||
return err;
|
||||
struct p9_fid *fid = filp->private_data;
|
||||
if (!fid->rdir)
|
||||
fid->rdir = kzalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL);
|
||||
return fid->rdir;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,20 +123,16 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||
|
||||
buflen = fid->clnt->msize - P9_IOHDRSZ;
|
||||
|
||||
err = v9fs_alloc_rdir_buf(filp, buflen);
|
||||
if (err)
|
||||
goto exit;
|
||||
rdir = (struct p9_rdir *) fid->rdir;
|
||||
rdir = v9fs_alloc_rdir_buf(filp, buflen);
|
||||
if (!rdir)
|
||||
return -ENOMEM;
|
||||
|
||||
err = mutex_lock_interruptible(&rdir->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
while (err == 0) {
|
||||
while (1) {
|
||||
if (rdir->tail == rdir->head) {
|
||||
err = v9fs_file_readn(filp, rdir->buf, NULL,
|
||||
buflen, filp->f_pos);
|
||||
if (err <= 0)
|
||||
goto unlock_and_exit;
|
||||
return err;
|
||||
|
||||
rdir->head = 0;
|
||||
rdir->tail = err;
|
||||
|
@ -169,9 +143,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||
rdir->tail - rdir->head, &st);
|
||||
if (err) {
|
||||
p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
|
||||
err = -EIO;
|
||||
p9stat_free(&st);
|
||||
goto unlock_and_exit;
|
||||
return -EIO;
|
||||
}
|
||||
reclen = st.size+2;
|
||||
|
||||
|
@ -180,19 +153,13 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||
|
||||
p9stat_free(&st);
|
||||
|
||||
if (over) {
|
||||
err = 0;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
if (over)
|
||||
return 0;
|
||||
|
||||
rdir->head += reclen;
|
||||
filp->f_pos += reclen;
|
||||
}
|
||||
}
|
||||
|
||||
unlock_and_exit:
|
||||
mutex_unlock(&rdir->mutex);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,21 +185,16 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
|
|||
|
||||
buflen = fid->clnt->msize - P9_READDIRHDRSZ;
|
||||
|
||||
err = v9fs_alloc_rdir_buf(filp, buflen);
|
||||
if (err)
|
||||
goto exit;
|
||||
rdir = (struct p9_rdir *) fid->rdir;
|
||||
rdir = v9fs_alloc_rdir_buf(filp, buflen);
|
||||
if (!rdir)
|
||||
return -ENOMEM;
|
||||
|
||||
err = mutex_lock_interruptible(&rdir->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (err == 0) {
|
||||
while (1) {
|
||||
if (rdir->tail == rdir->head) {
|
||||
err = p9_client_readdir(fid, rdir->buf, buflen,
|
||||
filp->f_pos);
|
||||
if (err <= 0)
|
||||
goto unlock_and_exit;
|
||||
return err;
|
||||
|
||||
rdir->head = 0;
|
||||
rdir->tail = err;
|
||||
|
@ -245,8 +207,7 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
|
|||
&curdirent);
|
||||
if (err < 0) {
|
||||
p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
|
||||
err = -EIO;
|
||||
goto unlock_and_exit;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* d_off in dirent structure tracks the offset into
|
||||
|
@ -261,20 +222,13 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
|
|||
curdirent.d_type);
|
||||
oldoffset = curdirent.d_off;
|
||||
|
||||
if (over) {
|
||||
err = 0;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
if (over)
|
||||
return 0;
|
||||
|
||||
filp->f_pos = curdirent.d_off;
|
||||
rdir->head += err;
|
||||
}
|
||||
}
|
||||
|
||||
unlock_and_exit:
|
||||
mutex_unlock(&rdir->mutex);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -80,10 +80,6 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
|||
p9_client_clunk(fid);
|
||||
return err;
|
||||
}
|
||||
if (file->f_flags & O_TRUNC) {
|
||||
i_size_write(inode, 0);
|
||||
inode->i_blocks = 0;
|
||||
}
|
||||
if ((file->f_flags & O_APPEND) &&
|
||||
(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
|
||||
generic_file_llseek(file, 0, SEEK_END);
|
||||
|
|
|
@ -192,9 +192,6 @@ int v9fs_uflags2omode(int uflags, int extended)
|
|||
break;
|
||||
}
|
||||
|
||||
if (uflags & O_TRUNC)
|
||||
ret |= P9_OTRUNC;
|
||||
|
||||
if (extended) {
|
||||
if (uflags & O_EXCL)
|
||||
ret |= P9_OEXCL;
|
||||
|
|
|
@ -186,7 +186,6 @@ static int v9fs_mapped_dotl_flags(int flags)
|
|||
{ O_CREAT, P9_DOTL_CREATE },
|
||||
{ O_EXCL, P9_DOTL_EXCL },
|
||||
{ O_NOCTTY, P9_DOTL_NOCTTY },
|
||||
{ O_TRUNC, P9_DOTL_TRUNC },
|
||||
{ O_APPEND, P9_DOTL_APPEND },
|
||||
{ O_NONBLOCK, P9_DOTL_NONBLOCK },
|
||||
{ O_DSYNC, P9_DOTL_DSYNC },
|
||||
|
@ -268,8 +267,14 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
|||
}
|
||||
|
||||
/* Only creates */
|
||||
if (!(flags & O_CREAT) || dentry->d_inode)
|
||||
return finish_no_open(file, res);
|
||||
if (!(flags & O_CREAT))
|
||||
return finish_no_open(file, res);
|
||||
else if (dentry->d_inode) {
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
return -EEXIST;
|
||||
else
|
||||
return finish_no_open(file, res);
|
||||
}
|
||||
|
||||
v9ses = v9fs_inode2v9ses(dir);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче