[Ocfs2-tools-devel] [PATCH 4/6] O2info: Add running codes for '--fs-features'.

tristan tristan.ye at oracle.com
Sun Apr 25 23:35:46 PDT 2010


Joel Becker wrote:
> On Fri, Apr 23, 2010 at 03:34:53PM -0700, Sunil Mushran wrote:
>   
>>> +	rc = ioctl(fd, OCFS2_IOC_INFO, &info);
>>> +	if (rc) {
>>> +		rc = errno;
>>> +		o2i_error(op, "ioctl failed: %s\n", strerror(rc));
>>> +		goto out;
>>> +	}
>>> +
>>> +	if (oif.if_req.ir_flags & OCFS2_INFO_FL_FILLED) {
>>> +		ofs->compat = oif.if_compat_features;
>>> +		ofs->incompat = oif.if_incompat_features;
>>> +		ofs->rocompat = oif.if_ro_compat_features;
>>> +	}
>>> +
>>> +out:
>>> +	return rc;
>>> +}
>>>   
>>>       
>> What happens if rc == 0 and flags is not FILLED. Best if
>> we ensure that cannot happen. As in, kernel should return
>> an error if it is not filled.
>>     
>
> 	He's correct here.  Remember, we allow !FILLED for forwards
> compatibility.  The kernel skips requests it doesn't understand rather
> than returning an error.  So if you pass N requests, you have to check
> each one to see if FILLED was set to determine whether the kernel
> understood it.  The 0 just means there was no actual error.
> 	But this brings up a good point.  As currently defined, we
> return our first error.  Imagine that we fill the first six requests out
> of an info_count of eight.  Then the seventh request has a bad pointer.
> Currently we return -EFAULT, and the caller misses the six finished
> requests.
> 	I can think of three solutions.  First, we can just leave it
> as-is - if there is any error, you get an error and assume nothing is
> filled in.
> 	Next, we could go with read(2) semantics.  Rather than returning
> 0 on success, we return the number of filled requests.  We only return
> an error if we had the error before we filled any request.  Say you have
> two requests.  The first request is successfully filled.  The second has
> a bad pointer.  You return 1.  The caller tries again passing only the
> second request.  Now they get -EFAULT.  Unknown requests are skipped.
> So if you pass in eight requests, and the call returns 4, you only
> need to walk the requests until you've found four that were FILLED.
> 	The biggest downside with this method is the same as for
> read(2): if you get a short count, you have to call again to find out
> why.
>
> --8<-------------------------------------------------------------------
> retry:
> 	rc = ioctl(fd, INFO, &info);
> 	if (rc < 0)
> 		goto error;
> 	assert(rc <= info.info_coutn);
> 	for (i = 0, seen = 0; i < rc; i++) {
> 		if (reqs[i].ir_flags & FILLED) {
> 			/* do something */
> 			seen++;
> 		}
> 	}
> 	/* Did we get to the end */
> 	if ((rc < info.info_count) && (i < info.info_count)) {
> 		info.info_requests = info.info_requests + i;
> 		info.info_count -= info.info_count;
> 		goto retry;
> 	}
> -->8-------------------------------------------------------------------
>
> 	That's pretty clunky for every user to do.  Of course, we can
> wrap in the library somewhat, so that the retry is handled by the
> library car.
> 	Finally, we could do it ASMLib style.  Add req.ir_error and
> OCFS2_INFO_FL_ERROR.  Here, we only return an error from the ioctl(2)
> when the failure was in the ioctl(2) call itself.  So the ioctl(2)
> returns 0 if it exists and the info structure is valid.  Any error on a
> particular request is set in ir_error; this causes FL_ERROR to be set.
>   

Hi Joel,

Here we only set the FL_ERROR to denote whether an error happened or 
not, we're not going to record the type of error, so why bother to add a 
new req.ir_error? can't it be just set in req.ir_flags?


> 	The caller now walks the requests and can determined that
> FL_ERROR is an error, FL_FILLED is completed, and neither means the
> request wasn't supported.
>
> Joel
>
>   




More information about the Ocfs2-tools-devel mailing list