Coda: add spin lock to protect accesses to struct coda_inode_info.
We mostly need it to protect cached user permissions. The c_flags field is advisory, reading the wrong value is harmless and in the worst case we hit a slow path where we have to make an extra upcall to the userspace cache manager when revalidating a dentry or inode. Signed-off-by: Yoshihisa Abe <yoshiabe@cs.cmu.edu> Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
3a99c63190
commit
b5ce1d83a6
@@ -45,13 +45,15 @@ static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
|
||||
static int coda_test_inode(struct inode *inode, void *data)
|
||||
{
|
||||
struct CodaFid *fid = (struct CodaFid *)data;
|
||||
return coda_fideq(&(ITOC(inode)->c_fid), fid);
|
||||
struct coda_inode_info *cii = ITOC(inode);
|
||||
return coda_fideq(&cii->c_fid, fid);
|
||||
}
|
||||
|
||||
static int coda_set_inode(struct inode *inode, void *data)
|
||||
{
|
||||
struct CodaFid *fid = (struct CodaFid *)data;
|
||||
ITOC(inode)->c_fid = *fid;
|
||||
struct coda_inode_info *cii = ITOC(inode);
|
||||
cii->c_fid = *fid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -71,6 +73,7 @@ struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,
|
||||
cii = ITOC(inode);
|
||||
/* we still need to set i_ino for things like stat(2) */
|
||||
inode->i_ino = hash;
|
||||
/* inode is locked and unique, no need to grab cii->c_lock */
|
||||
cii->c_mapcount = 0;
|
||||
unlock_new_inode(inode);
|
||||
}
|
||||
@@ -107,14 +110,20 @@ int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_bloc
|
||||
}
|
||||
|
||||
|
||||
/* Although we treat Coda file identifiers as immutable, there is one
|
||||
* special case for files created during a disconnection where they may
|
||||
* not be globally unique. When an identifier collision is detected we
|
||||
* first try to flush the cached inode from the kernel and finally
|
||||
* resort to renaming/rehashing in-place. Userspace remembers both old
|
||||
* and new values of the identifier to handle any in-flight upcalls.
|
||||
* The real solution is to use globally unique UUIDs as identifiers, but
|
||||
* retrofitting the existing userspace code for this is non-trivial. */
|
||||
void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid,
|
||||
struct CodaFid *newfid)
|
||||
{
|
||||
struct coda_inode_info *cii;
|
||||
struct coda_inode_info *cii = ITOC(inode);
|
||||
unsigned long hash = coda_f2i(newfid);
|
||||
|
||||
cii = ITOC(inode);
|
||||
|
||||
BUG_ON(!coda_fideq(&cii->c_fid, oldfid));
|
||||
|
||||
/* replace fid and rehash inode */
|
||||
|
||||
Reference in New Issue
Block a user