aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/xenbus
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 18:22:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 18:22:42 -0400
commit2f9e825d3e0e2b407ae8f082de5c00afcf7378fb (patch)
treef8b3ee40674ce4acd5508a0a0bf52a30904caf6c /drivers/xen/xenbus
parent7ae0dea900b027cd90e8a3e14deca9a19e17638b (diff)
parentde75d60d5ea235e6e09f4962ab22541ce0fe176a (diff)
Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block: (149 commits) block: make sure that REQ_* types are seen even with CONFIG_BLOCK=n xen-blkfront: fix missing out label blkdev: fix blkdev_issue_zeroout return value block: update request stacking methods to support discards block: fix missing export of blk_types.h writeback: fix bad _bh spinlock nesting drbd: revert "delay probes", feature is being re-implemented differently drbd: Initialize all members of sync_conf to their defaults [Bugz 315] drbd: Disable delay probes for the upcomming release writeback: cleanup bdi_register writeback: add new tracepoints writeback: remove unnecessary init_timer call writeback: optimize periodic bdi thread wakeups writeback: prevent unnecessary bdi threads wakeups writeback: move bdi threads exiting logic to the forker thread writeback: restructure bdi forker loop a little writeback: move last_active to bdi writeback: do not remove bdi from bdi_list writeback: simplify bdi code a little writeback: do not lose wake-ups in bdi threads ... Fixed up pretty trivial conflicts in drivers/block/virtio_blk.c and drivers/scsi/scsi_error.c as per Jens.
Diffstat (limited to 'drivers/xen/xenbus')
-rw-r--r--drivers/xen/xenbus/xenbus_client.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 7b3e973a1aee..7e49527189b6 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -133,17 +133,12 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev,
133} 133}
134EXPORT_SYMBOL_GPL(xenbus_watch_pathfmt); 134EXPORT_SYMBOL_GPL(xenbus_watch_pathfmt);
135 135
136static void xenbus_switch_fatal(struct xenbus_device *, int, int,
137 const char *, ...);
136 138
137/** 139static int
138 * xenbus_switch_state 140__xenbus_switch_state(struct xenbus_device *dev,
139 * @dev: xenbus device 141 enum xenbus_state state, int depth)
140 * @state: new state
141 *
142 * Advertise in the store a change of the given driver to the given new_state.
143 * Return 0 on success, or -errno on error. On error, the device will switch
144 * to XenbusStateClosing, and the error will be saved in the store.
145 */
146int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
147{ 142{
148 /* We check whether the state is currently set to the given value, and 143 /* We check whether the state is currently set to the given value, and
149 if not, then the state is set. We don't want to unconditionally 144 if not, then the state is set. We don't want to unconditionally
@@ -152,35 +147,65 @@ int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
152 to it, as the device will be tearing down, and we don't want to 147 to it, as the device will be tearing down, and we don't want to
153 resurrect that directory. 148 resurrect that directory.
154 149
155 Note that, because of this cached value of our state, this function 150 Note that, because of this cached value of our state, this
156 will not work inside a Xenstore transaction (something it was 151 function will not take a caller's Xenstore transaction
157 trying to in the past) because dev->state would not get reset if 152 (something it was trying to in the past) because dev->state
158 the transaction was aborted. 153 would not get reset if the transaction was aborted.
159
160 */ 154 */
161 155
156 struct xenbus_transaction xbt;
162 int current_state; 157 int current_state;
163 int err; 158 int err, abort;
164 159
165 if (state == dev->state) 160 if (state == dev->state)
166 return 0; 161 return 0;
167 162
168 err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d", 163again:
169 &current_state); 164 abort = 1;
170 if (err != 1) 165
166 err = xenbus_transaction_start(&xbt);
167 if (err) {
168 xenbus_switch_fatal(dev, depth, err, "starting transaction");
171 return 0; 169 return 0;
170 }
171
172 err = xenbus_scanf(xbt, dev->nodename, "state", "%d", &current_state);
173 if (err != 1)
174 goto abort;
172 175
173 err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state); 176 err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
174 if (err) { 177 if (err) {
175 if (state != XenbusStateClosing) /* Avoid looping */ 178 xenbus_switch_fatal(dev, depth, err, "writing new state");
176 xenbus_dev_fatal(dev, err, "writing new state"); 179 goto abort;
177 return err;
178 } 180 }
179 181
180 dev->state = state; 182 abort = 0;
183abort:
184 err = xenbus_transaction_end(xbt, abort);
185 if (err) {
186 if (err == -EAGAIN && !abort)
187 goto again;
188 xenbus_switch_fatal(dev, depth, err, "ending transaction");
189 } else
190 dev->state = state;
181 191
182 return 0; 192 return 0;
183} 193}
194
195/**
196 * xenbus_switch_state
197 * @dev: xenbus device
198 * @state: new state
199 *
200 * Advertise in the store a change of the given driver to the given new_state.
201 * Return 0 on success, or -errno on error. On error, the device will switch
202 * to XenbusStateClosing, and the error will be saved in the store.
203 */
204int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
205{
206 return __xenbus_switch_state(dev, state, 0);
207}
208
184EXPORT_SYMBOL_GPL(xenbus_switch_state); 209EXPORT_SYMBOL_GPL(xenbus_switch_state);
185 210
186int xenbus_frontend_closed(struct xenbus_device *dev) 211int xenbus_frontend_closed(struct xenbus_device *dev)
@@ -284,6 +309,23 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...)
284EXPORT_SYMBOL_GPL(xenbus_dev_fatal); 309EXPORT_SYMBOL_GPL(xenbus_dev_fatal);
285 310
286/** 311/**
312 * Equivalent to xenbus_dev_fatal(dev, err, fmt, args), but helps
313 * avoiding recursion within xenbus_switch_state.
314 */
315static void xenbus_switch_fatal(struct xenbus_device *dev, int depth, int err,
316 const char *fmt, ...)
317{
318 va_list ap;
319
320 va_start(ap, fmt);
321 xenbus_va_dev_error(dev, err, fmt, ap);
322 va_end(ap);
323
324 if (!depth)
325 __xenbus_switch_state(dev, XenbusStateClosing, 1);
326}
327
328/**
287 * xenbus_grant_ring 329 * xenbus_grant_ring
288 * @dev: xenbus device 330 * @dev: xenbus device
289 * @ring_mfn: mfn of ring to grant 331 * @ring_mfn: mfn of ring to grant