diff options
author | David Howells <dhowells@redhat.com> | 2007-07-16 02:40:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 12:05:43 -0400 |
commit | e8d6c554126b830217c5e9f549e0e21f865a0a8a (patch) | |
tree | c43219c6ef4e6a9b4f0ac46d6bd8b675dc249a8b /fs/afs/vnode.c | |
parent | b0fed3140f57c435d2783b698c5090f325c22bad (diff) |
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>
Diffstat (limited to 'fs/afs/vnode.c')
-rw-r--r-- | fs/afs/vnode.c | 130 |
1 files changed, 116 insertions, 14 deletions
diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c index 232c55dc245d..ac811e445b2d 100644 --- a/fs/afs/vnode.c +++ b/fs/afs/vnode.c | |||
@@ -887,11 +887,6 @@ int afs_vnode_get_volume_status(struct afs_vnode *vnode, struct key *key, | |||
887 | vnode->fid.unique, | 887 | vnode->fid.unique, |
888 | key_serial(key)); | 888 | key_serial(key)); |
889 | 889 | ||
890 | /* this op will fetch the status */ | ||
891 | spin_lock(&vnode->lock); | ||
892 | vnode->update_cnt++; | ||
893 | spin_unlock(&vnode->lock); | ||
894 | |||
895 | do { | 890 | do { |
896 | /* pick a server to query */ | 891 | /* pick a server to query */ |
897 | server = afs_volume_pick_fileserver(vnode); | 892 | server = afs_volume_pick_fileserver(vnode); |
@@ -905,20 +900,127 @@ int afs_vnode_get_volume_status(struct afs_vnode *vnode, struct key *key, | |||
905 | } while (!afs_volume_release_fileserver(vnode, server, ret)); | 900 | } while (!afs_volume_release_fileserver(vnode, server, ret)); |
906 | 901 | ||
907 | /* adjust the flags */ | 902 | /* adjust the flags */ |
908 | if (ret == 0) { | 903 | if (ret == 0) |
909 | afs_vnode_finalise_status_update(vnode, server); | 904 | afs_put_server(server); |
905 | |||
906 | _leave(" = %d", ret); | ||
907 | return ret; | ||
908 | |||
909 | no_server: | ||
910 | return PTR_ERR(server); | ||
911 | } | ||
912 | |||
913 | /* | ||
914 | * get a lock on a file | ||
915 | */ | ||
916 | int afs_vnode_set_lock(struct afs_vnode *vnode, struct key *key, | ||
917 | afs_lock_type_t type) | ||
918 | { | ||
919 | struct afs_server *server; | ||
920 | int ret; | ||
921 | |||
922 | _enter("%s{%x:%u.%u},%x,%u", | ||
923 | vnode->volume->vlocation->vldb.name, | ||
924 | vnode->fid.vid, | ||
925 | vnode->fid.vnode, | ||
926 | vnode->fid.unique, | ||
927 | key_serial(key), type); | ||
928 | |||
929 | do { | ||
930 | /* pick a server to query */ | ||
931 | server = afs_volume_pick_fileserver(vnode); | ||
932 | if (IS_ERR(server)) | ||
933 | goto no_server; | ||
934 | |||
935 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); | ||
936 | |||
937 | ret = afs_fs_set_lock(server, key, vnode, type, &afs_sync_call); | ||
938 | |||
939 | } while (!afs_volume_release_fileserver(vnode, server, ret)); | ||
940 | |||
941 | /* adjust the flags */ | ||
942 | if (ret == 0) | ||
943 | afs_put_server(server); | ||
944 | |||
945 | _leave(" = %d", ret); | ||
946 | return ret; | ||
947 | |||
948 | no_server: | ||
949 | return PTR_ERR(server); | ||
950 | } | ||
951 | |||
952 | /* | ||
953 | * extend a lock on a file | ||
954 | */ | ||
955 | int afs_vnode_extend_lock(struct afs_vnode *vnode, struct key *key) | ||
956 | { | ||
957 | struct afs_server *server; | ||
958 | int ret; | ||
959 | |||
960 | _enter("%s{%x:%u.%u},%x", | ||
961 | vnode->volume->vlocation->vldb.name, | ||
962 | vnode->fid.vid, | ||
963 | vnode->fid.vnode, | ||
964 | vnode->fid.unique, | ||
965 | key_serial(key)); | ||
966 | |||
967 | do { | ||
968 | /* pick a server to query */ | ||
969 | server = afs_volume_pick_fileserver(vnode); | ||
970 | if (IS_ERR(server)) | ||
971 | goto no_server; | ||
972 | |||
973 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); | ||
974 | |||
975 | ret = afs_fs_extend_lock(server, key, vnode, &afs_sync_call); | ||
976 | |||
977 | } while (!afs_volume_release_fileserver(vnode, server, ret)); | ||
978 | |||
979 | /* adjust the flags */ | ||
980 | if (ret == 0) | ||
981 | afs_put_server(server); | ||
982 | |||
983 | _leave(" = %d", ret); | ||
984 | return ret; | ||
985 | |||
986 | no_server: | ||
987 | return PTR_ERR(server); | ||
988 | } | ||
989 | |||
990 | /* | ||
991 | * release a lock on a file | ||
992 | */ | ||
993 | int afs_vnode_release_lock(struct afs_vnode *vnode, struct key *key) | ||
994 | { | ||
995 | struct afs_server *server; | ||
996 | int ret; | ||
997 | |||
998 | _enter("%s{%x:%u.%u},%x", | ||
999 | vnode->volume->vlocation->vldb.name, | ||
1000 | vnode->fid.vid, | ||
1001 | vnode->fid.vnode, | ||
1002 | vnode->fid.unique, | ||
1003 | key_serial(key)); | ||
1004 | |||
1005 | do { | ||
1006 | /* pick a server to query */ | ||
1007 | server = afs_volume_pick_fileserver(vnode); | ||
1008 | if (IS_ERR(server)) | ||
1009 | goto no_server; | ||
1010 | |||
1011 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); | ||
1012 | |||
1013 | ret = afs_fs_release_lock(server, key, vnode, &afs_sync_call); | ||
1014 | |||
1015 | } while (!afs_volume_release_fileserver(vnode, server, ret)); | ||
1016 | |||
1017 | /* adjust the flags */ | ||
1018 | if (ret == 0) | ||
910 | afs_put_server(server); | 1019 | afs_put_server(server); |
911 | } else { | ||
912 | afs_vnode_status_update_failed(vnode, ret); | ||
913 | } | ||
914 | 1020 | ||
915 | _leave(" = %d", ret); | 1021 | _leave(" = %d", ret); |
916 | return ret; | 1022 | return ret; |
917 | 1023 | ||
918 | no_server: | 1024 | no_server: |
919 | spin_lock(&vnode->lock); | ||
920 | vnode->update_cnt--; | ||
921 | ASSERTCMP(vnode->update_cnt, >=, 0); | ||
922 | spin_unlock(&vnode->lock); | ||
923 | return PTR_ERR(server); | 1025 | return PTR_ERR(server); |
924 | } | 1026 | } |