diff options
Diffstat (limited to 'fs/afs/vnode.c')
-rw-r--r-- | fs/afs/vnode.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c index 0e37f9949cb7..ec814660209f 100644 --- a/fs/afs/vnode.c +++ b/fs/afs/vnode.c | |||
@@ -753,3 +753,110 @@ no_server: | |||
753 | _leave(" = %ld [cnt %d]", PTR_ERR(server), orig_dvnode->update_cnt); | 753 | _leave(" = %ld [cnt %d]", PTR_ERR(server), orig_dvnode->update_cnt); |
754 | return PTR_ERR(server); | 754 | return PTR_ERR(server); |
755 | } | 755 | } |
756 | |||
757 | /* | ||
758 | * write to a file | ||
759 | */ | ||
760 | int afs_vnode_store_data(struct afs_writeback *wb, pgoff_t first, pgoff_t last, | ||
761 | unsigned offset, unsigned to) | ||
762 | { | ||
763 | struct afs_server *server; | ||
764 | struct afs_vnode *vnode = wb->vnode; | ||
765 | int ret; | ||
766 | |||
767 | _enter("%s{%x:%u.%u},%x,%lx,%lx,%x,%x", | ||
768 | vnode->volume->vlocation->vldb.name, | ||
769 | vnode->fid.vid, | ||
770 | vnode->fid.vnode, | ||
771 | vnode->fid.unique, | ||
772 | key_serial(wb->key), | ||
773 | first, last, offset, to); | ||
774 | |||
775 | /* this op will fetch the status */ | ||
776 | spin_lock(&vnode->lock); | ||
777 | vnode->update_cnt++; | ||
778 | spin_unlock(&vnode->lock); | ||
779 | |||
780 | do { | ||
781 | /* pick a server to query */ | ||
782 | server = afs_volume_pick_fileserver(vnode); | ||
783 | if (IS_ERR(server)) | ||
784 | goto no_server; | ||
785 | |||
786 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); | ||
787 | |||
788 | ret = afs_fs_store_data(server, wb, first, last, offset, to, | ||
789 | &afs_sync_call); | ||
790 | |||
791 | } while (!afs_volume_release_fileserver(vnode, server, ret)); | ||
792 | |||
793 | /* adjust the flags */ | ||
794 | if (ret == 0) { | ||
795 | afs_vnode_finalise_status_update(vnode, server); | ||
796 | afs_put_server(server); | ||
797 | } else { | ||
798 | afs_vnode_status_update_failed(vnode, ret); | ||
799 | } | ||
800 | |||
801 | _leave(" = %d", ret); | ||
802 | return ret; | ||
803 | |||
804 | no_server: | ||
805 | spin_lock(&vnode->lock); | ||
806 | vnode->update_cnt--; | ||
807 | ASSERTCMP(vnode->update_cnt, >=, 0); | ||
808 | spin_unlock(&vnode->lock); | ||
809 | return PTR_ERR(server); | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * set the attributes on a file | ||
814 | */ | ||
815 | int afs_vnode_setattr(struct afs_vnode *vnode, struct key *key, | ||
816 | struct iattr *attr) | ||
817 | { | ||
818 | struct afs_server *server; | ||
819 | int ret; | ||
820 | |||
821 | _enter("%s{%x:%u.%u},%x", | ||
822 | vnode->volume->vlocation->vldb.name, | ||
823 | vnode->fid.vid, | ||
824 | vnode->fid.vnode, | ||
825 | vnode->fid.unique, | ||
826 | key_serial(key)); | ||
827 | |||
828 | /* this op will fetch the status */ | ||
829 | spin_lock(&vnode->lock); | ||
830 | vnode->update_cnt++; | ||
831 | spin_unlock(&vnode->lock); | ||
832 | |||
833 | do { | ||
834 | /* pick a server to query */ | ||
835 | server = afs_volume_pick_fileserver(vnode); | ||
836 | if (IS_ERR(server)) | ||
837 | goto no_server; | ||
838 | |||
839 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); | ||
840 | |||
841 | ret = afs_fs_setattr(server, key, vnode, attr, &afs_sync_call); | ||
842 | |||
843 | } while (!afs_volume_release_fileserver(vnode, server, ret)); | ||
844 | |||
845 | /* adjust the flags */ | ||
846 | if (ret == 0) { | ||
847 | afs_vnode_finalise_status_update(vnode, server); | ||
848 | afs_put_server(server); | ||
849 | } else { | ||
850 | afs_vnode_status_update_failed(vnode, ret); | ||
851 | } | ||
852 | |||
853 | _leave(" = %d", ret); | ||
854 | return ret; | ||
855 | |||
856 | no_server: | ||
857 | spin_lock(&vnode->lock); | ||
858 | vnode->update_cnt--; | ||
859 | ASSERTCMP(vnode->update_cnt, >=, 0); | ||
860 | spin_unlock(&vnode->lock); | ||
861 | return PTR_ERR(server); | ||
862 | } | ||