AFS: implement file locking
Implement file locking for AFS. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
b0fed3140f
commit
e8d6c55412
130
fs/afs/vnode.c
130
fs/afs/vnode.c
@@ -887,11 +887,6 @@ int afs_vnode_get_volume_status(struct afs_vnode *vnode, struct key *key,
|
||||
vnode->fid.unique,
|
||||
key_serial(key));
|
||||
|
||||
/* this op will fetch the status */
|
||||
spin_lock(&vnode->lock);
|
||||
vnode->update_cnt++;
|
||||
spin_unlock(&vnode->lock);
|
||||
|
||||
do {
|
||||
/* pick a server to query */
|
||||
server = afs_volume_pick_fileserver(vnode);
|
||||
@@ -905,20 +900,127 @@ int afs_vnode_get_volume_status(struct afs_vnode *vnode, struct key *key,
|
||||
} while (!afs_volume_release_fileserver(vnode, server, ret));
|
||||
|
||||
/* adjust the flags */
|
||||
if (ret == 0) {
|
||||
afs_vnode_finalise_status_update(vnode, server);
|
||||
if (ret == 0)
|
||||
afs_put_server(server);
|
||||
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
|
||||
no_server:
|
||||
return PTR_ERR(server);
|
||||
}
|
||||
|
||||
/*
|
||||
* get a lock on a file
|
||||
*/
|
||||
int afs_vnode_set_lock(struct afs_vnode *vnode, struct key *key,
|
||||
afs_lock_type_t type)
|
||||
{
|
||||
struct afs_server *server;
|
||||
int ret;
|
||||
|
||||
_enter("%s{%x:%u.%u},%x,%u",
|
||||
vnode->volume->vlocation->vldb.name,
|
||||
vnode->fid.vid,
|
||||
vnode->fid.vnode,
|
||||
vnode->fid.unique,
|
||||
key_serial(key), type);
|
||||
|
||||
do {
|
||||
/* pick a server to query */
|
||||
server = afs_volume_pick_fileserver(vnode);
|
||||
if (IS_ERR(server))
|
||||
goto no_server;
|
||||
|
||||
_debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr));
|
||||
|
||||
ret = afs_fs_set_lock(server, key, vnode, type, &afs_sync_call);
|
||||
|
||||
} while (!afs_volume_release_fileserver(vnode, server, ret));
|
||||
|
||||
/* adjust the flags */
|
||||
if (ret == 0)
|
||||
afs_put_server(server);
|
||||
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
|
||||
no_server:
|
||||
return PTR_ERR(server);
|
||||
}
|
||||
|
||||
/*
|
||||
* extend a lock on a file
|
||||
*/
|
||||
int afs_vnode_extend_lock(struct afs_vnode *vnode, struct key *key)
|
||||
{
|
||||
struct afs_server *server;
|
||||
int ret;
|
||||
|
||||
_enter("%s{%x:%u.%u},%x",
|
||||
vnode->volume->vlocation->vldb.name,
|
||||
vnode->fid.vid,
|
||||
vnode->fid.vnode,
|
||||
vnode->fid.unique,
|
||||
key_serial(key));
|
||||
|
||||
do {
|
||||
/* pick a server to query */
|
||||
server = afs_volume_pick_fileserver(vnode);
|
||||
if (IS_ERR(server))
|
||||
goto no_server;
|
||||
|
||||
_debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr));
|
||||
|
||||
ret = afs_fs_extend_lock(server, key, vnode, &afs_sync_call);
|
||||
|
||||
} while (!afs_volume_release_fileserver(vnode, server, ret));
|
||||
|
||||
/* adjust the flags */
|
||||
if (ret == 0)
|
||||
afs_put_server(server);
|
||||
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
|
||||
no_server:
|
||||
return PTR_ERR(server);
|
||||
}
|
||||
|
||||
/*
|
||||
* release a lock on a file
|
||||
*/
|
||||
int afs_vnode_release_lock(struct afs_vnode *vnode, struct key *key)
|
||||
{
|
||||
struct afs_server *server;
|
||||
int ret;
|
||||
|
||||
_enter("%s{%x:%u.%u},%x",
|
||||
vnode->volume->vlocation->vldb.name,
|
||||
vnode->fid.vid,
|
||||
vnode->fid.vnode,
|
||||
vnode->fid.unique,
|
||||
key_serial(key));
|
||||
|
||||
do {
|
||||
/* pick a server to query */
|
||||
server = afs_volume_pick_fileserver(vnode);
|
||||
if (IS_ERR(server))
|
||||
goto no_server;
|
||||
|
||||
_debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr));
|
||||
|
||||
ret = afs_fs_release_lock(server, key, vnode, &afs_sync_call);
|
||||
|
||||
} while (!afs_volume_release_fileserver(vnode, server, ret));
|
||||
|
||||
/* adjust the flags */
|
||||
if (ret == 0)
|
||||
afs_put_server(server);
|
||||
} else {
|
||||
afs_vnode_status_update_failed(vnode, ret);
|
||||
}
|
||||
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
|
||||
no_server:
|
||||
spin_lock(&vnode->lock);
|
||||
vnode->update_cnt--;
|
||||
ASSERTCMP(vnode->update_cnt, >=, 0);
|
||||
spin_unlock(&vnode->lock);
|
||||
return PTR_ERR(server);
|
||||
}
|
||||
|
Reference in New Issue
Block a user