1/* 2 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 59 21 * Temple Place - Suite 330, Boston MA 02111-1307, USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ 31 */ 32#ifndef __XFS_FREEBSD__ 33#define __XFS_FREEBSD__ 34 35#include <xfs_config.h> 36#include <xfs_compat.h> 37 38/* 39 * Some types are conditional depending on the target system. 40 * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits. 41 * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well 42 * as requiring XFS_BIG_BLKNOS to be set. 43 */ 44#define XFS_BIG_BLKNOS 1 45#define XFS_BIG_INUMS 0 46 47#include <xfs_types.h> 48#include <xfs_arch.h> 49 50#include <support/atomic.h> 51#include <support/kmem.h> 52#include <support/mrlock.h> 53#include <support/spin.h> 54#include <support/sv.h> 55#include <support/ktrace.h> 56#include <support/mutex.h> 57#include <support/rwsem.h> 58#include <support/rwlock.h> 59#include <support/sema.h> 60#include <support/debug.h> 61#include <support/move.h> 62#include <support/uuid.h> 63#include <support/time.h> 64 65#include <xfs_behavior.h> 66#include <xfs_cred.h> 67#include <xfs_vfs.h> 68#include <xfs_vnode.h> 69#include <xfs_stats.h> 70#include <xfs_sysctl.h> 71#include <xfs_iops.h> 72#include <xfs_super.h> 73#include <xfs_fs_subr.h> 74#include <xfs_buf.h> 75#include <xfs_frw.h> 76 77/* 78 * Feature macros (disable/enable) 79 */ 80#undef HAVE_REFCACHE /* Do not use refcache. */ 81#undef HAVE_SENDFILE /* sendfile(2) is available in FreeBSD. */ 82 83#ifndef EVMS_MAJOR 84#define EVMS_MAJOR 117 85#endif 86 87#define restricted_chown xfs_params.restrict_chown.val 88#define irix_sgid_inherit xfs_params.sgid_inherit.val 89#define irix_symlink_mode xfs_params.symlink_mode.val 90#define xfs_panic_mask xfs_params.panic_mask.val 91#define xfs_error_level xfs_params.error_level.val 92#define xfs_syncd_centisecs xfs_params.syncd_timer.val 93#define xfs_probe_dmapi xfs_params.probe_dmapi.val 94#define xfs_probe_ioops xfs_params.probe_ioops.val 95#define xfs_probe_quota xfs_params.probe_quota.val 96#define xfs_stats_clear xfs_params.stats_clear.val 97#define xfs_inherit_sync xfs_params.inherit_sync.val 98#define xfs_inherit_nodump xfs_params.inherit_nodump.val 99#define xfs_inherit_noatime xfs_params.inherit_noatim.val 100#define xfs_buf_timer_centisecs xfs_params.xfs_buf_timer.val 101#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val 102#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val 103#define xfs_rotorstep xfs_params.rotorstep.val 104 105#define current_cpu() smp_processor_id() 106#define current_pid() (curthread->td_proc->p_pid) 107 108#define NBPP PAGE_SIZE 109#define DPPSHFT (PAGE_SHIFT - 9) 110#define NDPP (1 << (PAGE_SHIFT - 9)) 111#define dtop(DD) (((DD) + NDPP - 1) >> DPPSHFT) 112#define dtopt(DD) ((DD) >> DPPSHFT) 113#define dpoff(DD) ((DD) & (NDPP-1)) 114 115#define NBBY 8 /* number of bits per byte */ 116#define NBPC PAGE_SIZE /* Number of bytes per click */ 117#define BPCSHIFT PAGE_SHIFT /* LOG2(NBPC) if exact */ 118 119/* number of BB's per block device block */ 120#define BLKDEV_BB BTOBB(BLKDEV_IOSIZE) 121 122/* bytes to clicks */ 123#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) 124#define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) 125#define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT) 126#define io_btoc(x) (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT) 127#define io_btoct(x) ((__psunsigned_t)(x)>>IO_BPCSHIFT) 128 129/* off_t bytes to clicks */ 130#define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) 131#define offtoct(x) ((xfs_off_t)(x)>>BPCSHIFT) 132 133/* clicks to off_t bytes */ 134#define ctooff(x) ((xfs_off_t)(x)<<BPCSHIFT) 135 136/* clicks to bytes */ 137#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) 138#define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT) 139#define io_ctob(x) ((__psunsigned_t)(x)<<IO_BPCSHIFT) 140 141#ifndef CELL_CAPABLE 142#define FSC_NOTIFY_NAME_CHANGED(vp) 143#endif 144 145#ifndef ENOATTR 146#define ENOATTR ENODATA /* Attribute not found */ 147#endif 148 149/* Note: EWRONGFS never visible outside the kernel */ 150#define EWRONGFS EINVAL /* Mount with wrong filesystem type */ 151 152/* 153 * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't 154 * return codes out of its known range in errno. 155 * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't 156 * conflict with any code we use already or any code a driver may use) 157 * XXX Some options (currently we do #2): 158 * 1/ New error code ["Filesystem is corrupted", _after_ glibc updated] 159 * 2/ 990 ["Unknown error 990"] 160 * 3/ EUCLEAN ["Structure needs cleaning"] 161 * 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace] 162 */ 163#define EFSCORRUPTED 990 /* Filesystem is corrupted */ 164 165#define SYNCHRONIZE() __compiler_membar() 166#define __return_address __builtin_return_address(0) 167 168/* 169 * IRIX (BSD) quotactl makes use of separate commands for user/group, 170 * whereas on Linux the syscall encodes this information into the cmd 171 * field (see the QCMD macro in quota.h). These macros help keep the 172 * code portable - they are not visible from the syscall interface. 173 */ 174#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */ 175#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */ 176 177/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ 178/* we may well need to fine-tune this if it ever becomes an issue. */ 179#define DQUOT_MAX_HEURISTIC 1024 /* NR_DQUOTS */ 180#define ndquot DQUOT_MAX_HEURISTIC 181 182/* IRIX uses the current size of the name cache to guess a good value */ 183/* - this isn't the same but is a good enough starting point for now. */ 184#define DQUOT_HASH_HEURISTIC files_stat.nr_files 185 186/* IRIX inodes maintain the project ID also, zero this field on Linux */ 187#define DEFAULT_PROJID 0 188#define dfltprid DEFAULT_PROJID 189 190#define FINVIS 0x0102 /* don't update timestamps - XFS */ 191 192#define howmany(x, y) (((x)+((y)-1))/(y)) 193#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 194 195#define xfs_sort(a,n,s,fn) qsort(a,n,s,fn) 196 197 198static inline int xfs_itruncate_data(void *ip, xfs_off_t off) { 199 printf ("xfs_itruncate_data NI\n"); 200 return 0; 201} 202 203/* 204 * Juggle IRIX device numbers - still used in ondisk structures 205 */ 206#define XFS_DEV_BITSMAJOR 14 207#define XFS_DEV_BITSMINOR 18 208#define XFS_DEV_MAXMAJ 0x1ff 209#define XFS_DEV_MAXMIN 0x3ffff 210#define XFS_DEV_MAJOR(dev) ((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \ 211 & XFS_DEV_MAXMAJ)) 212#define XFS_DEV_MINOR(dev) ((int)((dev)&XFS_DEV_MAXMIN)) 213#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \ 214 | (minor&XFS_DEV_MAXMIN))) 215 216#define XFS_DEV_TO_KDEVT(dev) mk_kdev(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev)) 217 218 219/* Produce a kernel stack trace */ 220 221static inline void xfs_stack_trace(void) 222{ 223 kdb_backtrace(); 224} 225 226#define xfs_statvfs_fsid(statp, mp) \ 227 ({ \ 228 (statp)->f_fsid.val[0] = /*dev2udev(mp->m_dev) */ 1; \ 229 (statp)->f_fsid.val[1] = 0; \ 230 }) 231 232 233/* Move the kernel do_div definition off to one side */ 234 235#if defined __i386__ 236/* For ia32 we need to pull some tricks to get past various versions 237 * of the compiler which do not like us using do_div in the middle 238 * of large functions. 239 */ 240static inline __u32 xfs_do_div(void *a, __u32 b, int n) 241{ 242 __u32 mod; 243 244 switch (n) { 245 case 4: 246 mod = *(__u32 *)a % b; 247 *(__u32 *)a = *(__u32 *)a / b; 248 return mod; 249 case 8: 250 { 251 unsigned long __upper, __low, __high, __mod; 252 __u64 c = *(__u64 *)a; 253 __upper = __high = c >> 32; 254 __low = c; 255 if (__high) { 256 __upper = __high % (b); 257 __high = __high / (b); 258 } 259 asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); 260 asm("":"=A" (c):"a" (__low),"d" (__high)); 261 *(__u64 *)a = c; 262 return __mod; 263 } 264 } 265 266 /* NOTREACHED */ 267 return 0; 268} 269 270/* Side effect free 64 bit mod operation */ 271static inline __u32 xfs_do_mod(void *a, __u32 b, int n) 272{ 273 switch (n) { 274 case 4: 275 return *(__u32 *)a % b; 276 case 8: 277 { 278 unsigned long __upper, __low, __high, __mod; 279 __u64 c = *(__u64 *)a; 280 __upper = __high = c >> 32; 281 __low = c; 282 if (__high) { 283 __upper = __high % (b); 284 __high = __high / (b); 285 } 286 asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); 287 asm("":"=A" (c):"a" (__low),"d" (__high)); 288 return __mod; 289 } 290 } 291 292 /* NOTREACHED */ 293 return 0; 294} 295#else 296 297#define do_div(n, base) ({\ 298 int __res; \ 299 __res = ((__u64)(n)) % (__u32)(base); \ 300 (n) = ((__u64)(n)) / (__u32)(base); \ 301 __res; }) 302 303static inline __u32 xfs_do_div(void *a, __u32 b, int n) 304{ 305 __u32 mod; 306 307 switch (n) { 308 case 4: 309 mod = *(__u32 *)a % b; 310 *(__u32 *)a = *(__u32 *)a / b; 311 return mod; 312 case 8: 313 mod = do_div(*(__u64 *)a, b); 314 return mod; 315 } 316 317 /* NOTREACHED */ 318 return 0; 319} 320 321/* Side effect free 64 bit mod operation */ 322static inline __u32 xfs_do_mod(void *a, __u32 b, int n) 323{ 324 switch (n) { 325 case 4: 326 return *(__u32 *)a % b; 327 case 8: 328 { 329 __u64 c = *(__u64 *)a; 330 return do_div(c, b); 331 } 332 } 333 334 /* NOTREACHED */ 335 return 0; 336} 337#endif 338 339#undef do_div 340#define do_div(a, b) xfs_do_div(&(a), (b), sizeof(a)) 341#define do_mod(a, b) xfs_do_mod(&(a), (b), sizeof(a)) 342 343static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y) 344{ 345 x += y - 1; 346 do_div(x, y); 347 return(x * y); 348} 349 350#endif /* __XFS_FREEBSD__ */ 351