Re: To Unmount Or Not To Unmount
Ingo Weinhold <bonefish-CFLBMwTPW48UNGrzBIF7/[email protected]> Tue, 23 Sep 2003 23:09:44 +0200
| Newsgroups | gmane.os.openbeos.storage |
|---|---|
| Message-ID | <[email protected]> |
On 2003-09-23 at 20:38:24 [+0200], Axel D=F6rfler wrote: > Tyler Dauwalder <tyler-cyCl/[email protected]> wrote: > > On 2003-09-22 at 13:24:33 [-0700], Ingo Weinhold wrote: > > > In favor of unmounting on commit speaks, that the behavior would be > > > consistent with the other modifying methods. On the other hand, > > > mounting/unmounting can be done by a third party at any time, even > > > if one > > > is preparing modifications at that time. > > I thought we were going to serialize all mounting and unmounting > > through > > the ddm. Thus, the system unmount() call ought to work via ddm calls, > > which > > means (assuming we use "on commit" semantics) that unmount() will > > simply > > fail if someone is preparing modifications on a given partition's > > device >=20 > That's what I thought, too... that's what the integration with the VFS > is all about, right? I should clarify the situations that can occur: 1) Partition is busy: There are scheduled or already executing jobs, that= =20 affect the partition. Jobs are scheduled, when=20 BDiskDevice::CommitModifications() is invoked. 2) A user has invoked BDiskDevice::PrepareModifications() (started a=20 transaction, to use that term) but not yet called=20 BDiskDevice::{Cancel,Commit}Modifications() (rolled back respectively=20 committed the transaction). a) Mount()/Unmount() is invoked on a BPartition object belonging to the=20 very same BDiskDevice object. b) Mount()/Unmount() is invoked on a BPartition object belonging to anoth= er=20 user (but of course referring to the same partition). c) mount()/unmount() is invoked for the partition. There's no further distinction of cases for 1), because in any case, the=20 same must happen: mount(), unmount(), Mount(), Unmount() must fail, for=20 otherwise we'd risk, that something bad will happen, if the mount state=20 changes behind the back of a job that operates on that partition. What shall happen in the case 2)a)-c) was subject of my mail. :-) > > (correct? I've forgotten how fine the locking granularity is when you > > prep modifications, but I think it's by device isn't it?). Yep it is. > > Furthermore,=20 > > once Commit() has been called, aren't the partitions of interest lock= ed=20 > > until all the jobs that affect them are completed? Not locked, but marked busy. That is you can still read/write lock them (= in=20 the kernel), but certain operations on it shall fail, namely preparing ne= w=20 modifications for them (more precisely: PrepareModifications() will work=20 fine, but any operation that would affect a busy partition will fail), an= d=20 mounting/unmounting. > > This seems like an=20 > > (almost :-) reasonable restriction to me: once you start planning a s= et=20 > > of jobs that involve a partition, you can't mount/unmount it until yo= u=20 > > cancel or no more=20 > > jobs remain that affect that partition. Please don't mix that up. Until you commit the changes you're in the=20 situation 2) (and there aren't any jobs yet), that is, in principle,=20 there'd be no problem with mounting/unmounting immediately. At least from= =20 the DDM point of view. > > We could add an appropriate > > error > > code so we could give a reasonable error message in Tracker and > > mount()/unmount(), suggesting that "The partition is locked, perhaps > > you're > > mucking around with things in DriveSetup?" similar to the busy > > message you > > get when you try to unmount a CD you're currently playing in > > SoundPlay. The > > only problem I see with this so far is that it does seems better to > > allow a > > partition to be unmounted even if jobs are being prepared for it, but > > perhaps this would be justification for a hybrid approach with > > Unmount() as > > addressed below. >=20 > Not sure about that - the jobs in question should know about the drive > status; I could imagine that their operation is different when the disk > is mounted vs. unmounted. > Maybe we should think about that deeply, first, too :-) Well, as far as the jobs go, there are no choices. As soon as they are=20 created, the partitions that are going to be affected are marked busy and= =20 mounting/unmounting and modification requests must fail. That point is, that the jobs are only created when the modifications are=20 committed. Until then, we are free to mount/unmount would-be affected=20 partitions. [...] > > > So, perhaps a hybrid approach is the best solution: When one has > > > already > > > called PrepareModifications() on the device, the Mount() and > > > Unmount() > > > invocations will take effect after the modifications are committed, > > > otherwise the mounting/unmounting is done immediately. > > > > > > Mmh, maybe that's confusing? It would make the mount/unmount > > > handling in > > > the disk device manager a bit more complicated, but as far as I can > > > judge > > > it at the moment, it should be feasible. > > I don't like the hybrid in general. I think I would rather see > > Mount() and > > Unmount() follow the rules like everybody else. For Mount() at least, > > I > > don't see any gain in making it work in two different ways. For > > Unmount(), > > though, perhaps the hybrid approach would be worth the effort, just > > to > > allow a partition to be unmounted even if jobs are being prepared for > > it. >=20 > Is it really hybrid? It sounds like Mount()/Unmount() would just call > PrepareModifications() if needed themselves. I didn't think of that. That would also be where the synchronous=20 CommitModifications() mode would come handy... in case anyone still=20 remembers the discussion about that. ;-) The drawback of that approach -- if one considers it one -- is that one=20 cannot mount/unmount a partition when another app is preparing=20 modifications for the same disk device. > Which would kinda be the > job of mount()/unmount(). Here you lost me. > But I think it's often (for the user) more appropriate to fail the > mounting process in that moment (as Tyler suggested, methinks). OK. I imagine an error message like `An error occured: General OS error.'= =20 Alright, just kidding... ;-) > > > Oh, there's still the general question whether the user has to > > > Unmount() > > > the concerned partition explicitely, when e.g. CanResize() > > > reported, that > > > it works only when the partition is unmounted, or whether Resize() > > > would > > > automagically do the unmounting (or at least mark the partition to > > > be > > > unmounted). > > Perhaps an unmount call should just be placed in from of the > > offending job > > in the job queue when it's built. What I was thinking of, was, that when a job gets executed, it would itse= lf=20 first invoke the respective Validate*() hooks of the disk system again an= d=20 learn, if the disk system needs a currently mounted partition unmounted, = or=20 if something's fishy and it should rather fail on the spot. So, if it realizes that the partition is mounted, but the disk system can= =20 only operate on it when unmounted, it could either a) unmount the partiti= on=20 or b) fail. The problem with a) is, that it's a bit beyond the control of= =20 the user. If, as Axel says, unmounting would always work not heeding=20 pending vnodes, then the user might risk losing data, I suppose. > > Of course, if the user if playing > > MP3s or > > whatever off the partition at the time, we'd need a way to notify the > > user > > to stop using the partition so it may be unmounted for processing. >=20 > That won't be necessary - the VFS will be able to unmount partitions at > any time; open descriptors won't prevent that any longer, they will > just be invalidated - and since that's the only connection to the file > anyway... Cool feature. :-) It must be used with care, I believe, for one gambles with the user's dat= a. > > So, to sum up, I think I would prefer to use "on commit" semantics > > and try > > and get the rest of the system to work reasonably and logically > > within the > > normal DiskDevice job framework, with perhaps the exception of > > allowing > > hybrid semantics with Unmount() to allow unmounting while jobs are > > being > > prepped. What do you think? I don't really like having different semantics for Mount() and Unmount().= =20 Either both should have the hybrid semantics or neither one should. > What would we gain because of the latter?` Obviously that one can unmount a partition, while another app is preparin= g=20 modifications for the same disk device (mind you, it doesn't even need to= =20 be the same partition, nor does it play a role whether any changes have=20 been made at all, yet). Just to throw another alternative onto the pitch: The Mount()/Unmount()=20 methods could have a boolean parameter indicating whether the operation=20 shall be carried out immediately or being queued. Not sure, if that makes= =20 any sense in case of Mount(), though. Usually invoking the modifying=20 methods on a BPartition object indeed immediately changes the object.=20 That's a bit complicated for Mount(), since one can't get a valid dev_t=20 until the partition is really mounted. So, maybe only a `bool immediately =3D true' parameter for Unmount(), whi= le=20 Mount() would always work immediately and fail, if the partition was=20 modified? CU, Ingo