Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 45846
b: refs/heads/master
c: da977b2
h: refs/heads/master
v: v3
  • Loading branch information
Eric Van Hensbergen authored and Linus Torvalds committed Jan 26, 2007
1 parent f0a9347 commit d320915
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 130 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ff76e1dfc8728278ee231feeb93146f9c57c3ec3
refs/heads/master: da977b2c7eb4d6312f063a7b486f2aad99809710
69 changes: 66 additions & 3 deletions trunk/fs/9p/fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/idr.h>
#include <asm/semaphore.h>

#include "debug.h"
#include "v9fs.h"
Expand Down Expand Up @@ -84,6 +85,7 @@ struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid)
new->iounit = 0;
new->rdir_pos = 0;
new->rdir_fcall = NULL;
init_MUTEX(&new->lock);
INIT_LIST_HEAD(&new->list);

return new;
Expand All @@ -102,11 +104,11 @@ void v9fs_fid_destroy(struct v9fs_fid *fid)
}

/**
* v9fs_fid_lookup - retrieve the right fid from a particular dentry
* v9fs_fid_lookup - return a locked fid from a dentry
* @dentry: dentry to look for fid in
* @type: intent of lookup (operation or traversal)
*
* find a fid in the dentry
* find a fid in the dentry, obtain its semaphore and return a reference to it.
* code calling lookup is responsible for releasing lock
*
* TODO: only match fids that have the same uid as current user
*
Expand All @@ -124,7 +126,68 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)

if (!return_fid) {
dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n");
return_fid = ERR_PTR(-EBADF);
}

if(down_interruptible(&return_fid->lock))
return ERR_PTR(-EINTR);

return return_fid;
}

/**
* v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it
* @dentry: dentry to look for fid in
*
* find a fid in the dentry and then clone to a new private fid
*
* TODO: only match fids that have the same uid as current user
*
*/

struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry)
{
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF);
struct v9fs_fcall *fcall = NULL;
int fid, err;

base_fid = v9fs_fid_lookup(dentry);

if(IS_ERR(base_fid))
return base_fid;

if(base_fid) { /* clone fid */
fid = v9fs_get_idpool(&v9ses->fidpool);
if (fid < 0) {
eprintk(KERN_WARNING, "newfid fails!\n");
new_fid = ERR_PTR(-ENOSPC);
goto Release_Fid;
}

err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall);
if (err < 0) {
dprintk(DEBUG_ERROR, "clone walk didn't work\n");
v9fs_put_idpool(fid, &v9ses->fidpool);
new_fid = ERR_PTR(err);
goto Free_Fcall;
}
new_fid = v9fs_fid_create(v9ses, fid);
if (new_fid == NULL) {
dprintk(DEBUG_ERROR, "out of memory\n");
new_fid = ERR_PTR(-ENOMEM);
}
Free_Fcall:
kfree(fcall);
}

Release_Fid:
up(&base_fid->lock);
return new_fid;
}

void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid)
{
v9fs_t_clunk(v9ses, fid->fid);
v9fs_fid_destroy(fid);
}
5 changes: 5 additions & 0 deletions trunk/fs/9p/fid.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ struct v9fs_fid {
struct list_head list; /* list of fids associated with a dentry */
struct list_head active; /* XXX - debug */

struct semaphore lock;

u32 fid;
unsigned char fidopen; /* set when fid is opened */
unsigned char fidclunked; /* set when fid has already been clunked */
Expand All @@ -55,3 +57,6 @@ struct v9fs_fid *v9fs_fid_get_created(struct dentry *);
void v9fs_fid_destroy(struct v9fs_fid *fid);
struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid);
int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry);
struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry);
void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid);

47 changes: 7 additions & 40 deletions trunk/fs/9p/vfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,53 +55,22 @@ int v9fs_file_open(struct inode *inode, struct file *file)
struct v9fs_fid *vfid;
struct v9fs_fcall *fcall = NULL;
int omode;
int fid = V9FS_NOFID;
int err;

dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file);

vfid = v9fs_fid_lookup(file->f_path.dentry);
if (!vfid) {
dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n");
return -EBADF;
}

fid = v9fs_get_idpool(&v9ses->fidpool);
if (fid < 0) {
eprintk(KERN_WARNING, "newfid fails!\n");
return -ENOSPC;
}
vfid = v9fs_fid_clone(file->f_path.dentry);
if (IS_ERR(vfid))
return PTR_ERR(vfid);

err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall);
if (err < 0) {
dprintk(DEBUG_ERROR, "rewalk didn't work\n");
if (fcall && fcall->id == RWALK)
goto clunk_fid;
else {
v9fs_put_idpool(fid, &v9ses->fidpool);
goto free_fcall;
}
}
kfree(fcall);

/* 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);
err = v9fs_t_open(v9ses, vfid->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;
goto Clunk_Fid;
}

file->private_data = vfid;
vfid->fid = fid;
vfid->fidopen = 1;
vfid->fidclunked = 0;
vfid->iounit = fcall->params.ropen.iounit;
Expand All @@ -112,10 +81,8 @@ int v9fs_file_open(struct inode *inode, struct file *file)

return 0;

clunk_fid:
v9fs_t_clunk(v9ses, fid);

free_fcall:
Clunk_Fid:
v9fs_fid_clunk(v9ses, vfid);
kfree(fcall);

return err;
Expand Down
Loading

0 comments on commit d320915

Please sign in to comment.