libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2009-2011, 2013 Peter Miller 00004 * Written by Peter Miller <pmiller@opensource.org.au> 00005 * 00006 * This program is free software; you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 3 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but WITHOUT 00012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00014 * License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <libexplain/ac/errno.h> 00021 #include <libexplain/ac/linux/fs.h> 00022 #include <libexplain/ac/sys/ioctl.h> 00023 00024 #include <libexplain/buffer/einval.h> 00025 #include <libexplain/buffer/fildes_not_open_for_writing.h> 00026 #include <libexplain/buffer/int64_t.h> 00027 #include <libexplain/iocontrol/blkdiscard.h> 00028 #include <libexplain/iocontrol/generic.h> 00029 #include <libexplain/string_buffer.h> 00030 00031 00032 #ifdef BLKDISCARD 00033 00034 static void 00035 print_data(const explain_iocontrol_t *p, explain_string_buffer_t *sb, 00036 int errnum, int fildes, int request, const void *data) 00037 { 00038 (void)p; 00039 (void)errnum; 00040 (void)fildes; 00041 (void)request; 00042 explain_buffer_uint64_array(sb, data, 2); 00043 } 00044 00045 00046 static void 00047 print_explanation(const explain_iocontrol_t *p, explain_string_buffer_t *sb, 00048 int errnum, int fildes, int request, const void *data) 00049 { 00050 switch (errnum) 00051 { 00052 case EBADF: 00053 if (explain_buffer_fildes_not_open_for_writing(sb, fildes, "fildes")) 00054 goto generic; 00055 break; 00056 00057 case EFAULT: 00058 goto generic; 00059 00060 case EINVAL: 00061 { 00062 const uint64_t *u; 00063 uint64_t start; 00064 uint64_t len; 00065 00066 u = data; 00067 start = u[0]; 00068 len = u[1]; 00069 if (start & 511) 00070 explain_buffer_einval_multiple(sb, "data[0]", 512); 00071 else if (len & 511) 00072 explain_buffer_einval_multiple(sb, "data[1]", 512); 00073 else 00074 { 00075 explain_buffer_einval_too_large(sb, "data[0] + data[1]"); 00076 #if defined(BLKGETSIZE64) 00077 { 00078 uint64_t dev_size_bytes; 00079 00080 if (ioctl(fildes, BLKGETSIZE64, &dev_size_bytes) >= 0) 00081 { 00082 explain_string_buffer_printf 00083 ( 00084 sb, 00085 " (%llu > %llu)", 00086 (unsigned long long)start + len, 00087 (unsigned long long)dev_size_bytes 00088 ); 00089 } 00090 } 00091 #elif defined(BLKGETSIZE) 00092 { 00093 unsigned long nblocks; 00094 00095 if (ioctl(fildes, BLKGETSIZE, &nblocks) >= 0) 00096 { 00097 explain_string_buffer_printf 00098 ( 00099 sb, 00100 " (%llu > %llu)", 00101 (unsigned long long)start + len, 00102 (unsigned long long)nblocks << 9 00103 ); 00104 } 00105 } 00106 #endif 00107 } 00108 } 00109 break; 00110 00111 case EOPNOTSUPP: 00112 goto generic; 00113 00114 case ENOMEM: 00115 goto generic; 00116 00117 case EIO: 00118 goto generic; 00119 00120 default: 00121 generic: 00122 explain_iocontrol_generic.print_explanation(p, sb, errnum, fildes, 00123 request, data); 00124 break; 00125 } 00126 } 00127 00128 00129 const explain_iocontrol_t explain_iocontrol_blkdiscard = 00130 { 00131 "BLKDISCARD", /* name */ 00132 BLKDISCARD, /* value */ 00133 0, /* disambiguate */ 00134 0, /* print_name */ 00135 print_data, 00136 print_explanation, 00137 0, /* print_data_returned */ 00138 sizeof(uint64_t[2]), /* data_size */ 00139 "uint64_t[2]", /* data_type */ 00140 IOCONTROL_FLAG_SIZE_DOES_NOT_AGREE, /* flags */ 00141 __FILE__, 00142 __LINE__, 00143 }; 00144 00145 #else /* ndef BLKDISCARD */ 00146 00147 const explain_iocontrol_t explain_iocontrol_blkdiscard = 00148 { 00149 0, /* name */ 00150 0, /* value */ 00151 0, /* disambiguate */ 00152 0, /* print_name */ 00153 0, /* print_data */ 00154 0, /* print_explanation */ 00155 0, /* print_data_returned */ 00156 0, /* data_size */ 00157 0, /* data_type */ 00158 0, /* flags */ 00159 __FILE__, 00160 __LINE__, 00161 }; 00162 00163 #endif /* BLKDISCARD */ 00164 00165 00166 /* vim: set ts=8 sw=4 et : */