forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
v9fs has been plagued by an over-complicated approach trying to map Linux dentry semantics to Plan 9 fid semantics. Our previous approach called for aggressive flushing of the dcache resulting in several problems (including wierd cwd behavior when running /bin/pwd). This patch dramatically simplifies our handling of this fid management. Fids will not be clunked as promptly, but the new approach is more functionally correct. We now clunk un-open fids only when their dentry ref_count reaches 0 (and d_delete is called). Another simplification is we no longer seek to match fids to the process-id or uid of the action initiator. The uid-matching will need to be revisited when we fix the security model. Signed-off-by: Eric Van Hensbergen <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
- Loading branch information
Showing
4 changed files
with
15 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/* | ||
* V9FS FID Management | ||
* | ||
* Copyright (C) 2005 by Eric Van Hensbergen <[email protected]> | ||
* Copyright (C) 2005, 2006 by Eric Van Hensbergen <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
|
@@ -57,7 +57,6 @@ int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) | |
} | ||
|
||
fid->uid = current->uid; | ||
fid->pid = current->pid; | ||
list_add(&fid->list, fid_list); | ||
return 0; | ||
} | ||
|
@@ -88,7 +87,7 @@ struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) | |
new->rdir_fcall = NULL; | ||
INIT_LIST_HEAD(&new->list); | ||
|
||
return new; | ||
return new; | ||
} | ||
|
||
/** | ||
|
@@ -103,76 +102,14 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) | |
kfree(fid); | ||
} | ||
|
||
/** | ||
* v9fs_fid_walk_up - walks from the process current directory | ||
* up to the specified dentry. | ||
*/ | ||
static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) | ||
{ | ||
int fidnum, cfidnum, err; | ||
struct v9fs_fid *cfid, *fid; | ||
struct dentry *cde; | ||
struct v9fs_session_info *v9ses; | ||
|
||
v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode); | ||
cfid = v9fs_fid_lookup(current->fs->pwd); | ||
if (cfid == NULL) { | ||
dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n"); | ||
return ERR_PTR(-ENOENT); | ||
} | ||
|
||
cfidnum = cfid->fid; | ||
cde = current->fs->pwd; | ||
/* TODO: take advantage of multiwalk */ | ||
|
||
fidnum = v9fs_get_idpool(&v9ses->fidpool); | ||
if (fidnum < 0) { | ||
dprintk(DEBUG_ERROR, "could not get a new fid num\n"); | ||
err = -ENOENT; | ||
goto clunk_fid; | ||
} | ||
|
||
while (cde != dentry) { | ||
if (cde == cde->d_parent) { | ||
dprintk(DEBUG_ERROR, "can't find dentry\n"); | ||
err = -ENOENT; | ||
goto clunk_fid; | ||
} | ||
|
||
err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL); | ||
if (err < 0) { | ||
dprintk(DEBUG_ERROR, "problem walking to parent\n"); | ||
goto clunk_fid; | ||
} | ||
|
||
cfidnum = fidnum; | ||
cde = cde->d_parent; | ||
} | ||
|
||
fid = v9fs_fid_create(v9ses, fidnum); | ||
if (fid) { | ||
err = v9fs_fid_insert(fid, dentry); | ||
if (err < 0) { | ||
kfree(fid); | ||
goto clunk_fid; | ||
} | ||
} | ||
|
||
return fid; | ||
|
||
clunk_fid: | ||
v9fs_t_clunk(v9ses, fidnum); | ||
return ERR_PTR(err); | ||
} | ||
|
||
/** | ||
* v9fs_fid_lookup - retrieve the right fid from a particular dentry | ||
* @dentry: dentry to look for fid in | ||
* @type: intent of lookup (operation or traversal) | ||
* | ||
* search list of fids associated with a dentry for a fid with a matching | ||
* thread id or uid. If that fails, look up the dentry's parents to see if you | ||
* can find a matching fid. | ||
* find a fid in the dentry | ||
* | ||
* TODO: only match fids that have the same uid as current user | ||
* | ||
*/ | ||
|
||
|
@@ -187,26 +124,7 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) | |
return_fid = list_entry(fid_list->next, struct v9fs_fid, list); | ||
|
||
if (!return_fid) { | ||
struct dentry *par = current->fs->pwd->d_parent; | ||
int count = 1; | ||
while (par != NULL) { | ||
if (par == dentry) | ||
break; | ||
count++; | ||
if (par == par->d_parent) { | ||
dprintk(DEBUG_ERROR, | ||
"got to root without finding dentry\n"); | ||
break; | ||
} | ||
par = par->d_parent; | ||
} | ||
|
||
/* XXX - there may be some duplication we can get rid of */ | ||
if (par == dentry) { | ||
return_fid = v9fs_fid_walk_up(dentry); | ||
if (IS_ERR(return_fid)) | ||
return_fid = NULL; | ||
} | ||
dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); | ||
} | ||
|
||
return return_fid; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters