afs: Fix cell DNS lookup
[linux-2.6-microblaze.git] / fs / afs / vl_rotate.c
index 65629d7..3f84548 100644 (file)
@@ -43,11 +43,29 @@ bool afs_begin_vlserver_operation(struct afs_vl_cursor *vc, struct afs_cell *cel
 static bool afs_start_vl_iteration(struct afs_vl_cursor *vc)
 {
        struct afs_cell *cell = vc->cell;
+       unsigned int dns_lookup_count;
+
+       if (cell->dns_source == DNS_RECORD_UNAVAILABLE ||
+           cell->dns_expiry <= ktime_get_real_seconds()) {
+               dns_lookup_count = smp_load_acquire(&cell->dns_lookup_count);
+               set_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags);
+               queue_work(afs_wq, &cell->manager);
+
+               if (cell->dns_source == DNS_RECORD_UNAVAILABLE) {
+                       if (wait_var_event_interruptible(
+                                   &cell->dns_lookup_count,
+                                   smp_load_acquire(&cell->dns_lookup_count)
+                                   != dns_lookup_count) < 0) {
+                               vc->error = -ERESTARTSYS;
+                               return false;
+                       }
+               }
 
-       if (wait_on_bit(&cell->flags, AFS_CELL_FL_NO_LOOKUP_YET,
-                       TASK_INTERRUPTIBLE)) {
-               vc->error = -ERESTARTSYS;
-               return false;
+               /* Status load is ordered after lookup counter load */
+               if (cell->dns_source == DNS_RECORD_UNAVAILABLE) {
+                       vc->error = -EDESTADDRREQ;
+                       return false;
+               }
        }
 
        read_lock(&cell->vl_servers_lock);